Python - подходы к лемматизации с примерами

Опубликовано: 4 Января, 2022

Ниже приводится пошаговое руководство по изучению различных подходов к лемматизации в Python, а также несколько примеров и реализации кода. Настоятельно рекомендуется придерживаться данного потока, если у вас нет понимания темы, и в этом случае вы можете найти любой из подходов, приведенных ниже.

Что такое лемматизация?
В отличие от стемминга, лемматизация намного мощнее. Он выходит за рамки сокращения слов и рассматривает весь словарный запас языка для применения морфологического анализа к словам, стремясь удалить только флективные окончания и вернуть базовую или словарную форму слова, известную как лемма .

Для ясности взгляните на следующие примеры, приведенные ниже:

 Оригинальное слово ---> Корневой Word (лемма) Характеристика

   встреча ---> встреча (извлечение основного слова)
   было ---> быть (преобразование времени в настоящее время)
   мыши ---> мышь (от множественного числа до единственного числа)

TIP: Always convert your text to lowercase before performing any NLP task including lemmatizing.

Различные подходы к лемматизации:
Мы рассмотрим 9 различных подходов к выполнению лемматизации, а также несколько примеров и реализаций кода.

  1. WordNet
  2. WordNet (с тегом POS)
  3. TextBlob
  4. TextBlob (с тегом POS)
  5. СПАСИБО
  6. TreeTagger
  7. Шаблон
  8. Gensim
  9. Стэнфордский CoreNLP

1. Лемматизатор Wordnet
Wordnet - это общедоступная лексическая база данных более чем 200 языков, которая обеспечивает семантические отношения между своими словами. Это одна из самых ранних и наиболее часто используемых техник лемматизирования.

  • Он присутствует в библиотеке nltk в Python.
  • Wordnet связывает слова в смысловые отношения. (например, синонимы)
  • Он группирует синонимы в виде синсетов .
    • synsets : группа элементов данных, которые семантически эквивалентны.

Как использовать:

  1. Загрузите пакет nltk : в командной строке или в терминале anaconda введите:
    pip install nltk
  2. Загрузите Wordnet с сайта nltk : в консоли pyhton выполните следующие действия:
    import nltk
    nltk.download('wordnet')
    nltk.download('averaged_perceptron_tagger')

Код:

import nltk
nltk.download( 'wordnet' )
from nltk.stem import WordNetLemmatizer
# Create WordNetLemmatizer object
wnl = WordNetLemmatizer()
# single word lemmatization examples
list1 = [ 'kites' , 'babies' , 'dogs' , 'flying' , 'smiling' ,
'driving' , 'died' , 'tried' , 'feet' ]
for words in list1:
print (words + " ---> " + wnl.lemmatize(words))
#> kites ---> kite
#> babies ---> baby
#> dogs ---> dog
#> flying ---> flying
#> smiling ---> smiling
#> driving ---> driving
#> died ---> died
#> tried ---> tried
#> feet ---> foot

Код:

# sentence lemmatization examples
string = 'the cat is sitting with the bats on the striped mat under many flying geese'
# Converting String into tokens
list2 = nltk.word_tokenize(string)
print (list2)
#> ['the', 'cat', 'is', 'sitting', 'with', 'the', 'bats', 'on',
# 'the', 'striped', 'mat', 'under', 'many', 'flying', 'geese']
lemmatized_string = ' ' .join([wnl.lemmatize(words) for words in list2])
print (lemmatized_string)
#> the cat is sitting with the bat on the striped mat under many flying goose

2. Лемматизатор Wordnet (с тегом POS)
В описанном выше подходе мы заметили, что результаты Wordnet не были на должном уровне. Такие слова, как «сидеть», «летать» и т. Д., Остались прежними после лемматизации. Это потому, что в данном предложении эти слова рассматриваются как существительные, а не как глаголы. Чтобы решить эту проблему, мы используем теги POS (часть речи).

Мы добавляем тег с определенным словом, определяющим его тип (глагол, существительное, прилагательное и т. Д.).
Например,

Слово + Тип (тег POS) -> Лемматизированное слово
вождение + глагол 'v' -> драйв
собаки + существительное -> собака

Код:

3. TextBlob
TextBlob - это библиотека Python, используемая для обработки текстовых данных. Он предоставляет простой API для доступа к своим методам и выполнения основных задач НЛП.
Загрузите пакет TextBlob: в командной строке или в терминале anaconda введите:
pip install textblob

Код:

from textblob import TextBlob, Word
my_word = 'cats'
# create a Word object
w = Word(my_word)
print (w.lemmatize())
#> cat
sentence = 'the bats saw the cats with stripes hanging upside down by their feet.'
s = TextBlob(sentence)
lemmatized_sentence = " " .join([w.lemmatize() for w in s.words])
print (lemmatized_sentence)
#> the bat saw the cat with stripe hanging upside down by their foot

4. TextBlob (с тегом POS)
То же, что и в подходе Wordnet без использования соответствующих тегов POS, мы наблюдаем те же ограничения и в этом подходе. Итак, мы используем один из наиболее мощных аспектов модуля TextBlob - теги «Часть речи», чтобы решить эту проблему.

Код:

from textblob import TextBlob
# Define function to lemmatize each word with its POS tag
# POS_TAGGER_FUNCTION : TYPE 2
def pos_tagger(sentence):
sent = TextBlob(sentence)
tag_dict = { "J" : 'a' , "N" : 'n' , "V" : 'v' , "R" : 'r' }
words_tags = [(w, tag_dict.get(pos[ 0 ], 'n' )) for w, pos in sent.tags]
lemma_list = [wd.lemmatize(tag) for wd, tag in words_tags]
return lemma_list
# Lemmatize
sentence = "the bats saw the cats with stripes hanging upside down by their feet"
lemma_list = pos_tagger(sentence)
lemmatized_sentence = " " .join(lemma_list)
print (lemmatized_sentence)
#> the bat saw the cat with stripe hang upside down by their foot
lemmatized_sentence = " " .join([w.lemmatize() for w in t_blob.words])
print (lemmatized_sentence)
#> the bat saw the cat with stripe hanging upside down by their foot

Here is a link for all the types of tag abbreviations with their meanings. (scroll down for the tags table)

5. СПАСИБО
spaCy - это библиотека Python с открытым исходным кодом, которая анализирует и «понимает» большие объемы текста. Доступны отдельные модели для определенных языков (английский, французский, немецкий и т. Д.).

Загрузите пакет spaCy : (a) Откройте приглашение или терминал anaconda от имени администратора и выполните команду:
                pip install -U spacy
                
            (b) Теперь откройте программу или терминал anaconda в обычном режиме и выполните команду:
                python -m spacy download en

В случае успеха вы должны увидеть такое сообщение:

    Связывание выполнено успешно
    C:  Anaconda3  envs  spacyenv  lib  site-packages  en_core_web_sm ->
    C:  Anaconda3  envs  spacyenv  lib  site-packages  spacy  data  en

Теперь вы можете загрузить модель через nlp = spacy.load('en_core_web_sm')

Код:

import spacy
nlp = spacy.load( 'en_core_web_sm' )
# Create a Doc object
doc = nlp(u 'the bats saw the cats with best stripes hanging upside down by their feet' )
# Create list of tokens from given string
tokens = []
for token in doc:
tokens.append(token)
print (tokens)
#> [the, bats, saw, the, cats, with, best, stripes, hanging, upside, down, by, their, feet]
lemmatized_sentence = " " .join([token.lemma_ for token in doc])
print (lemmatized_sentence)
#> the bat see the cat with good stripe hang upside down by -PRON- foot

В приведенном выше коде мы заметили, что этот подход был более мощным, чем наши предыдущие подходы, так как:

  • Были обнаружены даже Про-существительные. (обозначено -PRON- )
  • Даже самое лучшее было заменено на хорошее.

6. TreeTagger
TreeTagger - это инструмент для аннотирования текста с помощью части речи и информации леммы. TreeTagger был успешно использован для тегирования более 25 языков и может быть адаптирован к другим языкам, если доступен корпус обучения с тегами вручную.

Слово POS Лемма
в DT в
TreeTagger НП TreeTagger
является ВБЗ быть
легкий JJ легкий
к К к
использовать VB использовать
. ПОСЛАЛ .
 Как использовать:
1. Загрузите пакет TreeTagger : в командной строке или в терминале anaconda введите:
                      pip install treetaggerwrapper

2. Загрузите программное обеспечение TreeTagger: нажмите TreeTagger и загрузите программное обеспечение в соответствии с вашей ОС. 
(Шаги по установке указаны на сайте)

Код:

# 6. TREETAGGER LEMMATIZER
import pandas as pd
import treetaggerwrapper as tt
t_tagger = tt.TreeTagger(TAGLANG = 'en' , TAGDIR = 'C:WindowsTreeTagger' )
pos_tags = t_tagger.tag_text( "the bats saw the cats with best stripes hanging upside down by their feet" )
original = []
lemmas = []
tags = []
for t in pos_tags:
original.append(t.split( ' ' )[ 0 ])
tags.append(t.split( ' ' )[ 1 ])
lemmas.append(t.split( ' ' )[ - 1 ])
Results = pd.DataFrame({ 'Original' : original, 'Lemma' : lemmas, 'Tags' : tags})
print (Results)
#> Original Lemma Tags
# 0 the the DT
# 1 bats bat NNS
# 2 saw see VVD
# 3 the the DT
# 4 cats cat NNS
# 5 with with IN
# 6 best good JJS
# 7 stripes stripe NNS
# 8 hanging hang VVG
# 9 upside upside RB
# 10 down down RB
# 11 by by IN
# 12 their their PP$
# 13 feet foot NNS

7. Выкройка
Pattern - это пакет Python, обычно используемый для веб-майнинга, обработки естественного языка, машинного обучения и сетевого анализа. У него много полезных возможностей НЛП. Он также содержит особую функцию, о которой мы поговорим ниже.

 Как использовать:
Загрузить пакет шаблонов: в командной строке или в терминале anaconda введите:
               
pip install pattern

Код:

# PATTERN LEMMATIZER
pattern import
from pattern.en import lemma, lexeme
from pattern.en import parse
sentence = "the bats saw the cats with best stripes hanging upside down by their feet"
lemmatized_sentence = " " .join([lemma(word) for word in sentence.split()])
print (lemmatized_sentence)
#> the bat see the cat with best stripe hang upside down by their feet
# Special Feature : to get all possible lemmas for each word in the sentence
all_lemmas_for_each_word = [lexeme(wd) for wd in sentence.split()]
print (all_lemmas_for_each_word)
#> [['the', 'thes', 'thing', 'thed'],
# ['bat', 'bats', 'batting', 'batted'],
# ['see', 'sees', 'seeing', 'saw', 'seen'],
# ['the', 'thes', 'thing', 'thed'],
# ['cat', 'cats', 'catting', 'catted'],
# ['with', 'withs', 'withing', 'withed'],
# ['best', 'bests', 'besting', 'bested'],
# ['stripe', 'stripes', 'striping', 'striped'],
# ['hang', 'hangs', 'hanging', 'hung'],
# ['upside', 'upsides', 'upsiding', 'upsided'],
# ['down', 'downs', 'downing', 'downed'],
# ['by', 'bies', 'bying', 'bied'],
# ['their', 'theirs', 'theiring', 'theired'],
# ['feet', 'feets', 'feeting', 'feeted']]

NOTE : if the above code raises an error saying ‘generator raised StopIteration’. Just run it again. It will work after 3-4 tries.  

8. Генсим
Gensim разработан для обработки больших текстовых коллекций с использованием потоковой передачи данных. Его средства лемматизации основаны на пакете шаблонов, который мы установили выше.

  • Для выполнения лемматизации можно использовать функцию gensim.utils.lemmatize (). Этот метод входит в состав модуля utils в Python.
  • Мы можем использовать этот лемматизатор из шаблона для извлечения токенов в кодировке UTF8 в их базовой форме = лемме.
  • По умолчанию учитываются только существительные , глаголы , прилагательные и наречия (все остальные леммы отбрасываются).
  • Например
 Слово ---> Лемматизированное слово 
есть / есть / быть ---> b e
пила ---> см.
Как использовать:
1. Загрузите пакет Pattern : в командной строке или в терминале anaconda введите:
                  pip install pattern
                  
2. Загрузите пакет Gensim: откройте командную строку или терминал anaconda от имени администратора и введите:
                 pip install -U gensim
                        ИЛИ
                 
pip3 install -U gensim (if using python3)

Код:

from gensim.utils import lemmatize
sentence = "the bats saw the cats with best stripes hanging upside down by their feet"
lemmatized_sentence = [word.decode( 'utf-8' ).split( '.' )[ 0 ] for word in lemmatize(sentence)]
print (lemmatized_sentence)
#> ['bat / NN', 'see / VB', 'cat / NN', 'best / JJ',
# 'stripe / NN', 'hang / VB', 'upside / RB', 'foot / NN']

NOTE : if the above code raises an error saying ‘generator raised StopIteration‘. Just run it again. It will work after 3-4 tries.  

В приведенном выше коде, как вы, возможно, уже заметили, лемматизатор gensim игнорирует такие слова, как 'the' , 'with' , 'by', поскольку они не попадают в 4 категории лемм, упомянутых выше. (существительное / глагол / прилагательное / наречие)
9. Стэнфордский CoreNLP
CoreNLP позволяет пользователям выводить лингвистические аннотации для текста, включая границы маркеров и предложений, части речи, именованные сущности, числовые и временные значения, анализ зависимостей и групп, тональность, атрибуцию цитат и отношения.

  • CoreNLP - это универсальный инструмент для обработки естественного языка в Java!
  • CoreNLP в настоящее время поддерживает 6 языков, включая арабский, китайский, английский, французский, немецкий и испанский.
 Как использовать:
1. Получите JAVA 8: загрузите Java 8 (в соответствии с вашей ОС) и установите ее.

2. Получите пакет Stanford_coreNLP:
    2.1) Скачать Stanford_CoreNLP и разархивируйте его.                   
    2.2) Открытый терминал 
                  
    (а) перейдите в каталог, в который вы извлекли указанный выше файл, выполнив
    cd C:  Users  ...  stanford-corenlp-4.1.0 на терминале
                        
    (б) затем запустите сервер Stanford CoreNLP, выполнив на терминале следующую команду: 
    java -mx4g -cp "*" edu.stanford.nlp.pipeline.StanfordCoreNLPServer -annotators "tokenize, ssplit, pos, lemma, parse, sentiment" -port 9000 -timeout 30000
    ** (оставьте свой терминал открытым, пока вы используете этот лемматизатор) ** 
    
3. Загрузите пакет Standford CoreNLP: откройте командную строку или терминал anaconda, введите:
                        
pip install stanfordcorenlp

Код:

from stanfordcorenlp import StanfordCoreNLP
import json
# Connect to the CoreNLP server we just started
nlp = StanfordCoreNLP( ' http://localhost ' , port = 9000 , timeout = 30000 )
# Define proporties needed to get lemma
props = { 'annotators' : 'pos, lemma' , 'pipelineLanguage' : 'en' , 'outputFormat' : 'json' }
sentence = "the bats saw the cats with best stripes hanging upside down by their feet"
parsed_str = nlp.annotate(sentence, properties = props)
print (parsed_str)
#> "sentences": [{"index": 0,
# "tokens": [
# {
# "index": 1,
# "word": "the",
# "originalText": "the",
# "lemma": "the", <--------------- LEMMA
# "characterOffsetBegin": 0,
# "characterOffsetEnd": 3,
# "pos": "DT",
# "before": "",
# "after": " "
# },
# {
# "index": 2,
# "word": "bats",
# "originalText": "bats",
# "lemma": "bat", <--------------- LEMMA
# "characterOffsetBegin": 4,
# "characterOffsetEnd": 8,
# "pos": "NNS",
# "before": " ",
# "after": " "
# },
# {
# "index": 3,
# "word": "saw",
# "originalText": "saw",
# "lemma": "see", <--------------- LEMMA
# "characterOffsetBegin": 9,
# "characterOffsetEnd": 12,
# "pos": "VBD",
# "before": " ",
# "after": " "
# },
# {
# "index": 4,
# "word": "the",
# "originalText": "the",
# "lemma": "the", <--------------- LEMMA
# "characterOffsetBegin": 13,
# "characterOffsetEnd": 16,
# "pos": "DT",
# "before": " ",
# "after": " "
# },
# {
# "index": 5,
# "word": "cats",
# "originalText": "cats",
# "lemma": "cat", <--------------- LEMMA
# "characterOffsetBegin": 17,
# "characterOffsetEnd": 21,
# "pos": "NNS",
# "before": " ",
# "after": " "
# },
# {
# "index": 6,
# "word": "with",
# "originalText": "with",
# "lemma": "with", <--------------- LEMMA
# "characterOffsetBegin": 22,
# "characterOffsetEnd": 26,
# "pos": "IN",
# "before": " ",
# "after": " "
# },
# {
# "index": 7,
# "word": "best",
# "originalText": "best",
# "lemma": "best", <--------------- LEMMA
# "characterOffsetBegin": 27,
# "characterOffsetEnd": 31,
# "pos": "JJS",
# "before": " ",
# "after": " "
# },
# {
# "index": 8,
# "word": "stripes",
# "originalText": "stripes",
# "lemma": "stripe", <--------------- LEMMA
# "characterOffsetBegin": 32,
# "characterOffsetEnd": 39,
# "pos": "NNS",
# "before": " ",
# "after": " "
# },
# {
# "index": 9,
# "word": "hanging",
# "originalText": "hanging",
# "lemma": "hang", <--------------- LEMMA
# "characterOffsetBegin": 40,
# "characterOffsetEnd": 47,
# "pos": "VBG",
# "before": " ",
# "after": " "
# },
# {
# "index": 10,
# "word": "upside",
# "originalText": "upside",
# "lemma": "upside", <--------------- LEMMA
# "characterOffsetBegin": 48,
# "characterOffsetEnd": 54,
# "pos": "RB",
# "before": " ",
# "after": " "
# },
# {
# "index": 11,
# "word": "down",
# "originalText": "down",
# "lemma": "down", <--------------- LEMMA
# "characterOffsetBegin": 55,
# "characterOffsetEnd": 59,
# "pos": "RB",
# "before": " ",
# "after": " "
# },
# {
# "index": 12,
# "word": "by",
# "originalText": "by",
# "lemma": "by", <--------------- LEMMA
# "characterOffsetBegin": 60,
# "characterOffsetEnd": 62,
# "pos": "IN",
# "before": " ",
# "after": " "
# },
# {
# "index": 13,
# "word": "their",
# "originalText": "their",
# "lemma": "they"#, <--------------- LEMMA
# "characterOffsetBegin": 63,
# "characterOffsetEnd": 68,
# "pos": "PRP$",
# "before": " ",
# "after": " "
# },
# {
# "index": 14,
# "word": "feet",
# "originalText": "feet",
# "lemma": "foot", <--------------- LEMMA
# "characterOffsetBegin": 69,
# "characterOffsetEnd": 73,
# "pos": "NNS",
# "before": " ",
# "after": ""
# }
# ]
# }
# ]

Код:

# To get the lemmatized sentece as output
# ** RUN THE ABOVE SCRIPT FIRST **
lemma_list = []
for item in parsed_dict[ 'sentences' ][ 0 ][ 'tokens' ]:
for key, value in item.items():
if key = = 'lemma' :
lemma_list.append(value)
print (lemma_list)
#> ['the', 'bat', 'see', 'the', 'cat', 'with', 'best', 'stripe', 'hang', 'upside', 'down', 'by', 'they', 'foot']
lemmatized_sentence = " " .join(lemma_list)
print (lemmatized_sentence)
#>the bat see the cat with best stripe hang upside down by the foot

Заключение:
Итак, это различные подходы к лемматизации, на которые вы можете ссылаться, работая над проектом НЛП