0

私はピアソンの相関関係を持つ類似度ユーザーに関するPythonのコードを持っています。私は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]ます。よろしくお願いします。

4

1 に答える 1

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(値を気にすることはないため、実際にはリストとして作成する必要があります) を対象としています。

ここのコードから実際に角括弧を省略できることに注意してください。完全なリストをすべて事前に生成するリスト内包表記ではなく、計算する反復可能なジェネレーター オブジェクトを作成する「遅延」ジェネレーター式になります。要求に応じて、各値を 1 つずつ。

とにかく、リスト内包表記の項目が何であるかを調べてみましょう:

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べきです) であり、値はさらにネストされたディクショナリで、映画の名前から評価にマッピングされます。

したがって、このステートメントは、特定の映画セットに対する 1 人のレビュアーのスコアを合計し、それらを に割り当てますsum1。サンプルデータでは、これは になる1.0 + 2.0 + 4.0ため、sum1割り当てられ7.0ます。

于 2014-09-19T09:56:53.660 に答える