都内で働くSEの技術的なひとりごと

都内でサラリーマンやってます。マイクロソフト系(たまに、OSS系などマイクロソフト以外の技術も...)の技術的なことについて書いています。日々の仕事の中で、気になったことを技術要素関係なく気まぐれに選んでいるので記事内容は開発言語、インフラ等ばらばらです。なお、当ブログで発信、発言は私個人のものであり、所属する組織、企業、団体等とは何のかかわりもございません。ブログの内容もきちんと検証して使用してください。よろしくお願いします♪

『 昨日から片頭痛ある 』、『 昨日から頭痛がある 』という文がCONTAINS 関数で『 頭痛 』を指定すると、『 昨日から片頭痛ある 』という文がヒットしないので、なんとかヒットさせる術がないかどうか悩んでみたり、色々な人にヒアリングしたけど、やっぱりワードブレーカーを作る暇はないので、少し格好悪いけど『アノ』案でいくことに決めたので、内容をまとめてみた っていう記事を書いたけど、.NET からMeCab をどうやって使っていいのかわからないので、調査してみた

今回のやることを説明してみる

 前回の記事で MeCab で形態要素解析すると書いていましたが、その箇所の検証が抜けていました。

『 昨日から片頭痛ある 』、『 昨日から頭痛がある 』という文がCONTAINS 関数で『 頭痛 』を指定すると、『 昨日から片頭痛ある 』という文がヒットしないので、なんとかヒットさせる術がないかどうか悩んでみたり、色々な人にヒアリングしたけど、やっぱりワードブレーカーを作る暇はないので、少し格好悪いけど『アノ』案でいくことに決めたので、内容をまとめてみた - 都内で働くSEの技術的なひとりごと

 C#MeCab を使用した実装をやってみたいと思います。

使用する環境を説明してみる

 今回は、Microsoft Azure 上の仮想サーバではなく、私の Windows 8.1 Update1、64ビット 上で 動作している  Visual Studio 2013 Update2 を使用します。

どんな部品を使うか紹介してみる

 NMeCab ( エヌメカブ、エヌメカ ) というイケてる部品がありました。


NMeCab - 形態素解析エンジンMeCabの.NET版 (エヌメカブ ケイタイソカイセキ エンジン メカブ ノ ドットネット バン) プロジェクト日本語トップページ - SourceForge.JP

NMeCabは、オープンソース形態素解析エンジンMeCabの解析処理部分を、.NETライブラリとして移植したものです。
オリジナル版MeCabと同じ辞書を使用し、同じ解析結果を得ることができます。
純粋なC#言語で作成されており、ラッパーではないため、インストールがシンプルで、高速性と安定性にも優れています。

  C#化されているんですね。すばらしい。

早速、調査とかいろいろやってみる

 早速使ってみましょう。2014-04-29 版を使用します。サンプルアプリケーションが格納されていますので、試してみましょう。きちんと解析できていますね。

f:id:koogucc11:20141010162421p:plain

 次はソースコードの解析です。ソリューションファイルを開いてみましょう。どんな感じの構成なのか、コードマップを開いてみましょう。

f:id:koogucc11:20141010165607p:plain

  コードマップ開くまでもありませんね。早速、解析しましょう。下記の箇所が参考になりますね。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
private void DoAnalyzeButton_Click(object sender, EventArgs e)
{
try
{
this.tagger.LatticeLevel = this.LatticeLevel;
this.tagger.OutPutFormatType = this.OutputFormat;
this.tagger.AllMorphs = this.AllMorphsCheckBox.Checked;
this.tagger.Partial = this.PartialCheckBox.Checked;

this.toolStripStatusLabel1.Text = "Analyzing ...";
Stopwatch sw = Stopwatch.StartNew();

if (NBestCheckBox.Checked)
{
this.ResultTextBox.Text = this.tagger.ParseNBest((int)NBestNumericUpDown.Value,
this.TargetTextBox.Text);
}
else
{
this.ResultTextBox.Text = this.tagger.Parse(this.TargetTextBox.Text);
}

sw.Stop();
this.toolStripStatusLabel1.Text = string.Format("Finish ({0:0.000}sec)",
sw.Elapsed.TotalSeconds);
}
catch (Exception ex)
{
this.toolStripStatusLabel1.Text = "ERROR";
MessageBox.Show(ex.ToString(), "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

 MeCabTagger クラスを見てみましょう。下記のようなクラス構造です。非常にシンプルですね。

f:id:koogucc11:20141010192132p:plain

 まず、プロパティから調べてみましょう。

  • AllMorphs
    true:全出力
    false:ベスト解のみ
    ※今回の要件では、false で十分です。
  • LatticeLevel
    0:最適解のみが出力可能なレベル (デフォルト, 高速)
    1:N-best 解が出力可能なレベル (中速)
    2:ソフトわかち書きが可能なレベル (低速) ※この辺りのパラメーターはよくわかりません...
  • OutPutFormatType
    解析結果のフォーマット 『lattice』 wakati』『dump』の何れかを指定する。今回の要件では、『lattice』で十分ですね。
  • Partial
    部分解析モード....うーん。
  • Theta
    ソフト分かち書きの温度パラメータ....これ、わかりません。

 むぅ...難しい。細かいところは後で勉強することにしましょう。

 次にメソッドを調べてみましょう。

  • Parse
  • ParseToNode
  • ParseNBest
  • ParseNBestToNode

 N-Best 解は勉強しないといけないので、今回は ParseToNode メソッドをい使用することにします。

 この適当な調査結果wwからできたサンプルソースは下記の通りです。『昨日から片頭痛がある』が『昨日 から 片 頭痛 が ある 。』と変更することができます。

1
2
3
4
5
6
7
8
9
10
11
1213
1415
16
17
18
19
20
2122
var mt = MeCabTagger.Create();
string str = "";

mt.AllMorphs = false;
mt.LatticeLevel = 0;
mt.OutPutFormatType = "lattice";
mt.Partial = false;
mt.Theta = 0.75f;

var mn = mt.ParseToNode("昨日から片頭痛がある。");

while (mn != null)
{
if (mn.CharType > 0)
{
str = str + mn.Surface + " ";
}
mn = mn.Next;
}

mt.Dispose();
mt = null;

終わりに何か一言いってみる

  SQL ServerMeCab のように形態要素解析できる日は来るのでしょうか。

入門 自然言語処理

入門 自然言語処理