about MeCab (3) 品詞IDの指定
品詞を品詞名で出力するのではなく、品詞IDを指定してそれを出力することが出来る
http://mecab.sourceforge.net/posid.html
定義した品詞IDは出力時に%hを指定することで参照される
% mecab -F"%m\t%h\n" -E"EOS\n"
品詞IDの定義
pos-id.defを編集する。
形式
マッチパターン ID マッチパターンの記述 *: すべての文字列にマッチ (AB|CD|EF): AB もしくは CD もしくは EF にマッチ AB: 文字列 AB のみに完全マッチ
pos-id を変更したら, 辞書をリコンパイルする必要があります.
定義例
単純な例 名詞 1 動詞 2 形容詞 3 副詞 4 助詞 5 接続詞 6 助動詞 7 連体詞 8 感動詞 9 * 10
ちょっと複雑な例 名詞 1 (助詞|助動詞) 2 (副詞|形容詞|連体詞) 3 * 4
もっと複雑な例
その他,間投,*,* 0
フィラー,*,*,* 1
感動詞,*,*,* 2
記号,アルファベット,*,* 3
記号,一般,*,* 4
記号,括弧開,*,* 5
記号,括弧閉,*,* 6
記号,句点,*,* 7
記号,空白,*,* 8
記号,読点,*,* 9
形容詞,自立,*,* 10
形容詞,接尾,*,* 11
形容詞,非自立,*,* 12
助詞,格助詞,一般,* 13
助詞,格助詞,引用,* 14
助詞,格助詞,連語,* 15
助詞,係助詞,*,* 16
助詞,終助詞,*,* 17
助詞,接続助詞,*,* 18
助詞,特殊,*,* 19
about Mecab (2) 出力フォーマットの定義とその指定方法
ユーザによる出力フォーマットの定義とその指定方法
http://mecab.sourceforge.net/format.html
- node
- 一つの形態素を出力,デフォルトは空文字
- unk
- 一つの未知語形態素を出力、デフォルトはnodeと同一フォーマット
- bos
- 形態素解析の結果に先立って出力、デフォルトは空文字
- eos
- 形態素解析の結果のあとに出力,デフォルトは"EOS\n"
これらをもとに指定する。パラメータ詳細は後述。
指定方法
on commandline
mecab --node-format=STR --bos-format=STR --eos-format --unk-format=STR
mecabrcファイルに記述する方法
任意の文字列KEYを使って以下のように定義
node-format-KEY = STR
unk-format-KEY = STR
eos-format-KEY = STR
bos-format-KEY = STR
コマンドラインから呼び出すには
mecab -Okey
on python
import MeCab m = MeCab.Tagger("Okey")
出力フォーマットのパラメータ
%s | 形態素の種類(0:通常、1:未知語, 2:文頭、 3:文末) |
%S | 入力文 |
%L | 入力文の長さ |
%m | 形態素の表層文字列 |
%M | 形態素の空白文字を含む表層文字列 |
%h | 素性の内部ID |
%% | %そのもの |
%c | 単語生起コスト |
%H | 素性(品詞、活用、読み)などをCSVで表現したもの |
%t | 文字種id |
%P | 周辺確率 |
%pi | 形態素に付与されるユニークなID |
%pS | 形態素が空白文字列で始まる場合,その空白文字列を表示 %pS%mと%Mは同一 |
%ps | 開始位置 |
%pe | 集良一 |
%pC | 一つ前の形態素との連接コスト |
%pw | %cと同じ |
%pc | 連接コスト+単語生起コスト (文頭から累積) |
%pn | 連接コスト+単語生起コスト(その形態素単独 = %pw+%pC) |
%pb | 最適パスの場合*, それ以外は'' |
%pP | 周辺確率 |
%pA | blpha, forward log確率 |
%pB | beta, backward log確率 |
%pl | 形態素の表層文字としての長さ, strlen(%m)と同じ |
%pL | 空白文字列を含む形態素の表層文字列としての長さ,strlen(%M)と同じ |
%phl | 左文脈id |
%phr | 右文脈id |
%f[N] | csvで表記された素性のN番目の要素 |
%f[N1, N2, N3,...] | N1, N2, N3番目の素性を","をデリミタとして表示 |
%Fc[N1, N2, N3,...] | N1, N2, N3番目の素性を"C"をデリミタとして表示 ただし、要素が空の場合は以降表示が省略 ex) %F-[N1, N2] |
\s | ' '半角スペース |
例
# ChaSen node-format-chasen = %m\t%f[7]\t%f[6]\t%F-[0,1,2,3]\t%f[4]\t %f]5],\n #; 表層文字列 f[7] f[6] F[0]-F[1]-F[2]-F[3] f[4]f[5] unk-format-chasen = %m\t%m\t%F-[0,1,2,3]\t\t\n eos-format-chasen = EOS\n # 表層文字列 表層文字列F[0]-F[1]-F[2]-F[3]
f[n] ?csvファイルはどれだろう?
MeCab説明書きの写経 (1)
さて、取得したテキストの解析にあたって、MeCab/CaboChaで実際にどういうことが出来るのかしらということで、MeCabとCaboChaの説明書きを写経 & まとめてみた
- http://mecab.sourceforge.net/
- Google Code Archive - Long-term storage for Google Code Project Hosting.
まずはMeCabから。
MeCabはオープンソースの形態素解析エンジン.パラメータの推定に Conditional Random Fields (CRF) を用いている、とか。CRF++を用いて、辞書スコアなどの学習ができる?とかなんとかはこれから読む。
形態素解析は
形態素解析とは、自然言語で書かれた文を形態素(Morpheme, おおまかにいえば、言語で意味を持つ最小単位)の列に分割し、それぞれの品詞を判別する作業を指す。
wikipedia 形態素解析
形態素解析に手を出してみた
第一歩目は,twitterから取得したテキストをMeCabを使って形態素に分割すること。
import twitter import MeCab id = 'xxxxx' pass = 'xxxxx' api = twitter.Api(id, pass) posts = api.GetFriendsTimeline(count=200)
mecabによりテキストを形態素に分解し,その結果をparseddataのタプルに保存する
entry = posts[0].text.encode('utf-8') m = MeCab.Tagger("Ochasen") parsed = m.parseToNode(entry) parseddata = [] while parsed.next: if len(n.surface)>0: parseddata.append((parsed.surface.decode("utf-8"), (parsed.feature.decode("utf-8").rsplit(',')), parsed.cost)) parsed = parsed.next
結果
BOS/EOS,*,*,*,*,*,*,*,* 0
テレ朝 名詞 固有名詞 組織 * * * テレ朝 テレアサ テレアサ 4144 野球 名詞 一般 * * * * 野球 ヤキュウ ヤキュー 1990 ニュース 名詞 一般 * * * * ニュース ニュース ニュース 5521 始まっ 動詞 自立 * * 五段・ラ行 連用タ接続 始まる ハジマッ ハジマッ 12662 た 助動詞 * * * 特殊・タ 基本形 た タ タ 11722
タプルの第一要素が分割した表層文字列、第二要素が解析結果…ここはそれぞれが何か良くまだわかってない&表示方法は「m = MeCab.Tagger("Ochasen")」で指定かな,ってことでマニュアル読む。第三要素が、その要素の「コスト」となっております。とりあえず、解析ができることはわかった。
あとで
def getLDRWeatherHacks(): url = 'http://weather.livedoor.com/forecast/webservice/rest/v1' parameters['day'] = 'today' parameters['city'] = '01' postdata = urllib.urlencode(parameters) weatherxml = urllib.urlopen(url, postdata).read() tree = etree.fromstring(weatherxml) wtokens['forecastday'] = [tree.xpath('//forecastday')[0].text] wtokens['day'] = [tree.xpath('//day')[0].text] wtokens['telop'] = [tree.xpath('//telop')[0].text] wtokens['temperature'] = [tree.xpath('//temperature/max/celsius')[0].text, tree.xpath('//temperature/min/celsius')[0].text] wtokens['area'] = [tree.xpath('//location@area')[0]] wtokens['pref'] = [tree.xpath('//location@pref')[0]] wtokens['city'] = [tree.xpath('//location@city')[0]] wtokens['title'] = [tree.xpath('//title')[0].text] return wtokens def getLDRWHdict(): pdict[u'道北'] = { 'areacode':'1a', 'citylist':{ u'稚内':'1', u'旭川':'2', u'留萌':'3', }, } # ### pref pdict[u'道央'] = { 'areacode':'1b', 'citylist':{ u'札幌':'4', u'岩見沢':'5', u'倶知安':'6', }, } # ### pref pdict[u'道東'] = { 'areacode':'1c', 'citylist':{ u'網走':'7', u'北見':'8', u'紋別':'9', u'根室':'10', u'釧路':'11', u'帯広':'12', }, } # ### pref pdict[u'道南'] = { 'areacode':'1d', 'citylist':{ u'室蘭':'13', u'浦河':'14', u'函館':'15', u'江差':'16', }, } return pdict def getforecastpoint(entry): weatherdict = getLDRWHdict() forecastpoint = {'cityindx':[], 'cityname':[], 'areaname':[], 'areacode':[]} for area in weatherdict.keys(): for city in weatherdict[area]['citylist'].keys(): if entry.find(city) != -1: ## forecastpoint['cityindx'] = weatherdict[area]['citylist'][city] ## forecastpoint['cityname'] = city ## forecastpoint['areaname'] = area ## forecastpoint['areacode'] = weatherdict[area]['areacode'] forecastpoint['cityindx'].append(weatherdict[area]['citylist'][city]) forecastpoint['cityname'].append(city) forecastpoint['areaname'].append(area) forecastpoint['areacode'].append(weatherdict[area]['areacode']) return forecastpoint def getforecastday(entry): daydict['today']=[u'今日', u'きょう'] day = 'today' indx = [entry.find(x) for x in daydict[day] if entry.find(x) != -1] if len(indx): daycandidate.append(day)