蛇使いな彼女BLOG
【第136回】キーフレーズ抽出の実行
2025.09.05

【冒頭あいさつ】
9月になりましたが、まだまだ暑いですね。
今年も11月ごろまで残暑が続くなんて言われてましたが、相当体に堪えます。
皆さんしっかり休息をとってお過ごしください。
さて、今日は前回インストールしたkeyphrase_extractorsについて、サンプルコードが実行できるか試してみたいと思います。
実は当初keyphrase_extractorsではなく、KeyBERTを使おうと計画していたんですが、
既存のTensorFlowバージョンが原因でインポートエラーになったため、急遽代替としてこちらをインストールしました。
ですが、poetryのおかげでまるっと関連ライブラリを移植できたので、
keyphrase_extractorsをインストールしたつもりが、結果的にKeyBERTも一緒にインストールできていたようです。
from keybert import KeyBERT model = KeyBERT() doc = "Genius is one percent inspiration and ninety-nine percent perspiration." keywords = model.extract_keywords(doc, top_n=5) print(keywords)
>>> print(keywords)
[('inspiration', 0.4589), ('genius', 0.3993), ('perspiration', 0.3964), ('percent', 0.3208), ('ninety', 0.2292)]
>>>
KeyBERTは単語と文章のコサイン類似度から重要度を割り出していて、
「天才とは、1%のひらめきと 99%の努力です。」に対して、「ひらめき」「天才」などが関連キーワードであることを示しています。
一見画期的に思えますが、KeyBERTの欠点は長文に対して効果が薄いことや、日本語に対応していない点などいくつか挙げられます。
試しに以下の日本語をモデルに入力してみると…
doc = "天才とは、1%のひらめきと 99%の努力です。"
>>> print(keywords)
[('のひらめきと', 0.721), ('天才とは', 0.7165), ('の努力です', 0.5947), ('99', 0.2065)]
>>>
結果、助詞が混じるし、さっきと比べてなんか数値おかしくない?(笑)
他にも調べるとたくさん問題が出てきますが、
このような欠点を改善するために様々な方法が研究されており、
keyphrase_extractorsもそのうちの1つで比較的新しいツールです。
それではKeyBERT同様、keyphrase_extractorsでも埋め込みモデルのサンプルコードを使って検証します。
from keyphrase_extractors import ( EmbeddingModel, EmbeddingPrompts, SentenceEmbeddingBasedExtractor, ) from keyphrase_extractors.embedding_based import SentenceEmbeddingBasedExtractionConfig input_text = "天才とは、1%のひらめきと 99%の努力です。" embedding_model_config = EmbeddingModel( name="cl-nagoya/ruri-base", device="cpu", prompts=EmbeddingPrompts(query="クエリ: ", passage="文章: "), trust_remote_code=True, batchsize=32, show_progress_bar=False, ) extraction_config = SentenceEmbeddingBasedExtractionConfig( diversity_mode="normal", max_filtered_phrases=30, max_filtered_sentences=30, threshold=0.7, filter_sentences=True, grammar_phrasing=True, ngram_range=None, use_masked_distance=False, minimum_characters=100, ) extractor = SentenceEmbeddingBasedExtractor( model_config=embedding_model_config, extraction_config=extraction_config, max_characters=10000, stop_words=None, flat_output=True, use_order=False, logger=None, ) keyphrases = extractor.get_keyphrase(input_text=input_text, top_n_phrases=30) print("cl-nagoya/ruri-base") print(keyphrases.keyphrases) print("-" * 80)
元のサンプルコードのコピペですが、1か所変更点があるので、先に説明しておきます。
12行目のEmbeddingModelで、 device="mps"→device="cpu" に書き換えていますが、
そもそもdevice=“mps” はAppleのみに対応しているそうで、そのまま実行するとWindowsではランタイムエラーになります。
RuntimeError: PyTorch is not linked with support for mps devices
以前PyTorchでGPUの利用やCUDA というソフトウェアのインストールがどうとか話していたと思いますが、
小規模プロジェクトであればCPUでも十分動くことが分かっているので、ディバイスを持っていない人はこの設定を書き換えましょう。
>>> print(keyphrases.keyphrases)
[[Keyphrase(phrase='天才', score=0.03278688524590164), Keyphrase(phrase='ひらめき', score=0.03252247488101534), Keyphrase(phrase='努力', score=0.032266458495966696), Keyphrase(phrase='1', score=0.032018442622950824), Keyphrase(phrase='%', score=0.03177805800756621), Keyphrase(phrase='99', score=0.031544957774465976)]]
--------------------------------------------------------------------------------
結果、keyphrase_extractorsの結果は助詞が含まれておらず、スコアも修正もされていますね。
終わりに
今回は埋め込みモデルに焦点を当てましたが、
最近はどこの企業も生成AIが主流になってきている?(個人的な意見です)ことから、
通常業務でもLangrilaのようにAzure OpenAIや Geminiのような大規模言語モデルをAPI経由で呼び出して処理するのが当たり前になるんですかね~🤔。
そういう意味ではDBの中身をガラッと変える必要があったり、システムの連携を図っている会社は大なり小なりどこも過渡期な気がします。