1

行がユーザーでテレビ番組が列であるユーザーとテレビ番組の隣接リストを作成する必要があります。ユーザーがそのテレビ番組をフォローしている場合、マトリックスには1があり、それ以外の場合はゼロになります。この情報は私がすでにツイッターから集めたものです。合計で140のテレビ番組と約530000のユニークユーザーがいます。次のコードを使用して、Pythonを使用してマトリックスを生成しています。

  • NoTvShows:テレビ番組(ID)の総数
  • unique_user:すべてのユニークユーザー
  • collected_users:これはリストのリストです。サブリストはテレビ番組に対応し、フォロワーのIDをリストします。
for i in range(0,NoTvShows):
    for every_user in unique_users:
        if every_user in collected_users[i]:
            matrix.append(1)
        else:
            matrix.append(0)
    main_matrix.append(matrix)
    matrix = []

the_matrix = zip(*main_matrix)
simplejson.dump(the_matrix,fwrite)
fwrite.close()

サーバーでプログラムを実行しようとすると、多くの時間とメモリを消費するため、クラッシュします。numpyを使用してマトリックスのサイズを縮小し、それを使用してユーザー間の類似性を計算できることはわかっています。ただし、このコードでnumpyをコーディングして、縮小された行列を生成する方法がわかりません。

この点で誰かが私を導いてくれることを願っています

ありがとうございました

リチャ

4

3 に答える 3

6

マトリックスのほとんどのエントリはおそらく 0 であるため、( @phg で提案されているように)スパース マトリックスは適切です (ほとんどのユーザーがいくつかのテレビ番組のみをフォローしていると仮定します)。

ただし、おそらくもっと重要なことは、最初にそれらを適切なコンパクトな numpy 配列に配置するのではなく、非常に非効率的な方法でマトリックスを構築している (python リストのリストを大量に作成し、それらをコピーする) ことです。inまた、ループにはまったく必要ない場合でも、(ステートメントを使用して) リストを検索するのに膨大な時間を費やしています。

このコードはフォロワー リストをループし、 #user_idsディクショナリ内の各 ID のユーザーを検索します。かなり簡単に疎行列クラスに適応させることができます (単に に切り替えるだけnp.zerosscipy.sparse.coo_matrixと思います)。

user_ids = dict((user, i) for i, user in enumerate(unique_users))

follower_matrix = np.zeros(NoTvShows, len(unique_users), dtype=bool)
for show_idx, followers in enumerate(collected_users):
    for user in followers:
        follower_matrix[show_idx, user_ids[user]] = 1

マトリックスを取得したら、必要な場合を除き、JSON として保存したくありません。これは、数値マトリックスの非常に無駄な形式です。numpy.savenumpy でデータ マトリックスのみを使用している場合に最適です。numpy.savetxtも機能し、少なくともブラケットとコンマを排除し、おそらく書き込み中のメモリ オーバーヘッドが少なくなります。しかし、0-1 行列があり、それがブール データ型の場合、numpy.save行列要素ごとに 1 ビットしか必要としないのに対し、numpy.savetxt必要なのは 2 バイト = 16 ビット (ASCII'0'または'1'プラス スペースまたは改行) であり、json は少なくとも 3 バイトを使用します。私は(カンマ、スペース、および各行にいくつかの括弧)だと思います。


次元削減技術についても話しているかもしれません。それも非常に可能です。ある種の PCA タイプの手法、トピック モデル、おそらくクラスタリングに基づくものによって、140 次元のベクトル (テレビ番組がフォローされています) をより低い次元に縮小するための手法がたくさんあります。唯一の懸念は、マトリックスの構築に時間がかかることですが、それはまったく役に立ちません (これらの手法は通常、完全な元のマトリックスを必要とし、低次元のバージョンを提供するためです)。ここで私の提案を試してみてください。十分でない場合は、スパース行列を試してから、データを減らすための派手な方法について心配してください (おそらく、データのサブセットで次元削減を学習し、残りを構築することによって)。

于 2012-04-27T06:35:21.830 に答える
3

スペースを削減するために疎行列を使用することもできます。私はscipyのためにこれを見つけました: http://docs.scipy.org/doc/scipy/reference/sparse.html

おっしゃる通りだと思います。

于 2012-04-27T06:19:04.543 に答える
1

興味がある場合の別のアプローチを次に示します。ユーザーが保存されている順序であると想定していますが、数値または文字列の ID にすることができます。

# The setup
users = ['bob', 'dave', 'steve']
users = np.array(users)
collected_users = [['bob'], ['dave'], ['steve', 'dave'], ['bob', 'steve', 'dave']]
NoTvShows = len(collected_users)

# The meat
matrix = np.zeros((NoTvShows, len(users)), 'bool')
for i, watches in enumerate(collected_users):
    index = users.searchsorted(watches)
    matrix[i, index] = 1
于 2012-04-27T18:47:12.103 に答える