Pearson在Python中的相关性

时间:2014-09-19 08:53:51

标签: python similarity pearson

我有一个关于相似性用户的python代码与Pearson的Correlation,我想分析计算步骤,因为我是Python的初学者呵呵。当我尝试手动计算并与该程序的结果进行比较时,结果总是不同的。我想知道在尝试手动计算时我是否错了。代码是这样的:

# A dictionary of movie critics and their ratings of a small set of movies


critics={'User 1': {'Spiderman': 1.0, 'Batman Begins': 2.0, 'Superman': 4.0},
  'User 2': {'Spiderman': 2.0, 'Batman Begins': 3.0, 'Superman': 3.0}
}


from math import sqrt

# Returns the Pearson correlation coefficient for p1 and p2
def sim_pearson(prefs,p1,p2):
  # Get the list of mutually rated items
  si={}
  for item in prefs[p1]:
    if item in prefs[p2]: si[item]=1

  # if they are no ratings in common, return 0
  if len(si)==0: return 0

  # Sum calculations
  n=len(si)

  # Sums of all the preferences
  sum1=sum([prefs[p1][it] for it in si])
  sum2=sum([prefs[p2][it] for it in si])

  # Sums of the squares
  sum1Sq=sum([pow(prefs[p1][it],2) for it in si])
  sum2Sq=sum([pow(prefs[p2][it],2) for it in si])

  # Sum of the products
  pSum=sum([prefs[p1][it]*prefs[p2][it] for it in si])

  # Calculate r (Pearson score)
  num=pSum-(sum1*sum2/n)
  den=sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n))
  if den==0: return 0

  r=num/den

  return r


def main():
    z = sim_pearson(critics, 'User 1','User 2')
    print z

if __name__ == "__main__":
    main()

我想计算用户1和用户2之间的相似度。但我对此部分感到困惑:

([prefs[p1][it] for it in si])

这是什么意思?

如果我使用这个程序,相似的结果是:0.755928946018

是真的,这段代码([prefs[p1][it] for it in si])的含义乘以用户1的等级?像1*2*4一样?或者它必须乘以用户2的评级?喜欢(1*2)+(1*3)+(4*3)

我对[p1][it]感到困惑。我希望你能帮助我,谢谢你的进步。

1 个答案:

答案 0 :(得分:1)

让我们把你感到困惑的行打破并分解:

sum1=sum([prefs[p1][it] for it in si])

让我们从外到内工作。最外面的部分是赋值语句,因此我们计算一些值以分配给sum1

sum1 = ...

现在,让我们看一下分配的内容:

sum1 = sum(...)

内置sum函数希望传递一个可迭代对象(例如列表)。让我们看看论点是什么:

sum1 = sum([... for it in si])

外方括号告诉我们,我们正在获取一份清单。 for it in si语法意味着这是列表推导。 Python运行for循环来生成列表的项目。我很确定变量名it代表“item”。循环遍在字典si的键上(实际上它应该是作为列表创建的,因为你从不关心它的值)。

值得注意的是,你实际上可以省略代码中的方括号,而不是一个列表理解,它在前面产生一个完整的列表,它将是一个“懒惰”的生成器表达式,它创建一个可迭代的生成器在请求时逐个计算每个值的对象。

无论如何,让我们找出列表理解的内容是什么:

sum1 = sum([...[it] for it in si])

[it]中的方括号是索引语法,因为它们位于另一个表达式的右侧。您可以使用整数和具有任何类型的可散列对象(例如字符串)的字典来索引列表和元组。在这种情况下,它们的键是it,这是列表推导中的循环变量。让我们看看我们正在索引的内容:

sum1 = sum([...[p1][it] for it in si])

[it]索引正在应用于先前索引的结果,这次使用[p1],这是函数的参数。让我们看看这个索引是做什么的:

sum1 = sum([prefs[p1][it] for it in si])

索引正在prefs上完成,p1是一个包含字典的全局变量。该词典的关键是审阅者(这是sum1必须的),值是进一步嵌套的词典,从电影名称映射到评级。

因此,该声明为一组特定的电影添加了一个评论者的分数,并将它们分配给1.0 + 2.0 + 4.0。对于您的示例数据,这将是sum1,因此7.0将被分配{{1}}。