Как классифицировать производные слова, которые имеют значение, как одинаковые токены? - PullRequest
0 голосов
/ 30 января 2020

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

Например, я бы хотел, чтобы gasoline и gas были рассматривается как один и тот же токен в предложениях типа The price of gasoline has risen. и "Gas" is a colloquial form of the word gasoline in North American English. Conversely, in BE the term would be "petrol".. Поэтому, если эти два предложения составляют всю статью, счет для gas (или gasoline) будет равен 3 (petrol не будет учитываться) .

Я пытался использовать стеммеры и лемматизаторы НЛТК, но безрезультатно. Большинство из них, похоже, воспроизводят gas как gas и gasoline как gasolin, что совершенно не полезно для моих целей. Я понимаю, что это обычное поведение. Я проверил поток , который кажется немного похожим, однако ответы там не совсем применимы к моему случаю, так как я требую, чтобы слова были получены друг от друга.

Как относиться к производным словам одинакового значения с одинаковыми токенами, чтобы сосчитать их вместе?

1 Ответ

2 голосов
/ 31 января 2020

Я предлагаю двухэтапный подход:

Сначала найдите синонимы, сравнив вложения слов (только не стоп-слова). Это должно удалить похожие письменные слова, которые означают что-то еще, например, gasoline и gaseous.

Затем проверьте, имеют ли синонимы общий смысл. По сути if "gas" is in "gasolin" и наоборот. Этого будет достаточно, потому что вы сравниваете только свои синонимы.

import spacy
import itertools
from nltk.stem.porter import *
threshold = 0.6

#compare the stems of the synonyms
stemmer = PorterStemmer()
def compare_stems(a, b):
  if stemmer.stem(a) in stemmer.stem(b):
    return True
  if stemmer.stem(b) in stemmer.stem(a):
    return True
  return False

candidate_synonyms = {}
#add a candidate to the candidate dictionary of sets
def add_to_synonym_dict(a,b):
  if a not in candidate_synonyms:
    if b not in candidate_synonyms:
      candidate_synonyms[a] = {a, b}
      return
    a, b = b,a
  candidate_synonyms[a].add(b)

nlp = spacy.load('en_core_web_lg') 

text = u'The price of gasoline has risen. "Gas" is a colloquial form of the word gasoline in North American English. Conversely in BE the term would be petrol. A gaseous state has nothing to do with oil.'

words = nlp(text)

#compare every word with every other word, if they are similar
for a, b in itertools.combinations(words, 2):
  #check if one of the word pairs are stopwords or punctuation
  if a.is_stop or b.is_stop or a.is_punct or b.is_punct:
    continue
  if a.similarity(b) > threshold:
    if compare_stems(a.text.lower(), b.text.lower()):
      add_to_synonym_dict(a.text.lower(), b.text.lower())



print(candidate_synonyms)
#output: {'gasoline': {'gas', 'gasoline'}}

Затем вы можете подсчитывать кандидатов-синонимов по их появлению в тексте.

Примечание: Я выбрал порог для синонимов с 0,6 случайно. Вы бы, вероятно, проверили, какой порог соответствует вашей задаче Кроме того, мой код - простой и грязный пример, это можно сделать намного чище. `

...