テキスト類似度の調べ方(コサイン類似度の仕組みと具体例)
2つの文章がどれくらい似ているかを数値で知りたいとき、よく使われるのがコサイン類似度です。文章に含まれる単語をベクトルとして扱い、そのベクトル同士の向きの近さを0から100%で表します。たとえば同じ内容を少し言い換えただけの文章なら74%、まったく違う単語で書き直した文章なら6%といった数値が出ます。この記事では、その計算の中身と、実際の数値例を使って読み方を説明します。
どうやって計算しているか
仕組み自体は難しくありません。まず両方の文章を小文字化し、句読点を取り除いて単語ごとに分割します。次に「the」や「is」のような、それ単体では意味を持たない一文字の単語や一般的なストップワードを除きます(このストップワード辞書は現状、英語・ポルトガル語・スペイン語・フランス語・ドイツ語・イタリア語をカバーしていて、日本語のストップワード処理は入っていません。日本語テキストを試す場合はこの点を覚えておくと結果を解釈しやすくなります)。
残った単語ごとに、それぞれの文章で何回登場したかを数え、単語の出現回数を並べたベクトルを2本作ります。あとはこの2本のベクトルのコサイン類似度、つまり内積を2つのベクトルの大きさの積で割った値を計算するだけです。完全に同じ単語構成なら1(100%)に近づき、共通の単語がまったくなければ0になります。
重要なのは、これが意味を理解しているわけではないという点です。単語がどれだけ重なっているかを数えているだけで、同じことを別の言葉で表現していても、単語が違えばスコアは低くなります。この特性は後の実例でそのまま効いてきます。
実例1:言い換えただけの商品説明(重複コンテンツのリスク)
まずは、同じ商品ページを少しだけ言い換えて2つ作ってしまった、というよくあるケースです。
テキストA: “Buy affordable wireless bluetooth headphones with active noise cancellation and thirty hour battery life. Free shipping on every order today.”
テキストB: “Shop cheap wireless bluetooth headphones featuring active noise cancellation and a thirty hour battery. Enjoy free shipping on every order this week.”
このツールはどの言語のテキストでも使えますが、数値をそのまま検証できるよう、この記事の実例は英語のまま掲載しています。この2つをツールに入力すると、結果は74%(High similarity、高い類似度)になります。
内訳を見るとわかりやすいです。
| 区分 | 単語数 | 単語 |
|---|---|---|
| 両方に共通 | 13 | active, battery, bluetooth, cancellation, every, free, headphones, hour, noise, order, shipping, thirty, wireless |
| Aのみ | 4 | affordable, buy, life, today |
| Bのみ | 5 | cheap, enjoy, featuring, shop, week |
人間がざっと読めば「言い回しが違う2つの文章」に見えますが、意味を運んでいる単語のほとんどはそのまま共通しています。74%というスコアは、中間帯である「moderate(40〜69%)」を超えて、ツール自身の「high」判定のすぐ上に位置します。自分のサイト内で似たページを量産していないか確認するには、まさにこういう数値が警告になります。
実例2:同じ内容を完全に書き直した場合(このツールの盲点)
次は、実例1のテキストAと同じ内容を、単語を総取り替えして書き直した場合です。
テキストC(実例1のテキストAと同一): “Buy affordable wireless bluetooth headphones with active noise cancellation and thirty hour battery life. Free shipping on every order today.”
テキストD: “Our over ear audio devices block outside sound automatically and last more than a full day per charge, and delivery costs nothing no matter what you order.”
内容としては、ワイヤレス系のヘッドホンで、周囲の音を遮断し、バッテリーが一日中もち、送料が無料だという同じ4つのポイントを述べています。人間が読めば「言っていることは同じ」と判断するはずです。ところがツールでこの2つを比較すると、結果は6%(Low similarity、低い類似度)で、共通する単語は”order”の1語だけです。
これがこのツールの正直な弱点です。単語の重なりしか見ていないので、意味は同じでも語彙を総入れ替えされると類似度は一気に下がります。だからこのツールが得意なのは、実例1のような「急いで少し言い換えただけ」の雑な重複を見つけることであり、実例2のように丁寧に言い換えられた文章を盗用検出のように使うことはできません。高いスコアは重複の強いシグナルですが、低いスコアが出たからといって「オリジナルだ」と結論づけることはできない、と覚えておいてください。
スコアの目安
ツール内で使われている判定帯は次のとおりです。
| スコア | 判定 |
|---|---|
| 70%以上 | High similarity(高い類似度) |
| 40〜69% | Moderate similarity(中程度の類似度) |
| 1〜39% | Low similarity(低い類似度) |
| 0% | 共通する単語なし |
自分のテキストで試す
下のツールに2つの文章を貼り付けると、その場でコサイン類似度が計算されます。処理はすべてブラウザ内で完結し、入力したテキストはどこにも送信されません。
類似度を計算するには両方のテキストを入力してください
TFコサイン類似度 · ストップワード除去 · ブラウザで実行
よくある誤解と気をつけたい点
本物のAI埋め込みモデルだと思ってしまう。名前に「Embedding」とついていますが、OpenAIのtext-embedding-3のような意味理解モデルではありません。単語の出現回数だけを見るシンプルなコサイン類似度です。実例2のように、意味が同じでも語彙が違えば低スコアになるのはこのためです。
低いスコアを「重複していない証拠」として扱ってしまう。丁寧に書き直された文章は0%近くまで下がることがあり、それでも内容としては実質同じというケースは十分にあり得ます。低スコアは「言葉遣いが違う」という意味であって、「オリジナルである」という意味ではありません。
短い文と長いページを比べて、スコアが低いことに驚く。短い文の内容がそっくりそのまま長いページに含まれていても、長いページ側には他にも大量の固有の単語があるので、ベクトル全体で見ると割合が薄まり、スコアは下がります。部分一致を調べたいときはこの効果を差し引いて考える必要があります。
ストップワードが除外されていることを意識していない。一般的な単語ばかりで構成された非常に短い文章同士は、意味のある単語がほとんど残らず、正当な理由でスコアが0%になることがあります。異常な結果ではなく、仕組み上こうなります。
よくある質問
OpenAIのtext-embedding-3のような本物の埋め込みモデルと何が違いますか。
本物の埋め込みモデルは文の意味をベクトル化するので、語彙が違っても意味が近ければ高いスコアになります。このツールは単語の出現回数だけを比較するコサイン類似度で、意味は一切考慮しません。実例2で6%しか出なかったのはそのためです。
SEOの重複コンテンツ対策として、何%を超えたら注意すべきですか。
目安として70%以上の「high」帯は真剣に見直したほうがいい水準です。ただし数値だけで判断せず、共通している単語と、それぞれにしかない単語の内訳を必ず確認してください。実例1のように共通語が内容の核心部分を占めている場合は、数値以上に重複の実質が大きいことがあります。
言い換えられた盗用コンテンツも見つけられますか。
見つけられません。実例2で示したとおり、同じ内容でも語彙を総入れ替えされると6%まで下がります。このツールは「単語をそのまま使い回した雑な重複」を見つけるのには向いていますが、丁寧な言い換えによる盗用の検出には使えません。
ストップワードはスコアに含まれますか。
含まれません。一文字の単語や一般的なストップワードは比較前に取り除かれます。現状このストップワード辞書は英語・ポルトガル語・スペイン語・フランス語・ドイツ語・イタリア語をカバーしていて、日本語向けの除外リストはまだありません。
入力したテキストはサーバーに送信されますか。
送信されません。計算はすべてあなたのブラウザ内で完結し、外部には一切送られません。
入力を保存して他の人と共有できますか。
この記事に埋め込まれたツールでは共有リンクは作れません。入力内容をURLに保存して共有したい場合は、テキスト類似度計算の単体ページを開いてください。そちらでは入力済みの状態のリンクを発行できます。