datamining04 textmining
TRANSCRIPT
Wikipediaによるテキストマイニング入門
@nokuno
#TokyoWebmining
2010/05/16
1. はじめに
2. テキストマイニング入門
3. Wikipediaデータの解析
4. まとめ
アジェンダ
2
1. はじめに
3
Twitter: @nokuno
はてな:id:nokuno
Social IME開発者
自然言語処理とか
RとかPRMLとか
Web業界でプログラマをやってます
自己紹介
4
Wikipedia
Webテキスト
中規模データ
構造データ
テキストマイニング
自然言語処理
機械学習
知識発見
「Wikipediaのデータ」を題材に、
「テキストマイニング」の基本について話します
概要
5
圧縮状態で1.1GB、解凍後の本文だけで1.3GB
クローラを使わないでください
スパムサイトを作らないでください(泣
Wikipediaの全記事データをXML形式で
ダウンロードできる(無料)
Wikipediaデータベースとは
6
http://ja.wikipedia.org/wiki/Wikipedia:データベースダウンロード
結論
7
みんな寄付してね☆
2. テキストマイニング入門
8
テキストデータを入力して、統計データを出力する
テキストマイニングの流れ
9
本文抽出
形態素解析
統計量の抽出
統計量の集計
頻度順にソート
前処理
いろいろ変える
定型処理
OS: CentOS 5.4 (64bit)
CPU: Dual-Core AMD Opteron 1210
Memory: 4GB
HDD: 1.5TB
プログラミング言語:Python
LinuxやPythonを使ったことのない人は、
適宜置き換えて見てください
開発環境
10
ダウンロードして解凍してみても、
なんだかよく分からんXMLデータになってる
Wikipediaデータベース
11
$ wget http://dumps.wikimedia.org/jawiki/latest/jawiki-latest-pages-articles.xml.bz2
$ ls –lh
-rw-rw-r-- 1 nokuno nokuno 1.1G 3月 13 17:50 jawiki-latest-pages-articles.xml.bz2
$ bzip2 -d < jawiki-latest-pages-articles.xml.bz2 | head
<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.4/"
<siteinfo>
<sitename>Wikipedia</sitename>
<base>http://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3
<generator>MediaWiki 1.16alpha-wmf</generator>
Wikipediaに特化したツールWP2TXTを使います
本文抽出
12
$ wp2txt jawiki-latest-pages-articles.xml.bz2 –o plain –l –d -t
コマンド 元データ オプション
$ ls -lh plain/
合計 1.3G
-rw-rw-r-- 1 nokuno nokuno 11M 3月 13 21:38 jawiki-latest-pages-articles.xml-001.txt
-rw-rw-r-- 1 nokuno nokuno 11M 3月 13 21:39 jawiki-latest-pages-articles.xml-002.txt
・・・-rw-rw-r-- 1 nokuno nokuno 5.1M 3月 13 22:33 jawiki-latest-pages-articles.xml-128.txt
http://wp2txt.rubyforge.org/
英語には単語がスペースでわかち書きされているが、
日本語なので単語に分割する必要がある。
本文抽出後のデータ
13
$ head plain/jawiki-latest-pages-articles.xml-002.txt
[[東京オリンピック]]
東京オリンピック(Games of the XVIII Olympiad)は、1964年に日本の東京で開かれた第18回夏季オリンピック。
日本で初めてのオリンピックである。また、アジア地域における初のオリンピックとなった。歴史的には、第二次世界大戦で敗戦した日本が、再び国際社会に復帰するシンボル的な意味を持った。また、1940年代から1960年代にかけてヨーロッパ諸国やアメリカによる植民地支配
を破り、次々と独立を成し遂げたアジアやアフリカ諸国による初出場が相次ぎ、過去最高の出場国数となった。
mecabを使ってわかち書きすると、
単語ごとにスペース区切りになります。
形態素解析
14
$ cat plain/*.txt | mecab -Owakati > wakati.txt
$ head wakati.txt
アンパサンド (, &) と は 「 ~ と… 」 を 意味する記号である 。 英語のに相当する ラテン語のの合字で 、 を と 記述する こと が あるのはそのため 。Z に続く ラテン文字 アルファベ ット の 27 字目 と さ れ た時期 も ある 。
記号名の 「 アンパサンド 」 は 、 ラテン語の 「 & はそれ自身 " and " を 表す 」から き て いる 。
プログラミング言語では 、 C など多数の言語で AND 演算子 として用い られる 。 以下は C の例 。
単語の出現頻度単語の連接頻度品詞の連接頻度単語の長さの分布
統計を取りたい単位で1行になるよう分解する。
今回は単語なので、単語の出現頻度が求まる。
統計量の抽出
15
$ sed -e “s/ /¥n/g” wakati.txt > unigram_raw.txt
$ head unigram_raw.txt
アンパサンド(,
&)
とは「~と…
」
統計量の例
※欲しい統計量によって処理が異なる
sort と uniq –c で一発だが、
処理時間がかかるので注意
統計量の集計
16
$ time sort unigram_raw.txt | uniq -c > unigram_count.txt
real 858m21.881s
user 634m50.300s
sys 0m34.462s
$ head -1000 unigram_count.txt | tail
4 (・∀・)3 (
9 ( )
1 ( ^^367 (、
※ここが遅ければHadoopで分散するのがおすすめ
低頻度語は必要ないので切り捨てると、
この後の計算量を大幅に減らすことができる
頻度によるカットオフ
17
#!/usr/bin/pythonimport sysfor line in sys.stdin:
(freq, word) = line.strip().split(" ", 1)if int(freq) >= 10:
print freq, word
$ threshold.py < unigram_count.txt > unigram_threshold.txt
頻度10未満の単語をカットオフすると、データ量が1.6GBから38MBに減少!
threshold.py
高頻度の語を知りたいので、頻度順にソートする
頻度順にソート
18
$ sort –nr < unigram_threshold.txt > unigram.txt
$ head unigram.txt
13299512 の12465063 、9252722 。8292049 に7887615 は6665658 を6312389 た5814518 が5699061 で4210801 て
助詞の頻度が多い日本語の性質を表
している
出現頻度 単語
全部の処理をまとめると、以下のようになる
処理のまとめ
19
cat plain/*.txt ¥
| mecab –Owakati ¥
| sed -e "s/ /¥n/g" ¥
| sort ¥
| uniq –c ¥
| threshold.py ¥
| sort –nr ¥
> unigram.txt
← 入力:プレーンテキスト← 形態素解析← 単語ごとに出力← 単語でソート← 同じ単語をカウント← 低頻度語をカット← 出現頻度でソート← 出力:単語の出現頻度
3. Wikipediaデータの解析
20
単語の使用頻度も、いろいろ比較してみると面白い
単語の使用頻度
21
$ egrep "Yahoo|Google|ヤフー|グーグル" unigram.txt | head
1819 Google
1814 Yahoo
250 ヤフー227 グーグル
$ egrep "曜日" unigram.txt | head
5188 日曜日5129 土曜日4437 金曜日3087 月曜日2153 木曜日
例1: YahooとGoogleを比較してみると…
例2: 曜日対決とか…
$ egrep "男性|女性" unigram.txt
59747 女性29723 男性
例3: 男性 VS 女性
$ cat plain/*.txt | mecab -Owakati | ngram.py -n 2 | sort | uniq -c |
threshold.py | sort -nr > bigram.txt
$ head bigram.txt
た 。 2533413
は 、 1766469
ている 1658736
さ れ 1557955
し た 1550797
である 1248466
し て 1189456
ある 。 1174078
1行1単語にする代わりに、1行N単語にすればOK
単語の連接頻度(Nグラム)
22
for line in sys.stdin:words = line.split()for i in range(len(words)-n):
print " ".join(words[i:i+n])
ngram.py(コア部分)
相互情報量により関連語抽出
単独の出現頻度によるバイアスを取り除く
単語の関連度抽出(PMI)
23
$ head pmi2.txt
語ろ う 14.914123
SANSPO . 14.904073
つければ 14.894320
罪刑法定主義 14.894222
譲ろ う 14.884564
ディレク TV 14.884564
一昔前 14.884468
北蒲原郡 14.884172
東蒲原郡 14.883664
),(
)()(ln),(
yxP
yPxPyxPMI
x: 単語1
y: 単語2
P(x): 単語1の出現確率P(y): 単語2の出現確率P(x,y): 単語1と単語2の連接確率
Mecabの機能で品詞を出力し、その頻度を集計
品詞の頻度/連接頻度
24
$ cat plain/*.txt | mecab -F “%f[0] “ | ngram.py -n 2 | sort | uniq -c | sort -nr >
pos-bigram.txt
$ cat plain/*.txt | mecab -F "%F-[0,1,2,3,4,5]¥n" | sort | uniq -c | sort -nr >
detail-unigram.txt
$ head pos-bigram.txt
57171199 名詞名詞48260752 名詞助詞34616174 助詞名詞20892571 記号名詞15128482 助詞動詞13697491 名詞記号7260792 名詞動詞6898083 動詞助動詞6042161 動詞記号5835910 助詞記号
$ head detail-unigram.txt
52272673 名詞-一般26332520 助詞-格助詞-一般25200654 名詞-サ変接続12892080 助詞-連体化12474855 記号-読点10718807 名詞-数9714020 助詞-係助詞9254576 記号-句点8251500 名詞-接尾-一般6428869 助動詞特殊・タ-基本形
読みを付与して単語の頻度を求める
読み+単語の頻度
25
$ cat plain/*.txt | mecab -F "%f[8]¥t%m¥n" -U "%m¥t%m¥n"
| sort | uniq -c | threshold.py | sort -nr > yomi-unigram.txt
$ head yomi-unigram.txt
ノ の 13406477
、 、 12466311
。 。 9253307
ニ に 8296579
ワ は 7891955
ヲ を 6668753
タ た 6316055
ガ が 5816995
デ で 5700954
$ grep "^タン" yomi-unigram.txt | head
タントー 担当 55347
タンジョー 誕生 21875
タンイ 単位 20013
タンドク 単独 11744
タンニ 単に 11324
タン 単 10308
タンジュン 単純 9696
タンマツ 端末 8048
タンコーボン 単行本 5854
タンペン 短編 5781
読み付きunigramとbigramを連結して辞書作成、
grepを駆使して予測変換・漢字変換もどき
読み+単語の連接頻度
26
$ grep "^ニホン" yomi.txt | head
ニホンゴ 日本語 24611
ニホンシャ に 本社 9701
ニホンテレビ 日本テレビ 9501
ニホンカイ 日本海 4266
ニホンゴデ 日本語で 4045
ニホンゴノ 日本語の 3866
ニホン にほん 3386
ニホンゴバン 日本語版 3189
ニホンショキ 日本書紀 2687
ニホンコークー 日本航空 2175
$ grep "^ジショノ " yomi.txt | head
ジショノ 辞書の 202
ジショノ 地所の 36
ジショノ 字書の 13
ジショノ 自書の 11
※Ctrl+V <TAB>でタブ文字を入力できます
$ cat yomi-bigram.txt yomi-unigram.txt | sort -nr | combine.py > yomi.txt
人工言語に自然言語処理の手法を適用した
予約語の使用頻度ランキングとかが分かる
LinuxカーネルのC言語のソースコード、
約300MBのテキストデータを分析した
余談:ソースコード分析
27
$ grep -f clang.txt unigram.txt | head
744082 struct
640613 if
461066 int
361736 return
290246 static
226806 void
218881 unsigned
203139 for
4. まとめ
28
今回使わなかった情報もいっぱい
リンク構造
カテゴリやリダイレクトなど
テキストマイニング以外にも使える
グラフマイニング
オントロジー生成
Wikipediaはテキストマイニングの題材の宝庫で、
無料でデータが手に入るので素晴らしい
Wikipediaのデータは便利
29
高度な手法は遅い
クラスター分析はかなり重い
SVMとかやらなくても、NaiveBayesで十分?
頻度カウントの特徴
離散データならではの性質を利用
低頻度のデータを捨てることで圧縮
数学的には多項分布の最尤推定
頻度カウントという単純な手法でも、
それなりに面白い結果が出る
テキストマイニングは簡単
30
ご清聴ありがとうございました
31
テキストデータを入力して、統計データを出力する
テキストマイニングの流れ
32
本文抽出
形態素解析
統計量の抽出
統計量の集計
頻度順にソート
<mediawiki xmlns=~
日本で初めてのオリンピックで~
日本で初めてのオリンピック で~
日本で
422363 日本5699061で