本稿では、単語の出現頻度と文書間の希少性に基づくTF-IDFと、グラフベースのアルゴリズムであるTextRankを用いたキーワード抽出の実装方法を解説する。これらの手法は文脈を考慮しないが、シンプルで効率的な抽出が可能である。より高度な意味解析が必要な場合は、LDAやLSIなどのトピックモデルを検討されたい。
TF-IDFによるキーワード抽出
TF-IDF(Term Frequency-Inverse Document Frequency) は、単語の重要度を評価する統計的手法である。
各要素は以下のように定義される:
- TF(単語頻度):ある文書内における単語の出現回数を示し、その文書内での単語の重要性を反映する。
- IDF(逆文書頻度):全文書数をその単語が出現する文書数で割り、対数を取った値。多くの文書に出現する単語はIDFが小さくなり、特定の文書にしか現れない単語はIDFが大きくなる。
計算式: TF-IDF(t,d) = TF(t,d) × IDF(t)
ここで、tは単語、dは文書を表す。
主な利点:
- 文書中の重要な単語を強調し、一般的な単語を抑制できる
- 情報検索やテキスト分類など様々な用途に適用可能
- 実装が容易で計算コストが低い
- 単一文書の場合でも、文書を段落や文に分割することで適用可能
制約:
- 単語間の意味的関係や文脈を考慮しない
- 単語の順序やフレーズ構造を無視する
実装例:
import jieba
from gensim import corpora, models
# テキストを文単位に分割
full_text = (
'6月19日,《2012年度"中国爱心城市"公益活动新闻发布会》在京举行。'
'中华社会救助基金会理事长许嘉璐到会讲话。基金会高级顾问朱发忠,全国老龄'
'办副主任朱勇,民政部社会救助司助理巡视员周萍,中华社会救助基金会副理事长耿志远,'
'重庆市民政局巡视员谭明政。晋江市人大常委会主任陈健倩,以及10余个省、市、自治区民政局'
'领导及四十多家媒体参加了发布会。中华社会救助基金会秘书长时正新介绍本年度"中国爱心城'
'市"公益活动将以"爱心城市宣传、孤老关爱救助项目及第二届中国爱心城市大会"为主要内容,重庆市'
'、呼和浩特市、长沙市、太原市、蚌埠市、南昌市、汕头市、沧州市、晋江市及遵化市将会积极参加'
'这一公益活动。中国雅虎副总编张银生和凤凰网城市频道总监赵耀分别以各自媒体优势介绍了活动'
'的宣传方案。会上,中华社会救助基金会与"第二届中国爱心城市大会"承办方晋江市签约,许嘉璐理'
'事长接受晋江市参与"百万孤老关爱行动"向国家重点扶贫地区捐赠的价值400万元的款物。晋江市人大'
'常委会主任陈健倩介绍了大会的筹备情况。'
)
sentences = [s.strip() for s in full_text.split('。') if s.strip()]
# 各文を形態素解析で分割
tokenized_sent = [list(jieba.cut(s)) for s in sentences]
# 辞書の作成とBoWへの変換
word_dict = corpora.Dictionary(tokenized_sent)
bow_corpus = [word_dict.doc2bow(tokens) for tokens in tokenized_sent]
# TF-IDFモデルの学習
tfidf_model = models.TfidfModel(bow_corpus)
# TF-IDFスコアの計算
score_dict = {}
for bow_vec in tfidf_model[bow_corpus]:
for idx, score in bow_vec:
word = word_dict[idx]
score_dict[word] = score_dict.get(word, 0.0) + score
# スコア降順でソートし、上位N語を抽出
sorted_words = sorted(score_dict.items(), key=lambda x: x[1], reverse=True)
top_n = 10
print(sorted_words[:top_n])
TextRankによるキーワード抽出
TextRankは、文書内の単語間の共起関係に基づくグラフベースのランキングアルゴリズムである。jiebaライブラリに組み込みの実装が用意されている。
主なパラメータ:
topK:抽出するキーワード数(デフォルトは20)withWeight:重みスコアを出力するかどうか(True/False)allowPOS:抽出する単語の品詞を制限(デフォルトは('ns', 'n', 'vn', 'v'))withFlag:Trueの場合、単語と重みのペアリストを返す
実装例:
from jieba import analyse
full_text = (
'6月19日,《2012年度"中国爱心城市"公益活动新闻发布会》在京举行。'
'中华社会救助基金会理事长许嘉璐到会讲话。基金会高级顾问朱发忠,全国老龄'
'办副主任朱勇,民政部社会救助司助理巡视员周萍,中华社会救助基金会副理事长耿志远,'
'重庆市民政局巡视员谭明政。晋江市人大常委会主任陈健倩,以及10余个省、市、自治区民政局'
'领导及四十多家媒体参加了发布会。中华社会救助基金会秘书长时正新介绍本年度"中国爱心城'
'市"公益活动将以"爱心城市宣传、孤老关爱救助项目及第二届中国爱心城市大会"为主要内容,重庆市'
'、呼和浩特市、长沙市、太原市、蚌埠市、南昌市、汕头市、沧州市、晋江市及遵化市将会积极参加'
'这一公益活动。中国雅虎副总编张银生和凤凰网城市频道总监赵耀分别以各自媒体优势介绍了活动'
'的宣传方案。会上,中华社会救助基金会与"第二届中国爱心城市大会"承办方晋江市签约,许嘉璐理'
'事长接受晋江市参与"百万孤老关爱行动"向国家重点扶贫地区捐赠的价值400万元的款物。晋江市人大'
'常委会主任陈健倩介绍了大会的筹备情况。'
)
# TextRank抽出器の生成
tr_extractor = analyse.textrank
# 基本的な使用例:上位10語を抽出
result1 = tr_extractor(full_text, topK=10)
print("基本抽出:", result1)
# 重み付きで出力
result2 = tr_extractor(full_text, topK=10, withWeight=True)
print("重み付き:", result2)
# 特定の品詞(動詞のみ)に制限
result3 = tr_extractor(full_text, topK=10, withWeight=True, allowPOS=('v'))
print("動詞のみ:", result3)
# 単語と重みのペアリストとして取得
result4 = tr_extractor(full_text, topK=10, allowPOS=('v'), withFlag=True)
print("ペア形式:", result4)
これらの手法は単純ではあるが、多くのテキストマイニングタスクにおいて有効なベースラインとして機能する。実際のアプリケーションでは、ストップワード除去やカスタム辞書の追加などの前処理を組み合わせることで、より精度の高い抽出が可能となる。