テキストマイニングの手法を試してみた
参考サイトを見ながらテキストマイニングの手法である感情分析、 "ワードクラウド、共起ネットワークを試したのでまとめました。
コードの詳細はこちら。
データセットはlivedoorニュースを使用しています。
分かち書きにはインストールが楽な Janome を使っています。
感情分析
感情分析とは、書かれた文章の意見がポジティブな意見なのか、ネガティブな意見なのか、それともニュートラルなのかを、一連の単語から判断し、分類する手法です。
tokenizer = AutoTokenizer.from_pretrained("daigo/bert-base-japanese-sentiment")
model = AutoModelForSequenceClassification.from_pretrained(
"daigo/bert-base-japanese-sentiment"
)
sentiment_analyzer = pipeline("sentiment-analysis",
model="daigo/bert-base-japanese-sentiment",
tokenizer="daigo/bert-base-japanese-sentiment"
)
target = df[0].split('。')
list(map(sentiment_analyzer, target))
[[{'label': 'ネガティブ', 'score': 0.569209098815918}],
[{'label': 'ネガティブ', 'score': 0.5467233061790466}],
[{'label': 'ポジティブ', 'score': 0.9214903712272644}],
[{'label': 'ポジティブ', 'score': 0.6558299660682678}],
[{'label': 'ポジティブ', 'score': 0.6881355047225952}],
[{'label': 'ポジティブ', 'score': 0.9059264659881592}],
[{'label': 'ポジティブ', 'score': 0.9445911049842834}],
[{'label': 'ポジティブ', 'score': 0.9561293721199036}],
[{'label': 'ポジティブ', 'score': 0.9077903628349304}],
[{'label': 'ネガティブ', 'score': 0.5847344994544983}],
(略)
テキストごとにポジティブ、ネガティブのラベルとスコアをDataFrameにまとめるとこんな感じです。
ポジティブ、ネガティブのラベルごとにグラフ化するとわかりやすくなりますね。
ワードクラウド
ワードクラウドとは、文章中で出現頻度が高い単語を複数選び出し、その頻度に応じた大きさで図示する手法でです。
wordcloud = WordCloud(
background_color='white', # 背景色
font_path="ipaexg00401/ipaexg.ttf", # ダウンロードしたフォントのパス
width=1000, # 横幅
height=500, # 高さ
)
t = Tokenizer()
fig = plt.figure(figsize=(10,5))
tokens = t.tokenize(df[0])
noun_space = ' '.join(map(str, list([token.surface for token in tokens])))
wordcloud.generate(noun_space)
plt.imshow(wordcloud)
plt.axis('off')
plt.show() # 表示
plt.tight_layout()
「という」や「ある」といった無駄なワードが目立ちます。
正規表現等で削除すればより必要な情報が得られそうです。
共起ネットワーク
共起ネットワークとは、個々人のコメント間の共通性をネットワーク図にして示す方法です。
token_filters = [
POSKeepFilter(['名詞']) # 名詞を抽出
]
analyzer = Analyzer(token_filters=token_filters)
noun_list = list([token.surface for token in analyzer.analyze(df[0])])
pair_list = list(itertools.combinations(
[n for n in noun_list if len(noun_list) >=2], 2)
)
cnt_pairs = Counter(pair_list)
# 上位50件を抽出
tops = sorted(
cnt_pairs.items(),
key=lambda x: x[1], reverse=True
)[:50]
# 重み付きデータの生成
noun_1 = []
noun_2 = []
frequency = []
# データフレームの作成
for n,f in tops:
noun_1.append(n[0])
noun_2.append(n[1])
frequency.append(f)
df_G = pd.DataFrame({'前出名詞': noun_1, '後出名詞': noun_2, '出現頻度': frequency})
# 重み付きデータの設定
weighted_edges = np.array(df_G)
# グラフオブジェクトの生成
G = nx.Graph()
# 重み付きデータの読み込み
G.add_weighted_edges_from(weighted_edges)
# ネットワーク図の描画
plt.figure(figsize=(10,5))
nx.draw_networkx(G,
node_shape = "s",
node_color = "c",
node_size = 500,
edge_color = "gray",
font_family = "IPAexGothic" # フォントの指定
);
plt.show()
こんな感じで単語の関係をネットワークで確認することができます。
以上になります、最後までお読みいただきありがとうございました。
Discussion