12

これはコーディング固有の問題ではないことは承知していますが、このような質問をするのに最適な場所です。ご容赦ください。

以下のような辞書があり、各人の好きな項目が 10 個リストされているとします。

likes={
    "rajat":{"music","x-men","programming","hindi","english","himesh","lil wayne","rap","travelling","coding"},
    "steve":{"travelling","pop","hanging out","friends","facebook","tv","skating","religion","english","chocolate"},
    "toby":{"programming","pop","rap","gardens","flowers","birthday","tv","summer","youtube","eminem"},
    "ravi":{"skating","opera","sony","apple","iphone","music","winter","mango shake","heart","microsoft"},
    "katy":{"music","pics","guitar","glamour","paris","fun","lip sticks","cute guys","rap","winter"},
    "paul":{"office","women","dress","casuals","action movies","fun","public speaking","microsoft","developer"},
    "sheila":{"heart","beach","summer","laptops","youtube","movies","hindi","english","cute guys","love"},
    "saif":{"women","beach","laptops","movies","himesh","world","earth","rap","fun","eminem"}
    "mark":{"pilgrimage","programming","house","world","books","country music","bob","tom hanks","beauty","tigers"},
    "stuart":{"rap","smart girls","music","wrestling","brock lesnar","country music","public speaking","women","coding","iphone"},
    "grover":{"skating","mountaineering","racing","athletics","sports","adidas","nike","women","apple","pop"},
    "anita":{"heart","sunidhi","hindi","love","love songs","cooking","adidas","beach","travelling","flowers"},
    "kelly":{"travelling","comedy","tv","facebook","youtube","cooking","horror","movies","dublin","animals"},
    "dino":{"women","games","xbox","x-men","assassin's creed","pop","rap","opera","need for speed","jeans"},
    "priya":{"heart","mountaineering","sky diving","sony","apple","pop","perfumes","luxury","eminem","lil wayne"},
    "brenda":{"cute guys","xbox","shower","beach","summer","english","french","country music","office","birds"}
}

また、ユーザーベースまたはアイテムベースのフィルタリングの適切な例またはチュートリアルを教えていただけると助かります。

4

6 に答える 6

10

(免責事項、私はこの分野に精通しておらず、集合フィルタリングについての知識があります。以下は、私が有用だと思ったリソースのコレクションです)

この基本は、「集合知プログラミング」の本の第2章で非常に包括的に説明されています。サンプルコードはPythonであり、これはもう1つの利点です。

このサイトも役立つかもしれません- データマイニングのプログラマーガイド、特にレコメンデーションシステムとアイテムベースのフィルタリングについて説明している第2章と第3章。

つまり、ピアソン相関係数コサイン類似度k最近傍法などを計算するなどの手法を使用して、ユーザーが気に入った/購入した/投票したアイテムに基づいてユーザー間の類似性を判断できます。

この目的のために作成されたさまざまなPythonライブラリがあります。たとえば、 pysuggestCrabpython-recsysSciPy.stats.stats.pearsonrなどです。

ユーザー数がアイテム数を超える大規模なデータセットの場合、データを反転し、代わりにアイテム間の相関を計算して(つまり、アイテムベースのフィルタリング)、それを使用して類似ユーザーを推測することで、ソリューションをより適切にスケーリングできます。当然、これをリアルタイムで行うのではなく、バックエンドタスクとして定期的な再計算をスケジュールします。いくつかのアプローチは、並列化/分散化して、計算時間を大幅に短縮することができます(それにスローするリソースがあると仮定します)。

于 2012-07-16T12:35:42.823 に答える
7

Python recsys ライブラリを使用したソリューション [ http://ocelma.net/software/python-recsys/build/html/quickstart.html ]

from recsys.algorithm.factorize import SVD
from recsys.datamodel.data import Data

likes={
    "rajat":{"music","x-men","programming","hindi","english","himesh","lil wayne","rap","travelling","coding"},
    "steve":{"travelling","pop","hanging out","friends","facebook","tv","skating","religion","english","chocolate"},
    "toby":{"programming","pop","rap","gardens","flowers","birthday","tv","summer","youtube","eminem"},
    "ravi":{"skating","opera","sony","apple","iphone","music","winter","mango shake","heart","microsoft"},
    "katy":{"music","pics","guitar","glamour","paris","fun","lip sticks","cute guys","rap","winter"},
    "paul":{"office","women","dress","casuals","action movies","fun","public speaking","microsoft","developer"},
    "sheila":{"heart","beach","summer","laptops","youtube","movies","hindi","english","cute guys","love"},
    "saif":{"women","beach","laptops","movies","himesh","world","earth","rap","fun","eminem"},
    "mark":{"pilgrimage","programming","house","world","books","country music","bob","tom hanks","beauty","tigers"},
    "stuart":{"rap","smart girls","music","wrestling","brock lesnar","country music","public speaking","women","coding","iphone"},
    "grover":{"skating","mountaineering","racing","athletics","sports","adidas","nike","women","apple","pop"},
    "anita":{"heart","sunidhi","hindi","love","love songs","cooking","adidas","beach","travelling","flowers"},
    "kelly":{"travelling","comedy","tv","facebook","youtube","cooking","horror","movies","dublin","animals"},
    "dino":{"women","games","xbox","x-men","assassin's creed","pop","rap","opera","need for speed","jeans"},
    "priya":{"heart","mountaineering","sky diving","sony","apple","pop","perfumes","luxury","eminem","lil wayne"},
    "brenda":{"cute guys","xbox","shower","beach","summer","english","french","country music","office","birds"}
}

data = Data()
VALUE = 1.0
for username in likes:
    for user_likes in likes[username]:
        data.add_tuple((VALUE, username, user_likes)) # Tuple format is: <value, row, column>

svd = SVD()
svd.set_data(data)
k = 5 # Usually, in a real dataset, you should set a higher number, e.g. 100
svd.compute(k=k, min_values=3, pre_normalize=None, mean_center=False, post_normalize=True)

svd.similar('sheila')
svd.similar('rajat')

結果:

In [11]: svd.similar('sheila')
Out[11]: 
[('sheila', 0.99999999999999978),
 ('brenda', 0.94929845546505753),
 ('anita', 0.85943494201162518),
 ('kelly', 0.53385495931440263),
 ('saif', 0.39985366653259058),
 ('rajat', 0.30757664244952165),
 ('toby', 0.28541364367155014),
 ('priya', 0.26184289111194581),
 ('steve', 0.25043700194182622),
 ('katy', 0.21812807229358305)]

In [12]: svd.similar('rajat')
Out[12]: 
[('rajat', 1.0000000000000004),
 ('mark', 0.89164019482177692),
 ('katy', 0.65207273451425907),
 ('stuart', 0.61675507205285718),
 ('steve', 0.55730648750670264),
 ('anita', 0.49836982296014803),
 ('brenda', 0.42759524471725929),
 ('kelly', 0.40436047539358799),
 ('toby', 0.35972227835054826),
 ('ravi', 0.31113813325818901)]
于 2013-05-14T17:26:16.520 に答える
3

SequenceMatcherin difflibは、このような場合に役立ちます。使用するratio()と、ドキュメントから、2 つのシーケンス間の類似性に対応する 0 から 1 の間の値が返されます。

範囲 [0, 1] の float としてシーケンスの類似度の尺度を返します。ここで、T は両方のシーケンスの要素の総数、M は一致の数です。これは 2.0*M / T です。シーケンスが同一の場合は 1.0、共通点がない場合は 0.0 であることに注意してください。

あなたの例から、他のすべての人に対してのみ比較します(内部を'rajat'切り替えることで辞書に修正されます):{}[]

import difflib
for key in likes:
    print 'rajat', key, difflib.SequenceMatcher(None,likes['rajat'],likes[key]).ratio()
#Output:
rajat sheila 0.2
rajat katy 0.2
rajat brenda 0.1
rajat saif 0.2
rajat dino 0.2
rajat toby 0.2
rajat mark 0.1
rajat steve 0.1
rajat priya 0.1
rajat grover 0.0
rajat ravi 0.1
rajat rajat 1.0
rajat stuart 0.2
rajat kelly 0.1
rajat paul 0.0
rajat anita 0.2
于 2012-07-16T10:46:31.880 に答える
1

私が考えることができる最も基本的なアプローチは、各人の好きなもののリスト間の交差を見つけることです。好きなものが最も一致する2人の人が最も多くの交差を持つことになります。

みたいなのlist(set(list1).intersection(list2))が使えます。これにより、交差点を定義するアイテムのリストが返されます。

このアプローチは、各ユーザーのいいねを他のすべてのユーザーと比較する必要があるため、多数のエントリに十分に対応できないことに注意してください。これは、約 O(n^2) の複雑さを持ちます。ここで、n はエントリの数です。ユーザー。

一部のコメントでは、協調フィルタリングについて言及していますが、これは通常、同じアイテムを異なるユーザーによってランク付けし、ランク間の類似点を見つけることに適用されるため、いくつかのアイテムを同じ方法でランク付けしているユーザーを推定できますが、そうではありませんその他 (ここでは、他のアイテムで同様のランクを付けたユーザーのランクを使用します)。まったく同じ問題ではないと思います。

于 2012-07-16T10:45:24.673 に答える
0
for k in likes:
    if likes["rajat"] & likes[k]:
        print k, likes["rajat"] & likes[k]
    else:
        print k,  " No Like with rajat" 

Output

sheila set(['hindi', 'english'])
katy set(['music', 'rap'])
brenda set(['english'])
saif set(['himesh', 'rap'])
dino set(['x-men', 'rap'])
toby set(['programming', 'rap'])
mark set(['programming'])
steve set(['travelling', 'english'])
priya set(['lil wayne'])
grover No Likes with rajat
ravi set(['music'])
rajat set(['lil wayne', 'x-men', 'himesh', 'coding', 'programming', 'music', 'hindi',  'rap', 'english', 'travelling'])
stuart set(['music', 'coding', 'rap'])
kelly set(['travelling'])
paul No Likes with rajat
anita set(['travelling', 'hindi'])

これは、「rajat」の一般的なようなものを辞書の他のメンバーと比較します。これを行うためのより良い方法があるはずです

于 2012-07-16T11:01:19.203 に答える