我正在尝试通过比较其个人资料中使用的关键字(来自网站)来识别用户的相似之处。例如,Alice = pizza, music, movies
,Bob = cooking, guitar, movie
和Eve = knitting, running, gym
。理想情况下,Alice
和Bob
最相似。我放下了一些简单的代码来计算相似度。为了考虑可能的复数/单数形式的关键字,我使用类似的东西:
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 intelligence
,data science
,whole food
等。通过标记化,我只需将这些词分成2个(例如artificial
和intelligence
),但这会影响我的相似性度量。什么是(将是)考虑这些类型的单词的最佳方法?
答案 0 :(得分:1)
有很多方法可以实现这一目标。一种方法是自己创建嵌入(向量)。这有两个好处:首先,您可以使用bi,tri和beyond(n-)克作为您的标记,其次,您可以定义最适合您需求的空间 - - 维基百科数据是一般性的,但是,儿童的故事将是一个更小众的数据集(更合适/"准确"如果您正在解决与儿童和/或故事有关的问题)。有几种方法,当然word2vec
是最受欢迎的,还有几种方法可以帮助您(例如gensim
)。
但是,我猜你想要的东西已经存在了。现在最好的嵌入词是:
我们感兴趣的是快速解决您的问题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。