KH Coderでツイートを分類するでツイートをKH Coderを使ってクラスタリングしてみたが、今度はPython3でやってみる。KH Coderでツイートを分類するで「スイーツ シュークリーム」「スイーツ ジェラート」「スイーツ バームクーヘン」「スイーツ どら焼き」「スイーツ たい焼き」「スイーツ 羊羹」を検索ワードとして収集したツイートを使う。mecab-ipadic-NEologdで形態素解析を新語に対応させるでインストールしたMeCabとmecab-ipadic-NEologdで形態素解析を行い、各スイーツのツイートをTF-IDFでベクトル化する。そして、ベクトル化した文章間の距離をもとにクラスタリングし、最後にデンドログラムを作成する。
Raspberry PiをJupyter Notebookサーバにするの手順でBash on Ubuntu on Windowsに構築したJupyter Notebookサーバ。
必要なPythonライブラリをインストールする。
続いて、PythonでMeCabとmecab-ipadic-NEologdを使える環境にしておく(mecab-ipadic-NEologdで形態素解析を新語に対応させるを参照)。
さらに、matplotlibで日本語を使えるようにしておく(Raspberry PiとPython3でグラフを作成する参照)。
KH Coderでツイートを分類するで収集したツイートのテキストsweets.txt(スイーツ名がH1タグで囲まれている)から、スイーツ名をインデックスとするPnadasのデータフレームを作成する。
作成したデータフレームは以下の通り。
MeCabでツイートを分かち書きして、scikit-learnのTfidfVectorizerでTF-IDFを計算する。今回は「名詞」「動詞」「形容詞」「副詞」「感動詞」のみを使う。さらに、ツイート収集時の検索ワードは使用しない。
以下のようなTF-IDFが得られる。行は各スイーツのツイート、列は語。
最後にscipyのlinkageとdendrogramでデンドログラムを作成する。ここではコサイン距離を使ってクラスタリングする。
以下のようなデンドログラムが作成された。「たい焼き」「どら焼き」と「シュークリーム」「バームクーヘン」がそれぞれ近くにあって、直感に近い分類になった。
KH Coderでツイートを分類するで作成したKH Coderによるデンドログラムとは違う結果になったけれど、クラスタリングの方法や距離が違うので単純な比較はできない。
環境
Raspberry PiをJupyter Notebookサーバにするの手順でBash on Ubuntu on Windowsに構築したJupyter Notebookサーバ。
Pythonライブラリ等のインストール
必要なPythonライブラリをインストールする。
続いて、PythonでMeCabとmecab-ipadic-NEologdを使える環境にしておく(mecab-ipadic-NEologdで形態素解析を新語に対応させるを参照)。
さらに、matplotlibで日本語を使えるようにしておく(Raspberry PiとPython3でグラフを作成する参照)。
ツイートテキストの読み込み
KH Coderでツイートを分類するで収集したツイートのテキストsweets.txt(スイーツ名がH1タグで囲まれている)から、スイーツ名をインデックスとするPnadasのデータフレームを作成する。
import codecs
import re
import pandas as pd
def get_sweets():
with codecs.open('sweets2.txt', 'r', 'shift_jis', 'ignore') as f:
lines = f.readlines()
pat = re.compile('(.+)
')
cat = ''
sweets = {}
for line in lines:
match = pat.match(line)
if match:
cat = match.group(1)
sweets[cat] = ''
else:
sweets[cat] += line
# スイーツ名をインデックスにしてDataframe作成
return pd.DataFrame.from_dict(sweets, orient='index')
def main():
df = get_sweets()
df.index.name = 'スイーツ名'
df.columns = ['ツイート']
if __name__ == '__main__':
main()
作成したデータフレームは以下の通り。
TF-IDFでベクトル化する
MeCabでツイートを分かち書きして、scikit-learnのTfidfVectorizerでTF-IDFを計算する。今回は「名詞」「動詞」「形容詞」「副詞」「感動詞」のみを使う。さらに、ツイート収集時の検索ワードは使用しない。
import codecs
import re
import pandas as pd
import MeCab
from sklearn.feature_extraction.text import TfidfVectorizer
def wakati(text):
"""
対象とする品詞のみでわかち書き
"""
# 取り込む品詞
cat_list = ['名詞', '動詞', '形容詞', '副詞', '感動詞']
# ストップワード
stop_list = ['スイーツ', '羊羹', 'ジェラート', 'どら焼き', 'シュークリーム', 'バームクーヘン', 'たい焼き']
# 辞書としてmecab-ipadic-neologdを使う
m = MeCab.Tagger('-Ochasen -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd')
m.parse('')
node = m.parseToNode(text)
wd_list = []
while node:
cat = node.feature.split(',')[0]
if cat in cat_list and node.surface not in stop_list:
wd_list.append(node.surface)
node = node.next
return ' '.join(wd_list)
def calc_tfidf(wakati_list):
"""
TF-IDFでベクトル化
"""
# token_pattern=u'(?u)\\b\\w+\\b : 文字列長が 1 の単語を処理対象に含める
vectorizer = TfidfVectorizer(token_pattern='(?u)\\b\\w+\\b')
vecs = vectorizer.fit_transform(wakati_list)
print('TF-IDF=',)
print(vecs.toarray().shape)
print(vecs.toarray())
return vecs
def main():
df = get_sweets()
df.index.name = 'スイーツ名'
df.columns = ['ツイート']
# ツイートをわかち書きにする
df['wakati'] = df['ツイート'].apply(wakati)
# TF-IDF計算
vecs = calc_tfidf(df['wakati'].tolist())
if __name__ == '__main__':
main()
以下のようなTF-IDFが得られる。行は各スイーツのツイート、列は語。
デンドログラムの作成
最後にscipyのlinkageとdendrogramでデンドログラムを作成する。ここではコサイン距離を使ってクラスタリングする。
import codecs
import re
import pandas as pd
import MeCab
from sklearn.feature_extraction.text import TfidfVectorizer
from scipy.cluster.hierarchy import dendrogram, linkage
import matplotlib
%matplotlib inline
import matplotlib.pyplot as plt
# matplotlibの日本語フォント指定
font = {'family' : 'IPAexGothic'}
matplotlib.rc('font', **font)
def gen_cluster(X, labels):
# コサイン距離を使ってクラスタリングする
Z = linkage(X, metric='cosine')
# デンドログラムの作成
plt.figure(figsize=(10, 5))
plt.ylabel('距離')
dendrogram(
Z,
leaf_rotation=90.,
leaf_font_size=12.,
labels=labels
)
plt.show()
def main():
df = get_sweets()
df.index.name = 'スイーツ名'
df.columns = ['ツイート']
# ツイートをわかち書きにする
df['wakati'] = df['ツイート'].apply(wakati)
# TF-IDF計算
vecs = calc_tfidf(df['wakati'].tolist())
# デンドログラムの作成
gen_cluster(vecs.toarray(), df.index.values)
if __name__ == '__main__':
main()
結果
以下のようなデンドログラムが作成された。「たい焼き」「どら焼き」と「シュークリーム」「バームクーヘン」がそれぞれ近くにあって、直感に近い分類になった。

KH Coderでツイートを分類するで作成したKH Coderによるデンドログラムとは違う結果になったけれど、クラスタリングの方法や距離が違うので単純な比較はできない。
0 件のコメント:
コメントを投稿