とりあえず使ってみることを重視するため、深い/細かい話には立ち入らない。
LDAとは?
- Latent Dirichlet Allocationの略。
- トピックモデルの一種。
- ドキュメントは複数のトピックから成り立っていると仮定。
- 入力=ドキュメント集合、出力=各ドキュメントのトピック分布、各トピックの語句分布
やること
日経225の企業をwikipediaの文章を元にクラスタリングする。
事前準備として、225銘柄一覧に記載されている企業のwikiページのHTMLを取得しておく。HTMLはhtml/配下に企業名.htmlというファイル名で格納しておく。
$ ls html | head -n 10 ANAホールディングス.html DOWAホールディングス.html IHI.html J.フロント リテイリング.html JFEホールディングス.html JXホールディングス.html KDDI.html MS&ADインシュアランスグループホールディングス.html NTN.html NTTデータ.html
前処理
html/配下に格納されたHTMLを前処理して、text/配下に格納する。
行った前処理は以下のとおり。
- Javascript/CSSの記述削除
- HTMLタグの除去
- MeCabで分かち書き
# -*- coding: utf-8 -*- import os from bs4 import BeautifulSoup import MeCab for f_name in os.listdir('html'): f_path = 'html/' + f_name with open(f_path, 'r') as f: data = f.read() soup = BeautifulSoup(data, 'lxml') for script in soup.find_all('script'): script.decompose() for script in soup.find_all('style'): script.decompose() text = soup.getText() text = [line for line in text.splitlines() if line] text = '\n'.join(text) tagger = MeCab.Tagger('-Owakati') wakati_text = tagger.parse(text.encode('utf-8')) t_path = 'text/{name}.txt'.format(name = os.path.splitext(f_name)[0]) open(t_path, 'w').write(wakati_text)
LDAモデルの学習
前処理したテキストを使ってLDAモデルを学習する。
- Dictionaryの作成(tokenのid化、document ごとのtokenの頻度計算など)
- 汎用的な語句(60%以上のドキュメントで使われる語句)の除去
- bag of words形式の行列作成
- LDAモデルの構築
- ドキュメント-トピック配分の行列を作成し保存
import logging import os import pickle import gensim logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO) TOPIC_NUM = 30 texts = [file('text/' + f_name, 'r').read().split() for f_name in os.listdir('text')] dictionary = gensim.corpora.Dictionary(texts) dictionary.filter_extremes(no_below=1, no_above=0.6, keep_n=None) corpus = [dictionary.doc2bow(text) for text in texts] lda = gensim.models.ldamodel.LdaModel(corpus, num_topics=TOPIC_NUM, id2word = dictionary, passes=20) topics = [] for c in corpus: topic = [0] * TOPIC_NUM for (tpc, prob) in lda.get_document_topics(c): topic[tpc] = prob topics.append(topic) pickle.dump(topics, open("topics.p", "w"))
クラスタリング
トピック配分を特徴量としてK−meansでクラスタリング。
- 特徴量のL2ノルム正規化
- K-meansの学習
- ドキュメントのクラスタリング
# -*- coding: utf-8 -*- import pickle import os from sklearn.preprocessing import Normalizer from sklearn.cluster import KMeans N_CLUSTER = 20 xs = pickle.load(open('topics.p', 'r')) ys = [os.path.splitext(f_name)[0] for f_name in os.listdir('text')] xs = Normalizer().fit_transform(xs) kmeans = KMeans(n_clusters=N_CLUSTER, init='k-means++', max_iter=100, n_init=1) kmeans.fit(xs) clusters = kmeans.predict(xs) for i in range(N_CLUSTER): text = 'cluster {clr}:'.format(clr = i) companies = [y for k, y in enumerate(ys) if clusters[k] == i] print text + " ".join(companies)
結果
それっぽく分かれているところを色つけしてみた。
cluster 0: SUMCO りそなホールディングス オークマ クラレ コニカミノルタ サッポロホールディングス トクヤマ ユニチカ 三井化学 三井造船 三井金属鉱業 三菱マテリアル 双日 商船三井 大林組 宇部興産 帝人 日新製鋼 日本製紙 日本製鋼所 日東電工 日立造船 昭和電工 東レ 東宝 => 三井グループ
cluster 1: JXホールディングス MS&ADインシュアランスグループホールディングス アステラス製薬 アドバンテスト 三井住友トラスト・ホールディングス 信越化学工業 国際石油開発帝石 大和証券グループ本社 太平洋セメント 損保ジャパン日本興亜ホールディングス 日本水産 日産化学工業
cluster 2: KDDI NTTドコモ アマダホールディングス ディー・エヌ・エー デンソー ブリヂストン 京王電鉄 宝ホールディングス 富士通 東海カーボン => 携帯電話関連
cluster 3: オリンパス キッコーマン セブン&アイ・ホールディングス マルハニチロ 三井物産 明治ホールディングス 清水建設 王子ホールディングス
cluster 4: IHI J.フロント リテイリング ふくおかフィナンシャルグループ ニチレイ 三菱UFJフィナンシャル・グループ 三菱商事 三越伊勢丹ホールディングス 千代田化工建設 第一生命保険
cluster 5: NTTデータ TDK いすゞ自動車 アルプス電気 クレディセゾン コナミホールディングス ソフトバンク テルモ トヨタ自動車 トレンドマイクロ マツダ ヤマトホールディングス 三菱地所 大平洋金属 大成建設 太陽誘電 富士重工業 小田急電鉄 新日鐵住金 日本碍子 日本通運 日野自動車 昭和シェル石油 東武鉄道 東海旅客鉄道 松井証券 沖電気工業 積水ハウス 花王 長谷工コーポレーション => 自動車関連、鉄道関連
cluster 6: ミネベア 中外製薬 味の素 大日本住友製薬 富士電機 日本曹達 日本精工 日清製粉グループ本社 横河電機 武田薬品工業
cluster 7: ジェイテクト スカパーJSATホールディングス 京成電鉄 古河機械金属 古河電気工業 日本軽金属ホールディングス 東日本旅客鉄道 東洋製罐グループホールディングス 西日本旅客鉄道
cluster 8: TOTO クボタ ヤマハ ユニーグループ・ホールディングス 中部電力 日清紡ホールディングス 東京電力 横浜ゴム 関西電力
cluster 9: カシオ計算機 キヤノン ミツミ電機 凸版印刷 富士フイルムホールディングス 川崎汽船 日本化薬
cluster 10: SCREENホールディングス みずほフィナンシャルグループ コムシスホールディングス ヤフー リコー 三井住友フィナンシャルグループ 住友大阪セメント 旭硝子 東京海上ホールディングス 野村ホールディングス 電通 => 金融関連
cluster 11: シチズンホールディングス シャープ パナソニック 北越紀州製紙 川崎重工業 日立建機 旭化成
cluster 12: 伊藤忠商事 大阪ガス 日本郵船 日本電気 東京ガス 東急不動産ホールディングス
cluster 13: ANAホールディングス DOWAホールディングス スズキ ファナック 三菱ケミカルホールディングス 住友金属鉱山 東京ドーム
cluster 14: イオン ジーエス・ユアサコーポレーション ソニー ソニーフィナンシャルホールディングス デンカ ニコン ファーストリテイリング 三井不動産 丸井グループ 東ソー 東京建物 東芝 高島屋
cluster 15: 三菱重工業 丸紅 安川電機 日本ハム 日立製作所 本田技研工業 東京エレクトロン 神戸製鋼所
cluster 16: JFEホールディングス アサヒグループホールディングス ダイキン工業 日本板硝子 日本電信電話 日産自動車 東邦亜鉛 豊田通商
cluster 17: T&Dホールディングス あおぞら銀行 セコム 千葉銀行 新生銀行 横浜銀行 第一三共 静岡銀行 => 銀行関連
cluster 18: エーザイ キリンホールディングス フジクラ 三菱倉庫 三菱自動車工業 住友不動産 住友化学 住友商事 住友重機械工業 住友電気工業 協和発酵キリン 大和ハウス工業 大日本印刷 小松製作所 日本たばこ産業 日本電気硝子 明電舎 東京急行電鉄 東洋紡 荏原製作所 鹿島建設 => 住友グループ
cluster 19: NTN パイオニア 三菱電機 京セラ 塩野義製薬 日揮 資生堂
改善点
- 他の情報源からもドキュメントを集める
- 汎用語句の閾値をチューニングする
- トピックの数をチューニングする
- クラスタの数をチューニングする
0 件のコメント:
コメントを投稿