3

クラスのレコメンダー システム プロジェクトでは、現在、約 7000 人のユーザー (行) と 4000 の映画 (列) を持つデータセットの項目ベースの類似性マトリックスを構築して保存しようとしています。だから私が持っているのは、UserIDs をインデックスとして、MovieIDs を列として、評価を値として持つピボット テーブルです。ご想像のとおり、多くの 0-評価があります。

現在、scipy パッケージの pearsonr 関数を使用しています。すべての距離を保存するには、すべての列間のピアソン係数を計算し、それらを対称的な映画 - 映画行列に保存する必要があると考えました。これまでの私のコード(ご覧のとおり、私はPython /コーディングが初めてです):

import pandas as pd
import numpy as np
from scipy.stats import pearsonr

pd.read_csv('data.csv')
data = data.pivot(index = 'UserID', columns = 'MovieID', values = "Rating")

similarity_data = pd.DataFrame(index=data.columns, columns=data.columns)

for i in range(0,len(data.columns)):
    for j in range(0,len(data.columns)):
        similarity_data.iloc[i,j] =  pearsonr(data.iloc[:,i],data.iloc[:,j])[0]

ご想像のとおり、これには永遠の時間がかかります。私は、これをより効率的に行う方法を見つけたいと思っています。私の最初のアイデアは、行列が対称であることを利用することでした。しかし、私は方法を理解できませんでした。

私の考えは次のようなものでした:

for i in range(0,len(data.columns)):
    for j in range(0,len(data.columns)):
        similarity_data.iloc[i,j] =  pearsonr(data.iloc[:,i],data.iloc[:,j+i])[0]
        similarity_data[j,i] = similarity_data.iloc[i,j]

ただし、これを機能させたとしても、ここでの問題は 2 つの for ループにあるのではないかと心配しています。どういうわけかマップまたはラムダのアプローチを使用しようとしていましたが、どこにも行けませんでした。

これを改善する方法はありますか(おそらく多くの場合)?

4

2 に答える 2

3

np.corrcoefこれは、単純なループオーバーよりも約 1000 倍高速ですscipy.stats.pearsonr。例えば:

from scipy.stats import pearsonr
import numpy as np
import pandas as pd

# make some small data
df = pd.DataFrame(np.random.rand(100, 40))

C1 = np.array([[pearsonr(df[i], df[j])[0] for i in df] for j in df])
C2 = np.corrcoef(df.values.T)
np.allclose(C1, C2)
# True

時間は次のとおりです。

%timeit np.array([[pearsonr(df[i], df[j])[0] for i in df] for j in df])
10 loops, best of 3: 154 ms per loop

%timeit np.corrcoef(df.values.T)
10000 loops, best of 3: 116 µs per loop

それでも、結果は約 1600 万のエントリを持つ密な行列になるため、高速な計算にはなりません。これらすべての値を本当に格納する必要があるかどうか、または (たとえば) 最近隣の相関を計算するだけのアルゴリズムを使用できるかどうかについて考えるかもしれません。

于 2015-11-14T00:25:16.063 に答える
1

同じ相関行列が得られませんnp.corrcoef(data)か?

そうでない場合は、対称結果行列の半分のみを計算し、が に等しいpearsonr()場合はまったく呼び出さないことで、パフォーマンスをおおよそ 2 倍にすることができるはずです。ij

于 2015-11-13T23:54:58.120 に答える