目次
実行例
サンプル・プログラム
| TextPairSimilarity.php | サンプル・プログラム本体 |
| .pahooEnv | クラウドサービスを利用するためのアカウント情報などを記入する .env ファイル。 使い方は「各種クラウド連携サービス(WebAPI)の登録方法」を参照。include_path が通ったディレクトリに配置すること。 |
| pahooInputData.php | データ入力に関わる関数群。 使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 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 | 初版 |
| バージョン | 更新日 | 内容 |
|---|---|---|
| 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) =============================================================
取得したアプリケーションIDは、.pahooEnv に設定するか、定数 NINJAS_API_KEY に直接代入する。
その他の定数は自由に変更可能である。
API Ninjas:Text Similarity API
| URL |
|---|
| https://api.api-ninjas.com/v1/textsimilarity |
| フィールド名 | 要否 | 内 容 |
|---|---|---|
| Content-Type | 必須 | "application/json" |
| X-Api-Key | 必須 | API Key 入手手順は「各種WebAPIの登録方法 - API Ninjas」参照。無料 |
| フィールド名 | 要否 | 内 容 |
|---|---|---|
| text1 | 必須 | 1つ目の比較対象テキスト。UTF-8エンコード。 |
| text2 | 必須 | 2つ目の比較対象テキスト。UTF-8エンコード。 |
応答データ(JSON形式)
{
"similarity": 0.8506996631622314
}
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: }
テキスト比較の実行例
まず、「元のテキスト」として、以下のWikipediaの引用文を入れる。これは「PHP: Hypertext Preprocessor」からの抜粋である。
PHP: Hypertext Preprocessor(ピー・エイチ・ピー ハイパーテキスト プリプロセッサー)とは、動的にHTMLデータを生成することによって、動的なウェブページを実現することを主な目的としたプログラミング言語、およびその言語処理系である。「比較するテキスト」には、以下の文章を入れてみよう。
PHPは、HTML埋め込み型のサーバサイド・スクリプト言語として分類される。この言語処理系自体は、C言語で記述されている。
PHP(Hypertext Preprocessor;ピー・エイチ・ピー)とは、動的にHTMLデータを生成することによって、動的なウェブページを実現すること目的としたプログラミング言語である。結果は 0.96 である。
PHPは、HTML埋め込み型のサーバサイド・スクリプト言語の一種で、処理系自体はC言語で記述されている。
2つめの文章は、一見すると元の文章とは異なっているが、じつはWikipediaの引用文の順番を変えただけである。
このような違いでは、かなり高い類似度の値となる。
次に、「比較するテキスト」に以下の文章を入れて実行してみていただきたい。これは「PHPとは何か」(ぱふぅ家のホームページ)の冒頭部分である。
「PHP(Hypertext Preprocessor)」は、オープンソースのサーバ・サイド・スクリプト言語である。結果は 0.91 となる。
サーバ・サイド・スクリプトとは、データベースサーバなどのサーバ群と Web ブラウザ(クライアント)を結ぶインターフェースの役割をするもので、Webサーバ上で動作する。HTMLに比べて、動的なページを実現することができる。
「PHPで2つの文章の類似度を計算する(KAKASI版)」での、最初の比較例では 75.5%、2番目の比較例では 45.1% だった。
多少の単語が変わっても、文意が同じであればコサイン類似度は高くなることがわかる。
最期に、PHPとはまったく関係ない以下のテキストを「比較するテキスト」に入れてみると――
さきたま古墳公園(埼玉県行田市大字埼玉4834)は、8基の前方後円墳と1基の円墳が集中する東日本最大の古墳遺跡である。類似度は 0.14 になった。類似度は低いと判定できる。
1938年(昭和13年)8月に国の史跡の指定を受け、1968年(昭和43年)には金錯銘鉄剣(きんさくめいてっけん)が出土したことで一躍脚光を浴びた。
KAKASI を使った結果では 9.0% だった。
参考サイト
- Text Similarity API:API Ninjas
- 各種WebAPIの登録方法:ぱふぅ家のホームページ
- PHPで2つの文章の類似度を計算する:ぱふぅ家のホームページ
- PHPで2つの文章の類似度を計算する(KAKASI版):ぱふぅ家のホームページ
- PHPで2つの文章の類似度を計算する(MeCab版):ぱふぅ家のホームページ
- PHPで2つの文章の類似度を計算する(WebAPI版):ぱふぅ家のホームページ

今回は、gAPI Ninjasが提供する無償クラウドサービス「Text Similarity API」を利用し、2つの文章の類似度を計算プログラムを作ってみることにする。
(2026年1月24日)PHP8.5対応:curl_closeを使わない
(2025年8月13日).pahooEnv 導入,入力バリデーション強化
(2025年7月21日)利用するクラウドサービスをAPI Ninjasに変更