【问题标题】:How do you write a program to find if certain words are similar?您如何编写程序来查找某些单词是否相似?
【发布时间】:2012-12-18 09:50:36
【问题描述】:

即:“college”和“schoolwork”和“academy”属于同一个集群, “essay”、“scholarships”、“money”这些词也属于同一个集群。这是 ML 还是 NLP 问题?

【问题讨论】:

  • 这些词是相关的,而不是相似的。
  • 这是一个科学还是哲学问题?
  • 说真的,自然语言处理学科通常使用一些技术,其中之一是机器学习。如果没有基于某种 NLP 理论的模型,您可以使用哪些功能来解决这个作为 ML 问题的问题?

标签: machine-learning nlp


【解决方案1】:

我想您可以使用 ML 和 NLP 技术构建自己的此类关联数据库,但您也可以考虑查询现有资源(例如 WordNet)来完成工作。

【讨论】:

    【解决方案2】:

    关于您的问题的名言是 John Rupert Firth 在 1957 年的名言:

    你应该知道它所拥有的公司的一个词

    要开始深入研究这个主题,您可以查看this presentation

    【讨论】:

      【解决方案3】:

      如果您有大量与感兴趣的主题相关的文档,您可能需要查看Latent Direchlet Allocation。 LDA 是一种相当标准的 NLP 技术,它可以自动将单词聚类到主题中,其中单词之间的相似性由同一文档中的搭配决定(如果可以更好地满足您的需求,您可以将单个句子视为文档)。

      您会发现许多可用的 LDA 工具包。在推荐一个而不是另一个之前,我们需要更多关于您的确切问题的详细信息。无论如何,我还不足以作为专家提出这个建议,但我至少可以建议你看看 LDA。

      【讨论】:

        【解决方案4】:

        这取决于你对相似的定义有多严格。

        机器学习技术

        正如others 所指出的,您可以使用latent semantic analysis 或相关的latent Dirichlet allocation 之类的东西。

        语义相似度和 WordNet

        pointed out 一样,您可能希望将现有资源用于此类事情。

        许多研究论文 (example) 使用术语语义相似度。基本思想是计算这通常是通过在图上的两个单词之间找到distance 来完成的,如果单词是其父项的类型,则该单词是子项。示例:“songbird”将是“bird”的子级。如果您愿意,语义相似度可以用作创建集群的距离度量。

        示例实现

        另外,如果你对某个语义相似度度量的值设置一个阈值,你可以得到一个布尔值TrueFalse。这是我创建的 Gist (word_similarity.py),它使用 NLTK's 语料库阅读器来读取 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
        

        【讨论】:

        • @weseley:你给出阈值的依据是什么?
        • @WesleyBaugh 关于在达到阈值数字之前您执行了多少代码的任何指针?
        • 另外,这段代码告诉你,这里提到的所有相似度度量都没有区分两个词的“相似性”和“相关性”。例如,您会发现此代码为“love”和“hate”返回 True。它们显然是反义词,但仍然相关(通过“感觉”的概念)。更多信息:linguistics.stackexchange.com/questions/9084/…
        【解决方案5】:

        Word2Vec 可以发挥作用(在上下文/语义上)查找相似词。在word2vec中,我们将单词作为n维空间中的向量,可以计算单词之间的距离(欧几里得距离),也可以简单地进行聚类。

        在此之后,我们可以得出一些 b/w 2 词相似度的数值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-09-08
          • 2022-06-11
          • 2020-07-06
          • 1970-01-01
          • 1970-01-01
          • 2013-10-21
          • 1970-01-01
          相关资源
          最近更新 更多