इस ट्यूटोरियल का उद्देश्य आपको रिकमेंडर सिस्टम मॉडल बनाने में विशेषज्ञ बनाना नहीं है। बल्कि, मकसद आपको शुरुआत कराने का है—यह बताकर कि किस प्रकार के रिकमेंडर सिस्टम होते हैं और आप अपना एक सिस्टम कैसे बना सकते हैं।
इस ट्यूटोरियल में, आप सरल और कंटेंट-आधारित रिकमेंडर सिस्टम्स के एक बेसिक मॉडल बनाना सीखेंगे। भले ही ये मॉडल जटिलता, गुणवत्ता, या सटीकता के लिहाज से इंडस्ट्री स्टैंडर्ड के करीब न हों, लेकिन ये आपको बेहतर परिणाम देने वाले अधिक जटिल मॉडलों के निर्माण की दिशा में शुरुआत करने में मदद करेंगे।
आज डेटा साइंस के सबसे लोकप्रिय अनुप्रयोगों में रिकमेंडर सिस्टम शामिल हैं। इनका उपयोग यह “रेटिंग” या “पसंद” का अनुमान लगाने में किया जाता है कि कोई उपयोगकर्ता किसी आइटम को क्या देगा। लगभग हर बड़ी टेक कंपनी किसी न किसी रूप में इन्हें लागू करती है। Amazon ग्राहकों को प्रोडक्ट सुझाने के लिए, YouTube ऑटोप्ले में अगला वीडियो चुनने के लिए, और Facebook पसंद करने के लिए पेज और फॉलो करने के लिए लोगों की सिफारिश करने के लिए इसका उपयोग करता है।
इसके अलावा, Netflix, Amazon Prime, Hulu, और Hotstar जैसी कंपनियों के लिए, उनके बिजनेस मॉडल और उसकी सफलता काफी हद तक उनकी सिफारिशों की प्रभावशीलता पर निर्भर करती है। Netflix ने 2009 में अपने सिस्टम में 10% सुधार करने वाले किसी भी व्यक्ति को एक मिलियन डॉलर का इनाम भी रखा था।
रेस्तरां, फिल्मों और ऑनलाइन डेटिंग जैसे डोमेन के लिए भी लोकप्रिय रिकमेंडर सिस्टम मौजूद हैं। शोध लेख, विशेषज्ञ और सहयोगी खोजने, तथा वित्तीय सेवाओं के लिए भी रिकमेंडर सिस्टम विकसित किए गए हैं। YouTube बड़े पैमाने पर आपकी हिस्ट्री के आधार पर वीडियो सुझाने के लिए रिकमेंडेशन सिस्टम का उपयोग करता है। उदाहरण के लिए, यदि आप बहुत सारे शैक्षिक वीडियो देखते हैं, तो वह उसी प्रकार के वीडियो सुझाएगा।
लेकिन आखिर ये रिकमेंडर सिस्टम होते क्या हैं?
व्यापक रूप से, रिकमेंडर सिस्टम 3 प्रकार के होते हैं:
सिंपल रिकमेंडर: मूवी की लोकप्रियता और/या शैली के आधार पर हर उपयोगकर्ता को सामान्य सिफारिशें देते हैं। इस सिस्टम के पीछे मूल विचार यह है कि जो फिल्में अधिक लोकप्रिय और समीक्षकों द्वारा सराही गई हैं, उन्हें औसत दर्शक द्वारा पसंद किए जाने की संभावना अधिक होती है। एक उदाहरण IMDB Top 250 हो सकता है।
कंटेंट-आधारित रिकमेंडर: किसी विशेष आइटम के आधार पर उससे मिलते-जुलते आइटम सुझाते हैं। यह सिस्टम सिफारिशें देने के लिए आइटम के मेटाडेटा—जैसे फिल्मों के लिए जेनर, डायरेक्टर, डिस्क्रिप्शन, अभिनेता आदि—का उपयोग करता है। इनके पीछे सामान्य विचार यह है कि यदि किसी व्यक्ति को कोई विशिष्ट आइटम पसंद है, तो उसे उससे मिलता-जुलता आइटम भी पसंद आएगा। और इसे सुझाने के लिए यह उपयोगकर्ता के पिछले आइटम मेटाडेटा का उपयोग करेगा। एक अच्छा उदाहरण YouTube है, जहां आपकी हिस्ट्री के आधार पर वह आपको नए वीडियो सुझाता है जिन्हें आप संभवतः देखेंगे।
कोलैबोरेटिव फिल्टरिंग इंजन: ये सिस्टम व्यापक रूप से उपयोग किए जाते हैं और वे अन्य उपयोगकर्ताओं की पिछली रेटिंग्स और पसंद के आधार पर अनुमान लगाने की कोशिश करते हैं कि कोई उपयोगकर्ता किसी आइटम को क्या रेटिंग/पसंद देगा। कोलैबोरेटिव फिल्टर, कंटेंट-आधारित के विपरीत, आइटम मेटाडेटा की आवश्यकता नहीं रखते।
सिंपल रिकमेंडर
जैसा कि पिछले सेक्शन में बताया गया, सिंपल रिकमेंडर ऐसे बुनियादी सिस्टम होते हैं जो किसी निश्चित मीट्रिक या स्कोर के आधार पर टॉप आइटम सुझाते हैं। इस सेक्शन में, आप IMDB Top 250 Movies का एक सरल क्लोन बनाएंगे, जिसके लिए IMDB से एकत्रित मेटाडेटा का उपयोग किया जाएगा।
इसमें शामिल चरण निम्नलिखित हैं:
फिल्मों को रेट करने के लिए मीट्रिक या स्कोर तय करें।
हर फिल्म के लिए स्कोर की गणना करें।
स्कोर के आधार पर फिल्मों को सॉर्ट करें और शीर्ष परिणाम निकालें।
डेटासेट के बारे में
डेटासेट फाइलों में Full MovieLens Dataset में सूचीबद्ध सभी 45,000 फिल्मों का मेटाडेटा शामिल है। डेटासेट में जुलाई 2017 या उससे पहले रिलीज़ हुई फिल्में शामिल हैं। यह डेटासेट कलाकार, क्रू, प्लॉट कीवर्ड, बजट, रेवेन्यू, पोस्टर्स, रिलीज़ डेट, भाषाएं, प्रोडक्शन कंपनियां, देश, TMDB वोट काउंट और वोट एवरेज जैसे फीचर पॉइंट्स को कैप्चर करता है।
इन फीचर पॉइंट्स का उपयोग कंटेंट और कोलैबोरेटिव फिल्टरिंग के लिए आपके मशीन लर्निंग मॉडल को ट्रेन करने में किया जा सकता है।
इस डेटासेट में निम्नलिखित फाइलें शामिल हैं:
movies_metadata.csv: इस फाइल में Full MovieLens डेटासेट में शामिल ~45,000 फिल्मों की जानकारी होती है। फीचर्स में पोस्टर्स, बैकड्रॉप्स, बजट, जेनर, रेवेन्यू, रिलीज़ डेट, भाषाएं, प्रोडक्शन देश और कंपनियां शामिल हैं।
keywords.csv: हमारी MovieLens फिल्मों के प्लॉट कीवर्ड्स शामिल हैं। स्ट्रिंगिफाइड JSON ऑब्जेक्ट के रूप में उपलब्ध।
credits.csv: सभी फिल्मों के कास्ट और क्रू की जानकारी शामिल है। स्ट्रिंगिफाइड JSON ऑब्जेक्ट के रूप में उपलब्ध।
links.csv: इस फाइल में Full MovieLens डेटासेट में शामिल सभी फिल्मों के TMDB और IMDB IDs हैं।
links_small.csv: फुल डेटासेट की 9,000 फिल्मों के एक छोटे सबसेट के TMDB और IMDB IDs शामिल हैं।
ratings_small.csv: 9,000 फिल्मों पर 700 उपयोगकर्ताओं की 100,000 रेटिंग्स का सबसेट।
Full MovieLens Dataset में 26 मिलियन रेटिंग्स और 750,000 टैग एप्लिकेशंस शामिल हैं, जो इस डेटासेट की सभी 45,000 फिल्मों पर 270,000 उपयोगकर्ताओं से आए हैं। इसे आधिकारिक GroupLens वेबसाइट से एक्सेस किया जा सकता है।
नोट: आज के ट्यूटोरियल में उपयोग किया गया सबसेट डेटासेट यहां से डाउनलोड किया जा सकता है।
अपने डेटासेट को लोड करने के लिए, आप pandas DataFrame लाइब्रेरी का उपयोग करेंगे। pandas लाइब्रेरी मुख्यतः डेटा मैनिपुलेशन और विश्लेषण के लिए उपयोग होती है। यह आपके डेटा को रो-कॉलम फॉर्मेट में प्रस्तुत करती है। Pandas लाइब्रेरी के पीछे NumPy array होता है जो pandas डेटा ऑब्जेक्ट्स के इम्प्लीमेंटेशन का आधार है। pandas संख्यात्मक टेबल्स, टाइम-सीरीज़, इमेजरी और प्राकृतिक भाषा प्रोसेसिंग डेटासेट्स को मैनिपुलेट करने के लिए आसान-से-उपयोग डेटा स्ट्रक्चर्स और ऑपरेशंस उपलब्ध करवाती है। मूलतः, pandas उन डेटासेट्स के लिए उपयोगी है जिन्हें आसानी से टेबुलर रूप में दर्शाया जा सकता है।
ऊपर दिए गए किसी भी चरण को करने से पहले, आइए आपके मूवी मेटाडेटा डेटासेट को एक pandas DataFrame में लोड करते हैं:
# Import Pandasimport pandas as pd
# Load Movies Metadata
metadata = pd.read_csv('movies_metadata.csv', low_memory=False)# Print the first three rows
metadata.head(3)संचालित द्वारा
सबसे बुनियादी मीट्रिक में से एक यह हो सकता है कि रेटिंग के आधार पर टॉप 250 फिल्में तय की जाएं।
हालांकि, मीट्रिक के रूप में रेटिंग का उपयोग करने में कुछ खामियां हैं:
पहली बात, यह किसी फिल्म की लोकप्रियता को ध्यान में नहीं रखता। इसलिए, 10 वोटरों से 9 की रेटिंग वाली फिल्म को 10,000 वोटरों से 8.9 की रेटिंग वाली फिल्म से ‘बेहतर’ माना जाएगा।
उदाहरण के लिए, मान लीजिए आप चीनी खाना मंगवाना चाहते हैं, आपके पास कुछ विकल्प हैं—एक रेस्तरां को केवल 5 लोगों ने 5-स्टार दिए हैं, जबकि दूसरे रेस्तरां को 1000 लोगों ने 4.5 रेटिंग दी है। आप किसे पसंद करेंगे? दूसरे को, है न?
बेशक, अपवाद भी हो सकता है कि पहला रेस्तरां कुछ ही दिन पहले खुला है; इसलिए कम लोगों ने वोट किए, जबकि दूसरा रेस्तरां एक साल से चल रहा है।
इसी से जुड़ा एक मुद्दा यह भी है कि यह मीट्रिक कम वोटरों वाली और तिरछी और/या अत्यधिक ऊंची रेटिंग वाली फिल्मों का पक्ष लेगा। जैसे-जैसे वोटरों की संख्या बढ़ती है, किसी फिल्म की रेटिंग नियमित होती जाती है और एक ऐसे मान के करीब पहुंचती है जो फिल्म की गुणवत्ता को दर्शाती है और उपयोगकर्ता को यह बेहतर अंदाजा देती है कि उसे कौन-सी फिल्म चुननी चाहिए। जिन फिल्मों पर अत्यंत कम वोट हैं, उनकी गुणवत्ता का अंदाजा लगाना मुश्किल होता है, ऐसे में निष्कर्ष निकालने के लिए आपको बाहरी स्रोतों पर विचार करना पड़ सकता है।
इन कमियों को देखते हुए, आपको एक वेटेड रेटिंग निकालनी चाहिए जो औसत रेटिंग और प्राप्त वोटों की संख्या दोनों को ध्यान में रखे। ऐसा सिस्टम यह सुनिश्चित करेगा कि 100,000 वोटरों से 9 की रेटिंग वाली फिल्म को उसी रेटिंग लेकिन केवल कुछ सौ वोटरों वाली फिल्म से (काफी) अधिक स्कोर मिले।
चूंकि आप IMDB के Top 250 का क्लोन बनाना चाह रहे हैं, आइए इसके वेटेड रेटिंग फॉर्मूले का ही मीट्रिक/स्कोर के रूप में उपयोग करें। गणितीय रूप से, इसे इस प्रकार दर्शाया जाता है:
m चार्ट में सूचीबद्ध होने के लिए आवश्यक न्यूनतम वोट हैं;
R फिल्म की औसत रेटिंग है;
C पूरे रिपोर्ट में औसत वोट है।
आपके पास पहले से ही हर फिल्म के लिए v (vote_count) और R (vote_average) के मान मौजूद हैं। C को भी इन्हीं डेटा से सीधे निकाला जा सकता है।
m का उपयुक्त मान निर्धारित करना एक हाइपरपैरामीटर है जिसे आप अपनी आवश्यकतानुसार चुन सकते हैं, क्योंकि m का कोई एक सही मान नहीं है। आप इसे एक प्रारंभिक नेगेटिव फ़िल्टर के रूप में मान सकते हैं जो केवल उन फिल्मों को हटा देगा जिनके वोट एक निश्चित थ्रेसहोल्ड m से कम हैं। आपके फ़िल्टर की चयनात्मकता आपके विवेक पर निर्भर है।
इस ट्यूटोरियल में, आप कटऑफ m को 90वें परसेंटाइल के रूप में उपयोग करेंगे। दूसरे शब्दों में, किसी फिल्म को चार्ट में शामिल होने के लिए सूची की कम से कम 90% फिल्मों से अधिक वोट होने चाहिए। (इसके विपरीत, यदि आप 75वां परसेंटाइल चुनते, तो आप वोटों की संख्या के लिहाज से शीर्ष 25% फिल्मों पर विचार करते। जैसे-जैसे परसेंटाइल घटेगा, शामिल फिल्मों की संख्या बढ़ेगी)।
पहले चरण के रूप में, आइए सभी फिल्मों में औसत रेटिंग C की गणना pandas के .mean() फंक्शन का उपयोग करके करें:
# Calculate mean of vote average column
C = metadata['vote_average'].mean()print(C)संचालित द्वारा
ऊपर दिए आउटपुट से आप देख सकते हैं कि IMDB पर किसी फिल्म की औसत रेटिंग 10 में से लगभग 5.6 है।
अब, आइए 90वें परसेंटाइल में किसी फिल्म को प्राप्त वोटों की संख्या m की गणना करें। pandas लाइब्रेरी का .quantile() मेथड इस काम को बेहद आसान बना देता है:
# Calculate the minimum number of votes required to be in the chart, m
m = metadata['vote_count'].quantile(0.90)print(m)संचालित द्वारा
अब जबकि आपके पास m है, आप बस ग्रेटर-दैन-इक्वल टू कंडीशन का उपयोग करके 160 या उससे अधिक वोट काउंट वाली फिल्मों को फ़िल्टर कर सकते हैं:
आप .copy() मेथड का उपयोग कर सकते हैं ताकि नया q_movies DataFrame आपके मूल metadata DataFrame से स्वतंत्र रहे। यानी q_movies DataFrame में किए गए किसी भी बदलाव का असर मूल metadata DataFrame पर नहीं पड़ेगा।
# Filter out all qualified movies into a new DataFrame
q_movies = metadata.copy().loc[metadata['vote_count']>= m]
q_movies.shape
संचालित द्वारा
ऊपर दिए आउटपुट से स्पष्ट है कि लगभग 10% फिल्मों के वोट काउंट 160 से अधिक हैं और वे इस सूची में शामिल होने की योग्यता रखती हैं।
अगला और सबसे महत्वपूर्ण कदम है प्रत्येक योग्य फिल्म के लिए वेटेड रेटिंग की गणना करना। इसके लिए, आप ये करेंगे:
weighted_rating() नाम का एक फंक्शन परिभाषित करें;
चूंकि आपने पहले ही m और C की गणना कर ली है, इन्हें फंक्शन में आर्ग्युमेंट के रूप में पास करें;
q_movies डेटा फ्रेम से vote_count (v) और vote_average (R) कॉलम चुनें;
अंत में, वेटेड एवरेज की गणना करें और परिणाम रिटर्न करें।
आप एक नया फीचर score परिभाषित करेंगे, जिसका मान आप इस फंक्शन को योग्य फिल्मों के DataFrame पर अप्लाई करके निकालेंगे:
# Function that computes the weighted rating of each moviedefweighted_rating(x, m=m, C=C):
v = x['vote_count']
R = x['vote_average']# Calculation based on the IMDB formulareturn(v/(v+m)* R)+(m/(m+v)* C)संचालित द्वारा
# Define a new feature 'score' and calculate its value with `weighted_rating()`
q_movies['score']= q_movies.apply(weighted_rating, axis=1)संचालित द्वारा
अंत में, score फीचर कॉलम के आधार पर DataFrame को अवरोही क्रम में सॉर्ट करते हैं और शीर्ष 20 फिल्मों के शीर्षक, वोट काउंट, वोट एवरेज, और वेटेड रेटिंग (स्कोर) आउटपुट करते हैं।
#Sort movies based on score calculated above
q_movies = q_movies.sort_values('score', ascending=False)#Print the top 15 movies
q_movies[['title','vote_count','vote_average','score']].head(20)संचालित द्वारा
title
vote_count
vote_average
score
314
The Shawshank Redemption
8358.0
8.5
8.445869
834
The Godfather
6024.0
8.5
8.425439
10309
Dilwale Dulhania Le Jayenge
661.0
9.1
8.421453
12481
The Dark Knight
12269.0
8.3
8.265477
2843
Fight Club
9678.0
8.3
8.256385
292
Pulp Fiction
8670.0
8.3
8.251406
522
Schindler's List
4436.0
8.3
8.206639
23673
Whiplash
4376.0
8.3
8.205404
5481
Spirited Away
3968.0
8.3
8.196055
2211
Life Is Beautiful
3643.0
8.3
8.187171
1178
The Godfather: Part II
3418.0
8.3
8.180076
1152
One Flew Over the Cuckoo's Nest
3001.0
8.3
8.164256
351
Forrest Gump
8147.0
8.2
8.150272
1154
The Empire Strikes Back
5998.0
8.2
8.132919
1176
Psycho
2405.0
8.3
8.132715
18465
The Intouchables
5410.0
8.2
8.125837
40251
Your Name.
1030.0
8.5
8.112532
289
Leon: The Professional
4293.0
8.2
8.107234
3030
The Green Mile
4166.0
8.2
8.104511
1170
GoodFellas
3211.0
8.2
8.077459
ऊपर दिए आउटपुट से, आप देख सकते हैं कि सिंपल रिकमेंडर ने बढ़िया काम किया!
क्योंकि इस चार्ट में IMDB Top 250 चार्ट की कई फिल्में समान हैं: उदाहरण के लिए, आपकी शीर्ष दो फिल्में, "Shawshank Redemption" और "The Godfather", IMDB के समान हैं और हम सब जानते हैं कि वे वाकई कमाल की फिल्में हैं। सच कहें तो सभी शीर्ष 20 फिल्में उस सूची में होने की हकदार हैं, है न?
कंटेंट-आधारित रिकमेंडर
प्लॉट डिस्क्रिप्शन आधारित रिकमेंडर
ट्यूटोरियल के इस भाग में, आप ऐसा सिस्टम बनाना सीखेंगे जो किसी विशेष फिल्म से मिलती-जुलती फिल्में सुझाए। इसे हासिल करने के लिए, आप सभी फिल्मों के प्लॉट डिस्क्रिप्शंस के आधार पर पेयरवाइज़ cosine सिमिलैरिटी स्कोर की गणना करेंगे और उसी सिमिलैरिटी स्कोर थ्रेसहोल्ड के आधार पर फिल्में सुझाएंगे।
प्लॉट डिस्क्रिप्शन आपके metadata डेटासेट में overview फीचर के रूप में उपलब्ध है। आइए कुछ फिल्मों के प्लॉट देखते हैं:
#Print plot overviews of the first 5 movies.
metadata['overview'].head()संचालित द्वारा
0 Led by Woody, Andy's toys live happily in his ...1 When siblings Judy and Peter discover an encha...2A family wedding reignites the ancient feud be...3 Cheated on, mistreated and stepped on, the wom...4 Just when George Banks has recovered from his ...Name: overview,dtype: object
संचालित द्वारा
यह समस्या प्राकृतिक भाषा प्रोसेसिंग की है। इसलिए सिमिलैरिटी या डिससिमिलैरिटी की गणना करने से पहले आपको ऊपर के टेक्स्ट डेटा से किसी प्रकार के फीचर निकालने होंगे। सरल शब्दों में, कच्चे रूप में किसी भी दो ओवरव्यूज़ के बीच सिमिलैरिटी की गणना करना संभव नहीं है। इसके लिए, आपको हर ओवरव्यू या डॉक्युमेंट—जैसा कि अब इसे कहा जाएगा—के वर्ड वेक्टर्स की गणना करनी होगी।
नाम से स्पष्ट है कि वर्ड वेक्टर्स किसी डॉक्युमेंट में शब्दों का वेक्टराइज़्ड प्रतिनिधित्व होते हैं। वेक्टर अपने साथ अर्थगत जानकारी लिए होते हैं। उदाहरण के लिए, man और king के वेक्टर प्रतिनिधित्व एक-दूसरे के क़रीब होंगे जबकि man और woman के प्रतिनिधित्व एक-दूसरे से दूर होंगे।
आप प्रत्येक डॉक्युमेंट के लिए Term Frequency-Inverse Document Frequency (TF-IDF) वेक्टर की गणना करेंगे। इससे आपको एक मैट्रिक्स मिलेगा जहां प्रत्येक कॉलम ओवरव्यू वोकैब्युलरी के एक शब्द (वह सभी शब्द जो कम से कम एक डॉक्युमेंट में आते हैं) का प्रतिनिधित्व करेगा, और प्रत्येक कॉलम पहले की तरह एक फिल्म का प्रतिनिधित्व करेगा।
मूल रूप से, TF-IDF स्कोर किसी डॉक्युमेंट में किसी शब्द के आने की आवृत्ति है, जिसे उन डॉक्युमेंट्स की संख्या से डाउन-वेट किया जाता है जिनमें वह आता है। यह उन शब्दों के महत्व को कम करने के लिए किया जाता है जो प्लॉट ओवरव्यूज़ में अक्सर आते हैं और इसलिए अंतिम सिमिलैरिटी स्कोर की गणना में उनकी अहमियत कम होनी चाहिए।
सौभाग्य से, scikit-learn आपको एक बिल्ट-इन TfIdfVectorizer क्लास देता है जो कुछ ही लाइनों में TF-IDF मैट्रिक्स बना देता है।
scikit-learn से Tfidf मॉड्यूल इम्पोर्ट करें;
'the', 'an' आदि जैसे स्टॉप वर्ड्स हटाएं क्योंकि वे टॉपिक के बारे में कोई उपयोगी जानकारी नहीं देते;
not-a-number मानों को खाली स्ट्रिंग से बदलें;
अंत में, डेटा पर TF-IDF मैट्रिक्स कंस्ट्रक्ट करें।
#Import TfIdfVectorizer from scikit-learnfrom sklearn.feature_extraction.text import TfidfVectorizer
#Define a TF-IDF Vectorizer Object. Remove all english stop words such as 'the', 'a'
tfidf = TfidfVectorizer(stop_words='english')#Replace NaN with an empty string
metadata['overview']= metadata['overview'].fillna('')#Construct the required TF-IDF matrix by fitting and transforming the data
tfidf_matrix = tfidf.fit_transform(metadata['overview'])#Output the shape of tfidf_matrix
tfidf_matrix.shape
संचालित द्वारा
#Array mapping from feature integer indices to feature name.
tfidf.get_feature_names()[5000:5010]संचालित द्वारा
['avails','avaks','avalanche','avalanches','avallone','avalon','avant','avanthika','avanti','avaracious']संचालित द्वारा
ऊपर के आउटपुट से आप देखते हैं कि 45,000 फिल्मों वाले आपके डेटासेट में 75,827 अलग-अलग शब्द या वोकैब्युलरी हैं।
अब इस मैट्रिक्स के साथ, आप सिमिलैरिटी स्कोर की गणना कर सकते हैं। इसके लिए आप कई सिमिलैरिटी मैट्रिक्स का उपयोग कर सकते हैं, जैसे मैनहैटन, यूक्लिडियन, पियर्सन और कोसाइन सिमिलैरिटी स्कोर। फिर से, कौन-सा स्कोर सबसे अच्छा है इसका कोई एक सही उत्तर नहीं है। अलग-अलग मैट्रिक्स अलग-अलग परिस्थितियों में अच्छा काम करते हैं, और अलग-अलग मैट्रिक्स के साथ प्रयोग करना और परिणामों का अवलोकन करना अक्सर अच्छा विचार होता है।
आप cosine similarity का उपयोग दो फिल्मों के बीच समानता दर्शाने वाली संख्यात्मक राशि निकालने के लिए करेंगे। आप कोसाइन सिमिलैरिटी स्कोर का उपयोग करेंगे क्योंकि यह परिमाण से स्वतंत्र होता है और इसकी गणना अपेक्षाकृत आसान और तेज होती है (खासकर जब TF-IDF स्कोर के साथ उपयोग किया जाए, जैसा कि आगे समझाया जाएगा)। गणितीय रूप से, इसे इस प्रकार परिभाषित किया जाता है:
चूंकि आपने TF-IDF वेक्टराइज़र का उपयोग किया है, इसलिए प्रत्येक वेक्टर के बीच डॉट प्रोडक्ट निकालना सीधे आपको कोसाइन सिमिलैरिटी स्कोर देगा। इसलिए, आप cosine_similarities() के बजाय sklearn's linear_kernel() का उपयोग करेंगे क्योंकि यह तेज है।
यह 45466x45466 आकार का मैट्रिक्स लौटाएगा, यानी प्रत्येक फिल्म के overview की हर अन्य फिल्म के overview के साथ कोसाइन सिमिलैरिटी। इस प्रकार, प्रत्येक फिल्म 1x45466 कॉलम वेक्टर होगी जहां प्रत्येक कॉलम हर फिल्म के साथ सिमिलैरिटी स्कोर होगा।
# Import linear_kernelfrom sklearn.metrics.pairwise import linear_kernel
# Compute the cosine similarity matrix
cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)संचालित द्वारा
array([0.01504121,1.,0.04681953,...,0.,0.02198641,0.00929411])संचालित द्वारा
आप एक ऐसा फंक्शन परिभाषित करने जा रहे हैं जो मूवी का शीर्षक इनपुट के रूप में ले और 10 सबसे मिलती-जुलती फिल्मों की सूची आउटपुट करे। सबसे पहले, इसके लिए आपको मूवी टाइटल्स और DataFrame इंडेसेज़ का रिवर्स मैपिंग चाहिए। दूसरे शब्दों में, दिए गए टाइटल के आधार पर अपने metadata DataFrame में उस फिल्म का इंडेक्स पहचानने का एक तरीका चाहिए।
#Construct a reverse map of indices and movie titles
indices = pd.Series(metadata.index, index=metadata['title']).drop_duplicates()संचालित द्वारा
title
Toy Story 0
Jumanji 1
Grumpier Old Men 2
Waiting to Exhale 3
Father of the Bride Part II4
Heat 5
Sabrina 6
Tom and Huck 7
Sudden Death 8
GoldenEye 9dtype: int64
संचालित द्वारा
अब आप अपना रिकमेंडेशन फंक्शन परिभाषित करने की स्थिति में हैं। आप निम्नलिखित चरणों का पालन करेंगे:
दिए गए शीर्षक के आधार पर फिल्म का इंडेक्स प्राप्त करें।
उस फिल्म के लिए सभी फिल्मों के साथ कोसाइन सिमिलैरिटी स्कोर की सूची प्राप्त करें। इसे ट्यूपल्स की सूची में बदलें जहां पहला तत्व उसकी पोजीशन और दूसरा सिमिलैरिटी स्कोर हो।
उपरोक्त ट्यूपल्स की सूची को सिमिलैरिटी स्कोर (दूसरे तत्व) के आधार पर सॉर्ट करें।
इस सूची के शीर्ष 10 एलिमेंट लें। पहले एलिमेंट को अनदेखा करें क्योंकि वह स्वयं को संदर्भित करता है (किसी फिल्म के लिए सबसे मिलती-जुलती फिल्म वही फिल्म होती है)।
शीर्ष एलिमेंट्स के इंडेसेज़ के अनुरूप टाइटल्स रिटर्न करें।
# Function that takes in movie title as input and outputs most similar moviesdefget_recommendations(title, cosine_sim=cosine_sim):# Get the index of the movie that matches the title
idx = indices[title]# Get the pairwsie similarity scores of all movies with that movie
sim_scores =list(enumerate(cosine_sim[idx]))# Sort the movies based on the similarity scores
sim_scores =sorted(sim_scores, key=lambda x: x[1], reverse=True)# Get the scores of the 10 most similar movies
sim_scores = sim_scores[1:11]# Get the movie indices
movie_indices =[i[0]for i in sim_scores]# Return the top 10 most similar moviesreturn metadata['title'].iloc[movie_indices]संचालित द्वारा
get_recommendations('The Dark Knight Rises')संचालित द्वारा
12481 The Dark Knight
150 Batman Forever
1328 Batman Returns
15511Batman: Under the Red Hood
585 Batman
21194 Batman Unmasked: The Psychology of the Dark Kn...9230 Batman Beyond: Return of the Joker
18035Batman: Year One
19792Batman: The Dark Knight Returns, Part 13095Batman: Mask of the Phantasm
Name: title,dtype: object
संचालित द्वारा
1178 The Godfather: Part II44030 The Godfather Trilogy:1972-19901914 The Godfather: Part III23126 Blood Ties
11297 Household Saints
34717 Start Liquidation
10821 Election
38030A Mother Should Be Loved
17729 Short Sharp Shock
26293 Beck 28- Familjen
Name: title,dtype: object
संचालित द्वारा
आप देखते हैं कि, भले ही आपके सिस्टम ने मिलते-जुलते प्लॉट डिस्क्रिप्शन खोजने में ठीक-ठाक काम किया है, लेकिन सिफारिशों की गुणवत्ता उतनी अच्छी नहीं है। "The Dark Knight Rises" सभी Batman फिल्में लौटाता है, जबकि अधिक संभावना यह है कि जिसे यह फिल्म पसंद आई, वह अन्य Christopher Nolan की फिल्में देखना ज्यादा पसंद करेगा। यह ऐसी चीज़ है जिसे आपका मौजूदा सिस्टम कैप्चर नहीं कर सकता।
क्रेडिट्स, जेनर और कीवर्ड्स आधारित रिकमेंडर
बेहतर मेटाडेटा का उपयोग करके और अधिक बारीक विवरण कैप्चर करके आपके रिकमेंडर की गुणवत्ता बढ़ाई जा सकती है। ठीक यही आप इस सेक्शन में करने जा रहे हैं। आप निम्नलिखित मेटाडेटा के आधार पर एक रिकमेंडर सिस्टम बनाएंगे: शीर्ष 3 अभिनेता, निर्देशक, संबंधित जेनर, और फिल्म के प्लॉट कीवर्ड्स।
कीवर्ड्स, कास्ट और क्रू का डेटा आपके मौजूदा डेटासेट में उपलब्ध नहीं है, इसलिए पहला कदम इन्हें लोड करके आपके मुख्य DataFrame metadata में मर्ज करना होगा।
# Load keywords and credits
credits = pd.read_csv('credits.csv')
keywords = pd.read_csv('keywords.csv')# Remove rows with bad IDs.
metadata = metadata.drop([19730,29503,35587])# Convert IDs to int. Required for merging
keywords['id']= keywords['id'].astype('int')
credits['id']= credits['id'].astype('int')
metadata['id']= metadata['id'].astype('int')# Merge keywords and credits into your main metadata dataframe
metadata = metadata.merge(credits, on='id')
metadata = metadata.merge(keywords, on='id')संचालित द्वारा
# Print the first two movies of your newly merged metadata
metadata.head(2)संचालित द्वारा
नई फीचर्स—कास्ट, क्रू और कीवर्ड्स—में से आपको शीर्ष तीन अभिनेता, निर्देशक और उस फिल्म से जुड़े कीवर्ड्स निकालने होंगे।
लेकिन सबसे पहले, आपका डेटा “स्ट्रिंगिफाइड” लिस्ट्स के रूप में मौजूद है। आपको इन्हें ऐसे रूप में बदलना होगा जो आपके लिए उपयोगी हो।
# Parse the stringified features into their corresponding python objectsfrom ast import literal_eval
features =['cast','crew','keywords','genres']for feature in features:
metadata[feature]= metadata[feature].apply(literal_eval)संचालित द्वारा
अगला कदम है ऐसी फ़ंक्शंस लिखना जो हर फ़ीचर से आवश्यक जानकारी निकालने में मदद करें।
सबसे पहले, आप NumPy पैकेज इम्पोर्ट करेंगे ताकि उसके NaN कॉन्स्टैंट तक पहुँच मिल सके। फिर, आप इसका उपयोग करके get_director() फ़ंक्शन लिख सकते हैं:
crew फ़ीचर से निर्देशक का नाम प्राप्त करें। यदि निर्देशक लिस्टेड नहीं है, तो NaN लौटाएँ।
defget_director(x):for i in x:if i['job']=='Director':return i['name']return np.nan
संचालित द्वारा
अब, आप एक फ़ंक्शन लिखेंगे जो शीर्ष 3 एलिमेंट्स या पूरी सूची—जो भी अधिक हो—वापस करेगा। यहाँ सूची से तात्पर्य cast, keywords, और genres से है।
defget_list(x):ifisinstance(x,list):
names =[i['name']for i in x]#Check if more than 3 elements exist. If yes, return only first three. If no, return entire list.iflen(names)>3:
names = names[:3]return names
#Return empty list in case of missing/malformed datareturn[]संचालित द्वारा
# Define new director, cast, genres and keywords features that are in a suitable form.
metadata['director']= metadata['crew'].apply(get_director)
features =['cast','keywords','genres']for feature in features:
metadata[feature]= metadata[feature].apply(get_list)संचालित द्वारा
# Print the new features of the first 3 films
metadata[['title','cast','director','keywords','genres']].head(3)संचालित द्वारा
title
cast
director
keywords
genres
0
Toy Story
[Tom Hanks, Tim Allen, Don Rickles]
John Lasseter
[jealousy, toy, boy]
[Animation, Comedy, Family]
1
Jumanji
[Robin Williams, Jonathan Hyde, Kirsten Dunst]
Joe Johnston
[board game, disappearance, based on children'...
[Adventure, Fantasy, Family]
2
Grumpier Old Men
[Walter Matthau, Jack Lemmon, Ann-Margret]
Howard Deutch
[fishing, best friend, duringcreditsstinger]
[Romance, Comedy]
अगला कदम है नामों और कीवर्ड इंस्टैंसेज़ को लोअरकेस में बदलना और उनके बीच की सभी स्पेसेज़ हटाना।
शब्दों के बीच की स्पेस हटाना एक महत्वपूर्ण प्रीप्रोसेसिंग स्टेप है। यह इसलिए किया जाता है ताकि आपका वेक्टराइज़र "Johnny Depp" और "Johnny Galecki" के Johnny को एक जैसा न गिने। इस प्रोसेसिंग के बाद, उपर्युक्त अभिनेताओं को "johnnydepp" और "johnnygalecki" के रूप में दर्शाया जाएगा और आपके वेक्टराइज़र के लिए वे अलग-अलग होंगे।
एक और अच्छा उदाहरण जहाँ मॉडल एक ही वेक्टर रिप्रेज़ेंटेशन दे सकता है, वह है "bread jam" और "traffic jam"। इसलिए, मौजूद किसी भी स्पेस को हटाना बेहतर है।
नीचे दिया गया फ़ंक्शन आपके लिए ठीक यही करेगा:
# Function to convert all strings to lower case and strip names of spacesdefclean_data(x):ifisinstance(x,list):return[str.lower(i.replace(" ",""))for i in x]else:#Check if director exists. If not, return empty stringifisinstance(x,str):returnstr.lower(x.replace(" ",""))else:return''संचालित द्वारा
# Apply clean_data function to your features.
features =['cast','keywords','director','genres']for feature in features:
metadata[feature]= metadata[feature].apply(clean_data)संचालित द्वारा
अब आप अपनी "metadata soup" बनाने की स्थिति में हैं, जो एक स्ट्रिंग है जिसमें वह सारा मेटाडाटा होता है जिसे आप अपने वेक्टराइज़र को देना चाहते हैं (यानी कलाकार, निर्देशक और कीवर्ड)।
create_soup फ़ंक्शन बस सभी आवश्यक कॉलम्स को एक स्पेस से जोड़ देगा। यह अंतिम प्रीप्रोसेसिंग स्टेप है, और इस फ़ंक्शन का आउटपुट शब्द वेक्टर मॉडल में फीड किया जाएगा।
defcreate_soup(x):return' '.join(x['keywords'])+' '+' '.join(x['cast'])+' '+ x['director']+' '+' '.join(x['genres'])संचालित द्वारा
# Create a new soup feature
metadata['soup']= metadata.apply(create_soup, axis=1)संचालित द्वारा
अगले स्टेप वही हैं जो आपने अपने plot description based recommender के साथ किए थे। एक प्रमुख अंतर यह है कि आप TF-IDF की बजाय CountVectorizer() का उपयोग करते हैं। इसका कारण यह है कि यदि कोई अभिनेता/निर्देशक अपेक्षाकृत अधिक फिल्मों में काम कर चुका/चुकी है, तो आप उसकी उपस्थिति का वज़न कम नहीं करना चाहते। इस सन्दर्भ में उनका वज़न कम करना सहज रूप से उचित नहीं है।
CountVectorizer() और TF-IDF के बीच मुख्य अंतर inverse document frequency (IDF) कंपोनेंट है जो बाद वाले में मौजूद होता है और पहले वाले में नहीं।
# Import CountVectorizer and create the count matrixfrom sklearn.feature_extraction.text import CountVectorizer
count = CountVectorizer(stop_words='english')
count_matrix = count.fit_transform(metadata['soup'])संचालित द्वारा
ऊपर के आउटपुट से आप देख सकते हैं कि उस मेटाडाटा में 73,881 शब्दावली हैं जिन्हें आपने फीड किया।
अब, आप एम्बेडिंग्स के बीच दूरी मापने के लिए cosine_similarity का उपयोग करेंगे।
# Compute the Cosine Similarity matrix based on the count_matrixfrom sklearn.metrics.pairwise import cosine_similarity
cosine_sim2 = cosine_similarity(count_matrix, count_matrix)संचालित द्वारा
# Reset index of your main DataFrame and construct reverse mapping as before
metadata = metadata.reset_index()
indices = pd.Series(metadata.index, index=metadata['title'])संचालित द्वारा
अब आप अपनी get_recommendations() फ़ंक्शन को फिर से उपयोग कर सकते हैं और नए cosine_sim2 मैट्रिक्स को दूसरे आर्गुमेंट के रूप में पास कर सकते हैं।
get_recommendations('The Dark Knight Rises', cosine_sim2)संचालित द्वारा
12589 The Dark Knight
10210 Batman Begins
9311 Shiner
9874 Amongst Friends
7772 Mitchell
516 Romeo Is Bleeding
11463 The Prestige
24090 Quicksand
25038 Deadfall
41063 Sara
Name: title,dtype: object
संचालित द्वारा
get_recommendations('The Godfather', cosine_sim2)संचालित द्वारा
1934 The Godfather: Part III1199 The Godfather: Part II15609 The Rain People
18940 Last Exit
34488 Rege
35802 Manuscripts Don't Burn
35803 Manuscripts Don't Burn
8001 The Night of the Following Day
18261 The Son of No One
28683 In the Name of the Law
Name: title,dtype: object
संचालित द्वारा
बहुत बढ़िया! आप देख रहे हैं कि आपके रिकमेंडर ने अधिक मेटाडाटा के कारण अधिक जानकारी कैप्चर की है और बेहतर सिफारिशें दी हैं। बेशक, सिफारिशों में सुधार के लिए इस सिस्टम के साथ प्रयोग करने के अनेकों तरीके हैं।
कुछ सुझाव:
पॉपुलैरिटी फ़िल्टर जोड़ें: यह रिकमेंडर सबसे मिलते-जुलते 30 मूवीज़ लेगा, वेटेड रेटिंग्स की गणना करेगा (ऊपर दिए गए IMDB फ़ॉर्मूला का उपयोग करके), इन रेटिंग्स के आधार पर मूवीज़ को सॉर्ट करेगा और शीर्ष 10 मूवीज़ लौटाएगा।
अन्य क्रू सदस्य: अन्य क्रू सदस्यों के नाम, जैसे पटकथा लेखक और निर्माता, भी शामिल किए जा सकते हैं।
निर्देशक का बढ़ा हुआ वज़न: निर्देशक को अधिक वज़न देने के लिए, उसे सूप में कई बार उल्लेख किया जा सकता है ताकि एक ही निर्देशक वाली फ़िल्मों के समानता स्कोर्स बढ़ें।
Python के साथ Collaborative Filtering
इस ट्यूटोरियल में, आपने अपना खुद का Simple और Content-Based Movie Recommender Systems बनाना सीखा। एक और बेहद लोकप्रिय प्रकार का रिकमेंडर होता है जिसे collaborative filters कहा जाता है।
Collaborative filters को आगे दो प्रकारों में बाँटा जा सकता है:
User-based Filtering: ये सिस्टम उन उत्पादों की सिफारिश करते हैं जो समान उपयोगकर्ताओं को पसंद आए हों। उदाहरण के लिए, मान लीजिए एलिस और बॉब की किताबों में समान रुचि है (यानी वे काफी हद तक वही किताबें पसंद और नापसंद करते हैं)। अब, मान लें कि एक नई किताब आई है और एलिस ने उसे पढ़कर बहुत पसंद किया। तो बहुत संभव है कि बॉब को भी वह पसंद आए, और इसलिए सिस्टम वह किताब बॉब को सिफारिश करेगा।
Item-based Filtering: ये सिस्टम आपके द्वारा बनाए गए कंटेंट रिकमेंडेशन इंजन के काफ़ी समान हैं। ये सिस्टम इस आधार पर समान आइटम्स पहचानते हैं कि लोगों ने अतीत में उन्हें कैसे रेट किया है। उदाहरण के लिए, अगर एलिस, बॉब और ईव ने The Lord of the Rings और The Hobbit को 5 स्टार दिए हैं, तो सिस्टम इन आइटम्स को समान मानता है। इसलिए, अगर कोई The Lord of the Rings खरीदता है, तो सिस्टम उसे The Hobbit भी सिफारिश करता है।
रेटिंग सिस्टम पर आधारित collaborative filtering का एक उदाहरण:
आप इस ट्यूटोरियल में ये सिस्टम नहीं बनाएँगे, लेकिन इन्हें बनाने के लिए आवश्यक अधिकांश विचारों से आप पहले ही परिचित हैं। collaborative filters के साथ शुरुआत करने के लिए एक अच्छा स्थान MovieLens डेटासेट की जाँच करना है, जो यहाँ मिल सकता है।
निष्कर्ष
इस ट्यूटोरियल को पूरा करने पर बधाई!
आपने सफलतापूर्वक हमारा ट्यूटोरियल पूरा किया, जिसमें आपने Python में रिकमेंडर सिस्टम्स के बारे में सब कुछ सीखा। आपने simple और content-based रिकमेंडर्स बनाना सीखा।
आप सब के लिए एक अच्छा अभ्यास यह होगा कि आपने जिन MovieLens डेटासेट के सबसेट का उपयोग करके simple और content-based रिकमेंडर्स बनाए, उसी पर आधारित होकर Python में collaborative filtering लागू करें।
Python के साथ डेटा विश्लेषण की बुनियादी बातें सिर्फ चार घंटे में सीखें। यह ऑनलाइन पाठ्यक्रम Python इंटरफ़ेस का परिचय देगा और लोकप्रिय पैकेजों का अन्वेषण करेगा।
इस ट्यूटोरियल का उद्देश्य आपको रिकमेंडर सिस्टम मॉडल बनाने में विशेषज्ञ बनाना नहीं है। बल्कि, मकसद आपको शुरुआत कराने का है—यह बताकर कि किस प्रकार के रिकमेंडर सिस्टम होते हैं और आप अपना एक सिस्टम कैसे बना सकते हैं।
इस ट्यूटोरियल में, आप सरल और कंटेंट-आधारित रिकमेंडर सिस्टम्स के एक बेसिक मॉडल बनाना सीखेंगे। भले ही ये मॉडल जटिलता, गुणवत्ता, या सटीकता के लिहाज से इंडस्ट्री स्टैंडर्ड के करीब न हों, लेकिन ये आपको बेहतर परिणाम देने वाले अधिक जटिल मॉडलों के निर्माण की दिशा में शुरुआत करने में मदद करेंगे।
आज डेटा साइंस के सबसे लोकप्रिय अनुप्रयोगों में रिकमेंडर सिस्टम शामिल हैं। इनका उपयोग यह “रेटिंग” या “पसंद” का अनुमान लगाने में किया जाता है कि कोई उपयोगकर्ता किसी आइटम को क्या देगा। लगभग हर बड़ी टेक कंपनी किसी न किसी रूप में इन्हें लागू करती है। Amazon ग्राहकों को प्रोडक्ट सुझाने के लिए, YouTube ऑटोप्ले में अगला वीडियो चुनने के लिए, और Facebook पसंद करने के लिए पेज और फॉलो करने के लिए लोगों की सिफारिश करने के लिए इसका उपयोग करता है।
इसके अलावा, Netflix, Amazon Prime, Hulu, और Hotstar जैसी कंपनियों के लिए, उनके बिजनेस मॉडल और उसकी सफलता काफी हद तक उनकी सिफारिशों की प्रभावशीलता पर निर्भर करती है। Netflix ने 2009 में अपने सिस्टम में 10% सुधार करने वाले किसी भी व्यक्ति को एक मिलियन डॉलर का इनाम भी रखा था।
रेस्तरां, फिल्मों और ऑनलाइन डेटिंग जैसे डोमेन के लिए भी लोकप्रिय रिकमेंडर सिस्टम मौजूद हैं। शोध लेख, विशेषज्ञ और सहयोगी खोजने, तथा वित्तीय सेवाओं के लिए भी रिकमेंडर सिस्टम विकसित किए गए हैं। YouTube बड़े पैमाने पर आपकी हिस्ट्री के आधार पर वीडियो सुझाने के लिए रिकमेंडेशन सिस्टम का उपयोग करता है। उदाहरण के लिए, यदि आप बहुत सारे शैक्षिक वीडियो देखते हैं, तो वह उसी प्रकार के वीडियो सुझाएगा।
लेकिन आखिर ये रिकमेंडर सिस्टम होते क्या हैं?
व्यापक रूप से, रिकमेंडर सिस्टम 3 प्रकार के होते हैं:
सिंपल रिकमेंडर
जैसा कि पिछले सेक्शन में बताया गया, सिंपल रिकमेंडर ऐसे बुनियादी सिस्टम होते हैं जो किसी निश्चित मीट्रिक या स्कोर के आधार पर टॉप आइटम सुझाते हैं। इस सेक्शन में, आप IMDB Top 250 Movies का एक सरल क्लोन बनाएंगे, जिसके लिए IMDB से एकत्रित मेटाडेटा का उपयोग किया जाएगा।
इसमें शामिल चरण निम्नलिखित हैं:
फिल्मों को रेट करने के लिए मीट्रिक या स्कोर तय करें।
हर फिल्म के लिए स्कोर की गणना करें।
स्कोर के आधार पर फिल्मों को सॉर्ट करें और शीर्ष परिणाम निकालें।
डेटासेट के बारे में
डेटासेट फाइलों में
Full MovieLens Datasetमें सूचीबद्ध सभी 45,000 फिल्मों का मेटाडेटा शामिल है। डेटासेट में जुलाई 2017 या उससे पहले रिलीज़ हुई फिल्में शामिल हैं। यह डेटासेट कलाकार, क्रू, प्लॉट कीवर्ड, बजट, रेवेन्यू, पोस्टर्स, रिलीज़ डेट, भाषाएं, प्रोडक्शन कंपनियां, देश, TMDB वोट काउंट और वोट एवरेज जैसे फीचर पॉइंट्स को कैप्चर करता है।इन फीचर पॉइंट्स का उपयोग कंटेंट और कोलैबोरेटिव फिल्टरिंग के लिए आपके मशीन लर्निंग मॉडल को ट्रेन करने में किया जा सकता है।
इस डेटासेट में निम्नलिखित फाइलें शामिल हैं:
Full MovieLens Dataset में 26 मिलियन रेटिंग्स और 750,000 टैग एप्लिकेशंस शामिल हैं, जो इस डेटासेट की सभी 45,000 फिल्मों पर 270,000 उपयोगकर्ताओं से आए हैं। इसे आधिकारिक GroupLens वेबसाइट से एक्सेस किया जा सकता है।
नोट: आज के ट्यूटोरियल में उपयोग किया गया सबसेट डेटासेट यहां से डाउनलोड किया जा सकता है।
अपने डेटासेट को लोड करने के लिए, आप
pandasDataFrame लाइब्रेरी का उपयोग करेंगे।pandasलाइब्रेरी मुख्यतः डेटा मैनिपुलेशन और विश्लेषण के लिए उपयोग होती है। यह आपके डेटा को रो-कॉलम फॉर्मेट में प्रस्तुत करती है। Pandas लाइब्रेरी के पीछेNumPyarray होता है जो pandas डेटा ऑब्जेक्ट्स के इम्प्लीमेंटेशन का आधार है।pandasसंख्यात्मक टेबल्स, टाइम-सीरीज़, इमेजरी और प्राकृतिक भाषा प्रोसेसिंग डेटासेट्स को मैनिपुलेट करने के लिए आसान-से-उपयोग डेटा स्ट्रक्चर्स और ऑपरेशंस उपलब्ध करवाती है। मूलतः,pandasउन डेटासेट्स के लिए उपयोगी है जिन्हें आसानी से टेबुलर रूप में दर्शाया जा सकता है।ऊपर दिए गए किसी भी चरण को करने से पहले, आइए आपके मूवी मेटाडेटा डेटासेट को एक
pandasDataFrame में लोड करते हैं:3 पंक्तियाँ × 24 कॉलम
सबसे बुनियादी मीट्रिक में से एक यह हो सकता है कि रेटिंग के आधार पर टॉप 250 फिल्में तय की जाएं।
हालांकि, मीट्रिक के रूप में रेटिंग का उपयोग करने में कुछ खामियां हैं:
पहली बात, यह किसी फिल्म की लोकप्रियता को ध्यान में नहीं रखता। इसलिए, 10 वोटरों से 9 की रेटिंग वाली फिल्म को 10,000 वोटरों से 8.9 की रेटिंग वाली फिल्म से ‘बेहतर’ माना जाएगा।
उदाहरण के लिए, मान लीजिए आप चीनी खाना मंगवाना चाहते हैं, आपके पास कुछ विकल्प हैं—एक रेस्तरां को केवल 5 लोगों ने 5-स्टार दिए हैं, जबकि दूसरे रेस्तरां को 1000 लोगों ने 4.5 रेटिंग दी है। आप किसे पसंद करेंगे? दूसरे को, है न?
बेशक, अपवाद भी हो सकता है कि पहला रेस्तरां कुछ ही दिन पहले खुला है; इसलिए कम लोगों ने वोट किए, जबकि दूसरा रेस्तरां एक साल से चल रहा है।
इन कमियों को देखते हुए, आपको एक वेटेड रेटिंग निकालनी चाहिए जो औसत रेटिंग और प्राप्त वोटों की संख्या दोनों को ध्यान में रखे। ऐसा सिस्टम यह सुनिश्चित करेगा कि 100,000 वोटरों से 9 की रेटिंग वाली फिल्म को उसी रेटिंग लेकिन केवल कुछ सौ वोटरों वाली फिल्म से (काफी) अधिक स्कोर मिले।
चूंकि आप IMDB के Top 250 का क्लोन बनाना चाह रहे हैं, आइए इसके वेटेड रेटिंग फॉर्मूले का ही मीट्रिक/स्कोर के रूप में उपयोग करें। गणितीय रूप से, इसे इस प्रकार दर्शाया जाता है:
\begin{equation} \text Weighted Rating (\bf WR) = \left({{\bf v} \over {\bf v} + {\bf m}} \cdot R\right) + \left({{\bf m} \over {\bf v} + {\bf m}} \cdot C\right) \end{equation}
ऊपर दिए गए समीकरण में,
v किसी फिल्म के लिए वोटों की संख्या है;
m चार्ट में सूचीबद्ध होने के लिए आवश्यक न्यूनतम वोट हैं;
R फिल्म की औसत रेटिंग है;
C पूरे रिपोर्ट में औसत वोट है।
आपके पास पहले से ही हर फिल्म के लिए v
(vote_count)और R(vote_average)के मान मौजूद हैं। C को भी इन्हीं डेटा से सीधे निकाला जा सकता है।mका उपयुक्त मान निर्धारित करना एक हाइपरपैरामीटर है जिसे आप अपनी आवश्यकतानुसार चुन सकते हैं, क्योंकिmका कोई एक सही मान नहीं है। आप इसे एक प्रारंभिक नेगेटिव फ़िल्टर के रूप में मान सकते हैं जो केवल उन फिल्मों को हटा देगा जिनके वोट एक निश्चित थ्रेसहोल्डmसे कम हैं। आपके फ़िल्टर की चयनात्मकता आपके विवेक पर निर्भर है।इस ट्यूटोरियल में, आप कटऑफ
mको 90वें परसेंटाइल के रूप में उपयोग करेंगे। दूसरे शब्दों में, किसी फिल्म को चार्ट में शामिल होने के लिए सूची की कम से कम 90% फिल्मों से अधिक वोट होने चाहिए। (इसके विपरीत, यदि आप 75वां परसेंटाइल चुनते, तो आप वोटों की संख्या के लिहाज से शीर्ष 25% फिल्मों पर विचार करते। जैसे-जैसे परसेंटाइल घटेगा, शामिल फिल्मों की संख्या बढ़ेगी)।पहले चरण के रूप में, आइए सभी फिल्मों में औसत रेटिंग C की गणना pandas के
.mean()फंक्शन का उपयोग करके करें:ऊपर दिए आउटपुट से आप देख सकते हैं कि IMDB पर किसी फिल्म की औसत रेटिंग 10 में से लगभग 5.6 है।
अब, आइए 90वें परसेंटाइल में किसी फिल्म को प्राप्त वोटों की संख्या m की गणना करें।
pandasलाइब्रेरी का.quantile()मेथड इस काम को बेहद आसान बना देता है:अब जबकि आपके पास
mहै, आप बस ग्रेटर-दैन-इक्वल टू कंडीशन का उपयोग करके 160 या उससे अधिक वोट काउंट वाली फिल्मों को फ़िल्टर कर सकते हैं:आप
.copy()मेथड का उपयोग कर सकते हैं ताकि नयाq_moviesDataFrame आपके मूल metadata DataFrame से स्वतंत्र रहे। यानी q_movies DataFrame में किए गए किसी भी बदलाव का असर मूल metadata DataFrame पर नहीं पड़ेगा।ऊपर दिए आउटपुट से स्पष्ट है कि लगभग 10% फिल्मों के वोट काउंट 160 से अधिक हैं और वे इस सूची में शामिल होने की योग्यता रखती हैं।
अगला और सबसे महत्वपूर्ण कदम है प्रत्येक योग्य फिल्म के लिए वेटेड रेटिंग की गणना करना। इसके लिए, आप ये करेंगे:
weighted_rating()नाम का एक फंक्शन परिभाषित करें;mऔरCकी गणना कर ली है, इन्हें फंक्शन में आर्ग्युमेंट के रूप में पास करें;q_moviesडेटा फ्रेम सेvote_count(v) औरvote_average(R) कॉलम चुनें;आप एक नया फीचर
scoreपरिभाषित करेंगे, जिसका मान आप इस फंक्शन को योग्य फिल्मों के DataFrame पर अप्लाई करके निकालेंगे:अंत में,
scoreफीचर कॉलम के आधार पर DataFrame को अवरोही क्रम में सॉर्ट करते हैं और शीर्ष 20 फिल्मों के शीर्षक, वोट काउंट, वोट एवरेज, और वेटेड रेटिंग (स्कोर) आउटपुट करते हैं।ऊपर दिए आउटपुट से, आप देख सकते हैं कि
सिंपल रिकमेंडरने बढ़िया काम किया!क्योंकि इस चार्ट में IMDB Top 250 चार्ट की कई फिल्में समान हैं: उदाहरण के लिए, आपकी शीर्ष दो फिल्में, "Shawshank Redemption" और "The Godfather", IMDB के समान हैं और हम सब जानते हैं कि वे वाकई कमाल की फिल्में हैं। सच कहें तो सभी शीर्ष 20 फिल्में उस सूची में होने की हकदार हैं, है न?
कंटेंट-आधारित रिकमेंडर
प्लॉट डिस्क्रिप्शन आधारित रिकमेंडर
ट्यूटोरियल के इस भाग में, आप ऐसा सिस्टम बनाना सीखेंगे जो किसी विशेष फिल्म से मिलती-जुलती फिल्में सुझाए। इसे हासिल करने के लिए, आप सभी फिल्मों के प्लॉट डिस्क्रिप्शंस के आधार पर पेयरवाइज़
cosineसिमिलैरिटी स्कोर की गणना करेंगे और उसी सिमिलैरिटी स्कोर थ्रेसहोल्ड के आधार पर फिल्में सुझाएंगे।प्लॉट डिस्क्रिप्शन आपके
metadataडेटासेट मेंoverviewफीचर के रूप में उपलब्ध है। आइए कुछ फिल्मों के प्लॉट देखते हैं:यह समस्या प्राकृतिक भाषा प्रोसेसिंग की है। इसलिए सिमिलैरिटी या डिससिमिलैरिटी की गणना करने से पहले आपको ऊपर के टेक्स्ट डेटा से किसी प्रकार के फीचर निकालने होंगे। सरल शब्दों में, कच्चे रूप में किसी भी दो ओवरव्यूज़ के बीच सिमिलैरिटी की गणना करना संभव नहीं है। इसके लिए, आपको हर ओवरव्यू या डॉक्युमेंट—जैसा कि अब इसे कहा जाएगा—के वर्ड वेक्टर्स की गणना करनी होगी।
नाम से स्पष्ट है कि वर्ड वेक्टर्स किसी डॉक्युमेंट में शब्दों का वेक्टराइज़्ड प्रतिनिधित्व होते हैं। वेक्टर अपने साथ अर्थगत जानकारी लिए होते हैं। उदाहरण के लिए, man और king के वेक्टर प्रतिनिधित्व एक-दूसरे के क़रीब होंगे जबकि man और woman के प्रतिनिधित्व एक-दूसरे से दूर होंगे।
आप प्रत्येक डॉक्युमेंट के लिए
Term Frequency-Inverse Document Frequency(TF-IDF) वेक्टर की गणना करेंगे। इससे आपको एक मैट्रिक्स मिलेगा जहां प्रत्येक कॉलम ओवरव्यू वोकैब्युलरी के एक शब्द (वह सभी शब्द जो कम से कम एक डॉक्युमेंट में आते हैं) का प्रतिनिधित्व करेगा, और प्रत्येक कॉलम पहले की तरह एक फिल्म का प्रतिनिधित्व करेगा।मूल रूप से, TF-IDF स्कोर किसी डॉक्युमेंट में किसी शब्द के आने की आवृत्ति है, जिसे उन डॉक्युमेंट्स की संख्या से डाउन-वेट किया जाता है जिनमें वह आता है। यह उन शब्दों के महत्व को कम करने के लिए किया जाता है जो प्लॉट ओवरव्यूज़ में अक्सर आते हैं और इसलिए अंतिम सिमिलैरिटी स्कोर की गणना में उनकी अहमियत कम होनी चाहिए।
सौभाग्य से, scikit-learn आपको एक बिल्ट-इन
TfIdfVectorizerक्लास देता है जो कुछ ही लाइनों में TF-IDF मैट्रिक्स बना देता है।ऊपर के आउटपुट से आप देखते हैं कि 45,000 फिल्मों वाले आपके डेटासेट में 75,827 अलग-अलग शब्द या वोकैब्युलरी हैं।
अब इस मैट्रिक्स के साथ, आप सिमिलैरिटी स्कोर की गणना कर सकते हैं। इसके लिए आप कई सिमिलैरिटी मैट्रिक्स का उपयोग कर सकते हैं, जैसे मैनहैटन, यूक्लिडियन, पियर्सन और कोसाइन सिमिलैरिटी स्कोर। फिर से, कौन-सा स्कोर सबसे अच्छा है इसका कोई एक सही उत्तर नहीं है। अलग-अलग मैट्रिक्स अलग-अलग परिस्थितियों में अच्छा काम करते हैं, और अलग-अलग मैट्रिक्स के साथ प्रयोग करना और परिणामों का अवलोकन करना अक्सर अच्छा विचार होता है।
आप
cosine similarityका उपयोग दो फिल्मों के बीच समानता दर्शाने वाली संख्यात्मक राशि निकालने के लिए करेंगे। आप कोसाइन सिमिलैरिटी स्कोर का उपयोग करेंगे क्योंकि यह परिमाण से स्वतंत्र होता है और इसकी गणना अपेक्षाकृत आसान और तेज होती है (खासकर जब TF-IDF स्कोर के साथ उपयोग किया जाए, जैसा कि आगे समझाया जाएगा)। गणितीय रूप से, इसे इस प्रकार परिभाषित किया जाता है:चूंकि आपने TF-IDF वेक्टराइज़र का उपयोग किया है, इसलिए प्रत्येक वेक्टर के बीच डॉट प्रोडक्ट निकालना सीधे आपको कोसाइन सिमिलैरिटी स्कोर देगा। इसलिए, आप
cosine_similarities()के बजायsklearn's linear_kernel()का उपयोग करेंगे क्योंकि यह तेज है।यह 45466x45466 आकार का मैट्रिक्स लौटाएगा, यानी प्रत्येक फिल्म के
overviewकी हर अन्य फिल्म केoverviewके साथ कोसाइन सिमिलैरिटी। इस प्रकार, प्रत्येक फिल्म 1x45466 कॉलम वेक्टर होगी जहां प्रत्येक कॉलम हर फिल्म के साथ सिमिलैरिटी स्कोर होगा।आप एक ऐसा फंक्शन परिभाषित करने जा रहे हैं जो मूवी का शीर्षक इनपुट के रूप में ले और 10 सबसे मिलती-जुलती फिल्मों की सूची आउटपुट करे। सबसे पहले, इसके लिए आपको मूवी टाइटल्स और DataFrame इंडेसेज़ का रिवर्स मैपिंग चाहिए। दूसरे शब्दों में, दिए गए टाइटल के आधार पर अपने
metadataDataFrame में उस फिल्म का इंडेक्स पहचानने का एक तरीका चाहिए।अब आप अपना रिकमेंडेशन फंक्शन परिभाषित करने की स्थिति में हैं। आप निम्नलिखित चरणों का पालन करेंगे:
दिए गए शीर्षक के आधार पर फिल्म का इंडेक्स प्राप्त करें।
उस फिल्म के लिए सभी फिल्मों के साथ कोसाइन सिमिलैरिटी स्कोर की सूची प्राप्त करें। इसे ट्यूपल्स की सूची में बदलें जहां पहला तत्व उसकी पोजीशन और दूसरा सिमिलैरिटी स्कोर हो।
उपरोक्त ट्यूपल्स की सूची को सिमिलैरिटी स्कोर (दूसरे तत्व) के आधार पर सॉर्ट करें।
इस सूची के शीर्ष 10 एलिमेंट लें। पहले एलिमेंट को अनदेखा करें क्योंकि वह स्वयं को संदर्भित करता है (किसी फिल्म के लिए सबसे मिलती-जुलती फिल्म वही फिल्म होती है)।
शीर्ष एलिमेंट्स के इंडेसेज़ के अनुरूप टाइटल्स रिटर्न करें।
आप देखते हैं कि, भले ही आपके सिस्टम ने मिलते-जुलते प्लॉट डिस्क्रिप्शन खोजने में ठीक-ठाक काम किया है, लेकिन सिफारिशों की गुणवत्ता उतनी अच्छी नहीं है। "The Dark Knight Rises" सभी Batman फिल्में लौटाता है, जबकि अधिक संभावना यह है कि जिसे यह फिल्म पसंद आई, वह अन्य Christopher Nolan की फिल्में देखना ज्यादा पसंद करेगा। यह ऐसी चीज़ है जिसे आपका मौजूदा सिस्टम कैप्चर नहीं कर सकता।
क्रेडिट्स, जेनर और कीवर्ड्स आधारित रिकमेंडर
बेहतर मेटाडेटा का उपयोग करके और अधिक बारीक विवरण कैप्चर करके आपके रिकमेंडर की गुणवत्ता बढ़ाई जा सकती है। ठीक यही आप इस सेक्शन में करने जा रहे हैं। आप निम्नलिखित मेटाडेटा के आधार पर एक रिकमेंडर सिस्टम बनाएंगे: शीर्ष 3 अभिनेता, निर्देशक, संबंधित जेनर, और फिल्म के प्लॉट कीवर्ड्स।
कीवर्ड्स, कास्ट और क्रू का डेटा आपके मौजूदा डेटासेट में उपलब्ध नहीं है, इसलिए पहला कदम इन्हें लोड करके आपके मुख्य DataFrame
metadataमें मर्ज करना होगा।2 पंक्तियाँ × 27 कॉलम
नई फीचर्स—कास्ट, क्रू और कीवर्ड्स—में से आपको शीर्ष तीन अभिनेता, निर्देशक और उस फिल्म से जुड़े कीवर्ड्स निकालने होंगे।
लेकिन सबसे पहले, आपका डेटा “स्ट्रिंगिफाइड” लिस्ट्स के रूप में मौजूद है। आपको इन्हें ऐसे रूप में बदलना होगा जो आपके लिए उपयोगी हो।
अगला कदम है ऐसी फ़ंक्शंस लिखना जो हर फ़ीचर से आवश्यक जानकारी निकालने में मदद करें।
सबसे पहले, आप NumPy पैकेज इम्पोर्ट करेंगे ताकि उसके
NaNकॉन्स्टैंट तक पहुँच मिल सके। फिर, आप इसका उपयोग करकेget_director()फ़ंक्शन लिख सकते हैं:crew फ़ीचर से निर्देशक का नाम प्राप्त करें। यदि निर्देशक लिस्टेड नहीं है, तो
NaNलौटाएँ।अब, आप एक फ़ंक्शन लिखेंगे जो शीर्ष 3 एलिमेंट्स या पूरी सूची—जो भी अधिक हो—वापस करेगा। यहाँ सूची से तात्पर्य
cast,keywords, औरgenresसे है।अगला कदम है नामों और कीवर्ड इंस्टैंसेज़ को लोअरकेस में बदलना और उनके बीच की सभी स्पेसेज़ हटाना।
शब्दों के बीच की स्पेस हटाना एक महत्वपूर्ण प्रीप्रोसेसिंग स्टेप है। यह इसलिए किया जाता है ताकि आपका वेक्टराइज़र "Johnny Depp" और "Johnny Galecki" के Johnny को एक जैसा न गिने। इस प्रोसेसिंग के बाद, उपर्युक्त अभिनेताओं को "johnnydepp" और "johnnygalecki" के रूप में दर्शाया जाएगा और आपके वेक्टराइज़र के लिए वे अलग-अलग होंगे।
एक और अच्छा उदाहरण जहाँ मॉडल एक ही वेक्टर रिप्रेज़ेंटेशन दे सकता है, वह है "bread jam" और "traffic jam"। इसलिए, मौजूद किसी भी स्पेस को हटाना बेहतर है।
नीचे दिया गया फ़ंक्शन आपके लिए ठीक यही करेगा:
अब आप अपनी "metadata soup" बनाने की स्थिति में हैं, जो एक स्ट्रिंग है जिसमें वह सारा मेटाडाटा होता है जिसे आप अपने वेक्टराइज़र को देना चाहते हैं (यानी कलाकार, निर्देशक और कीवर्ड)।
create_soupफ़ंक्शन बस सभी आवश्यक कॉलम्स को एक स्पेस से जोड़ देगा। यह अंतिम प्रीप्रोसेसिंग स्टेप है, और इस फ़ंक्शन का आउटपुट शब्द वेक्टर मॉडल में फीड किया जाएगा।अगले स्टेप वही हैं जो आपने अपने
plot description based recommenderके साथ किए थे। एक प्रमुख अंतर यह है कि आपTF-IDFकी बजायCountVectorizer()का उपयोग करते हैं। इसका कारण यह है कि यदि कोई अभिनेता/निर्देशक अपेक्षाकृत अधिक फिल्मों में काम कर चुका/चुकी है, तो आप उसकी उपस्थिति का वज़न कम नहीं करना चाहते। इस सन्दर्भ में उनका वज़न कम करना सहज रूप से उचित नहीं है।CountVectorizer()औरTF-IDFके बीच मुख्य अंतर inverse document frequency (IDF) कंपोनेंट है जो बाद वाले में मौजूद होता है और पहले वाले में नहीं।ऊपर के आउटपुट से आप देख सकते हैं कि उस मेटाडाटा में 73,881 शब्दावली हैं जिन्हें आपने फीड किया।
अब, आप एम्बेडिंग्स के बीच दूरी मापने के लिए
cosine_similarityका उपयोग करेंगे।अब आप अपनी
get_recommendations()फ़ंक्शन को फिर से उपयोग कर सकते हैं और नएcosine_sim2मैट्रिक्स को दूसरे आर्गुमेंट के रूप में पास कर सकते हैं।बहुत बढ़िया! आप देख रहे हैं कि आपके रिकमेंडर ने अधिक मेटाडाटा के कारण अधिक जानकारी कैप्चर की है और बेहतर सिफारिशें दी हैं। बेशक, सिफारिशों में सुधार के लिए इस सिस्टम के साथ प्रयोग करने के अनेकों तरीके हैं।
कुछ सुझाव:
पॉपुलैरिटी फ़िल्टर जोड़ें: यह रिकमेंडर सबसे मिलते-जुलते 30 मूवीज़ लेगा, वेटेड रेटिंग्स की गणना करेगा (ऊपर दिए गए IMDB फ़ॉर्मूला का उपयोग करके), इन रेटिंग्स के आधार पर मूवीज़ को सॉर्ट करेगा और शीर्ष 10 मूवीज़ लौटाएगा।
अन्य क्रू सदस्य: अन्य क्रू सदस्यों के नाम, जैसे पटकथा लेखक और निर्माता, भी शामिल किए जा सकते हैं।
निर्देशक का बढ़ा हुआ वज़न: निर्देशक को अधिक वज़न देने के लिए, उसे सूप में कई बार उल्लेख किया जा सकता है ताकि एक ही निर्देशक वाली फ़िल्मों के समानता स्कोर्स बढ़ें।
Python के साथ Collaborative Filtering
इस ट्यूटोरियल में, आपने अपना खुद का Simple और Content-Based Movie Recommender Systems बनाना सीखा। एक और बेहद लोकप्रिय प्रकार का रिकमेंडर होता है जिसे collaborative filters कहा जाता है।
Collaborative filters को आगे दो प्रकारों में बाँटा जा सकता है:
User-based Filtering: ये सिस्टम उन उत्पादों की सिफारिश करते हैं जो समान उपयोगकर्ताओं को पसंद आए हों। उदाहरण के लिए, मान लीजिए एलिस और बॉब की किताबों में समान रुचि है (यानी वे काफी हद तक वही किताबें पसंद और नापसंद करते हैं)। अब, मान लें कि एक नई किताब आई है और एलिस ने उसे पढ़कर बहुत पसंद किया। तो बहुत संभव है कि बॉब को भी वह पसंद आए, और इसलिए सिस्टम वह किताब बॉब को सिफारिश करेगा।Item-based Filtering: ये सिस्टम आपके द्वारा बनाए गए कंटेंट रिकमेंडेशन इंजन के काफ़ी समान हैं। ये सिस्टम इस आधार पर समान आइटम्स पहचानते हैं कि लोगों ने अतीत में उन्हें कैसे रेट किया है। उदाहरण के लिए, अगर एलिस, बॉब और ईव ने The Lord of the Rings और The Hobbit को 5 स्टार दिए हैं, तो सिस्टम इन आइटम्स को समान मानता है। इसलिए, अगर कोई The Lord of the Rings खरीदता है, तो सिस्टम उसे The Hobbit भी सिफारिश करता है।रेटिंग सिस्टम पर आधारित collaborative filtering का एक उदाहरण:
आप इस ट्यूटोरियल में ये सिस्टम नहीं बनाएँगे, लेकिन इन्हें बनाने के लिए आवश्यक अधिकांश विचारों से आप पहले ही परिचित हैं। collaborative filters के साथ शुरुआत करने के लिए एक अच्छा स्थान MovieLens डेटासेट की जाँच करना है, जो यहाँ मिल सकता है।
निष्कर्ष
इस ट्यूटोरियल को पूरा करने पर बधाई!
आपने सफलतापूर्वक हमारा ट्यूटोरियल पूरा किया, जिसमें आपने Python में रिकमेंडर सिस्टम्स के बारे में सब कुछ सीखा। आपने simple और content-based रिकमेंडर्स बनाना सीखा।
आप सब के लिए एक अच्छा अभ्यास यह होगा कि आपने जिन MovieLens डेटासेट के सबसेट का उपयोग करके simple और content-based रिकमेंडर्स बनाए, उसी पर आधारित होकर Python में collaborative filtering लागू करें।
यदि आप अभी-अभी Python शुरू कर रहे हैं और अधिक सीखना चाहते हैं, तो DataCamp का Introduction to Data Science in Python कोर्स लें।