Как мне сделать слово «Стемминг» или «Лемматизация»? - PullRequest
106 голосов
/ 21 апреля 2009

Я пробовал PorterStemmer и Snowball, но оба не работают на всех словах, пропуская некоторые очень распространенные.

Мои тестовые слова: « кошки, бегущие по кактусам, кактусам, сообществам кактусов », и оба получают право наполовину меньше.

Смотри также:

Ответы [ 21 ]

1 голос
/ 06 апреля 2012

Самая последняя версия стеммера в NLTK - Snowball.

Примеры того, как его использовать, вы можете найти здесь:

http://nltk.googlecode.com/svn/trunk/doc/api/nltk.stem.snowball2-pysrc.html#demo

1 голос
/ 21 апреля 2009

Если я могу процитировать мой ответ на вопрос, который упомянул StompChicken:

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

Поскольку у них нет понимания языка и они не запускаются из словаря терминов, у них нет возможности распознавать и реагировать соответствующим образом на нерегулярные случаи, такие как «run» / «run».

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

1 голос
/ 23 мая 2012

Вы можете использовать стеммер Морфа. UW загрузил стебель морфы в Maven central , если вы планируете использовать его из приложения Java. Есть обертка, которая делает его намного проще в использовании. Вам просто нужно добавить его как зависимость и использовать класс edu.washington.cs.knowitall.morpha.MorphaStemmer. Экземпляры являются потокобезопасными (исходный JFlex имел ненужные поля класса для локальных переменных). Создайте класс и запустите morpha и слово, которое вы хотите использовать.

new MorphaStemmer().morpha("climbed") // goes to "climb"
1 голос
/ 07 октября 2018

Лучшие пакеты Python (в произвольном порядке) для лемматизации: spacy, nltk, gensim, pattern, CoreNLP и TextBlob. Я предпочитаю реализацию spaCy и gensim (на основе шаблона), потому что они идентифицируют POS-тег слова и автоматически назначают соответствующую лемму. Это дает более уместные леммы, сохраняя значение в неизменном виде.

Если вы планируете использовать nltk или TextBlob, вам нужно позаботиться о том, чтобы вручную найти правильный POS-тег и найти нужную лемму.

Пример лемматизации с spaCy:

# Run below statements in terminal once. 
pip install spacy
spacy download en

import spacy

# Initialize spacy 'en' model
nlp = spacy.load('en', disable=['parser', 'ner'])

sentence = "The striped bats are hanging on their feet for best"

# Parse
doc = nlp(sentence)

# Extract the lemma
" ".join([token.lemma_ for token in doc])
#> 'the strip bat be hang on -PRON- foot for good'

Пример лемматизации с Gensim:

from gensim.utils import lemmatize
sentence = "The striped bats were hanging on their feet and ate best fishes"
lemmatized_out = [wd.decode('utf-8').split('/')[0] for wd in lemmatize(sentence)]
#> ['striped', 'bat', 'be', 'hang', 'foot', 'eat', 'best', 'fish']

Приведенные выше примеры были заимствованы из этой лемматизации страницы.

1 голос
/ 21 апреля 2009

Выполните поиск для Lucene, я не уверен, есть ли порт PHP, но я знаю, что Lucene доступен для многих платформ. Lucene - библиотека индексации и поиска OSS (от Apache). Естественно, это и дополнения сообщества могут иметь что-то интересное, чтобы посмотреть. По крайней мере, вы можете узнать, как это делается на одном языке, чтобы вы могли перевести «идею» в PHP

0 голосов
/ 13 июня 2018

Я настоятельно рекомендую использовать Spacy (базовый анализ текста и тегирование) и Textacy (обработка текста более высокого уровня, построенная поверх Spacy).

Лемматизированные слова доступны по умолчанию в Spacy в качестве атрибута .lemma_ токена, и текст можно лемматизировать, выполняя много другой предварительной обработки текста с помощью textacy. Например, при создании пакета терминов или слов или, как правило, непосредственно перед выполнением некоторой обработки, которая требует этого.

Я бы посоветовал вам проверить оба варианта перед написанием любого кода, поскольку это может сэкономить вам много времени!

0 голосов
/ 10 мая 2018
df_plots = pd.read_excel("Plot Summary.xlsx", index_col = 0)
df_plots
# Printing first sentence of first row and last sentence of last row
nltk.sent_tokenize(df_plots.loc[1].Plot)[0] + nltk.sent_tokenize(df_plots.loc[len(df)].Plot)[-1]

# Calculating length of all plots by words
df_plots["Length"] = df_plots.Plot.apply(lambda x : 
len(nltk.word_tokenize(x)))

print("Longest plot is for season"),
print(df_plots.Length.idxmax())

print("Shortest plot is for season"),
print(df_plots.Length.idxmin())



#What is this show about? (What are the top 3 words used , excluding the #stop words, in all the #seasons combined)

word_sample = list(["struggled", "died"])
word_list = nltk.pos_tag(word_sample)
[wnl.lemmatize(str(word_list[index][0]), pos = word_list[index][1][0].lower()) for index in range(len(word_list))]

# Figure out the stop words
stop = (stopwords.words('english'))

# Tokenize all the plots
df_plots["Tokenized"] = df_plots.Plot.apply(lambda x : nltk.word_tokenize(x.lower()))

# Remove the stop words
df_plots["Filtered"] = df_plots.Tokenized.apply(lambda x : (word for word in x if word not in stop))

# Lemmatize each word
wnl = WordNetLemmatizer()
df_plots["POS"] = df_plots.Filtered.apply(lambda x : nltk.pos_tag(list(x)))
# df_plots["POS"] = df_plots.POS.apply(lambda x : ((word[1] = word[1][0] for word in word_list) for word_list in x))
df_plots["Lemmatized"] = df_plots.POS.apply(lambda x : (wnl.lemmatize(x[index][0], pos = str(x[index][1][0]).lower()) for index in range(len(list(x)))))



#Which Season had the highest screenplay of "Jesse" compared to "Walt" 
#Screenplay of Jesse =(Occurences of "Jesse")/(Occurences of "Jesse"+ #Occurences of "Walt")

df_plots.groupby("Season").Tokenized.sum()

df_plots["Share"] = df_plots.groupby("Season").Tokenized.sum().apply(lambda x : float(x.count("jesse") * 100)/float(x.count("jesse") + x.count("walter") + x.count("walt")))

print("The highest times Jesse was mentioned compared to Walter/Walt was in season"),
print(df_plots["Share"].idxmax())
#float(df_plots.Tokenized.sum().count('jesse')) * 100 / #float((df_plots.Tokenized.sum().count('jesse') + #df_plots.Tokenized.sum().count('walt') + #df_plots.Tokenized.sum().count('walter')))
0 голосов
/ 27 сентября 2009

.Net lucene имеет встроенный портер. Вы можете попробовать это. Но обратите внимание, что определение портера не учитывает контекст слова при выводе леммы. (Изучите алгоритм и его реализацию, и вы увидите, как он работает)

0 голосов
/ 22 апреля 2015

Попробуйте это здесь: http://www.twinword.com/lemmatizer.php

Я ввел ваш запрос в демо "cats running ran cactus cactuses cacti community communities" и получил ["cat", "running", "run", "cactus", "cactus", "cactus", "community", "community"] с необязательным флагом ALL_TOKENS.

Пример кода

Это API, поэтому вы можете подключиться к нему из любой среды. Вот как может выглядеть вызов PHP REST.

// These code snippets use an open-source library. http://unirest.io/php
$response = Unirest\Request::post([ENDPOINT],
  array(
    "X-Mashape-Key" => [API KEY],
    "Content-Type" => "application/x-www-form-urlencoded",
    "Accept" => "application/json"
  ),
  array(
    "text" => "cats running ran cactus cactuses cacti community communities"
  )
);
0 голосов
/ 15 декабря 2014

В Java я использую тартаргус-снежный ком для слов * *

Maven:

<dependency>
        <groupId>org.apache.lucene</groupId>
        <artifactId>lucene-snowball</artifactId>
        <version>3.0.3</version>
        <scope>test</scope>
</dependency>

Пример кода:

SnowballProgram stemmer = new EnglishStemmer();
String[] words = new String[]{
    "testing",
    "skincare",
    "eyecare",
    "eye",
    "worked",
    "read"
};
for (String word : words) {
    stemmer.setCurrent(word);
    stemmer.stem();
    //debug
    logger.info("Origin: " + word + " > " + stemmer.getCurrent());// result: test, skincar, eyecar, eye, work, read
}
...