FC2ブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

めかぶは好きですか?

お久しぶりです、Nanahuseです。

ついに冬クールのアニメが終わりましたね
今期も今期で色々見てきましたがSHIROBAKOとか四月は君の嘘とかローリンガールとかデレマスとかいろいろおもしろいのがあって幸せでした。
来季も期待できるの多いですし

さて、今日の話題は
「Mecabにはてなキーワードの単語を追加する」

Mecabとはなんぞやっていうと
例えば↓こんな文章↓があった時に

次世代型文系格闘魔法少女、頑張ってます (魔法少女リリカルなのはViVid アニメより)

Mecabを使うと

次世代 名詞,一般,*,*,*,*,次世代,ジセダイ,ジセダイ
名詞,接尾,一般,*,*,*,型,ガタ,ガタ
文系 名詞,一般,*,*,*,*,文系,ブンケイ,ブンケイ
格闘 名詞,サ変接続,*,*,*,*,格闘,カクトウ,カクトー
魔法 名詞,一般,*,*,*,*,魔法,マホウ,マホー
少女 名詞,一般,*,*,*,*,少女,ショウジョ,ショージョ
記号,読点,*,*,*,*,、,、,、
頑張っ 動詞,自立,*,*,五段・ラ行,連用タ接続,頑張る,ガンバッ,ガンバッ
助詞,接続助詞,*,*,*,*,て,テ,テ
ます 助動詞,*,*,*,特殊・マス,基本形,ます,マス,マス

↑こんな風に文章を構成する要素だとか読みだとかを分析してくれるわけです。
こういう文構造を分析したりするのを形態素解析とか言います。ちなみに形態素解析はデータ解析に使えたり、会話するソフトが作れたりしなかったりするとても素敵なツールなんです

Mecabはそんな凄い形態素解析をしてくれる素敵な存在なわけなんですが
ちょいとした問題がありまして、

例えば↓こんな文章↓をMecabにかけると
魔法少女リリカルなのはViVidは高町なのはの一人娘、高町ヴィヴィオの物語です
魔法 名詞,一般,*,*,*,*,魔法,マホウ,マホー
少女 名詞,一般,*,*,*,*,少女,ショウジョ,ショージョ
リリカル 名詞,形容動詞語幹,*,*,*,*,リリカル,リリカル,リリカル
助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
名詞,非自立,一般,*,*,*,の,ノ,ノ
助詞,係助詞,*,*,*,*,は,ハ,ワ
Vivid 名詞,固有名詞,組織,*,*,*,*
助詞,係助詞,*,*,*,*,は,ハ,ワ
接頭詞,名詞接続,*,*,*,*,高,コウ,コー
名詞,一般,*,*,*,*,町,マチ,マチ
助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
名詞,非自立,一般,*,*,*,の,ノ,ノ
助詞,係助詞,*,*,*,*,は,ハ,ワ
助詞,連体化,*,*,*,*,の,ノ,ノ
一人娘 名詞,一般,*,*,*,*,一人娘,ヒトリムスメ,ヒトリムスメ
記号,読点,*,*,*,*,、,、,、
接頭詞,名詞接続,*,*,*,*,高,コウ,コー
名詞,一般,*,*,*,*,町,マチ,マチ
ヴィヴィオ 名詞,一般,*,*,*,*,*
助詞,連体化,*,*,*,*,の,ノ,ノ
物語 名詞,一般,*,*,*,*,物語,モノガタリ,モノガタリ
です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス

なんてふうに分析されてしまいます。
かなり見づらくなってしまっていますが単語単位で上手く分けられていません
なんでこれでは意味が通りません
Mecabは新聞だかを解析するようなソフトらしいのでこういうアニメとかの固有名詞がでてくると全然上手く動きません

そこで新しく単語を追加してアニメとかでもガンガンいけるようにしようという作戦です


とりあえず↓こちらのサイト様↓を参考にしつつやっていきます。
 はてなキーワードからMecCab辞書を生成する(Ruby版)
http://www.mwsoft.jp/programming/munou/mecab_hatena.html


まずははてなダイアリーキーワードの一覧を以下のリンクより拾ってきまして

 はてなダイアリー日記「はてなダイアリーキーワードふりがなリストを公開しました」
 http://d.hatena.ne.jp/hatenadiary/20060922/1158908401
新しい作品のタイトルを適当に試してみましたが現在も更新されてるみたいです。
と言うか「はてなダイアリー日記」って「はてな日記日記」ですよね←


それを辞書用のCSVファイルに変換するためのプログラムを作成!
プログラムはカンマを抜く処理と出力される形式をちょっと変えただけでほとんど参考サイト様にあったruby用のソースを書き換えただけですが『続きから』のところに適当に貼り付けて置くのでどうぞ
※Mecabのライブラリを使用するため実行ファイルのある場所にMecabをインストールしたところ(標準だとC:\Program Files (x86)\MeCabとか。以降Mecab\とだけ表記)のbinの中にある「libmecab.dll」をコピーして下さい。
※Visual Basic .net コンソールアプリケーションです。Visual studio 2013で動作確認してます

そんでもって、出来上がった辞書用CSVファイル(hatena.csv)をMecab\dic\ipadicの中にコピーして

cd C:\Program Files (x86)\MeCab\bin
mecab-dict-index -d"C:\Program Files (x86)\MeCab\dic\ipadic" -f shift-jis -t shift-jis

真上の斜体文字になってる二行をメモ帳で「make_dic.bat」って名前で保存して、右クリックメニューから管理者として実行
※フォルダパスの部分は各自の環境に合わせて変えて下さい。
成功すると「done」って表示とともにMecab\binのなかに「matrix.bin」「sys.dic」「char.bin」「unk.dic」って4つのファイルが作成されるのでそれをMecab\dic\ipadicの中にコピーして上書きすると完了

これで先ほどの文章を形態素解析にかけると
魔法少女リリカルなのはViVidは高町なのはの一人娘、高町ヴィヴィオの物語です
魔法少女リリカルなのはViVid 名詞,一般,*,*,*,*,魔法少女リリカルなのはViVid,マホウショウジョリリカルナノハウ゛ィウ゛ィッド,マホウショウジョリリカルナノハウ゛ィウ゛ィッド,はてなキーワード,
助詞,係助詞,*,*,*,*,は,ハ,ワ
高町なのは 名詞,一般,*,*,*,*,高町なのは,タカマチナノハ,タカマチナノハ,はてなキーワード,
助詞,連体化,*,*,*,*,の,ノ,ノ
一人娘 名詞,一般,*,*,*,*,一人娘,ヒトリムスメ,ヒトリムスメ
記号,読点,*,*,*,*,、,、,、
高町ヴィヴィオ 名詞,一般,*,*,*,*,高町ヴィヴィオ,タカマチウ゛ィウ゛ィオ,タカマチウ゛ィウ゛ィオ,はてなキーワード,
助詞,連体化,*,*,*,*,の,ノ,ノ
物語 名詞,一般,*,*,*,*,物語,モノガタリ,モノガタリ
です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス

驚くほどの効果が実感できました。
これなら上手くデータを扱えます

そんなわけで以上になります。


以下続きから今回の作戦で使用したVisual Basicのソースです。
Imports System.Runtime.InteropServices

Module Module1

Sub Main()
Dim cReader As New System.IO.StreamReader(System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)+"\keywordlist_furigana.csv", System.Text.Encoding.GetEncoding("EUC-JP"))
Dim sw As New System.IO.StreamWriter(System.Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)+"\hatena.csv", False, System.Text.Encoding.GetEncoding("shift_jis"))
'閉じる
Dim node As String()
Dim node_count As Integer = 0
Dim area_count As Integer = 0
Dim name_count As Integer = 0

Dim feature As String()
Dim cost As Integer = 0
Dim kana As String
Dim count As Long = 0
Dim count2 As Long = 1



' 読み込みできる文字がなくなるまで繰り返す
While (cReader.Peek() >= 0)
count += 1
If count = 500 * count2 Then
Console.WriteLine(count.ToString + "件目")
count2 += 1
End If

' ファイルを 1 行ずつ読み込む
Dim stBuffer As String = cReader.ReadLine.Replace("’", "'")

Dim stArrayData As String() = stBuffer.Split(vbTab)
If stArrayData(0) = "" Or stArrayData(1) = "" Then Continue While

If System.Text.RegularExpressions.Regex.IsMatch(stArrayData(1), "[0-9]{4}(\/|\-)[0-9]{2}(\/|\-)[0-9]{2}") Then Continue While
If System.Text.RegularExpressions.Regex.IsMatch(stArrayData(1), "[0-9]{4}年") Then Continue While
If System.Text.RegularExpressions.Regex.IsMatch(stArrayData(1), "[0-9]{1,2}月[0-9]{1,2}日") Then Continue While

If System.Text.RegularExpressions.Regex.IsMatch(stArrayData(1), "[[:cntrl:]]") Then Continue While
If System.Text.RegularExpressions.Regex.IsMatch(stArrayData(1), "はてな") Then Continue While
If System.Text.RegularExpressions.Regex.IsMatch(stArrayData(1), ",") Then stArrayData(1) = stArrayData(1).Replace(",", "")




Using Mecab1 As New MeCab
node = Mecab1.Parse(stArrayData(1)).Split(ControlChars.Lf)
End Using

'システム辞書で1語として解析可能の場合は登録しない
If node.Length <> 3 Then

area_count = 0
name_count = 0
node_count = node.Length - 2
cost = 0

'ノードと種類をカウント
For Each node_text As String In node
If node_text = "EOS" Or node_text = "BOS" Then
Exit For
End If
feature = node_text.Split(",")
If feature(2) = "地域" Then
area_count += 1
ElseIf feature(2) = "人名" Then
name_count += 1
End If
Next

If area_count <> node_count And name_count <> node_count Then
cost = -400 * (stArrayData(1).Length ^ 1.5)
If cost < -36000 Then cost = -36000
kana = StrConv(stArrayData(0), Microsoft.VisualBasic.VbStrConv.Katakana, &H411)
sw.WriteLine(stArrayData(1) + ",-1,-1," + cost.ToString + ",名詞,一般,*,*,*,*," + stArrayData(1) + "," + kana + "," + kana + ",はてなキーワード,")
If stArrayData(1) <> stArrayData(1).ToUpper Then sw.WriteLine(stArrayData(1).ToUpper + ",-1,-1," + cost.ToString + ",名詞,一般,*,*,*,*," + stArrayData(1) + "," + kana + "," + kana + ",はてなキーワード,")
If stArrayData(1) <> stArrayData(1).ToLower Then sw.WriteLine(stArrayData(1).ToLower + ",-1,-1," + cost.ToString + ",名詞,一般,*,*,*,*," + stArrayData(1) + "," + kana + "," + kana + ",はてなキーワード,")
End If
End If
End While

' cReader を閉じる
cReader.Close()
sw.Close()

End Sub


Class MeCab
Implements IDisposable


Public Shared Function mecab_new2(ByVal arg As String) As IntPtr
End Function


Public Shared Function mecab_sparse_tostr(ByVal m As IntPtr, ByVal str As String) As IntPtr
End Function


Public Shared Sub mecab_destroy(ByVal m As IntPtr)
End Sub

Private ptrMeCab As IntPtr

Sub New()
Me.New(String.Empty)
End Sub

Sub New(ByVal Arg As String)
ptrMeCab = mecab_new2(Arg)
End Sub

Public Function Parse(ByVal [String] As String) As String
Dim ptrResult As IntPtr = mecab_sparse_tostr(ptrMeCab, [String])
Dim strResult As String = Marshal.PtrToStringAnsi(ptrResult)
Return strResult
End Function

Public Overloads Sub Dispose() Implements IDisposable.Dispose
mecab_destroy(ptrMeCab)
GC.SuppressFinalize(Me)
End Sub

Protected Overrides Sub Finalize()
Dispose()
End Sub
End Class

End Module
スポンサーサイト

コメントの投稿

非公開コメント

プロフィール

ややさん@頑張らない

Author:ややさん@頑張らない
 
このブログのは
Iris :TCGが好き系オタク
Nanahuse :PCが好き系オタク

の二人の提供でお送りしております

ゲームレビューまとめはこちらからどうぞ

*相互リンク募集中です。コメント欄などで一言かけてもらえると嬉しいです。
ブロともなども気軽にどうぞ。
*リンクフリー

最新記事
最新コメント
月別アーカイブ
カテゴリ
TCG (8)
ついった
フリーエリア
ピュア×コネクト アストラエアの白き永遠 応援中!! ALcot『Clover Day's』応援中!
フリーエリア
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。