PHPで2つの文章の類似度を計算する(gooラボ版)

(1/1)
PHPで2つの文章の類似度を計算する」「PHPで2つの文章の類似度を計算する(KAKASI版)」「PHPで2つの文章の類似度を計算する(MeCab版)」「PHPで2つの文章の類似度を計算する(WebAPI版)」で、PHPの組み込み関数  similar_text  や N-gram、「KAKASI」による形態素解析を利用して、異なる2つの文章の類似度を計算する方法を紹介した。
今回は、gooラボが提供するWebAPI「テキストペア類似度API」を利用し、2つの文章の類似度を計算プログラムを作ってみることにする。

(2022年2月12日)PHP8対応,リファラ・チェック改良

目次

実行例

PHPで2つの文章の類似度を計算する(gooラボ版)

サンプル・プログラム

圧縮ファイルの内容
TextPairSimilarity.phpサンプル・プログラム本体

準備:各種初期値

  33: //表示幅(ピクセル)
  34: define('WIDTH', 600);
  35: 
  36: //gooラボ アプリケーションID
  37: //https://labs.goo.ne.jp/apiregister/ にて登録のこと.
  38: define('GOOLABS_APPLICATION_ID', '***************************************');
  39: 
  40: //初期値
  41: define('DEF_TEXT1',  '東京都内で新型コロナ・ウイルスの感染が拡大している。');
  42: define('DEF_TEXT2',  '東京都は新型コロナ・ウイルスの感染者を新たに65人以上確認した。');
  43: 
  44: //gooラボ リクエストURL
  45: define('GOOLABS_TEXTPAIR_URL', 'https://labs.goo.ne.jp/api/textpair');

gooラボが提供するWebAPIを利用するために、アプリケーションIDを入手する必要がある(無料)。入手手順は「各種WebAPIの登録方法 - gooラボ」を参照のこと。
取得したアプリケーションIDは、定数 GOOLABS_APPLICATION_ID に格納する。

その他の定数は自由に変更可能である。

gooラボ:テキストペア類似度API]

gooラボ:テキストペア類似度API」は、入力パラメータ(IN)としてJSON形式のデータをPOSTで渡し、出力結果(OUT)が JSONで戻るというAPIである。
WebAPIのURL
URL
https://labs.goo.ne.jp/api/textpair

入力パラメータ(JSON)
フィールド名 要否 内  容
app_id 必須 アプリケーションID
入手手順は各種WebAPIの登録方法 - gooラボ。無料。
request_id 任意 リクエストID
省略時は”labs.goo.ne.jp[タブ文字]リクエスト受付時刻[タブ文字]連番”となる。
text1 必須 1つ目の比較対象テキスト。UTF-8エンコード。
text2 必須 2つ目の比較対象テキスト。UTF-8エンコード。
応答データ構造(json) request_id リクエストと同じ値 score テキストペア類似度
score(テキストペア類似度)は、0.0から1.0の範囲の小数で、0に近いほど類似度が低く、1に近いほど類似度が高い。ただし、単純比例では無いため、注意が必要。概ね0.6以上の数値である場合、類似度が高いと言える。

解説:JSON形式データをPOST渡し

 180: /**
 181:  * JSON形式データをPOST渡し
 182:  * @param   string $url リクエストURL
 183:  * @param   array  $data POST変数を格納した連想配列("変数名"=>"値") 
 184:  * @return  string 取得したコンテンツ/FALSE 取得エラー
 185: */
 186: function post($url, $data = array()) {
 187:     //JSON化
 188:     $data_json = json_encode($data);
 189: 
 190:     //cURL送信
 191:     $curl = curl_init();
 192:     curl_setopt($curl, CURLOPT_URL , $url);
 193:     curl_setopt($curl, CURLOPT_HEADER, 1) ; 
 194:     curl_setopt($curl, CURLOPT_POST, TRUE);
 195:     curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);   //結果を文字列で
 196:     curl_setopt($curl, CURLOPT_POSTFIELDS, $data_json);
 197:     curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
 198:     curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
 199:     curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
 200:     curl_setopt($curl, CURLOPT_TIMEOUT, 5);
 201:     $res1 = @curl_exec($curl);
 202:     $res2 = @curl_getinfo($curl);
 203:     curl_close($curl);
 204: 
 205:     //結果処理
 206:     if ($res1 !FALSE) {
 207:         $json = substr($res1, $res2['header_size']);
 208:     } else {
 209:         $json = FALSE;
 210:     }
 211: 
 212:     return $json;
 213: }

gooラボ:テキストペア類似度API」へデータを渡すために、ユーザー関数 post を用意した。
cURL関数群と、 json_encode  を利用することで実現している。
APIからの応答結果を、JSONテキストでリターンする。

解説:テキストペア類似度API呼び出し

 215: /**
 216:  * 「gooラボ テキストペア類似度API」を用いてテキストを比較する
 217:  * @param   string $text1, $text2 比較するテキスト
 218:  * @param   string $errmsg        エラー・メッセージ格納用
 219:  * @return  int テキストペア類似度(0.0~1.0):1に近いほど類似度が高い
 220: */
 221: function getTextPairSimilarity($text1, $text2, &$errmsg) {
 222:     //WebAPIにパラメータをPOST渡しする
 223:     $url = GOOLABS_TEXTPAIR_URL;
 224:     $post = array(
 225:         'app_id' => GOOLABS_APPLICATION_ID,
 226:         'text1'  => $text1,
 227:         'text2'  => $text2,
 228:     );
 229:     $score = FALSE;
 230:     $errmsg = '';
 231: 
 232:     //バージョンチェック
 233:     if (isphp5over() == FALSE) {
 234:         $errmsg = 'PHP4 以下では動作しない';
 235:     } else {
 236:         //API呼び出し
 237:         $json = post($url, $post);
 238:         if ($json == FALSE) {
 239:             $errmsg = 'WebAPIが停止';
 240:         } else {
 241:             $obj = @json_decode($json);
 242:             if (isset($obj->score))     $score = (float)$obj->score;
 243:             else                        $errmsg = 'WebAPIでトラブル発生';
 244:         }
 245:     }
 246: 
 247:     return $score;
 248: }

gooラボ:テキストペア類似度API」を呼び出すために、ユーザー関数 getTextPairSimilarity を用意した。

テキスト比較の実行例

PHPで2つの文章の類似度を計算する(KAKASI版)」と同じテキストを使って実行してみよう。

まず、「元のテキスト」として、以下のWikipediaの引用文を入れる。これは「PHP: Hypertext Preprocessor」からの抜粋である。
PHP: Hypertext Preprocessor(ピー・エイチ・ピー ハイパーテキスト プリプロセッサー)とは、動的にHTMLデータを生成することによって、動的なウェブページを実現することを主な目的としたプログラミング言語、およびその言語処理系である。
PHPは、HTML埋め込み型のサーバサイド・スクリプト言語として分類される。この言語処理系自体は、C言語で記述されている。
「比較するテキスト」には、以下の文章を入れてみよう。
PHP(Hypertext Preprocessor;ピー・エイチ・ピー)とは、動的にHTMLデータを生成することによって、動的なウェブページを実現すること目的としたプログラミング言語である。
PHPは、HTML埋め込み型のサーバサイド・スクリプト言語の一種で、処理系自体はC言語で記述されている。
結果は 0.97 である。
2つめの文章は、一見すると元の文章とは異なっているが、じつはWikipediaの引用文の順番を変えただけである。
このような違いでは、かなり高い類似度の値となる。

次に、「比較するテキスト」に以下の文章を入れて実行してみていただきたい。これは「PHPとは何か」(ぱふぅ家のホームページ)の冒頭部分である。
「PHP(Hypertext Preprocessor)」は、オープンソースのサーバ・サイド・スクリプト言語である。
サーバ・サイド・スクリプトとは、データベースサーバなどのサーバ群と Web ブラウザ(クライアント)を結ぶインターフェースの役割をするもので、Webサーバ上で動作する。HTMLに比べて、動的なページを実現することができる。
結果は 0.78 となる。
PHPで2つの文章の類似度を計算する(KAKASI版)」での、最初の比較例では 75.5%、2番目の比較例では 45.1% だった。

ちなみに、PHPとはまったく関係ない以下のテキストを「比較するテキスト」に入れてみると――
さきたま古墳公園(埼玉県行田市大字埼玉4834)は、8基の前方後円墳と1基の円墳が集中する東日本最大の古墳遺跡である。
1938年(昭和13年)8月に国の史跡の指定を受け、1968年(昭和43年)には金錯銘鉄剣(きんさくめいてっけん)が出土したことで一躍脚光を浴びた。
類似度は 0.52 になる。0.6以下ということで、類似度は低いと言えよう。
一方、KAKASI を使った結果では 9.0% だった。

参考サイト

(この項おわり)
header