DeepMorphy は、ニューラル ネットワーク ベースのロシア語形態素解析ツールです。
DeepMorphy は、ロシア語の形態素解析ツールです。 .Net Standard 2.0 ライブラリとして利用可能です。できる:
DeepMorphy の用語は、pymorphy2 形態素解析器から部分的に借用されています。
グラムミーム(英語のグラムミーム) - 単語の文法カテゴリーの 1 つの意味 (過去形、単数形、男性形など)。
文法カテゴリは、いくつかの共通の特徴 (性別、時制、格など) を特徴付ける、相互に排他的な文法のセットです。 DeepMorphy でサポートされているすべてのカテゴリと文法のリストはここにあります。
タグ(英語のタグ) - 特定の単語を特徴付けるグラムのセット (たとえば、単語 hedgehog のタグ - 名詞、単数、主格、男性)。
Lemma (英語の補題) は単語の通常の形式です。
見出し語化(英語 lemmatization) - 単語を通常の形式に戻す。
語彙素は、 1 つの単語のすべての形式のセットです。
DeepMorphy の中核要素はニューラル ネットワークです。ほとんどの単語について、形態素解析と見出し語化はネットワークによって実行されます。一部の種類の単語はプリプロセッサによって処理されます。
プリプロセッサは 3 つあります。
ネットワークは、tensorflow フレームワーク上で構築およびトレーニングされました。 Opencorpora 辞書はデータセットとして機能します。 TensorFlowSharp を介して .Net に統合されます。
DeepMorphy での単語解析の計算グラフは、11 の「サブネット」で構成されます。
単語の形式を変える問題は、1 seq2seq ネットワークによって解決されます。
トレーニングは順番に実行され、最初にネットワークがカテゴリ別にトレーニングされます (順序は重要ではありません)。次に、タグによる主な分類、見出し語化、単語の形式を変更するネットワークを学習します。トレーニングは 3 つの Titan X GPU で実行されました。最新リリースのテスト データセットのネットワーク パフォーマンス メトリクスは、ここで確認できます。
DeepMorphy for .NET は .Net Standard 2.0 ライブラリです。唯一の依存関係は TensorflowSharp ライブラリです (ニューラル ネットワークは TensorflowSharp ライブラリを通じて起動されます)。
ライブラリは Nuget で公開されているため、Nuget を介してインストールするのが最も簡単です。
パッケージマネージャーがある場合:
Install-Package DeepMorphy
プロジェクトが PackageReference をサポートしている場合:
<PackageReference Include="DeepMorphy"/>
ソースからビルドしたい場合は、C# ソースがここにあります。 Rider は開発に使用されます (すべて問題なくスタジオで組み立てられるはずです)。
すべてのアクションは、MorphAnalyzer クラス オブジェクトを通じて実行されます。
var morph = new MorphAnalyzer ( ) ;
理想的には、オブジェクトを作成するときに辞書とネットワークのロードに時間がかかるため、これをシングルトンとして使用することをお勧めします。スレッドセーフ。作成時に、次のパラメーターをコンストラクターに渡すことができます。
解析には、Parse メソッドが使用されます (分析対象の単語を含む IEnumerable を入力として受け取り、分析の結果を含む IEnumerable を返します)。
var results = morph . Parse ( new string [ ]
{
"королёвские" ,
"тысячу" ,
"миллионных" ,
"красотка" ,
"1-ый"
} ) . ToArray ( ) ;
var morphInfo = results [ 0 ] ;
サポートされている文法カテゴリ、グラム、およびそのキーのリストはここにあります。グラム素 (タグ) の最も可能性の高い組み合わせを見つける必要がある場合は、MorphInfo オブジェクトの BestTag プロパティを使用する必要があります。
// выводим лучшую комбинацию граммем для слова
Console . WriteLine ( morphInfo . BestTag ) ;
単語自体に基づいて、その文法カテゴリの意味を明確に判断できるとは限らないため (同音異義語を参照)、DeepMorphy を使用すると、特定の単語の上位タグ (Tags プロパティ) を表示できます。
// выводим все теги для слова + их вероятность
foreach ( var tag in morphInfo . Tags )
Console . WriteLine ( $ " { tag } : { tag . Power } " ) ;
いずれかのタグにグラム数の組み合わせがありますか:
// есть ли в каком-нибудь из тегов прилагательные единственного числа
morphInfo . HasCombination ( "прил" , "ед" ) ;
最も可能性の高いタグにグラムの組み合わせはありますか:
// ясляется ли лучший тег прилагательным единственного числа
morphInfo . BestTag . Has ( "прил" , "ед" ) ;
最適なタグから特定の文法カテゴリを取得します。
// выводит часть речи лучшего тега и число
Console . WriteLine ( morphInfo . BestTag [ "чр" ] ) ;
Console . WriteLine ( morphInfo . BestTag [ "число" ] ) ;
タグは、複数の文法カテゴリに関する情報 (品詞や数字など) を一度に必要とする場合に使用されます。 1 つのカテゴリのみに興味がある場合は、MorphInfo オブジェクトの文法カテゴリの意味の確率へのインターフェイスを使用できます。
// выводит самую вероятную часть речи
Console . WriteLine ( morphInfo [ "чр" ] . BestGramKey ) ;
文法カテゴリーごとの確率分布を取得することもできます。
// выводит распределение вероятностей для падежа
foreach ( var gram in morphInfo [ "падеж" ] . Grams )
{
Console . WriteLine ( $ " { gram . Key } : { gram . Power } " ) ;
}
形態素解析とともに単語の補題を取得する必要がある場合は、アナライザーを次のように作成する必要があります。
var morph = new MorphAnalyzer ( withLemmatization : true ) ;
補題は単語タグから取得できます。
Console . WriteLine ( morphInfo . BestTag . Lemma ) ;
指定された単語に補題があるかどうかを確認します。
morphInfo . HasLemma ( "королевский" ) ;
CanBeSameLexeme メソッドを使用すると、単一の語彙素の単語を検索できます。
// выводим все слова, которые могут быть формой слова королевский
var words = new string [ ]
{
"королевский" ,
"королевские" ,
"корабли" ,
"пересказывают" ,
"королевского"
} ;
var results = morph . Parse ( words ) . ToArray ( ) ;
var mainWord = results [ 0 ] ;
foreach ( var morphInfo in results )
{
if ( mainWord . CanBeSameLexeme ( morphInfo ) )
Console . WriteLine ( morphInfo . Text ) ;
}
形態解析を行わずに見出し語化のみが必要な場合は、見出し語化メソッドを使用する必要があります。
var tasks = new [ ]
{
new LemTask ( "синяя" , morph . TagHelper . CreateTag ( "прил" , gndr : "жен" , nmbr : "ед" , @case : "им" ) ) ,
new LemTask ( "гуляя" , morph . TagHelper . CreateTag ( "деепр" , tens : "наст" ) )
} ;
var lemmas = morph . Lemmatize ( tasks ) . ToArray ( ) ;
foreach ( var lemma in lemmas )
Console . WriteLine ( lemma ) ;
DeepMorphy は語彙素内の単語の形式を変更できます。サポートされている語形変化のリストはここにあります。辞書の単語は、辞書で使用可能な形式内でのみ変更できます。単語の形式を変更するには、Inflect メソッドが使用されます。このメソッドは、InflectTask オブジェクトの列挙 (ソース単語、ソース単語のタグ、および単語を配置するタグを含みます) を入力として受け取ります。出力は、必要なフォームの列挙です (フォームを処理できなかった場合は null)。
var tasks = new [ ]
{
new InflectTask ( "синяя" ,
morph . TagHelper . CreateTag ( "прил" , gndr : "жен" , nmbr : "ед" , @case : "им" ) ,
morph . TagHelper . CreateTag ( "прил" , gndr : "муж" , nmbr : "ед" , @case : "им" ) ) ,
new InflectTask ( "гулять" ,
morph . TagHelper . CreateTag ( "инф_гл" ) ,
morph . TagHelper . CreateTag ( "деепр" , tens : "наст" ) )
} ;
var results = morph . Inflect ( tasks ) ;
foreach ( var result in results )
Console . WriteLine ( result ) ;
Lexeme メソッドを使用して、単語のすべての形式を取得することもできます (辞書の単語の場合は辞書からすべてを返し、他の単語の場合はサポートされている語形変化からすべての形式を返します)。
var word = "лемматизировать" ;
var tag = m . TagHelper . CreateTag ( "инф_гл" ) ;
var results = m . Lexeme ( word , tag ) . ToArray ( ) ;
このアルゴリズムの特徴の 1 つは、形式を変更したり語彙素を生成したりするときに、ネットワークが単語の存在しない (仮説的な) 形式、つまり言語で使用されていない形式を「発明」できることです。たとえば、以下に「will run」という単語がありますが、現時点ではこの言語では特に使用されていません。
var tasks = new [ ]
{
new InflectTask ( "победить" ,
m . TagHelper . CreateTag ( "инф_гл" ) ,
m . TagHelper . CreateTag ( "гл" , nmbr : "ед" , tens : "буд" , pers : "1л" , mood : "изъяв" ) )
} ;
Console . WriteLine ( m . Inflect ( tasks ) . First ( ) ) ;