- Stemming и лемматизация в Python
- Понимание stemming и лемматизации
- Что stemming?
- Создание stemmer с Porterstemmer
- Создание стеммера со снежным углом
- Что такое лемматизация?
- Создание лемматизатора с Python Spacy
- Создание лемматизатора с Python NLTK
- Лемматизация против stemming
- Заключение
- Читайте ещё по теме:
- Sample usage for stem¶
- Unit tests for the Porter stemmer¶
- Unit tests for Snowball stemmer¶
- Unit tests for ARLSTem Stemmer¶
- Unit tests for ARLSTem2 Stemmer¶
- Kein1945 / gist:9111512
- Kein1945 / gist:9111512
Stemming и лемматизация в Python
В области обработки натурального языка стемминг и лемматизация являются методами текстовых нормализации, используемые для приготовления текстов, документов для дальнейшего анализа.
Понимание stemming и лемматизации
Работая с языковыми данными, нам нужно признать тот факт, что слова, такие как «уход» и «забота», имеют одинаковое значение, но используемое в разных формах времен. Здесь мы используем stemming и лемматизацию, чтобы уменьшить слово к его базовой форме.
В этой статье мы будем выполнять stemming и Lemmatization с использованием библиотеки NLTK и библиотеки SPAcy.
Что stemming?
Компьютерная программа или подпрограмма, которую произошло слово, можно назвать программой stemming, stemming алгоритмом или stemmer. ( Wikipedia )
Stemming используется для предварительной обработки текстовых данных. Английский язык имеет много вариантов одного слова, поэтому для уменьшения неоднозначности для алгоритма машиностроения для изучения важно отфильтровать такие слова и уменьшить их в базовую форму.
NLTK предоставляет классы, чтобы выполнить stemming на словах. Наиболее широко используемые алгоритмы stemming – Porterstemmer , Snowballstemmer и т.п.
Создание stemmer с Porterstemmer
Давайте попробуем портрермермер для стеблевых слов.
#Importing required modules from nltk.stem.porter import PorterStemmer #Creating the class object stemmer = PorterStemmer() #words to stem words = ['rain','raining','faith','faithful','are','is','care','caring'] #Stemming the words for word in words: print(word+' -> '+ stemmer.stem(word))
rain --> rain raining --> rain faith --> faith faithful --> faith are --> are is --> is care --> care caring --> care
У класса Porterstemmer есть .stem Метод, который принимает слово в качестве входного аргумента и возвращает слово, уменьшается до его корневой формы.
Создание стеммера со снежным углом
Он также известен как алгоритм Porter2 stemming, поскольку он имеет тенденцию исправлять несколько недостатков в Porter stemmer. Давайте посмотрим, как его использовать.
#Importing the class from nltk.stem.snowball import SnowballStemmer #words to stem words = ['rain','raining','faith','faithful','are','is','care','caring'] #Creating the Class object snow_stemmer = SnowballStemmer(language='english') #Stemming the words for word in words: print(word+' -> '+snow_stemmer.stem(word))
rain --> rain raining --> rain faith --> faith faithful --> faith are --> are is --> is care --> care caring --> care
Выходы с обеих stemmer выглядят аналогичны, потому что мы использовали ограниченный текстовый корпус для демонстрации. Не стесняйтесь экспериментировать с разными словами и сравнить результаты двух.
Что такое лемматизация?
Лемматизация – это алгоритмический процесс нахождения леммы слова – это означает, что в отличие от stemming, что может привести к неправильному снижению слова, лемматизация всегда уменьшает слово в зависимости от его значения.
Это помогает в возвращении основания или словарной формы слова, которое известно как лемма.
При первом stemming и лемматизации могут выглядеть одинаково, но они на самом деле очень отличаются в следующем разделе, мы увидим разницу между ними.
Теперь давайте посмотрим, как выполнить лемматизацию на текстовых данных.
Создание лемматизатора с Python Spacy
Примечание: Python -M Spacy Скачать EN_CORE_WEB_SM
Вышеуказанная линия должна быть запускается, чтобы загрузить необходимый файл для выполнения лемматизации
#Importing required modules import spacy #Loading the Lemmatization dictionary nlp = spacy.load('en_core_web_sm') #Applying lemmatization doc = nlp("Apples and oranges are similar. Boots and hippos aren't.") #Getting the output for token in doc: print(str(token) + ' --> '+ str(token.lemma_))
Apples --> apple and --> and oranges --> orange are --> be similar --> similar . --> . Boots --> boot and --> and hippos --> hippos are --> be n't --> not . --> .
Приведенный выше код возвращает итератор Spacy.doc Тип объекта, который является лемматизированной формой входных слов. Мы можем получить доступ к лемматизированному слову, используя .LEMMA_ атрибут.
Посмотрите, как он автоматически тоненяет предложение для нас.
Создание лемматизатора с Python NLTK
NLTK использует WordNet. Метод NLTK Lemmatization основан на встроенной морской функции Worldnet.
Давайте посмотрим, как его использовать.
import nltk nltk.download('wordnet') #First download the required data
#Importing the module from nltk.stem import WordNetLemmatizer #Create the class object lemmatizer = WordNetLemmatizer() # Define the sentence to be lemmatized sentence = "Apples and oranges are similar. Boots and hippos aren't." # Tokenize the sentence word_list = nltk.word_tokenize(sentence) print(word_list) # Lemmatize list of words and join lemmatized_output = ' '.join([lemmatizer.lemmatize(w) for w in word_list]) print(lemmatized_output)
['Apples', 'and', 'oranges', 'are', 'similar', '.', 'Boots', 'and', 'hippos', 'are', "n't", '.'] Apples and orange are similar . Boots and hippo are n't .
Лемматизация против stemming
Я понимаю. Сначала он может быть запутанным на выбирать между stemming и лемматизацией, но лемматизация, безусловно, более эффективна, чем stemming.
Мы видели, что обе методы уменьшают каждое слово к его корню. В stemming это может быть просто уменьшенная форма целевого слова, в то время как лемматизация, уменьшается до истинного рута слова английского языка, поскольку лемматизация требует перекрестных ссылок на целевое слово в корпусе WordNet.
Stemming против лемматизации? Это вопрос компромисса между скоростью и деталями. Stemming обычно быстрее, чем лемматизация, но он может быть неточности. Принимая во внимание, что если нам нужна наша модель, чтобы быть как можно более подробной и как можно точнее, то лемматизация должна быть предпочтительной.
Заключение
В этой статье мы увидели, о том, о том, о том, о чем вотворить stemming и лемматизация. Мы видели различные способы, которыми мы можем реализовать stemming и лемматизацию.
Мы также сравниваем лемматизацию с stemming, чтобы расслабиться различиями между оба процессами. Счастливое обучение! 🙂.
Читайте ещё по теме:
Sample usage for stem¶
Stemmers remove morphological affixes from words, leaving only the word stem.
Unit tests for the Porter stemmer¶
>>> from nltk.stem.porter import *
Create a new Porter stemmer.
Test the stemmer on various pluralised words.
>>> plurals = ['caresses', 'flies', 'dies', 'mules', 'denied', . 'died', 'agreed', 'owned', 'humbled', 'sized', . 'meeting', 'stating', 'siezing', 'itemization', . 'sensational', 'traditional', 'reference', 'colonizer', . 'plotted']
>>> singles = [stemmer.stem(plural) for plural in plurals]
>>> print(' '.join(singles)) caress fli die mule deni die agre own humbl size meet state siez item sensat tradit refer colon plot
Unit tests for Snowball stemmer¶
>>> from nltk.stem.snowball import SnowballStemmer
See which languages are supported.
>>> print(" ".join(SnowballStemmer.languages)) arabic danish dutch english finnish french german hungarian italian norwegian porter portuguese romanian russian spanish swedish
Create a new instance of a language specific subclass.
>>> stemmer = SnowballStemmer("english")
>>> print(stemmer.stem("running")) run
Decide not to stem stopwords.
>>> stemmer2 = SnowballStemmer("english", ignore_stopwords=True) >>> print(stemmer.stem("having")) have >>> print(stemmer2.stem("having")) having
The ‘english’ stemmer is better than the original ‘porter’ stemmer.
>>> print(SnowballStemmer("english").stem("generously")) generous >>> print(SnowballStemmer("porter").stem("generously")) gener
Extra stemmer tests can be found in nltk.test.unit.test_stem .
Unit tests for ARLSTem Stemmer¶
>>> from nltk.stem.arlstem import ARLSTem
Create a Stemmer instance.
Unit tests for ARLSTem2 Stemmer¶
>>> from nltk.stem.arlstem2 import ARLSTem2
Create a Stemmer instance.
Kein1945 / gist:9111512
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- |
# Портирован с Java по мотивам http://www.algorithmist.ru/2010/12/porter-stemmer-russian.html |
import re |
class Porter : |
PERFECTIVEGROUND = re . compile ( u»((ив|ивши|ившись|ыв|ывши|ывшись)|((? <=[ая])(в|вши|вшись)))$" ) |
REFLEXIVE = re . compile ( u»(с[яь])$» ) |
ADJECTIVE = re . compile ( u»(ее|ие|ые|ое|ими|ыми|ей|ий|ый|ой|ем|им|ым|ом|его|ого|ему|ому|их|ых|ую|юю|ая|яя|ою|ею)$» ) |
PARTICIPLE = re . compile ( u»((ивш|ывш|ующ)|((? <=[ая])(ем|нн|вш|ющ|щ)))$" ) |
VERB = re . compile ( u»((ила|ыла|ена|ейте|уйте|ите|или|ыли|ей|уй|ил|ыл|им|ым|ен|ило|ыло|ено|ят|ует|уют|ит|ыт|ены|ить|ыть|ишь|ую|ю)|((? <=[ая])(ла|на|ете|йте|ли|й|л|ем|н|ло|но|ет|ют|ны|ть|ешь|нно)))$" ) |
NOUN = re . compile ( u»(а|ев|ов|ие|ье|е|иями|ями|ами|еи|ии|и|ией|ей|ой|ий|й|иям|ям|ием|ем|ам|ом|о|у|ах|иях|ях|ы|ь|ию|ью|ю|ия|ья|я)$» ) |
RVRE = re . compile ( u»^(.*?[аеиоуыэюя])(.*)$» ) |
DERIVATIONAL = re . compile ( u».*[^аеиоуыэюя]+[аеиоуыэюя].*ость?$» ) |
DER = re . compile ( u»ость?$» ) |
SUPERLATIVE = re . compile ( u»(ейше|ейш)$» ) |
I = re . compile ( u»и$» ) |
P = re . compile ( u»ь$» ) |
NN = re . compile ( u»нн$» ) |
def stem ( word ): |
word = word . lower () |
word = word . replace ( u’ё’ , u’е’ ) |
m = re . match ( Porter . RVRE , word ) |
if m and m . groups (): |
pre = m . group ( 1 ) |
rv = m . group ( 2 ) |
temp = Porter . PERFECTIVEGROUND . sub ( » , rv , 1 ) |
if temp == rv : |
rv = Porter . REFLEXIVE . sub ( » , rv , 1 ) |
temp = Porter . ADJECTIVE . sub ( » , rv , 1 ) |
if temp != rv : |
rv = temp |
rv = Porter . PARTICIPLE . sub ( » , rv , 1 ) |
else : |
temp = Porter . VERB . sub ( » , rv , 1 ) |
if temp == rv : |
rv = Porter . NOUN . sub ( » , rv , 1 ) |
else : |
rv = temp |
else : |
rv = temp |
rv = Porter . I . sub ( » , rv , 1 ) |
if re . match ( Porter . DERIVATIONAL , rv ): |
rv = Porter . DER . sub ( » , rv , 1 ) |
temp = Porter . P . sub ( » , rv , 1 ) |
if temp == rv : |
rv = Porter . SUPERLATIVE . sub ( » , rv , 1 ) |
rv = Porter . NN . sub ( u’н’ , rv , 1 ) |
else : |
rv = temp |
word = pre + rv |
return word |
stem = staticmethod ( stem ) |
if __name__ == ‘__main__’ : |
print Porter . stem ( u’устойчивость’ ) |
Kein1945 / gist:9111512
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- |
# Портирован с Java по мотивам http://www.algorithmist.ru/2010/12/porter-stemmer-russian.html |
import re |
class Porter : |
PERFECTIVEGROUND = re . compile ( u»((ив|ивши|ившись|ыв|ывши|ывшись)|((? <=[ая])(в|вши|вшись)))$" ) |
REFLEXIVE = re . compile ( u»(с[яь])$» ) |
ADJECTIVE = re . compile ( u»(ее|ие|ые|ое|ими|ыми|ей|ий|ый|ой|ем|им|ым|ом|его|ого|ему|ому|их|ых|ую|юю|ая|яя|ою|ею)$» ) |
PARTICIPLE = re . compile ( u»((ивш|ывш|ующ)|((? <=[ая])(ем|нн|вш|ющ|щ)))$" ) |
VERB = re . compile ( u»((ила|ыла|ена|ейте|уйте|ите|или|ыли|ей|уй|ил|ыл|им|ым|ен|ило|ыло|ено|ят|ует|уют|ит|ыт|ены|ить|ыть|ишь|ую|ю)|((? <=[ая])(ла|на|ете|йте|ли|й|л|ем|н|ло|но|ет|ют|ны|ть|ешь|нно)))$" ) |
NOUN = re . compile ( u»(а|ев|ов|ие|ье|е|иями|ями|ами|еи|ии|и|ией|ей|ой|ий|й|иям|ям|ием|ем|ам|ом|о|у|ах|иях|ях|ы|ь|ию|ью|ю|ия|ья|я)$» ) |
RVRE = re . compile ( u»^(.*?[аеиоуыэюя])(.*)$» ) |
DERIVATIONAL = re . compile ( u».*[^аеиоуыэюя]+[аеиоуыэюя].*ость?$» ) |
DER = re . compile ( u»ость?$» ) |
SUPERLATIVE = re . compile ( u»(ейше|ейш)$» ) |
I = re . compile ( u»и$» ) |
P = re . compile ( u»ь$» ) |
NN = re . compile ( u»нн$» ) |
def stem ( word ): |
word = word . lower () |
word = word . replace ( u’ё’ , u’е’ ) |
m = re . match ( Porter . RVRE , word ) |
if m and m . groups (): |
pre = m . group ( 1 ) |
rv = m . group ( 2 ) |
temp = Porter . PERFECTIVEGROUND . sub ( » , rv , 1 ) |
if temp == rv : |
rv = Porter . REFLEXIVE . sub ( » , rv , 1 ) |
temp = Porter . ADJECTIVE . sub ( » , rv , 1 ) |
if temp != rv : |
rv = temp |
rv = Porter . PARTICIPLE . sub ( » , rv , 1 ) |
else : |
temp = Porter . VERB . sub ( » , rv , 1 ) |
if temp == rv : |
rv = Porter . NOUN . sub ( » , rv , 1 ) |
else : |
rv = temp |
else : |
rv = temp |
rv = Porter . I . sub ( » , rv , 1 ) |
if re . match ( Porter . DERIVATIONAL , rv ): |
rv = Porter . DER . sub ( » , rv , 1 ) |
temp = Porter . P . sub ( » , rv , 1 ) |
if temp == rv : |
rv = Porter . SUPERLATIVE . sub ( » , rv , 1 ) |
rv = Porter . NN . sub ( u’н’ , rv , 1 ) |
else : |
rv = temp |
word = pre + rv |
return word |
stem = staticmethod ( stem ) |
if __name__ == ‘__main__’ : |
print Porter . stem ( u’устойчивость’ ) |