小説を読もうの累計ランキングをDoc2Vecで解析する その3

小説を読もうの累計ランキングを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
  戦闘、戦争は少なそう。まったり系、生産系の話?

まとめ

教師無しであるにもかかわらず、ちゃんと分類出来るのは面白い。最終的にやりたいことは自分が読みたいと思う小説を機械学習で探すことなので、今回の知見を後に生かせれば良いと思う。

小説を読もうの累計ランキングをDoc2Vecで解析する その4へ続く。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です