小説を読もうの累計ランキングをDoc2Vecで解析する その2の続き。
前回累積ランキングのクラスターを目視で確認をしたが、それぞれの特徴を的確に捉えることは出来なかった。今回はクラスターの特徴をTF-IDFを使って抽出してみる。
TF-IDFで分析する
今回もscikit-learnのライブラリを使用する。
import csv
from sklearn.feature_extraction.text import TfidfVectorizer
# 小説の本文を読み込む
with open('drive/My Drive/Colab Notebooks/syosetu/novel_datas.txt', 'r') as f:
novels = [[i, data.split('\t')[2]] for i, data in enumerate(f)]
docs = ['','','','','','']
# クラスタリング結果を読み込む
with open('drive/My Drive/Colab Notebooks/syosetu/novel_cluster.csv', 'r') as f:
reader = csv.reader(f)
for row in reader:
doc = novels[int(row[0])][1]
#doc = ' '.join(set(doc.split())) #同一タイトル内で重複削除
# クラスター毎に本文を纏める
docs[int(row[1]) - 1] += ' {0}'.format(doc)
# tf-idfの計算
vectorizer = TfidfVectorizer(max_df=0.90, max_features=100)
# 文書全体の90%以上で出現する単語は無視する
# 且つ、出現上位100までの単語で計算する
X = vectorizer.fit_transform(docs)
#print('feature_names:', vectorizer.get_feature_names())
words = vectorizer.get_feature_names()
for doc_id, vec in zip(range(len(docs)), X.toarray()):
print('doc_id:', doc_id + 1)
for w_id, tfidf in sorted(enumerate(vec), key=lambda x: x[1], reverse=True)[:20]:
lemma = words[w_id]
print('\t{0:s}: {1:f}'.format(lemma, tfidf))
実行結果は以下の通りとなった。
doc_id: 1
蔵人: 0.364076
魔物: 0.334649
ベルグリフ: 0.296258
魔王: 0.271560
アンジェリン: 0.264133
直継: 0.237363
ガリウス: 0.205239
魔術: 0.199051
lv: 0.197992
夜霧: 0.196315
マイン: 0.194641
パーティ: 0.190183
身体: 0.161838
女神: 0.156352
ハンター: 0.127054
魔族: 0.118583
メンバー: 0.107892
探索者: 0.106833
公爵: 0.104819
バス: 0.093903
doc_id: 2
魔物: 0.409209
ダリヤ: 0.387583
dp: 0.376927
ポーション: 0.287506
lv: 0.255560
lv: 0.232489
クマ: 0.227815
ゴブリン: 0.226827
聖女: 0.159725
薬草: 0.142533
魔石: 0.131330
兄さん: 0.124231
契約: 0.119544
討伐: 0.111881
加護: 0.104218
hp: 0.102685
ボックス: 0.094060
金貨: 0.082761
騎士団: 0.082761
パン: 0.079863
doc_id: 3
リアム: 0.810088
ドロップ: 0.416766
導書: 0.335092
領地: 0.152304
hp: 0.102806
殿下: 0.101409
スケルトン: 0.076152
mp: 0.049499
皇帝: 0.044091
キャラ: 0.041884
王子: 0.030461
兄さん: 0.017636
冒険: 0.011423
母さん: 0.011423
クマ: 0.010291
報酬: 0.007615
経験値: 0.007615
付与: 0.003808
契約: 0.003808
採取: 0.003808
doc_id: 4
名無し: 0.424656
スバル: 0.420209
コタロー: 0.326830
真昼: 0.262535
鑑定: 0.215285
耐性: 0.200477
ニート: 0.193944
ボーナス: 0.187787
魔物: 0.174278
ポーション: 0.166195
lv: 0.163557
ガチャ: 0.158615
ゴブリン: 0.158331
lv: 0.155643
プレイヤー: 0.132132
盗賊: 0.129854
身体: 0.105934
ユニーク: 0.091012
初期: 0.088848
キャラ: 0.084291
doc_id: 5
リーシェ: 0.737429
王子: 0.384356
アルノルト: 0.342548
殿下: 0.235180
学院: 0.227594
公爵: 0.123912
皇帝: 0.118855
バス: 0.103287
先生: 0.096089
剣士: 0.085170
訓練: 0.076434
母さん: 0.056780
学校: 0.054596
聖女: 0.053105
身体: 0.048044
それなり: 0.043677
キャラ: 0.034941
所属: 0.034941
騎士団: 0.030574
メンバー: 0.028390
doc_id: 6
魔物: 0.419558
lv: 0.318543
素材: 0.269150
幼女: 0.265192
魔術: 0.261251
レイ: 0.259408
身体: 0.239465
マイン: 0.205894
ゴブリン: 0.205821
魔石: 0.199376
爺さん: 0.186030
転移: 0.178751
万能: 0.166240
それなり: 0.112806
銀貨: 0.112292
採取: 0.104890
おじさん: 0.103126
金貨: 0.096973
美女: 0.094994
訓練: 0.094994
形態素解析をしたときに残ってしまった人名がいくつか含まれてしまっているが今回は無視する。
また、予想はしていたがサンプル数が少ないことと、似ている内容が多いため特徴がわかり難くなってしまった。それでもある程度の特徴はつかむことが出来た。
doc_id: 1
戦闘、戦争中心の話?
doc_id: 2
ダンジョン中心の話?
doc_id: 3
領地経営、内政中心の話?
doc_id: 4
ファンタジーだけど現実要素強めの話?
doc_id: 5
乙女ゲーム、内政中心の話?
doc_id: 6
戦闘、戦争は少なそう。まったり系、生産系の話?
まとめ
教師無しであるにもかかわらず、ちゃんと分類出来るのは面白い。最終的にやりたいことは自分が読みたいと思う小説を機械学習で探すことなので、今回の知見を後に生かせれば良いと思う。