即:“college”、“schoolwork”和“academy”属于同一个簇,“essay”、“scholarships”、“money”等词也属于同一个簇。这是 ML 还是 NLP 问题?
5 回答
这取决于您对相似的定义有多严格。
机器学习技术
正如其他人指出的那样,您可以使用潜在语义分析或相关的潜在狄利克雷分配之类的东西。
语义相似度和 WordNet
正如所指出的,您可能希望将现有资源用于此类事情。
许多研究论文(示例)使用术语语义相似性。基本思想是计算这通常是通过在图上找到两个词之间的距离来完成的,其中如果一个词是其父词的一种类型,那么它就是一个子词。示例:“songbird”将是“bird”的子级。如果您愿意,语义相似度可以用作创建集群的距离度量。
示例实现
另外,如果你对某个语义相似度度量的值设置一个阈值,你可以得到一个布尔值True
或False
。这是我创建的一个 Gist ( word_similarity.py ),它使用NLTK 的WordNet语料库阅读器。希望这可以为您指明正确的方向,并为您提供更多搜索词。
def sim(word1, word2, lch_threshold=2.15, verbose=False):
"""Determine if two (already lemmatized) words are similar or not.
Call with verbose=True to print the WordNet senses from each word
that are considered similar.
The documentation for the NLTK WordNet Interface is available here:
http://nltk.googlecode.com/svn/trunk/doc/howto/wordnet.html
"""
from nltk.corpus import wordnet as wn
results = []
for net1 in wn.synsets(word1):
for net2 in wn.synsets(word2):
try:
lch = net1.lch_similarity(net2)
except:
continue
# The value to compare the LCH to was found empirically.
# (The value is very application dependent. Experiment!)
if lch >= lch_threshold:
results.append((net1, net2))
if not results:
return False
if verbose:
for net1, net2 in results:
print net1
print net1.definition
print net2
print net2.definition
print 'path similarity:'
print net1.path_similarity(net2)
print 'lch similarity:'
print net1.lch_similarity(net2)
print 'wup similarity:'
print net1.wup_similarity(net2)
print '-' * 79
return True
示例输出
>>> sim('college', 'academy')
True
>>> sim('essay', 'schoolwork')
False
>>> sim('essay', 'schoolwork', lch_threshold=1.5)
True
>>> sim('human', 'man')
True
>>> sim('human', 'car')
False
>>> sim('fare', 'food')
True
>>> sim('fare', 'food', verbose=True)
Synset('fare.n.04')
the food and drink that are regularly served or consumed
Synset('food.n.01')
any substance that can be metabolized by an animal to give energy and build tissue
path similarity:
0.5
lch similarity:
2.94443897917
wup similarity:
0.909090909091
-------------------------------------------------------------------------------
True
>>> sim('bird', 'songbird', verbose=True)
Synset('bird.n.01')
warm-blooded egg-laying vertebrates characterized by feathers and forelimbs modified as wings
Synset('songbird.n.01')
any bird having a musical call
path similarity:
0.25
lch similarity:
2.25129179861
wup similarity:
0.869565217391
-------------------------------------------------------------------------------
True
>>> sim('happen', 'cause', verbose=True)
Synset('happen.v.01')
come to pass
Synset('induce.v.02')
cause to do; cause to act in a specified manner
path similarity:
0.333333333333
lch similarity:
2.15948424935
wup similarity:
0.5
-------------------------------------------------------------------------------
Synset('find.v.01')
come upon, as if by accident; meet with
Synset('induce.v.02')
cause to do; cause to act in a specified manner
path similarity:
0.333333333333
lch similarity:
2.15948424935
wup similarity:
0.5
-------------------------------------------------------------------------------
True
我想您可以建立自己的此类关联数据库,使用 ML 和 NLP 技术,但您也可以考虑查询现有资源(例如WordNet)来完成工作。
如果您有大量与感兴趣的主题相关的文档,您可能需要查看Latent Direchlet Allocation。LDA 是一种相当标准的 NLP 技术,可以自动将单词聚类到主题中,其中单词之间的相似性由同一文档中的搭配确定(如果可以更好地满足您的需求,您可以将单个句子视为文档)。
您会发现许多可用的 LDA 工具包。在推荐一个而不是另一个之前,我们需要更多关于您的确切问题的详细信息。无论如何,我还不足以提出这个建议,但我至少可以建议你看看 LDA。
Word2Vec 可以发挥作用(在上下文/语义上)查找相似的单词。在 word2vec 中,我们将单词作为 n 维空间中的向量,可以计算单词之间的距离(欧几里得距离),也可以简单地进行聚类。
在此之后,我们可以为 b/w 2 个词的相似度得出一些数值。