DeepMorphy es un analizador morfológico basado en redes neuronales para el idioma ruso.
DeepMorphy es un analizador morfológico del idioma ruso. Disponible como biblioteca .Net Standard 2.0. Poder:
La terminología en DeepMorphy está parcialmente tomada del analizador morfológico pymorphy2.
Grammeme (grammeme inglés): el significado de una de las categorías gramaticales de una palabra (por ejemplo, tiempo pasado, singular, masculino).
Una categoría gramatical es un conjunto de gramáticas mutuamente excluyentes que caracterizan algún rasgo común (por ejemplo, género, tiempo, caso, etc.). Aquí encontrará una lista de todas las categorías y gramáticas admitidas en DeepMorphy.
Etiqueta (etiqueta en inglés): un conjunto de gramáticas que caracterizan una palabra determinada (por ejemplo, una etiqueta para la palabra erizo - sustantivo, singular, caso nominativo, masculino).
Lemma (lema en inglés) es la forma normal de una palabra.
Lematización (ing. lematización): llevar una palabra a su forma normal.
Un lexema es un conjunto de todas las formas de una palabra.
El elemento central de DeepMorphy es la red neuronal. Para la mayoría de las palabras, la red realiza el análisis morfológico y la lematización. Algunos tipos de palabras son procesados por preprocesadores.
Hay 3 preprocesadores:
La red fue construida y entrenada en el marco de tensorflow. El diccionario Opencorpora sirve como conjunto de datos. Integrado en .Net a través de TensorFlowSharp.
El gráfico de cálculo para el análisis de palabras en DeepMorphy consta de 11 "subredes":
El problema de cambiar la forma de las palabras se resuelve mediante una red de 1 seq2seq.
El entrenamiento se realiza de forma secuencial, primero se entrenan las redes por categoría (el orden no importa). A continuación se entrena la clasificación principal por etiquetas, lematización y una red para cambiar la forma de las palabras. La capacitación se llevó a cabo en 3 GPU Titan X. Las métricas de rendimiento de la red en el conjunto de datos de prueba para la última versión se pueden ver aquí.
DeepMorphy para .NET es una biblioteca .Net Standard 2.0. Las únicas dependencias son la biblioteca TensorflowSharp (la red neuronal se inicia a través de ella).
La biblioteca está publicada en Nuget, por lo que es más fácil instalarla a través de ella.
Si hay un administrador de paquetes:
Install-Package DeepMorphy
Si el proyecto admite PackageReference:
<PackageReference Include="DeepMorphy"/>
Si alguien quiere compilar a partir de fuentes, entonces las fuentes de C# están aquí. Rider se utiliza para el desarrollo (todo debe montarse en el estudio sin ningún problema).
Todas las acciones se realizan a través del objeto de clase MorphAnalyzer:
var morph = new MorphAnalyzer ( ) ;
Idealmente, es mejor usarlo como singleton al crear un objeto, se dedica algo de tiempo a cargar diccionarios y la red. Hilo seguro. Al crear, puede pasar los siguientes parámetros al constructor:
Para el análisis, se utiliza el método Parse (toma un IEnumerable con palabras para el análisis como entrada y devuelve un IEnumerable con el resultado del análisis).
var results = morph . Parse ( new string [ ]
{
"королёвские" ,
"тысячу" ,
"миллионных" ,
"красотка" ,
"1-ый"
} ) . ToArray ( ) ;
var morphInfo = results [ 0 ] ;
La lista de categorías gramaticales admitidas, gramos y sus claves está aquí. Si necesita encontrar la combinación más probable de gramemas (etiqueta), entonces necesita usar la propiedad BestTag del objeto MorphInfo.
// выводим лучшую комбинацию граммем для слова
Console . WriteLine ( morphInfo . BestTag ) ;
Basándose en la palabra en sí, no siempre es posible determinar sin ambigüedades el significado de sus categorías gramaticales (ver homónimos), por lo que DeepMorphy le permite ver las etiquetas principales de una palabra determinada (propiedad Etiquetas).
// выводим все теги для слова + их вероятность
foreach ( var tag in morphInfo . Tags )
Console . WriteLine ( $ " { tag } : { tag . Power } " ) ;
¿Hay una combinación de gramos en alguna de las etiquetas?
// есть ли в каком-нибудь из тегов прилагательные единственного числа
morphInfo . HasCombination ( "прил" , "ед" ) ;
¿Hay una combinación de gramos en la etiqueta más probable?
// ясляется ли лучший тег прилагательным единственного числа
morphInfo . BestTag . Has ( "прил" , "ед" ) ;
Recuperar categorías gramaticales específicas de la mejor etiqueta:
// выводит часть речи лучшего тега и число
Console . WriteLine ( morphInfo . BestTag [ "чр" ] ) ;
Console . WriteLine ( morphInfo . BestTag [ "число" ] ) ;
Las etiquetas se utilizan cuando se necesita información sobre varias categorías gramaticales a la vez (por ejemplo, parte del discurso y número). Si solo está interesado en una categoría, puede utilizar la interfaz para las probabilidades de los significados de las categorías gramaticales de los objetos MorphInfo.
// выводит самую вероятную часть речи
Console . WriteLine ( morphInfo [ "чр" ] . BestGramKey ) ;
También puedes obtener la distribución de probabilidad por categoría gramatical:
// выводит распределение вероятностей для падежа
foreach ( var gram in morphInfo [ "падеж" ] . Grams )
{
Console . WriteLine ( $ " { gram . Key } : { gram . Power } " ) ;
}
Si, junto con el análisis morfológico, es necesario obtener lemas de palabras, entonces el analizador debe crearse de la siguiente manera:
var morph = new MorphAnalyzer ( withLemmatization : true ) ;
Los lemas se pueden obtener a partir de etiquetas de palabras:
Console . WriteLine ( morphInfo . BestTag . Lemma ) ;
Comprobar si una palabra determinada tiene un lema:
morphInfo . HasLemma ( "королевский" ) ;
El método CanBeSameLexeme se puede utilizar para encontrar palabras de un solo lexema:
// выводим все слова, которые могут быть формой слова королевский
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 ) ;
}
Si solo necesita lematización sin análisis morfológico, entonces debe utilizar el método 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 puede cambiar la forma de una palabra dentro de un lexema; la lista de inflexiones admitidas está aquí. Las palabras del diccionario sólo se pueden cambiar dentro de aquellas formas que están disponibles en el diccionario. Para cambiar la forma de las palabras, se utiliza el método Inflect; toma como entrada una enumeración de objetos InflectTask (contiene la palabra fuente, la etiqueta de la palabra fuente y la etiqueta en la que se debe colocar la palabra). El resultado es una enumeración con los formularios requeridos (si el formulario no se pudo procesar, entonces es nulo).
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 ) ;
También es posible obtener todas las formas de una palabra utilizando el método Lexeme (para las palabras del diccionario devuelve todo el contenido del diccionario, para otras, todas las formas de las inflexiones admitidas).
var word = "лемматизировать" ;
var tag = m . TagHelper . CreateTag ( "инф_гл" ) ;
var results = m . Lexeme ( word , tag ) . ToArray ( ) ;
Una de las características del algoritmo es que al cambiar la forma o generar un lexema, la red puede "inventar" una forma inexistente (hipotética) de la palabra, una forma que no se utiliza en el idioma. Por ejemplo, a continuación aparece la palabra "se ejecutará", aunque por el momento no se usa particularmente en el idioma.
var tasks = new [ ]
{
new InflectTask ( "победить" ,
m . TagHelper . CreateTag ( "инф_гл" ) ,
m . TagHelper . CreateTag ( "гл" , nmbr : "ед" , tens : "буд" , pers : "1л" , mood : "изъяв" ) )
} ;
Console . WriteLine ( m . Inflect ( tasks ) . First ( ) ) ;