【python】tfidfで世界各国の特徴的なキーワードを抽出してみる

目的

wikiペディアで世界各国について書かれたテキストデータを分析して、 それぞれの国の特徴的なキーワードを抽出してみる。

手順

  • gensimの準備
  • テキストデータの前処理
  • tfidf_modelを生成
  • 実験してみる

gensimの準備

一般的に、tfidfを行うのにはgensimというパッケージが使われる。 また、テキストデータを扱うのにmecabも必要。

まずはmecabをインストー

$ brew install mecab mecab-ipadic

次にpythonmecabを使うのに必要なパッケージをインストー

$ pip install mecab-python3

gensimをインストー

$ pip install gensim

テキストデータの前処理

今回の前処理は形態素解析をして名詞だけを抽出する。

使うテキストデータはwikipediaから取得してきた、世界各国について書かれた説明文。

kdy.hatenablog.com

取得してきたデータは、

日本.txt
チリ.txt
タンザニア.txt

みたいな感じで保存してある。

これらのファイルからtextデータを読み込んで名詞のみを抽出する。

import MeCab

def extract_nouns(text):
    tagger = MeCab.Tagger("-Ochasen")
    lines = tagger.parse(text).split("\n")
    nouns = [l.split("\t")[0] for l in lines if l.find("名詞") != -1]
    return nouns

もっといいやり方ありそうな気がする。。

これで各国の名詞リストができた。 そして各国の名詞リストのリストを作る。

こんな感じ。

docs = [
    ["アメリカ", "テキサス", ...],
    ["日本", "歌舞伎", ...],
    ...
]

以上が前処理。

tfidf_modelを生成

流れは、

  1. docsからdictionary作成
  2. dictionaryとdocsからcorpusを作成
  3. corpusからtfidf_modelを生成
  4. tfidf_modelを用いて各ドキュメントにおける単語ごとのtfidf値を計算する
from gensim import corpora, models

# dictionaryは各単語にidが割り振られたもの
dictionary = corpora.Dictionary(docs)
# corpusは各ドキュメントにどの単語が何回含まれているかカウントしたもの
corpus = [dictionary.doc2bow(doc) for doc in docs]
# tfidf_modelを生成
tfidf = models.TfidfModel(corpus)
# 各ドキュメントにおける単語ごとのtfidf値を計算
tfidf_values = [tfidf[x] for x in corpus]

実験してみる

計算した値を見てみると、単語のidとtfidf値が入っている

tfidf_values[0] = [
    (0, 0.9132503121273562),
    (1, 0.0037954215381356105),
    (2, 0.001606577372285196),
    (3, 0.021411927133364605),
    (4, 0.032117890700046905),
    (5, 0.00042249072410897783),
    ...
]

これじゃあよく分からないので、分かりやすいように変換。

具体的には、

  • ドキュメント毎にtfidf値上位20件の単語を抽出する
  • 単語idを単語に変換
  • 国名をkeyにしたdictにする

をした。

topics = {}
for country_name, values in zip(countries, tfidf_values):
    top20_values = sorted(values, key=lambda x: -x[1])[:20]
    topics[country_name] = {dictionary.get(k): v for k, v in top20_values}

完成!

再び実験

まずは我らがジャポン。

In [16]: sorted(topics["日本"].items(), key=lambda x: -x[1])
Out[16]:
[('平成', 0.20201770858956575),
 ('昭和', 0.16806236299803576),
 ('', 0.16476257462909494),
 ('琉球', 0.16053789322834894),
 ('天皇', 0.14507211984602714),
 ('>', 0.13761147979713498),
 ('倭国', 0.1334366425394185),
 ('日本書紀', 0.1301688298870359),
 ('」-', 0.1188498012012067),
 ('九州大学', 0.11319028685829208),
 ('沖縄', 0.11181114820192148),
 ('列島', 0.11117604373803007),
 ('所蔵', 0.10984171641939662),
 ('朝鮮', 0.10601424142594291),
 ('明治', 0.09979678569121815),
 ('', 0.09960583630066722),
 ('アイヌ', 0.09884195743660629),
 ('ヤマト', 0.09621174382954828),
 ('政令', 0.0950129439446579),
 ('附属', 0.09497115891577232)]

ふむふむ

次にイタリア

In [18]: sorted(topics["イタリア"].items(), key=lambda x: -x[1])
Out[18]:
[('イタリア', 0.6384797473274801),
 ('Italy', 0.1706914498606513),
 ('ミラノ', 0.16002323424436057),
 ('マフィア', 0.12365853620609034),
 ('ローマ', 0.10780564559223393),
 ('フィレンツェ', 0.10680423990969665),
 ('シチリア', 0.10319396907929852),
 ('ナポリ', 0.09601394054661636),
 ('カラビニエリ', 0.09345370992098458),
 ('ヴェネト', 0.0816072462990336),
 ('トスカーナ', 0.0816072462990336),
 ('サルデーニャ', 0.0797266087738087),
 ('ジェノヴァ', 0.07180690936238167),
 ('カラブリア', 0.06675264994356041),
 ('北イタリア', 0.06400929369774423),
 ('トリノ', 0.06283104569208396),
 ('', 0.06183303037242836),
 ('アドリア海', 0.06019648196292414),
 ('ムッソリーニ', 0.058290890213595424),
 ('ローマ帝国', 0.056789343996432505)]

ふむふむ

最後に北朝鮮

In [35]: sorted(topics["朝鮮民主主義人民共和国"].items(), key=lambda x: -x[1])
Out[35]:
[('北朝鮮', 0.5856926222951162),
 ('朝鮮', 0.4146451308891748),
 ('朝鮮民主主義人民共和国', 0.3281019474905615),
 ('', 0.2031771107167868),
 ('日成', 0.19871240504291468),
 ('平壌', 0.1951639692385769),
 ('正日', 0.13313183269492182),
 ('韓国', 0.12182239506873974),
 ('朝鮮半島', 0.1010844240425654),
 ('労働党', 0.10008468935542882),
 ('', 0.08547320261973776),
 ('', 0.07291249805294742),
 ('大韓民国', 0.06973664606281749),
 ('', 0.06686809714616936),
 ('ウォン', 0.06032340867374195),
 ('朝鮮人民軍', 0.058448121670941294),
 ('中国', 0.05782157995245687),
 ('', 0.05763953131590944),
 ('委員', 0.05697402977425215),
 ('開城', 0.056889591000700304)]

核!!!( ゚д゚)

以上

tfidf、サクッと簡単にできてそれっぽい分析ができるな〜