DeepMorphy 是一种基于神经网络的俄语词法分析器。
DeepMorphy 是俄语的词法分析器。作为 .Net Standard 2.0 库提供。能:
DeepMorphy 中的术语部分借用自 pymorphy2 形态分析器。
Grammeme (英语 grammeme)- 单词的语法类别之一的含义(例如,过去时、单数、阳性)。
语法类别是一组互斥的语法,它们描述了一些共同特征(例如,性别、时态、格等)。 DeepMorphy 支持的所有类别和语法的列表位于此处。
标签(英语标签)- 一组表征给定单词的语法(例如,单词刺猬的标签 - 名词、单数、主格、阳性)。
Lemma (英语引理)是单词的正常形式。
词形还原(eng. lemmatization) - 将单词恢复为正常形式。
词位是一个单词的所有形式的集合。
DeepMorphy 的核心要素是神经网络。对于大多数单词,形态分析和词形还原是由网络执行的。某些类型的单词由预处理器处理。
有 3 个预处理器:
该网络是在张量流框架上构建和训练的。 Opencorpora 字典用作数据集。通过 TensorFlowSharp 集成到 .Net 中。
DeepMorphy 中单词解析的计算图由 11 个“子网”组成:
改变单词形式的问题是通过1 seq2seq网络来解决的。
训练按顺序进行,首先按类别训练网络(顺序无关紧要)。接下来,训练主要的标签分类、词形还原和用于改变单词形式的网络。训练是在 3 个 Titan X GPU 上进行的,可以在此处查看最新版本测试数据集的网络性能指标。
DeepMorphy for .NET 是一个 .Net Standard 2.0 库。唯一的依赖项是 TensorflowSharp 库(神经网络通过它启动)。
该库在 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 [ "число" ] ) ;
当您同时需要有关多个语法类别的信息(例如,词性和数字)时,可以使用标签。如果您只对一种类别感兴趣,那么您可以使用 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 ) ;
}
如果只需要词形还原而不需要词法解析,那么需要使用 Lemmatize 方法:
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 ( ) ;
该算法的特点之一是,当改变形式或生成词位时,网络可以“发明”单词的不存在(假设)形式,即语言中未使用的形式。例如,下面你会看到“will run”这个词,尽管目前该语言中并没有特别使用它。
var tasks = new [ ]
{
new InflectTask ( "победить" ,
m . TagHelper . CreateTag ( "инф_гл" ) ,
m . TagHelper . CreateTag ( "гл" , nmbr : "ед" , tens : "буд" , pers : "1л" , mood : "изъяв" ) )
} ;
Console . WriteLine ( m . Inflect ( tasks ) . First ( ) ) ;