はじめに
9月末に記事の毎日投稿を始めておよそ2ヶ月が経過した。2021年12月1日時点で、公開中の記事と非公開記事が合わせて64本ある。今回は、これらの記事の解析を行う。
10月初めにも、過去記事解析を行った。そこで行ったのは、記事の文字数分布と文字数の時系列的推移である。今回は、これらの文字数解析に加え、自然言語処理を新たに行った。MeCabにより日本語文書を分かち書きし、tf-idfを計算し、各記事を固定長の文書ベクトルに変換した。
文書ベクトル作成のスクリプト
次のスクリプトで過去記事をtf-idfによりベクトル化し、ベクトルをヒートマップで可視化した。
from glob import glob import MeCab import numpy as np np.set_printoptions(precision=2) from sklearn.feature_extraction.text import TfidfVectorizer import seaborn as sns import matplotlib.pyplot as plt mecab = MeCab.Tagger("-Owakati") # read text files and parse them by mecab docs = np.array([]) for file in glob("C:/hogehoge" + "/*.txt"): with open(file, encoding="UTF-8") as f: text = f.read() words=mecab.parse(text) docs = np.append(docs, words) # calculate tf-idf vectorizer = TfidfVectorizer(use_idf=True, token_pattern=u'(?u)\\b\\w+\\b') vecs = vectorizer.fit_transform(docs) # draw heat map plt.figure() sns.heatmap(vecs.toarray()) plt.show()
なお、記事は保管ディレクトリ下にtxtファイル形式で保存されている。
tf-idfは(記事,単語)のペアに対して計算される値であり、当該記事中の当該単語の重要性を表す。たとえば、記事No. 13の中に「カモシカ」という単語が含まれていたとき、(記事No. 3,カモシカ)というペアに対して、tf-idf値が与えられる。
tfは当該記事中の当該単語の出現頻度である。当然、ある記事の中にたくさん出てくる単語は、その記事における重要度が高い。しかし、どの記事にも非特異的に多く出現する単語がある。たとえば、「する」や「とき」などがそれに該当する。そこで、単語が出現するのがどれぐらい珍しいかをidfにより、表現する。tf-idfはtfとidfの積である。その文書において重要である珍しい単語はtf-idf値が高い。
解析結果
まず、記事文字数の分布をヒストグラムで示す。2000文字以上の記事が数本ある。500文字前後の記事から2500文字前後の記事まで、記事数が右肩下がりに分布している。
次に、記事文字数の推移を確認する。振動を伴いながら、文字数が増加するトレンドが見られる。
そして、こちらがtf-idfによる文書ベクトルのヒートマップによる可視化結果である。行は一つの記事に相当し、縦軸は全記事数の64まである。列はある単語一つに関しての情報である。横軸は64記事の全体に一度でも出現する単語4415個に相当する。
一行一行が記事の固定長ベクトル化になっている。したがって、行ベクトルを文書ベクトルとして用いて、これから各種の解析を行うことができる。
文書ベクトルは、ほとんどの要素がゼロである疎なベクトルであった。ところどころに高いtf-idfをもつ要素があった。
考察
tf-idfのヒートマップを作成することにより、文書ベクトルの全体像を掴むことができた。
tf-idfによる文書ベクトルを用いて、記事のクラスタリングを行うことができる。ヒートマップ上の各要素がどの記事のどの単語に該当するかをインタラクティブに知ることのできる機能を実装できれば便利である。
結論
今回は、MeCabによる形態素解析とtf-idfの計算、ヒートマップの描画を行うことができた。近い将来に、文書ベクトルを用いて記事のクラスタリングまでを行いたい。
参考
tf-idfの計算は次の記事を参考にした。
- コード7区『TF-IDF で文書をベクトル化。python の TfidfVectorizer を使ってみる』(http://ailaby.com/tfidf/)