2012-07-16 11 views
12

मुझे पता है कि यह एक कोडिंग विशिष्ट समस्या नहीं है लेकिन यह ऐसे प्रश्न पूछने के लिए सबसे उपयुक्त जगह है। तो कृपया मेरे साथ भालू।उपयोगकर्ता आधारित फ़िल्टरिंग: अनुशंसा प्रणाली

मान लीजिए मैं नीचे दिए गए की तरह एक शब्दकोश है, लिस्टिंग दस प्रत्येक व्यक्ति

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"} 
} 

मैं लोगों को, जो समान likes.Or है कैसे निर्धारित कर सकते हैं के आइटम पसंद किए शायद जो दो व्यक्तियों most.Also जैसे लगते हैं यह हो जाएगा सहायक यदि आप मुझे उपयुक्त उदाहरण या उपयोगकर्ता आधारित या आइटम आधारित फ़िल्टरिंग के लिए ट्यूटोरियल पर इंगित कर सकते हैं।

+1

यह प्रोग्रामिंग सामूहिक खुफिया के [अध्याय 2] (http://books.google.co.uk/books?id=fEsZ3Ey-Hq4C&lpg=PP1&pg=PA7#v=onepage&q&f=false) द्वारा काफी व्यापक रूप से कवर किया गया है। उदाहरण कोड पायथन में हैं, जो एक और प्लस है। –

+0

मुझे इस पुस्तक से अवगत है लेकिन यह बहुत पुराना है (प्रकाशित 2007) और वेब काफी बदल गया है। इसलिए मुझे नहीं लगता कि इस पुस्तक के अधिकांश उदाहरण आज काम करेंगे। –

+4

मूल तकनीक अभी भी खड़ी है और आपके द्वारा प्रदत्त नमूना डेटा के लिए काम करना चाहिए। यदि आप कुछ और जटिल/स्केलेबल की तलाश में हैं तो आप अपने प्रश्न में इसका उल्लेख करना चाहेंगे। यह भी उल्लेखनीय हो सकता है कि आपने जो कोशिश की है या विचार किया है। –

उत्तर

10

करने के लिए एक बेहतर तरीका होना चाहिए (अस्वीकरण, मैं इस क्षेत्र में निपुण नहीं हूँ और केवल सामूहिक छानने की एक गुजर ज्ञान है। निम्नलिखित है कि मैं उपयोगी पाया है बस एक संसाधनों का संग्रह है)

इसकी मूल बातें Chapter 2 of the "Programming Collective Intelligence" book में काफी व्यापक रूप से शामिल हैं। उदाहरण कोड पायथन में हैं, जो एक और प्लस है।

आप भी इस साइट उपयोगी लग सकते - A Programmer's Guide to Data Mining, विशेष रूप से Chapter 2 और Chapter 3 में जो सिफारिश प्रणालियों और आइटम आधारित छानने चर्चा करता है। इस तरह की गणना Pearson Correlation Coefficient, Cosine Similarity, k-nearest neighbours, आदि आइटम वे की तरह है के आधार पर उपयोगकर्ताओं के बीच समानता का निर्धारण करने के रूप में

तकनीक संक्षेप में, एक का उपयोग कर सकते हैं/खरीदा/पर मतदान किया।

ध्यान दें कि इस उद्देश्य के लिए लिखे गए विभिन्न पायथन पुस्तकालय हैं, उदाहरण के लिए pysuggest, Crab, python-recsys, और SciPy.stats.stats.pearsonr

एक बड़े डेटा सेट के लिए जहां उपयोगकर्ताओं की संख्या आइटमों की संख्या से अधिक है, आप अपने डेटा को उलटा करके समाधान को बेहतर तरीके से स्केल कर सकते हैं और इसके बजाय वस्तुओं (यानी आइटम-आधारित फ़िल्टरिंग) के बीच सहसंबंध की गणना कर सकते हैं और समान उपयोगकर्ताओं को अनुमान लगाने के लिए इसका उपयोग कर सकते हैं । स्वाभाविक रूप से, आप वास्तविक समय में ऐसा नहीं करेंगे लेकिन बैकएंड कार्य के रूप में आवधिक पुनर्मूल्यांकन निर्धारित करेंगे। गणनाओं के समय को कम करने के लिए कुछ दृष्टिकोण समानांतर/वितरित किए जा सकते हैं (माना जाता है कि आपके पास संसाधनों को फेंकने के लिए) हैं।

1

सबसे बुनियादी दृष्टिकोण जो मैं सोच सकता हूं वह है कि प्रत्येक व्यक्ति की पसंद की सूची के बीच छेड़छाड़ को ढूंढना, जिन लोगों की पसंद सबसे ज्यादा मिलती है, उनमें सबसे अधिक संख्या में चौराहे होंगे।

list(set(list1).intersection(list2)) जैसे कुछ का उपयोग किया जा सकता है। यह उन वस्तुओं के साथ एक सूची लौटाएगा जो छेड़छाड़ को परिभाषित करते हैं।

ध्यान रखें कि यह दृष्टिकोण उच्च संख्या में प्रविष्टियों के लिए अच्छी तरह से स्केल नहीं करेगा, क्योंकि प्रत्येक उपयोगकर्ता की पसंदों की तुलना किसी अन्य से तुलना की जानी चाहिए, इसमें लगभग ओ (एन^2) की जटिलता है, जहां n उपयोगकर्ताओं की संख्या है।

अपनी टिप्पणी में से कुछ में आप सहयोगी को छानने का उल्लेख है, लेकिन है कि आमतौर पर अलग-अलग उपयोगकर्ताओं द्वारा स्थान पर रहीं ही आइटम होने, और फिर रैंकों के बीच समानता पाने के लिए लागू होता है, तो आप जो कुछ में स्थान आइटम नहीं हैं उपयोगकर्ताओं के लिए एक्सट्रपलेशन कर सकते हैं वैसे ही, लेकिन दूसरों को नहीं (यहां आप उन उपयोगकर्ताओं के रैंक का उपयोग करते हैं जिन्होंने अन्य वस्तुओं पर समान रैंक दिए हैं)। मुझे नहीं लगता कि यह एक ही समस्या है।

3

SequenceMatcherdifflib इस तरह की चीज़ के लिए उपयोगी है। आप ratio() का उपयोग करते हैं यह दो दृश्यों के बीच समानता के लिए इसी 0 और 1 के बीच कोई मान, डॉक्स से प्रस्तुत करती है:

वापसी रेंज में एक नाव के रूप में दृश्यों 'समानता का एक उपाय [0, 1] । जहां टी दोनों अनुक्रमों में तत्वों की कुल संख्या है, और एम मैचों की संख्या है, यह 2.0 * एम/टी है नोट करें कि यह 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 
+0

धन्यवाद लेकिन मैं "सहयोगी फ़िल्टरिंग" जैसी कुछ देख रहा हूं। सहयोगी फ़िल्टरिंग के संबंध में कोई भी मदद की सराहना की जाएगी। –

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']) 

यह "रजत" की तरह सामान्य की तुलना होगा dict के अन्य सदस्यों के साथ। इस

7

अजगर 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)] 
+0

धन्यवाद! मैं थोड़ी देर के लिए इस तरह कुछ ढूंढ रहा हूं – nickromano

+0

ग्रेट लाइब्रेरी! (मुझे लगता है कि आप लेखक हैं)। हालांकि, पायथन 3 के साथ संगत नहीं है। – Siddhartha

0

एक उपयोगकर्ता-आधारित छानने करने के लिए सीखने scikit भी उपयोग कर सकते हैं:

एक सरल ले रहा है उदाहरण के लिए, यदि आपके पास था:

"stuart":{"rap","rock"}

और आप के साथ अपने संगीत स्वाद समानता की जांच करना चाहता था:

"toby:{"hip-hop","pop","rap"}

आप sklearn के जोड़ो में कोज्या समानता समारोह का उपयोग कर सकते,

from sklearn.feature_extraction.text import CountVectorizer 
from sklearn.metrics.pairwise import cosine_similarity 

vec = CountVectorizer(analyzer='char') 
vec.fit(stuart_list) 

x = cosine_similarity(vec.transform(toby_list), 
       vec.transform(stuart_list)) 

जो आप की तरह एक कोज्या मैट्रिक्स दे देंगे:

[[ 0.166 0.327 1] 
[ 0.123 0.267 0.230]] 

जहां पहली पंक्ति rap की कोसाइन समानता का प्रतिनिधित्व करती है जिसमें सभी 3 टॉबी के विकल्प होते हैं। उचित ट्रायगोनोमेट्रिक शब्दों में, एक पूर्ण समानता का प्रतिनिधित्व करने वाले 1 पर ध्यान दें, इसका मतलब है कि 2 विकल्पों में 0º का कोण था (यानी समान थे) और इस प्रकार 1

दूसरी पंक्ति समान rock का कोसाइन का प्रतिनिधित्व करती है सभी 3 toby के विकल्पों के साथ समानता।

मुझे स्केलेर्न में दो सूचियों के बीच समग्र समानता खोजने का कोई तरीका नहीं मिला, हालांकि, कोसाइन मैट्रिक्स दिया गया है, आप वहां 1 एस की संख्या गिन सकते हैं और यह समानता संख्या हो सकती है। या आप 0.9 एस और ऊपर की संख्या को 'हिप-हॉप' और 'हिप्पोप' जैसे लगभग समान शब्दों के लिए खाते में गिना जा सकता है।

(स्केलेर्न में यूक्लिडियन समानता भी है जिसे कोसाइन समानता के विकल्प के रूप में उपयोग किया जा सकता है।)

संबंधित मुद्दे