PHPで2つの文章の類似度を計算する(API Ninjas版)

(1/1)
PHPで2つの文章の類似度を計算する」「PHPで2つの文章の類似度を計算する(KAKASI版)」「PHPで2つの文章の類似度を計算する(MeCab版)」「PHPで2つの文章の類似度を計算する(WebAPI版)」で、PHPの組み込み関数  similar_text  や N-gram、「KAKASI」による形態素解析を利用して、異なる2つの文章の類似度を計算する方法を紹介した。
今回は、gAPI Ninjasが提供する無償クラウドサービス「Text Similarity API」を利用し、2つの文章の類似度を計算プログラムを作ってみることにする。

(2026年1月24日)PHP8.5対応:curl_closeを使わない
(2025年8月13日).pahooEnv 導入,入力バリデーション強化
(2025年7月21日)利用するクラウドサービスをAPI Ninjasに変更

目次

実行例

PHPで2つの文章の類似度を計算する(API Ninjas版)

サンプル・プログラム

圧縮ファイルの内容
TextPairSimilarity.phpサンプル・プログラム本体
.pahooEnvクラウドサービスを利用するためのアカウント情報などを記入する .env ファイル。
使い方は「各種クラウド連携サービス(WebAPI)の登録方法」を参照。include_path が通ったディレクトリに配置すること。
pahooInputData.phpデータ入力に関わる関数群。
使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。
TextPairSimilarity.php 更新履歴
バージョン 更新日 内容
2.2.0 2026/01/24 PHP8.5対応:curl_closeを使わない
2.1.0 2025/08/13 .pahooEnv 導入,入力バリデーション強化
2.0.0 2025/07/21 利用するクラウドサービスをAPI Ninjasに変更
1.1 2022/02/12 PHP8対応,リファラ・チェック改良
1.0 2020/03/30 初版
pahooInputData.php 更新履歴
バージョン 更新日 内容
2.0.1 2025/08/11 getParam() bug-fix
2.0.0 2025/08/11 pahooLoadEnv() 追加
1.9.0 2025/07/26 getParam() 引数に$trim追加
1.8.1 2025/03/15 validRegexPattern() debug
1.8.0 2024/11/12 validRegexPattern() 追加

準備:各種初期値

TextPairSimilarity.php

  51: // 各種定数(START) ===========================================================
  52: 
  53: // 表示幅(ピクセル)
  54: define('WIDTH', 600);
  55: 
  56: // API Ninjas API Key
  57: // https://api-ninjas.com/profile にて登録したら,
  58: // .pahooEnv ファイルもしくは下記定数に直接記入する.
  59: if (isset($_ENV['PAHOO_NINJAS_API_KEY'])) {
  60:     define('NINJAS_API_KEY', $_ENV['PAHOO_NINJAS_API_KEY']);
  61: else {
  62:     define('NINJAS_API_KEY', '');
  63: }
  64: 
  65: // 入力テキストの初期値
  66: define('DEF_TEXT1',  '東京都内で新型コロナ・ウイルスの感染が拡大している。');
  67: define('DEF_TEXT2',  '東京都は新型コロナ・ウイルスの感染者を新たに65人以上確認した。');
  68: 
  69: // 入力テキストの最小長
  70: define('MIN_TEXT_LENGTH', 10);
  71: // 入力テキストの最大長
  72: define('MAX_TEXT_LENGTH', 400);
  73: 
  74: // Text Similarity API【変更不可】
  75: define('TEXT_SIMILARITY_URL', 'https://api.api-ninjas.com/v1/textsimilarity');
  76: 
  77: // 各種定数(END) =============================================================

API Ninjasが提供するクラウドサービスを利用するために、API Key を入手する必要がある(無料)。入手手順は「各種WebAPIの登録方法 - API Ninjas」を参照のこと。
取得したアプリケーションIDは、.pahooEnv に設定するか、定数 NINJAS_API_KEY に直接代入する。

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

API Ninjas:Text Similarity API

API Ninjas:Text Similarity API」は、API Key をHTTPヘッダに、比較するテキストを JSON形式のデータに変換してPOSTで渡し、出力結果が JSONで戻るという [REST API:blu] である。
クラウドサービスのURL
URL
https://api.api-ninjas.com/v1/textsimilarity

HTTPヘッダ
フィールド名 要否 内  容
Content-Type 必須 "application/json"
X-Api-Key 必須 API Key
入手手順は「各種WebAPIの登録方法 - API Ninjas」参照。無料
POSTデータ(JSON)
フィールド名 要否 内  容
text1 必須 1つ目の比較対象テキスト。UTF-8エンコード。
text2 必須 2つ目の比較対象テキスト。UTF-8エンコード。

応答データ(JSON形式)

{
    "similarity": 0.8506996631622314
}
similarity(類似度スコア)は、-1.0から +1.0の範囲の小数で、0に近いほど類似度が低く、1に近いほど類似度が高い。
Text Similarity API では、まず、受け取ったテキストの意味的特徴を数値化したベクトル(数値の配列)に変換する。この変換は「埋め込み(Embedding)」と呼ばれ、大規模言語モデルを用いる。1つの文を表現するのに768次元ベクトル、すなわち768個の数値を用いる。
埋め込みによって得られた2つの768次元ベクトルが、どれだけ同じ方向を向いているかを、コサイン類似度により求める。計算式は次の通り。 $$ \displaystyle cos(\theta) = \frac{A \times B}{\|A\| \times \|B\|} \\ \begin{align*} \\ A \times B &: \verb| ベクトルの内積| \\ \|A\| &: \verb| ベクトルの長さ(ノルム)| \end{align*} $$

解説:Text Similarity API 呼び出し

TextPairSimilarity.php

 141: /**
 142:  * 「gooラボ テキストペア類似度API」を用いてテキストを比較する
 143:  * @param   string $text1, $text2 比較するテキスト
 144:  * @param   string $errmsg        エラー・メッセージ格納用
 145:  * @return  int テキストペア類似度(0.0~1.0):1に近いほど類似度が高い
 146: */
 147: function getTextPairSimilarity($text1, $text2, &$errmsg) {
 148:     $errmsg = '';
 149:     $url = TEXT_SIMILARITY_URL;
 150:     // HTTPヘッダ
 151:     $headers = [
 152:         'Content-Type: application/json',
 153:         'X-Api-Key: ' . NINJAS_API_KEY,
 154:     ];
 155:     // POSTデータ
 156:     $data = [ 'text_1' => $text1, 'text_2' => $text2 ];
 157:     $post  = json_encode($data);
 158: 
 159:     // cURL送信
 160:     $ch = curl_init();
 161:     curl_setopt($ch, CURLOPT_URL , $url);
 162:     curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
 163:     curl_setopt($ch, CURLOPT_HEADER, FALSE); 
 164:     curl_setopt($ch, CURLOPT_POST, TRUE);
 165:     curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); // 結果を文字列で
 166:     curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
 167:     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
 168:     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
 169:     curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
 170:     curl_setopt($ch, CURLOPT_TIMEOUT, 5);
 171: 
 172:     // レスポンス処理
 173:     $response = curl_exec($ch);
 174:     $items = json_decode($response, TRUE);
 175:     $httpStatusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
 176:     // PHP8.5:非推奨関数
 177:     if (PHP_VERSION_ID < 80500) {
 178:         curl_close($ch);
 179:     }
 180:     if ($httpStatusCode !200) {
 181:         $errmsg = 'APIエラー';
 182:         if (isset($items['error'])) {
 183:             $errmsg .= (' > ' . $items['error']);
 184:         }
 185:         return FALSE;
 186:     }
 187: 
 188:     // コサイン類似度
 189:     return $items['similarity'];
 190: }

API Ninjas:Text Similarity API」を呼び出すために、ユーザー関数 getTextPairSimilarity を用意した。

テキスト比較の実行例

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

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

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

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

参考サイト

(この項おわり)
header