【问题标题】:Python: Jaccard Distance using word intersection but not character intersectionPython:使用单词交集但不使用字符交集的 Jaccard 距离
【发布时间】:2012-08-11 01:56:51
【问题描述】:

我没有意识到 Python 的 set 函数实际上将字符串分隔为单个字符。我为 Jaccard 编写了 python 函数并使用了 python 交集方法。我将两个集合传递给这个方法,在将这两个集合传递给我的 jaccard 函数之前,我在 setring 上使用了 set 函数。

示例:假设我有字符串NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg,我会调用set(NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg),它将字符串分成字符。因此,当我将它发送到 jaccard 函数交集时,实际上是看字符交集而不是单词到单词的交集。我怎样才能做到字对字交集。

#implementing jaccard
def jaccard(a, b):
    c = a.intersection(b)
    return float(len(c)) / (len(a) + len(b) - len(c))

如果我不对我的字符串 NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg 调用 set 函数,我会收到以下错误:

    c = a.intersection(b)
AttributeError: 'str' object has no attribute 'intersection'

而不是字符到字符的交集,我想做单词到单词的交集并获得 jaccard 相似度。

【问题讨论】:

    标签: python set intersection


    【解决方案1】:

    先尝试将字符串拆分为单词:

    word_set = set(your_string.split())
    

    例子:

    >>> word_set = set("NEW Fujifilm 16MP 5x".split())
    >>> character_set = set("NEW Fujifilm 16MP 5x")
    >>> word_set
    set(['NEW', '16MP', '5x', 'Fujifilm'])
    >>> character_set
    set([' ', 'f', 'E', 'F', 'i', 'M', 'j', 'm', 'l', 'N', '1', 'P', 'u', 'x', 'W', '6', '5'])
    

    【讨论】:

    • 实际上,当我在寻找完全匹配的交叉路口使用 add 函数时,这正是我正在寻找的东西。
    【解决方案2】:

    我的计算 Jaccard 距离的函数:

    def DistJaccard(str1, str2):
        str1 = set(str1.split())
        str2 = set(str2.split())
        return float(len(str1 & str2)) / len(str1 | str2)
    
    >>> DistJaccard("hola amigo", "chao amigo")
    0.333333333333
    

    【讨论】:

      【解决方案3】:

      这个属性不是集合所独有的:

      >>> list('NEW Fujifilm')
      ['N', 'E', 'W', ' ', 'F', 'u', 'j', 'i', 'f', 'i', 'l', 'm']
      

      这里发生的是字符串被视为可迭代序列并逐个字符处理。

      您在 set 中看到的相同:

      >>> set('string')
      set(['g', 'i', 'n', 's', 'r', 't'])
      

      要修复,请在现有集合上使用 .add(),因为 .add() 不使用 interable:

      >>> se=set()
      >>> se.add('NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg')
      >>> se
      set(['NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg'])
      

      或者,使用 split()、元组、列表或一些替代的可迭代对象,这样字符串就不会被视为可迭代对象:

      >>> set('something'.split())
      set(['something'])
      >>> set(('something',))
      set(['something'])
      >>> set(['something'])
      set(['something'])
      

      根据您的字符串逐字添加更多元素:

      >>> se=set(('Something',)) | set('NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg'.split())   
      

      或者,如果您在添加到集合时需要理解某些逻辑:

      >>> se={w for w in 'NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg'.split() 
               if len(w)>3}
      >>> se
      set(['Shoot', 'CAMERA', 'Point', 'screen.jpg', 'Zoom', 'Fujifilm', '16MP', 'Optical'])
      

      它现在按照你的预期工作:

      >>> 'Zoom' in se
      True
      >>> s1=set('NEW Fujifilm 16MP 5x Optical Zoom Point and Shoot CAMERA 2 7 screen.jpg'.split())
      >>> s2=set('Fujifilm Optical Zoom CAMERA NONE'.split())
      >>> s1.intersection(s2)
      set(['Optical', 'CAMERA', 'Zoom', 'Fujifilm'])
      

      【讨论】:

      • 从“单词到单词的交集”,我认为 OP 确实在 set(a.split()).intersection(b.split()) 之后(模数大小写和标点符号细节。)
      【解决方案4】:

      这是我根据set函数写的-

      def jaccard(a,b):
          a=a.split()
          b=a.split()
          union = list(set(a+b))
          intersection = list(set(a) - (set(a)-set(b)))
          print "Union - %s" % union
          print "Intersection - %s" % intersection
          jaccard_coeff = float(len(intersection))/len(union)
          print "Jaccard Coefficient is = %f " % jaccard_coeff
      

      【讨论】:

        猜你喜欢
        • 2014-11-10
        • 1970-01-01
        • 2021-08-22
        • 2023-03-07
        • 1970-01-01
        • 2018-07-10
        • 2019-08-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多