😺

大規模コーパスから類義語を取得する方法

2025/03/03に公開

大規模なテキストコーパスから類義語を取得する方法はいくつかあります。
以下では、シンプルな統計手法から深層学習を活用した最先端の方法までを紹介します。


1. シンプルな統計手法

(1) 共起頻度を利用する

方法

  1. コーパス内で 対象の単語と一緒に出現する単語(共起語) を集める。
  2. 共起回数が多い単語を類義語の候補として扱う。

具体例

例えば、コーパスに以下のような文章があるとします。

私は美味しいケーキを食べた。
このパンはとても美味しい。
料理が美味しいと嬉しい。

「美味しい」の類義語を見つけるには、

  • 「美味しい」とよく一緒に使われる単語 を探す(例:「料理」「食べた」「嬉しい」)。
  • 「料理」に着目し、「美味しい」と同じ文脈で使われる「おいしい」「旨い」などを見つける。

メリット・デメリット

メリット: 簡単に実装可能
⚠️ デメリット: 文脈を考慮しないため、意味がズレる可能性あり


2. Word2Vec(単語埋め込み)

(2) 分散表現を用いる

方法

  1. Word2Vec で単語をベクトル表現に変換する。
  2. コサイン類似度 を用いて、ベクトルが近い単語を類義語として取得する。

実装例(Python + Gensim)

from gensim.models import Word2Vec

# サンプルデータ
sentences = [["美味しい", "ケーキ"], ["美味しい", "料理"], ["美味しい", "パン"]]

# Word2Vec モデルの学習
model = Word2Vec(sentences, vector_size=100, window=5, min_count=1, workers=4)

# 「美味しい」に類似する単語を取得
similar_words = model.wv.most_similar("美味しい", topn=5)
print(similar_words)

メリット・デメリット

メリット: 文脈を考慮できるため、より自然な類義語が得られる
⚠️ デメリット: コーパスの質に依存する(適切なデータが必要)


3. FastText(サブワード埋め込み)

(3) 未知語対応 + サブワードを活用

方法

  • FastText は Word2Vec の改良版で、サブワード(n-gram) を考慮するため、未知語でも類義語を取得しやすい。

実装例(Python + fastText)

import fasttext

# 事前学習済みのFastTextモデルをロード
model = fasttext.load_model("cc.ja.300.bin")

# 「美味しい」の類義語を取得
similar_words = model.get_nearest_neighbors("美味しい", k=5)
print(similar_words)

メリット・デメリット

メリット: 未知語にも対応できる
⚠️ デメリット: 計算コストがやや高い


4. BERTを用いた類義語取得

(4) 文脈を考慮した最先端手法

方法

  • BERT(Transformerベースのモデル) を使用し、文脈に応じた類義語を取得する。
  • 単語埋め込みを計算し、コサイン類似度が高い単語を類義語として取得。

実装例(Python + Transformers)

from transformers import BertTokenizer, BertModel
import torch
from sklearn.metrics.pairwise import cosine_similarity

# BERTモデルのロード
tokenizer = BertTokenizer.from_pretrained("cl-tohoku/bert-base-japanese")
model = BertModel.from_pretrained("cl-tohoku/bert-base-japanese")

# 単語埋め込み取得関数
def get_embedding(word):
    tokens = tokenizer(word, return_tensors="pt")
    with torch.no_grad():
        output = model(**tokens)
    return output.last_hidden_state.mean(dim=1).numpy()

# 「美味しい」と他の単語の類似度を計算
word1 = get_embedding("美味しい")
word2 = get_embedding("旨い")  # 例:比較する単語
similarity = cosine_similarity(word1, word2)
print(f"類似度: {similarity}")

メリット・デメリット

メリット: 文脈を考慮して類義語を取得できる
⚠️ デメリット: 計算コストが高い、学習済みモデルが必要


5. 構造化データを活用する

(5) 辞書や知識グラフの活用

  • 国立国語研究所の 日本語WordNet や、ConceptNet を活用すると、あらかじめ定義された類義語を取得可能。

実装例(NLTKを使用したWordNet)

from nltk.corpus import wordnet as wn

# 日本語WordNetで「美味しい」の類義語を取得
synonyms = wn.synsets("美味しい", lang="jpn")
print([syn.lemma_names("jpn") for syn in synonyms])

メリット・デメリット

メリット: 品質の高い類義語が得られる
⚠️ デメリット: カバー範囲が狭い(新しい単語には弱い)


6. まとめ

手法 特徴 メリット デメリット
共起頻度 一緒に出やすい単語を類義語とする 簡単で高速 文脈を考慮しない
Word2Vec 単語のベクトル表現を使う 文脈をある程度考慮 コーパスに依存
FastText 未知語対応の単語ベクトル 未知語にも強い 計算コスト高
BERT 文脈を考慮した最新技術 最も精度が高い 計算が重い
辞書・WordNet 事前定義された類義語を利用 高品質な類義語取得 カバー範囲が狭い

🚀 おすすめの選び方

  • 簡単に試したい共起頻度 or Word2Vec
  • 未知語も扱いたいFastText
  • 文脈を重視したいBERT
  • 辞書ベースで確実な類義語を得たいWordNet

用途に応じて適切な手法を選びましょう!🔥
さらに詳しく知りたい場合は、コードを一緒に試してみましょう!💡

Discussion