使用NLTK处理复合词(2克)

时间:2018-03-21 10:30:49

标签: nlp nltk tokenize spacy

我正在尝试通过比较其个人资料中使用的关键字(来自网站)来识别用户的相似之处。例如,Alice = pizza, music, moviesBob = cooking, guitar, movieEve = knitting, running, gym。理想情况下,AliceBob最相似。我放下了一些简单的代码来计算相似度。为了考虑可能的复数/单数形式的关键字,我使用类似的东西:

from nltk.stem import WordNetLemmatizer
from nltk.tokenize import word_tokenize
wnl = WordNetLemmatizer()
w1 = ["movies", "movie"] 
tokens = [token.lower() for token in word_tokenize(" ".join(w1))]
lemmatized_words = [wnl.lemmatize(token) for token in tokens]

那样,lemmatized_words = ["movie", "movie"]。 然后,我使用spacy进行一些成对关键字比较,例如:

import spacy
nlp = spacy.load('en')
t1 = nlp(u"pizza")
t2 = nlp(u"food")
sim = t1.similarity(t2)

现在,问题开始时我必须处理复合词,例如:artificial intelligencedata sciencewhole food等。通过标记化,我只需将这些词分成2个(例如artificialintelligence),但这会影响我的相似性度量。什么是(将是)考虑这些类型的单词的最佳方法?

2 个答案:

答案 0 :(得分:1)

有很多方法可以实现这一目标。一种方法是自己创建嵌入(向量)。这有两个好处:首先,您可以使用bi,tri和beyond(n-)克作为您的标记,其次,您可以定义最适合您需求的空间 - - 维基百科数据是一般性的,但是,儿童的故事将是一个更小众的数据集(更合适/"准确"如果您正在解决与儿童和/或故事有关的问题)。有几种方法,当然word2vec是最受欢迎的,还有几种方法可以帮助您(例如gensim)。

但是,我猜你想要的东西已经存在了。现在最好的嵌入词是:

  • Numberbatch('经典'一流的合奏);
  • fastText,来自Facebook Research(在角色层面创建---一些词汇量不足的词语可以"理解"因此);
  • sense2vec,由Spacy背后的同一个人(使用词性(POS)作为附加信息创建,目的是消除歧义)。

我们感兴趣的是快速解决您的问题sense2vec。您应该阅读paper,但基本上这些单词嵌入是使用带有其他POS信息的Reddit创建的,并且(因此)能够区分跨越多个单词的实体(例如名词)。 This blog post非常了解sense2vec。这里有一些代码可以帮助您入门(取自之前的链接):

安装:

git clone https://github.com/explosion/sense2vec
pip install -r requirements.txt
pip install -e .
sputnik --name sense2vec --repository-url http://index.spacy.io install reddit_vectors

使用示例:

import sense2vec
model = sense2vec.load()
freq, query_vector = model["onion_rings|NOUN"]
freq2, query_vector2 = model["chicken_nuggets|NOUN"]
print(model.most_similar(query_vector, n=5)[0])
print(model.data.similarity(query_vector, query_vector2))

重要提示,sense2vec 需要 spacy>=0.100,<0.101,这意味着它会降级您当前的spacy安装,而不是太多如果您只加载en模型,则会出现问题。此外,这里是使用的POS标签:

ADJ ADP ADV AUX CONJ DET INTJ NOUN NUM PART PRON PROPN PUNCT SCONJ SYM VERB X

您可以使用spacy进行POS和依赖项标记,然后使用sense2vec来确定结果实体的相似性。或者,根据数据集的频率(不是太大),您可以按降序(n)顺序获取n-gram,并依次检查每个是sense2vec模型中的实体。

希望这有帮助!

答案 1 :(得分:0)

有使用nltk的方法:

from nltk.tokenize import MWETokenizer

tokenizer = MWETokenizer([("artificial","intelligence"), ("data","science")], separator=' ')

tokens = tokenizer.tokenize("I am really interested in data science and artificial intelligence".split())
print(tokens)

输出为:

['I', 'am', 'really', 'interested', 'in', 'data science', 'and', 'artificial intelligence']

如需更多参考,请阅读here