PHP関数「similar_text」で文字列の類似性を計算できる...かも!?

PHPの標準関数「similar_text」を使うことで文字列の類似性をパーセント(百分率)で計算できる...かも。

使い方は、

similar_text(文字列1,文字列2,変数A)

とするだけなので簡単。

※変数Aには文字列1と文字列2の類似率(百分率)の数値が格納される。
※返り値は、類似した文字列の数

《実験1》
<?php
$str1 = "nneko";
$str2 = "neko";
echo "類似数:";
echo similar_text($str1,$str2,$result);
echo "<br />";
echo "類似率:";
echo $result;
echo "<br />";
?>

《結果1》
類似数:4
類似率:88.888888888889

なんかよさそうだ、と思って、色々と試してみることにする。

《実験2》
<?php
$str_array = array();
$str_array = array(
array("neko","neko"),
array("nneko","neko"),
array("noneko","neko"),
array("nobneko","neko"),
array("nobuneko","neko"),
array("nobu","neko"),
array("nebu","neko"),
array("usagi","neko"),
array("The PHP development team would like to announce the immediate availability of PHP 5.3.6.","The PHP development team would like to announce the immediate availability of PHP 5.3.5 and 5.2.17."),
array("The PHP development team is proud to announce the first PHP 5.4 alpha release.","The PHP development team would like to announce the immediate availability of PHP 5.3.5 and 5.2.17."),
array("abcdefghijklmnopqrstuvwxyz .0123456789","The PHP development team would like to announce the immediate availability of PHP 5.3.5 and 5.2.17."),
array("PHP","php"),
array("ねこ","ねこ"),
array("ねこ","こねこ"),
array("ねこ","のらねこ"),
array("ねこ","うさぎ"),
array("猫","猫"),
array("猫","野良猫"),
array("私は猫が大好きです","猫の手も借りたいほど、とても忙しい"),
array("猫","美")
);

$tmp_str = "";
$tmp_str .= "<table border=\"1\">\n";
$tmp_str .= "<tr><th>No.</th><th>文字列1</th><th>文字列2</th><th>類似数</th><th>類似率</th></tr>\n";
$cnt = 0;
foreach($str_array as $value){
$cnt++;
$tmp_str .= "<tr>";
$tmp_str .= "<td>";
$tmp_str .= $cnt;
$tmp_str .= "</td>";
$tmp_str .= "<td>";
$tmp_str .= $value[0];
$tmp_str .= "</td>";
$tmp_str .= "<td>";
$tmp_str .= $value[1];
$tmp_str .= "</td>";
$tmp_str .= "<td>";
$tmp_str .= similar_text($value[0],$value[1],$result);
$tmp_str .= "</td>";
$tmp_str .= "<td>";
$tmp_str .= $result;
$tmp_str .= "</td>";
$tmp_str .= "</tr>\n";
}
$tmp_str .= "</table>\n";
echo $tmp_str;
?>

《結果2》

No.文字列1文字列2類似数類似率
1 neko neko 4 100
2 nneko neko 4 88.888888888889
3 noneko neko 4 80
4 nobneko neko 4 72.727272727273
5 nobuneko neko 4 66.666666666667
6 nobu neko 2 50
7 nebu neko 2 50
8 usagi neko 0 0
9 The PHP development team would like to announce the immediate availability of PHP 5.3.6. The PHP development team would like to announce the immediate availability of PHP 5.3.5 and 5.2.17. 87 93.048128342246
10 The PHP development team is proud to announce the first PHP 5.4 alpha release. The PHP development team would like to announce the immediate availability of PHP 5.3.5 and 5.2.17. 57 64.406779661017
11 abcdefghijklmnopqrstuvwxyz .0123456789 The PHP development team would like to announce the immediate availability of PHP 5.3.5 and 5.2.17. 7 10.21897810219
12 PHP php 0 0
13 ねこ ねこ 4 100
14 ねこ こねこ 4 80
15 ねこ のらねこ 4 66.666666666667
16 ねこ うさぎ 2 40
17 2 100
18 野良猫 2 50
19 私は猫が大好きです 猫の手も借りたいほど、とても忙しい 6 23.076923076923
20 1 50


※実験2のNo.11は、文字列1に「abcdefghijklmnopqrstuvwxyz .0123456789」 というように、26の小文字英字、半角スペース、ピリオド、0〜9までの数値を入れただけの「文章ではない文字列」なのだが、それだけで、「文章になっている文字列2」との類似率が10%台になってしまった。

※実験2のNo.12の文字列1と文字列2は文字列の大文字、小文字が異なるだけなのだが、類似率は0%になった。

※実験2のNo.13は全角文字列2文字を比較しているのだが、類似数が4になった。全角(=2バイト)ではなく、半角(=1バイト)で比較しているから、全角文字列2文字で100%の類似率となる場合は、半角文字列4文字での類似と同じことになり、類似数4となっているのだろう。

※No.16とNo.20は、比較する文字列が全て全角文字列になっており、それら全角文字列としては一致する文字列がないため、類似率は0%になるべきなのだが、そうなっていない。全角(=2バイト)で比較しているのではなく、半角(=1バイト)で比較しているのだろう。

実験してみて分かったことは、similar_text関数は、単純に半角文字列を1文字単位で比較しているだけのようであり、文字列の並び順、組み合わせ...つまり単語や文章としては比較していないようだった。

私にとっては、返ってくる結果が、期待通りではなかったので、使用する機会はないかも。

もちろん、使い方次第では、便利な関数のように思えるので、もし、使う場合は、上記のような「期待通りではない」結果が返ってくることについて注意をしておく必要がありそうだ。

前へ

PHPサーバ変数「$_SERVER」の出力方法

次へ

Apacheエラー「DocumentRoot must be a directory」の原因と解決方法