Giter Club home page Giter Club logo

nmecab's Introduction

.NET日本語形態素解析エンジンNMeCab

目次

リポジトリ移転について

2010年からOSDNで開発し公開してきたNMeCabですが、バージョン0.10.0からは、こちらGitHubで開発し公開していきます。

これは何?

NMeCabは.NETで開発した日本語形態素解析エンジンです。
その名の通り、元々はMeCabというOSSの日本語形態素解析エンジンをC++からC#へ移植したものですが、独自の機能追加も行っています。
辞書データはMeCabに対応したものをそのまま使用できます。
NMeCabバージョン0.10.0では、.NET Standard 2.0ライブラリにしてあります。(これに対応するランタイムは、.NET 5 以上、.NET Core 2.0 以上、.NET Framework 4.6.1 以上、などです)

そもそも形態素解析とは?

自然言語の文章を形態素(日本語では単語と同じ)に分割し、品詞・読み・活用型などの素性情報の付与も行うことです。
様々な自然言語処理の第一段階として使用されることを目的にしています。
プログラム言語コードのコンパイラのように、文字列を文法ベースで処理していると思われるかもしれませんが、実際にそのような処理を行っても日本語の文章にはほとんど通用しません。 MeCab/NMeCabの手法は、事前にコーパス(言語学的にまとめられた大量の資源)から統計的に抽出した情報(辞書)を使うものです。 コーパスベースの辞書引き(DoubleArrayTrieを活用)と、規則ベースの未知語抽出により、ラティスと呼ばれる候補の形態素の集合を作り、そこから統計的に最も確からしい形態素の並びを選び出す(Viterbiアルゴリズムを使用)、という流れで解析を行なっています。

NuGet

パッケージ NuGet ID NuGet Status
NMeCabライブラリ LibNMeCab Stat
IPA辞書 LibNMeCab.IpaDicBin Stat

辞書パッケージをNuGetでインストールすると、依存するNMeCabライブラリパッケージも同時にインストールされます。

使い方

以下は主にC#によるサンプルコードで説明していきます。

最も簡単な使い方

LibNMeCab.IpaDicBin をNuGetでインストールするだけで、必要なライブラリと辞書ファイルが一括でプロジェクトに追加され、NMeCabを使う準備が整います。

サンプルコード(C#):

using System;
using NMeCab.Specialized;

class Program
{
    static void Main()
    {
       using (var tagger = MeCabIpaDicTagger.Create()) // Taggerインスタンスを生成
       {
            var nodes = tagger.Parse("皇帝の新しい心"); // 形態素解析を実行
            foreach (var node in nodes) // 形態素ノード配列を順に処理
            {
                Console.WriteLine($"表層形:{node.Surface}");
                Console.WriteLine($"読み :{node.Reading}");
                Console.WriteLine($"品詞 :{node.PartsOfSpeech}");
                Console.WriteLine();
            }
        }
    }
}

サンプルコード(F#):

open NMeCab.Specialized

[<EntryPoint>]
let main argv =
    let sentence = "皇帝の新しい心"
    use tagger = MeCabIpaDicTagger.Create()

    sentence
    |> tagger.Parse
    |> Seq.iter (fun node ->
        printfn $"表層形:{node.Surface}"
        printfn $"読み :{node.Reading}"
        printfn $"品詞 :{node.PartsOfSpeech}"
        printfn "")
    0

サンプルコード(C#)の説明:

まず using NMeCab.Specialized; により、NMeCab.Specialized名前空間を参照します。

次に MeCabIpaDicTagger.Create() により、形態素解析処理の起点となるTaggerインスタンス(MeCabTaggerBase継承クラスのインスタンス)を生成します。

このTaggerインスタンスはIDisposableインターフェースを実装しており、使用後に Dispose() メソッドを呼び出す必要があります。 そのため、このサンプルでは using ステートメントを記述しています。

  • 補足
    • Taggerインスタンスが確保している辞書リソースへのハンドルを解放するのが、この Dispose() メソッドです。(.NETプログラミングに慣れない方は注意して下さい)
    • もちろん、一度確保した辞書リソースを再利用したい場合には、usingステートメントを記述せず、Taggerインスタンスをスコープの広い変数に保持して使い回すこともできます。アプリケーション終了時など任意のタイミングでDisposeしてください。
    • NMeCabのTaggerインスタンスはスレッドセーフです。

そのTaggerインスタンスを使い tagger.Parse("皇帝の新しい心") のように任意の文字列をParseメソッドに渡すだけで、形態素解析を実行できます。

結果は、形態素ノード(MeCabNodeBase継承クラスのインスタンス)の配列の形で返却されるので、ここではforeachループで処理しています。

  • 補足
    • 以前のNMeCabは実行パフォーマンスを重視し、オリジナルのMeCabと同様に、先頭ノードが返却され他のノードへは連結リストをたどってアクセスする方式でした。今のNMeCabでは、Linqなどから使いやすい、配列を返却する方式に変更してあります。
    • また、今でも必要に応じて、連結リスト(Prev、Nextプロパティ)により前後のノードへアクセスできるようにしてあります。

形態素解析により得られた情報が、形態素ノードのプロパティにより取得できます。 このサンプルでは、表層形( Surface )、読み( Reading )、品詞( PartsOfSpeech )を取得しコンソールに出力しています。

サンプルコードの結果:

表層形:皇帝
読み :コウテイ
品詞 :名詞

表層形:の
読み :ノ
品詞 :助詞

表層形:新しい
読み :アタラシイ
品詞 :形容詞

表層形:心
読み :ココロ
品詞 :名詞

他にもプロパティで取得できる情報があります。 VisualStudioのIntelliSenseなどにより閲覧できるよう、XML文書化コメントに記載してあるので確認してみてください。

  • 補足
    • このサンプルでは、IPA辞書を使用しており、Tagger・形態素ノードもIPA辞書に特化したものであるため、IPA辞書フォーマットの素性情報がプロパティにより取得できます。
    • 使用する辞書により「格納されている情報=素性文字列」のフォーマットが異なるので、以前のNMeCabはオリジナルのMeCabと同様に全ての素性文字列をまとめて取得できるだけとしていましたが、今は辞書により異なるプロパティを持つ形態素ノードを使い分ける設計としてあります。詳しくはMeCabNodeBaseクラスのソースコードや、新しい素性フォーマットへの対応を参照してください。
    • IPA辞書はやや古い辞書ですが、サイズが小さく、解析精度・分割一貫性が十分に高く、OSSであるため、最初の使用にお勧めできます。もし異なる辞書を使用したい場合は、次の章を参考にしてください。

辞書を自分で用意して使用する

LibNMeCab だけをNuGetでインストールし、辞書は自分で用意したものを使用することもできます。

辞書ファイルについて

NMeCabで使う辞書ファイルは、MeCabの mecab-dict-index コマンドを使って「解析用バイナリ辞書」にしたものである必要があります。 最初から解析用バイナリ辞書の状態で配布されているものを入手できれば簡単です。 バイナリ化する前の辞書しか入手できないときや、自分で辞書を作成するときは、MeCabのサイトなどを参照してください。 なお、文字コードが選べるときは「utf-8」にしておくことが無難です。

結果として以下のファイルが必要になりますので、任意のディレクトリにまとめて配置してください。これ以外のファイルは、同じディレクトリにあってもなくてもNMeCabの動作には影響しません。

  • char.bin
  • matrix.bin
  • sys.dic
  • uni.dic

Taggerクラスの一覧

NMeCabでは辞書の素性フォーマット別にTaggerクラスを用意してあります。 それぞれ異なる形態素ノードクラスを使用し、異なる素性情報プロパティにアクセスできます。

素性フォーマット 名前空間 Taggarクラス デフォルトの辞書ディレクトリ
汎用 NMeCab MeCabTagger dic
IPA辞書 NMeCab.Specialized MeCabIpaDicTagger IpaDic
UniDic ver 2.1.x NMeCab.Specialized MeCabUniDic21Tagger UniDic
UniDic ver 2.2.x NMeCab.Specialized MeCabUniDic22Tagger UniDic
  • 補足
    • 上記のデフォルトの辞書ディレクトリは、 MeCabTagger.create() のように辞書のパスを指定しなかった場合に適用されます。パスのルートはNMeCabのDLLの配置先です。
    • なお、NuGetで辞書パッケージをインストールした場合、このデフォルトの辞書ディレクトリに辞書ファイルが配置されます。

サンプル

まずは、汎用のTaggerインスタンスを生成して使うサンプルを示します。

サンプルコード(C#):

using System;
using NMeCab;

class Program
{
    static void Main()
    {
        var dicDir = @"C:\Program Files (x86)\MeCab\dic\ipadic"; // 辞書のパス

        using (var tagger = MeCabTagger.Create(dicDir)) // 汎用のTaggerインスタンスを生成
        {
            var nodes = tagger.Parse("皇帝の新しい心"); // 形態素解析を実行
            foreach (var node in nodes) // 形態素ノード配列を順に処理
            {
                Console.WriteLine($"表層形:{node.Surface}");
                Console.WriteLine($"素性 :{node.Feature}"); // 全ての素性文字列
                Console.WriteLine();
            }
        }
    }
}

汎用のTaggerクラス「MeCabTagger」はNMeCab名前空間にあるので、 using NMeCab; を記述しています。

MeCabTagger.Create(dicDir) により辞書のあるディレクトリへのパスを指定して汎用のTaggerインスタンスを生成し、 tagger.Parse(~ で汎用の形態素ノード配列の形で形態素解析結果を取得しています。

  • 補足
    • ここでは、WindowsでMeCabインストーラーを使いデフォルト設定でインストールしたときにIPA辞書ファイルが置かれるパスにしてみましたが、当然、任意のパスを指定できます。
    • このパス文字列は、その環境のランタイムの仕様に従っていれば大丈夫であり、相対パスなども指定可能です。(ちなみにパスの区切り文字をスラッシュにすれば、Windows/Unix系共通で使えるためお勧めです)
    • もし、パスが不正な時、辞書ファイルがない時・壊れている時などは、I/O系の例外がスローされます。

次にIPA辞書用のTaggarインスタンスを生成して使うサンプルを示します。

サンプルコード(C#):

using System;
using NMeCab.Specialized;

class Program
{
    static void Main()
    {
        var dicDir = @"C:\Program Files (x86)\MeCab\dic\ipadic"; // 辞書のパス

        using (var tagger = MeCabIpaDicTagger.Create(dicDir)) // IPAdic形式用のTaggerインスタンスを生成
        {
            var nodes = tagger.Parse("皇帝の新しい心"); // 形態素解析を実行
            foreach (var node in nodes) // 形態素ノード配列を順に処理
            {
                Console.WriteLine($"表層形:{node.Surface}");
                Console.WriteLine($"読み :{node.Reading}"); // 個別の素性
                Console.WriteLine($"品詞 :{node.PartsOfSpeech}"); // 〃
                Console.WriteLine();
            }
        }
    }
}

using NMeCab.Specialized; で名前空間の使用を宣言し、 MeCabIpaDicTagger.Create(dicDir) によって辞書のパスを指定しながらIPA辞書用Taggerインスタンスを生成し、 tagger.Parse(~ でIPA辞書用の形態素ノード配列の形で形態素解析結果を取得しています。

ユーザー辞書を使用する

システム辞書は必ず必要ですが、システム辞書に含まれていない単語を追加したいとき、ユーザー辞書を使うことも可能です。

やはりMeCabで解析用バイナリ辞書にしたファイルを、システム辞書と同じディレクトリに配置してください。 ファイル名は任意です。 複数のユーザー辞書を使用することも可能です。 文字コードと素性フォーマットはシステム辞書と同一にしてください。

サンプルコード(C#):

        var dicDir = @"C:\Program Files (x86)\MeCab\dic\ipadic"; // 辞書のパス
        var userDics = new[] { "usr1.dic", "usr2.dic" }; // ユーザー辞書ファイル名の一覧

        using (var tagger = MeCabIpaDicTagger.Create(dicDir, userDics)) // ユーザー辞書も指定してTaggerインスタンスを生成
        {

Taggerインスタンス生成メソッドの第2引数にユーザー辞書ファイル名の配列を渡すと、システム辞書と同時にそれらのユーザー辞書が読み込まれます。

Nベスト解

ここまでの解説では、Taggerインスタンスの Parse(string sentence) メソッドにより、最も確からしい形態素解析結果だけを取得していました。 Taggerインスタンスの ParseNBest(string sentence) メソッドを使うと、確からしい順番に複数の形態素解析結果を取得できます。 結果はイテレータで、内部の取得処理は遅延実行されます。 下のサンプルでは、LinqのTakeにより上位5件の結果を取得し表示しています。

サンプルコード(C#):

using System;
using System.Linq;
using NMeCab.Specialized;

class Program
{
    static void Main()
    {
        using (var tagger = MeCabIpaDicTagger.Create())
        {
            var results = tagger.ParseNBest("皇帝の新しい心"); // Nベスト解を取得
            foreach (var nodes in results.Take(5)) // 上位から5件までの解を処理
            {
                foreach (var node in nodes) // 形態素ノード配列を順に処理
                {
                    Console.WriteLine($"表層形:{node.Surface}");
                    Console.WriteLine($"読み :{node.Reading}");
                    Console.WriteLine($"品詞 :{node.PartsOfSpeech}");
                    Console.WriteLine();
                }

                Console.WriteLine("----");
            }
        }
    }
}

ソフトわかち書き

Taggerインスタンスの ParseSoftWakachi(string sentence, float theta) メソッドでは、その文章に含まれる可能性がある形態素を洗いざらい取得できます。 また取得した形態素ノードの Prob プロパティにより「その形態素の含まれる確率=周辺確率」も取得できます。 下のサンプルでは、周辺確率の大きな形態素だけを抽出して表示しています。

サンプルコード(C#):

using System;
using System.Linq;
using NMeCab.Specialized;

class Program
{
    static void Main()
    {
        using (var tagger = MeCabIpaDicTagger.Create())
        {
            var theta = 1f / 800f / 2f; // 温度パラメータ
            var nodes = tagger.ParseSoftWakachi("本部長", theta); // ソフトわかち解を取得

            foreach (var node in nodes.Where(n => n.Prob > 0.1f)) // 周辺確率>0.1の形態素ノードだけを処理
            {
                Console.WriteLine($"表層形 :{node.Surface}");
                Console.WriteLine($"読み  :{node.Reading}");
                Console.WriteLine($"品詞  :{node.PartsOfSpeech}");
                Console.WriteLine($"周辺確率:{node.Prob}");
                Console.WriteLine();
            }

            // さらに、周辺確率の上位から表層形の異なるものの5件までを取得
            var searchWords = nodes.OrderByDescending(n => n.Prob)
                                   .Select(n => n.Surface)
                                   .Distinct()
                                   .Take(5);
            Console.WriteLine($"上位ワード:{string.Join(",", searchWords)}");
        }
    }
}

サンプルコードの結果:

表層形 :本部
読み  :ホンブ
品詞  :名詞
周辺確率:0.5966396

表層形 :本
読み  :ホン
品詞  :接頭詞
周辺確率:0.2812245

表層形 :部長
読み  :ブチョウ
品詞  :名詞
周辺確率:0.3622776

表層形 :長
読み  :チョウ
品詞  :名詞
周辺確率:0.5903029

上位ワード:本部,長,部長,本,部

引数 theta は、周辺確率のなめらかさを指定する温度パラメータです。 温度パラメータを大きな値にすると、最も確からしい解の形態素の周辺確率が1または∞、その他は全て0となります。温度パラメータを0に近付けると、中間の周辺確率値も現れます。

  • 補足
    • 日本語の性質上、形態素解析の正解は一つでなく曖昧なケースがあります。またもちろん形態素解析エンジンの精度の限界もあります。そのために考案された手法がソフトわかち書きです。検索エンジンのインデクシングや将来のNLPなどに応用できるはずです。
    • 上のサンプルの温度パラメータには「辞書のコストファクター=800」の逆数の半分を指定していますが、どんな値が良いかを知るには試行錯誤が必要です。

ラティス出力

Taggerインスタンスの ParseToLattice(string sentence) メソッドでは、「解析情報の束=ラティス」のインスタンスを取得できます。

サンプルコード(C#):

using System;
using System.Linq;
using NMeCab.Specialized;

class Program
{
    static void Main()
    {
        using (var tagger = MeCabIpaDicTagger.Create())
        {
            var prm = new MeCabParam()
            {
                LatticeLevel = MeCabLatticeLevel.Two,
                Theta = 1f / 800f / 2f
            };

            var lattice = tagger.ParseToLattice("東京大学", prm); // ラティスを取得

            // ラティスから、ベスト解を取得し処理
            foreach (var node in lattice.GetBestNodes())
            {
                Console.Write(node.Surface);
                Console.CursorLeft = 10;
                Console.Write(node.Feature);
                Console.WriteLine();
            }

            Console.WriteLine("--------");

            // ラティスから、2番目と3番目のベスト解を取得し処理
            foreach (var result in lattice.GetNBestResults().Skip(1).Take(2))
            {
                foreach (var node in result)
                {
                    Console.Write(node.Surface);
                    Console.CursorLeft = 10;
                    Console.Write(node.Feature);
                    Console.WriteLine();
                }

                Console.WriteLine("----");
            }

            Console.WriteLine("--------");

            // ラティスから、開始位置別の形態素を取得し処理
            for (int i = 0; i < lattice.BeginNodeList.Length - 1; i++)
            {
                for (var node = lattice.BeginNodeList[i]; node != null; node = node.BNext)
                {
                    if (node.Prob <= 0.001f) continue;

                    Console.CursorLeft = i * 2;
                    Console.Write(node.Surface);
                    Console.CursorLeft = 10;
                    Console.Write(node.Prob.ToString("F3"));
                    Console.CursorLeft = 16;
                    Console.Write(node.Feature);
                    Console.WriteLine();
                }
            }

            Console.WriteLine("--------");

            // ラティスから、最終的な累積コストのみを取得
            Console.WriteLine(lattice.EosNode.Cost);
        }
    }
}

サンプルコードの結果:

東京大学  名詞,固有名詞,組織,*,*,*,東京大学,トウキョウダイガク,トーキョーダイガク
--------
東京      名詞,固有名詞,地域,一般,*,*,東京,トウキョウ,トーキョー
大学      名詞,一般,*,*,*,*,大学,ダイガク,ダイガク
----
東京      名詞,固有名詞,地域,一般,*,*,東京,トウキョウ,トーキョー
大        名詞,接尾,一般,*,*,*,大,ダイ,ダイ
学        名詞,接尾,一般,*,*,*,学,ガク,ガク
----
--------
東京大学  0.763 名詞,固有名詞,組織,*,*,*,東京大学,トウキョウダイガク,トーキョーダイガク
東京大    0.007 名詞,固有名詞,組織,*,*,*,東京大,トウキョウダイ,トーキョーダイ
東京      0.230 名詞,固有名詞,地域,一般,*,*,東京,トウキョウ,トーキョー
    大学  0.005 名詞,固有名詞,地域,一般,*,*,大学,ダイガク,ダイガク
    大学  0.004 名詞,固有名詞,人名,名,*,*,大学,ダイガク,ダイガク
    大学  0.200 名詞,一般,*,*,*,*,大学,ダイガク,ダイガク
    大    0.010 名詞,接尾,一般,*,*,*,大,ダイ,ダイ
    大    0.001 接頭詞,名詞接続,*,*,*,*,大,オオ,オー
    大    0.003 接頭詞,名詞接続,*,*,*,*,大,ダイ,ダイ
    大    0.005 名詞,一般,*,*,*,*,大,ダイ,ダイ
      学  0.021 名詞,接尾,一般,*,*,*,学,ガク,ガク
      学  0.002 名詞,固有名詞,人名,名,*,*,学,マナブ,マナブ
      学  0.004 名詞,一般,*,*,*,*,学,ガク,ガク
--------
3620

新しい素性フォーマットへの対応

MeCabNodeBaseMeCabTaggerBase を継承した独自のクラスをコーディングします。
このあたりの設計は、キャスト処理やリフレクション(new T)を排除し、利便性や実行パフォーマンスを向上させる目的から、ジェネリクスやラムダを多く使ったものとなっています。

MeCabNodeBase継承クラス

MeCabNodeBase を継承した形態素ノードクラスをコーディングします。この継承時には型引数で自クラスを指定してください。 そして、各々の素性情報の名称のプロパティをコーディングし、CSVである素性情報文字列の任意の列の値を、 GetFeatureAt(1) のように継承元クラスのメソッドで取得するようにしてください。

using NMeCab;

/// <summary>
/// MyDicの形態素ノードです。
/// </summary>
public class MyDicNode : MeCabNodeBase<MyDicNode>
{
    /// <summary>
    /// 素性情報1
    /// </summary>
    public string Feature1
    {
        get { return this.GetFeatureAt(0); }
    }

    /// <summary>
    /// 素性情報2
    /// </summary>
    public string Feature2
    {
        get { return this.GetFeatureAt(1); }
    }
}

MeCabTaggerBase継承クラス

MeCabTaggerBase を継承したTaggerクラスをコーディングします。 これは定型的なコードとなります。 下記をコピーして「MyDic」の部分を書き換えるだけでOKです。

using NMeCab;

/// <summary>
/// MyDicを使用する場合の形態素解析処理の起点を表します。
/// </summary>
public class MyDicTagger : MeCabTaggerBase<MyDicNode>
{
    /// <summary>
    /// コンストラクタ(非公開)
    /// </summary>
    private MyDicTagger()
    { }

    /// <summary>
    /// 形態素解析処理の起点を作成します。
    /// </summary>
    /// <param name="dicDir">使用する辞書のディレクトリへのパス</param>
    /// <param name="userDics">使用するユーザー辞書のファイル名のコレクション</param>
    /// <returns>形態素解析処理の起点</returns>
    public static MyDicTagger Create(string dicDir = null,
                                     string[] userDics = null)
    {
        return Create(dicDir,
                      userDics,
                      () => new MyDicTagger(), // Tagger生成関数
                      () => new MyDicNode(), // 形態素ノード生成関数
                      "MyDic"); // デフォルトの辞書ディレクトリ名
    }
}

使う!

上の2クラスができたら、作成したTaggerクラスのCreateメソッドを呼び出して使用します。

using System;

class Program
{
    static void Main()
    {
        var dicDir = @"C:\Program Files (x86)\MeCab\dic\mydic"; // 辞書のパス

        using (var tagger = MyDicTagger.Create(dicDir)) // MyDic形式用のTaggerインスタンスを生成
        {
            var nodes = tagger.Parse("皇帝の新しい心"); // 形態素解析を実行
            foreach (var node in nodes) // 形態素ノード配列を順に処理
            {
                Console.WriteLine($"素性情報1:{node.Feature1}");
                Console.WriteLine($"素性情報2:{node.Feature2}");
            }
        }
    }
}

ライセンス

NMeCabは GPL v2 / LGPL v2.1 のデュアルライセンスです。 2つのどちらか片方もしくは両方に基づいて使用できます。

  • 補足
    • ごく実用的に言うと「NMeCabをNuGetやDLL参照により使用するなら、個人・企業、商用・非商用、オープンソース・プロプライエタリ、ライセンス種別、どれにも関わらず無償で使用できる」ということです。(少なくともNMeCab開発者個人はこの見解です)
    • 無償なので当然ながら、不具合による損害があったとしてもNMeCab開発者は責任を負いません。
    • NMeCab自体がGPL/LGPLのデュアルライセンスに基づいてMeCabを移植・改変しており、そのことをCOPYINGファイルに記載しています。あなたがNMeCabを利用する際は、できるだけ、なんらかの形で、このCOPYINGファイルの文章を転載してください。あなたがNMeCabをどのライセンスに基づいて使用するのかも表明するようお願いします。

謝辞

Taku Kudo (@taku910) 氏のMeCabという素晴らしいソフトウェアの公開に感謝いたします。

Kouji Matsui (@kekyo) 氏の素晴らしい情報とコードの公開に感謝いたします。 LibNMeCab.IpaDicBin の辞書ファイルをNuGet/MSBuildで扱うコードは、 @kekyo氏によるGPL/LGPLデュアルライセンスのオープンソースをほぼそのまま使用させて頂いたものです。

リリースノート

メジャーバージョン番号を今でも0にしているのは、ベースにしたMeCabのバージョン番号を超えないようにするためです。

nmecab's People

Contributors

alissasabre avatar komutan avatar sj-h4 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

nmecab's Issues

Deal with “At 100% of Git LFS data quota”

UniDicをGit LFSでリポジトリにアップしたところ、翌日にGitHubからのメールで、1GBのストレージ容量を超えているとの知らせが。
対処が必要。

MeCabUniDicNode is incompatible with UniDic 2.2.0 or later

When using UniDic 2.3.0 (the latest version released on 2018) with NMeCab, some feature properties return wrong values. In particular, Kana, KanaBase, Form, FormBase, IConType, FConType, AType, AConType, and AModType are wrong.

I believe it is due to UniDic's breaking change on its feature layout made between UniDic 2.1.2 and 2.2.0. The new layout used in the recent releases are called "node-format-unidic22" in their dicrc file. As a result, when using the binary dictionary files distributed by NINJAL, the MeCabUniDicNode properties mentioned above return wrong values if the version of the UniDic is 2.2.0 or later.

I believe MeCabUniDicNode should be updated to support node-format-unidic22 (or, alternatively, another type, e.g., MeCabUniDic22Node, be added, preserving the existing type for the older versions of UniDic.)

Discussion: Could we merge project/packages both MeCab.DotNet and LibNMeCab

こんにちは、komutanさんの方の更新が続いていて良かったです。

私の方のMeCab.DotNetの方も、主に環境面でのissueについて更新を行っていますが、komutanさんの方の変更に追従できていなくて、どうしようかと思っています。いっそのこと、こちらのプロジェクトとの統合を考えてみたらどうだろうかと考え、まずは意見を聞きたくてissueを立てました。

MeCab.DotNetは、そもそも私がとあるイベント向けに.NET Core環境で使いたくて移植した、という経緯があったのですが、公開後、海外の方にも使われていることが分かり、(主に開発環境面での更新、例えば.NET Coreの新しいバージョンが出たなどで困らないよう)半ば義務感で更新を続けている状況です。

(イベントについては長文ですが私のブログにまとめています

いくつか私的なプロジェクト(主に非公開)で使用しているのですが、形態素解析自体の知識があるわけではないので、あくまで前述の範囲での更新となってしまっているのが気になっています。恐らくは、コア部分の機能改善についてはkomutanさんの方が進んでいると思いますので、例えば現在のように開発環境面での更新や機能強化という点で協力できる部分があると思います。

そこで、2つのプロジェクトの統合を考えたのですが、別々にforkしていた方が開発がやりやすいとか何か理由があるようでしたら、それはそれでも一向に構いませんので、そのように言って頂ければと思います。

統合した場合の問題点について、まだあまり深く考えていませんが:

  • ソースコードの統合: 何とか頑張ってやる :)
    • 外部インターフェイスの問題としては、一番大きなのは名前空間かなと思います。
    • 私案では、しばらく2つの名前空間のどちらでも参照できるような構造をとって、Obsoleteつけるなどして、最終的にどちらかに移行するのが良いかなと思います。
  • NuGetパッケージ: 上記のようなダブルインターフェイス定義されたライブラリを、別々のパッケージで(中身は同じで)配布しつつ、Obsoleteを付けて、最終的にどちらかに統一するという方法を考えます。
  • メソッドやプロパティの一部の(同居できない)非互換があれば、そこはbreaking changeで妥協する。

とりあえず、今思いついていることは書き出してみましたが、何か意見があればお願いします。

publish to nuget

まずは以下のαバージョン

  • ライブラリ本体のみのパッケージ
    — nmecabというnuget idは既に使用されていたので、libnmecabで。
    — sdk形式プロジェクトファイルによりビルド
  • ipadic付きパッケージ
    — 上記ライブラリ本体と依存するが、別のパッケージとする
    — 辞書ファイルを意識せず、静的メソッドでTaggerインスタンスを生成するだけで使用可能にする
    @kekyo 氏が、素晴らしいノウハウと更にソースコードも公開されているので、OSSとして流用させて頂く。

Support for the latest version of UniDic

Hello,

I'm trying to use NMeCab in my project, however I've noticed the code hasn't been updated since last year, and from what I can tell, the version of UniDic used in the latest version of NMeCab is obsolete.

In the code I have the option of crating a MeCabUniDic22Tagger, or an even older one MeCabUniDic21Tagger.

However it seems the latest version of UniDic is 3.1.

Could you provide an update that will bring the UniDic used in the project to the latest version?

Or is the current implementation compatible with the latest version of UniDic? Can I just swap the dictionary files in my project?

Option to modify IpaDic folder path

It's there a way to change the folder path where the IpaDic files are located when adding the library as PackageReference in the project file?

VBAで「クラスが登録されていません」と表示される

setup.batで登録後、参照設定を変更し、NMecabComにチェックを入れましたが、NmcParamオブジェクトで
「クラスが登録されていません」と表示されます。CreateObjectでも同様のエラーが表示されます。

im tagger As New NmcTagger
    Dim nodes As NmcNodeCollection
 'Dim param As New NmcParam
    Dim param As Object
    Set param = CreateObject("NMeCabCom.NmcParam")
    Debug.Assert Not (param Is Nothing)
    param.DicDir = "C:\NMeCabCom\bin\ipadic"
    
    '辞書の読み込み
    tagger.Create param
    
    Set nodes = tagger.Parse(text)
    Dim i As Integer
    For i = 0 To c.Count - 1
        Debug.Print nodes.GetItem(i).Surface & " " & nodes.GetItem(i).Feature
    Next

入力文字数が多いとtoo long sentence. という例外が発生する

300,000文字~650,000文字以上のstringを
MeCabTaggerのParseToNode()メソッドに入力すると
"too long sentence. "というメッセージの例外が発生します。

とりあえず入力文字列を分割して回避したのですが、
エレガントな解決方法があれば教えてください。

ちなみに例外が発生する文字数の閾値は
半角文字と全角文字の割合に依存しているようです。
英語の文章だと650,000文字程度のstringでも例外が発生しません。
日本語の文章だと上限の文字数が小さくなるようです。

Commercial Use

May I use this library in a commercial project? (feel free to answer in japanese)

Missing BSD file?

COPYINGファイルにBSDライセンスの記載がありますが、実体となるBSDファイルがないようです。

MeCabと同じ形態であれば下記のファイルと同等でしょうか?
オリジナルのBSD(四条項)なのか、修正BSD(三条項)なのかが不明だったので登録させていただきました。

https://github.com/taku910/mecab/blob/master/mecab/BSD

IndexOutOfRangeException from Parse method when the input ends with extra spaces

MeCabIpaDicTagger.Parse(string) throws IndexOutOfRangeException if the input string (the sentence parameter) contains one or more extra space (U+0020) characters at its end.

I think it should just parse the input, ignoring those extra spaces. Alternatively, it should indicate the error condition in a more reasonable manner, e.g., throwing ArgumentException("sentence"), if such a string should really be considered an error.

Sample code to reproduce the issue (please note a space after れ):

using System;
using NMeCab;

namespace NMecabIssue
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                using (var tagger = NMeCabIpaDic.CreateTagger())
                {
                    tagger.Parse("あれ ");
                }
            }
            catch (Exception e)
            {
                Console.Out.Write(e.ToString());
            }
        }
    }
}

Observed behaviour: to print an IndexOutOfRangeException.
Expected behaviour: to print nothing.
Tested version: LibNMeCab.IpaDicBin v0.10.0-beta (Downloaded with nuget)

Tagger creation throws IOException if another process uses the same dictionary in NMeCab

A Tagger creation method, such as NMeCabIpaDic.CreateTagger() or MeCabUniDicTagger.Create(string), throws IOException if another process is using the same set of dictionary files through NMeCab library. Considering the fact that NMeCab never updates/writes to dictionary files, I think the library should allow sharing of the same dictionary files between multiple processes.

Reproduction steps:

  1. Run my NMeCabDemo program by double clicking on the file NMeCabDemo.exe. The window of the program opens.
  2. Double click on the same file again while the first application window is still open.

Expected behaviour:
The second application window opens.

Observed behaviour:
A message box showing an IOException opens.

(Note that you need to use the latest version (v1.0.2) of the NMeCabDemo program to verify the above reproduction steps, because earlier versions included a bug to ignore the Exception during initialization...)

ユーザー辞書を使うときにincompatible dictionaryエラー

@komutan さん

お世話になります。

下記のコードでユーザー辞書user.dicを呼び出そうとすると、

            var mecabPath = Path.Combine(executionContext.FunctionAppDirectory, "Function", "ExtractContent", "MecabDic");
            using (var tagger = MeCabTagger.Create(mecabPath, new string[] { "user.dic" }))

LibNMeCab: incompatible dictionary. というエラーが発生します。

ソリューション: .Net Core 3.1 Azure Function
Nugetバージョン:LibNMeCab 0.10.0 Sunday, September 6, 2020 (9/6/2020)
フォルダ構成:

image

  • user.dicを外せば動けます。
  • user.dicはmecab-dict-indexで、-f -t utf-8, UTF-8, utf8など、色んな組み合わせでコンバインしてみたが、NGでした。
  • sys.dicはneologd辞書を使っています。
  • 上記の辞書一式をPyhthon Azure Functionでそのまま使う場合は問題なくできています。

辞書のコンバインではなく、NMecab自体の問題の可能性はございませんか?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.