文章からベクトル形式のBoWをbowvec変数に計算できました。
この情報を使ってクラスタリングしてみましょう。
クラスタリングは、sklearn.cluster.KMeansを使います。
%run 3.ipynb
Counter({'する': 3, '二': 3, '階': 3, '飛び降りる': 3, '抜かす': 3, 'ある': 3, '時': 2, 'いる': 2, '一': 2, '腰': 2, '事': 2, '人': 2, '親譲り': 1, '無鉄砲': 1, '供': 1, '損': 1, '小学校': 1, '居る': 1, '時分': 1, '学校': 1, '週間': 1, '無闇': 1, '聞く': 1, '知れる': 1, '理由': 1, '新築': 1, '首': 1, '出す': 1, '同級生': 1, '冗談': 1, '威張る': 1, 'そこ': 1, '出来る': 1, '弱虫': 1, 'ー': 1, 'い': 1, '囃す': 1, '小使': 1, '負ぶさる': 1, '帰る': 1, '来る': 1, 'おやじ': 1, '眼': 1, '奴': 1, '云う': 1, '次': 1, '飛ぶ': 1, '見せる': 1, '答える': 1})
0 {'親譲り': 1, '無鉄砲': 1, '供': 1, '時': 2, '損': 1, '...
1 {'親類': 1, 'もの': 1, '西洋': 1, '製': 1, 'ナイフ': 2, ...
2 {'庭': 2, '東': 1, '二': 1, '十': 2, '歩': 1, '行く':...
3 {'鉢': 1, '開く': 1, '頭': 3, 'こっち': 1, '胸': 1, '宛...
4 {'外': 1, 'いたずら': 1, 'やる': 1, '大工': 1, '兼': 1, ...
5 {'おやじ': 2, 'おれ': 2, '可愛がる': 1, 'くれる': 1, '母': ...
6 {'母': 2, '病気': 1, '死ぬ': 4, '二': 1, '三': 1, '日'...
7 {'母': 1, '死ぬ': 1, 'おやじ': 5, '兄': 3, '三': 1, '人...
8 {'時': 1, '仕方': 1, '観念': 1, 'する': 6, '先方': 1, '...
9 {'おれ': 5, '人': 2, '好く': 1, 'れる': 2, '性': 1, 'あ...
10 {'母': 1, '死ぬ': 1, '清': 2, 'おれ': 2, 'がる': 1, '供...
11 {'三': 3, '円': 4, '蝦蟇口': 2, '入れる': 2, '懐': 1, '...
12 {'みなさん': 1, 'ふう': 1, '川': 1, '言う': 2, 'れる': 2,...
13 {'ジョバンニ': 5, 'さん': 2, 'あなた': 1, 'わかる': 1, 'いる'...
14 {'先生': 1, '意外': 1, 'よう': 1, 'カムパネルラ': 1, '見る':...
15 {'ジョバンニ': 2, '赤': 1, 'なる': 3, 'うなずく': 1, 'いつか'...
16 {'天の川': 5, 'ほんとう': 1, '川': 3, '考える': 2, '一つ': ...
17 {'先生': 1, '中': 3, 'たくさん': 2, '光る': 5, '砂': 1, ...
18 {'教室': 2, 'じゅう': 1, '机': 1, '蓋': 1, 'あける': 1, ...
Name: Content, dtype: object
641
{'八', '始末', '便所', 'ふりかえる', 'なか', '球', '肴', '凸レンズ', '力', '急ぐ', '井戸端', 'こむ', '折戸', '引く', '幸', '通り', '誇
{'あう': 0, 'あかり': 1, 'あきらめる': 2, 'あける': 3, 'あげる': 4, 'あたる': 5, 'あと': 6, 'あなた': 7, 'あらす': 8, 'ある': 9,
from sklearn.cluster import KMeans
result = KMeans(2, random_state=18).fit_predict(bowvec.tolist())
result
KMeans(2, …)
とすることで、2つにクラスタリングします。random_state=18
とすることで、実行ごとに結果が変わらないようにしています。
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0], dtype=int32)
最初に12個の1が続き、次に7個の0が続きます。df
の先頭12行は「坊っちゃん」で、次の7行は「銀河鉄道の夜」なので、分類できていると考えられます。
df['Result'] = np.where(result, '坊っちゃん', '銀河鉄道の夜')
(df.Title == df.Result).all()
result
が0の場合に「銀河鉄道の夜」を、そうでない場合に「坊っちゃん」をResult
列に追加します。
True
(df.Title == df.Result).all()
がTrueになるので、全て元の小説と同じ分類になったことがわかります。
今回、BoWベクトルは641次元になります。
一般的にBoWは高次元になります。たいていの場合、そのまま分析してもうまくいかないことが多いです。
その場合、下記のような特徴が薄い単語を取り除いたりします。
- めったに使われない(データが少ない)。
- 頻繁に使われる(文章間で差が出ない)。
また、今回は頻度そのものを使いましたが、TF-IDFという特徴量も良く使われます。
コメント