Das Ziel dieses Tutorials ist es nicht, dich zu einem Experten für die Erstellung von Empfehlungssystemen zu machen. Stattdessen geht es darum, dir einen Überblick über die verschiedenen Arten von Empfehlungssystemen zu verschaffen und dir zu zeigen, wie du selbst eines aufbauen kannst.
In diesem Lernprogramm lernst du, wie du ein grundlegendes Modell für einfache und inhaltsbasierte Empfehlungssysteme erstellst. Auch wenn diese Modelle in Bezug auf Komplexität, Qualität und Genauigkeit nicht an den Industriestandard heranreichen, helfen sie dir, komplexere Modelle zu erstellen, die noch bessere Ergebnisse liefern.
Empfehlungssysteme gehören heute zu den beliebtesten Anwendungen der Datenwissenschaft. Sie werden verwendet, um die "Bewertung" oder "Präferenz" vorherzusagen, die ein Nutzer für einen Artikel abgeben würde. Fast jedes große Technologieunternehmen hat sie in irgendeiner Form eingesetzt. Amazon nutzt sie, um Kunden Produkte vorzuschlagen, YouTube nutzt sie, um zu entscheiden, welches Video als Nächstes abgespielt werden soll, und Facebook nutzt sie, um Seiten zu empfehlen, die man mögen und denen man folgen sollte.
Für einige Unternehmen wie Netflix, Amazon Prime, Hulu und Hotstar dreht sich das Geschäftsmodell und ihr Erfolg um die Wirksamkeit ihrer Empfehlungen. Netflix hat 2009 sogar eine Million Dollar für denjenigen ausgelobt, der sein System um 10% verbessern kann.
Es gibt auch beliebte Empfehlungssysteme für Bereiche wie Restaurants, Filme und Online-Dating. Empfehlungssysteme wurden auch entwickelt, um Forschungsartikel und Experten, Mitarbeiter und Finanzdienstleistungen zu finden. YouTube nutzt das Empfehlungssystem in großem Umfang, um dir Videos auf der Grundlage deines Verlaufs vorzuschlagen. Wenn du dir zum Beispiel viele Lehrvideos ansiehst, schlägt es dir diese Art von Videos vor.
Aber was sind diese Empfehlungssysteme?
Im Großen und Ganzen lassen sich Empfehlungssysteme in 3 Typen einteilen:
Einfache Empfehlungsprogramme: bieten jedem Nutzer allgemeine Empfehlungen, die auf der Popularität und/oder dem Genre des Films basieren. Die Grundidee hinter diesem System ist, dass Filme, die beliebter sind und von der Kritik gelobt werden, eine höhere Wahrscheinlichkeit haben, vom Durchschnittspublikum gemocht zu werden. Ein Beispiel wäre die IMDB Top 250.
Inhaltsbasierte Empfehlungssysteme: schlagen ähnliche Artikel auf der Grundlage eines bestimmten Artikels vor. Dieses System verwendet Metadaten wie Genre, Regisseur, Beschreibung, Schauspieler usw. für Filme, um diese Empfehlungen auszusprechen. Der Grundgedanke hinter diesen Empfehlungssystemen ist, dass eine Person, die ein bestimmtes Produkt mag, auch ein ähnliches Produkt mögen wird. Und um das zu empfehlen, nutzt es die Metadaten der vergangenen Artikel des Nutzers. Ein gutes Beispiel dafür ist YouTube, das dir anhand deines Verlaufs neue Videos vorschlägt, die du dir möglicherweise ansehen könntest.
Collaborative Filtering Engines: Diese Systeme sind weit verbreitet und versuchen, die Bewertung oder Präferenz, die ein Nutzer einem Artikel geben würde, auf der Grundlage früherer Bewertungen und Präferenzen anderer Nutzer vorherzusagen. Kollaborative Filter benötigen keine Objekt-Metadaten wie ihre inhaltsbasierten Gegenstücke.
Einfache Empfehlungsgeber
Wie im vorigen Abschnitt beschrieben, sind einfache Empfehlungssysteme grundlegende Systeme, die die besten Artikel auf der Grundlage einer bestimmten Metrik oder Punktzahl empfehlen. In diesem Abschnitt erstellst du einen vereinfachten Klon der IMDB Top 250 Movies mit Metadaten aus der IMDB.
Im Folgenden werden die einzelnen Schritte beschrieben:
Entscheide dich für eine Metrik oder Punktzahl, nach der du Filme bewerten willst.
Berechne die Punktzahl für jeden Film.
Sortiere die Filme nach der Punktzahl und gib die besten Ergebnisse aus.
Über den Datensatz
Die Datensatzdateien enthalten Metadaten für alle 45.000 Filme, die in der Full MovieLens Dataset aufgeführt sind. Der Datensatz besteht aus Filmen, die im Juli 2017 oder früher veröffentlicht wurden. Dieser Datensatz enthält Merkmale wie Besetzung, Crew, Stichwörter zur Handlung, Budget, Einnahmen, Plakate, Veröffentlichungstermine, Sprachen, Produktionsfirmen, Länder, TMDB-Stimmenzahlen und Stimmendurchschnitte.
Mit diesen Merkmalen kannst du deine Machine-Learning-Modelle für Content und Collaborative Filtering trainieren.
Dieser Datensatz besteht aus den folgenden Dateien:
movies_metadata.csv: Diese Datei enthält Informationen zu ~45.000 Filmen aus dem Full MovieLens-Datensatz. Zu den Funktionen gehören Plakate, Hintergründe, Budget, Genre, Einnahmen, Erscheinungsdaten, Sprachen, Produktionsländer und Unternehmen.
keywords.csv: Enthält die Schlüsselwörter für die Filmhandlung unserer MovieLens-Filme. Verfügbar in Form eines stringifizierten JSON-Objekts.
credits.csv: Hier findest du Informationen zu den Darstellern und der Crew für alle Filme. Verfügbar in Form eines stringifizierten JSON-Objekts.
links.csv: Diese Datei enthält die TMDB- und IMDB-IDs aller Filme, die im vollständigen MovieLens-Datensatz enthalten sind.
links_small.csv: Enthält die TMDB- und IMDB-IDs einer kleinen Teilmenge von 9.000 Filmen des vollständigen Datensatzes.
ratings_small.csv: Die Teilmenge von 100.000 Bewertungen von 700 Nutzern zu 9.000 Filmen.
Der vollständige MovieLens-Datensatz umfasst 26 Millionen Bewertungen und 750.000 Tag-Anwendungen von 270.000 Nutzern für alle 45.000 Filme in diesem Datensatz. Du kannst sie auf der offiziellen GroupLens-Website aufrufen.
Hinweis: Der Datensatz, der im heutigen Tutorial verwendet wird, kann hier heruntergeladen werden.
Um deinen Datensatz zu laden, verwendest du die pandas DataFrame-Bibliothek. pandas wird hauptsächlich für die Datenbearbeitung und -analyse verwendet. Sie stellt deine Daten in einem Zeilen-/Spaltenformat dar. Die Pandas-Bibliothek stützt sich auf das Array NumPy für die Implementierung von Pandas-Datenobjekten. pandas bietet Standard-Datenstrukturen und -Operationen für die Bearbeitung von numerischen Tabellen, Zeitreihen, Bildern und Datensätzen zur Verarbeitung natürlicher Sprache. Grundsätzlich ist pandas für Datensätze geeignet, die sich leicht in Tabellenform darstellen lassen.
Bevor du die oben genannten Schritte durchführst, laden wir deinen Film-Metadatensatz in einen 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)Bereitgestellt von
Eine Familienhochzeit entfacht die alte Fehde zwischen...
...
1995-12-22
0.0
101.0
[{'iso_639_1': 'en', 'name': 'Englisch'}]
Freigegeben
Ich schreie immer noch. Still Fighting. Immer noch bereit für...
Mürrische alte Männer
Falsch
6.5
92.0
3 Zeilen × 24 Spalten
Eine der grundlegendsten Metriken, die du dir vorstellen kannst, ist die Rangliste, um zu entscheiden, welche Filme in den Top 250 sind, basierend auf ihren jeweiligen Bewertungen.
Die Verwendung einer Bewertung als Maßstab hat jedoch ein paar Vorbehalte:
Zum einen berücksichtigt sie nicht die Popularität eines Films. Daher wird ein Film mit einer Bewertung von 9 von 10 Wählern als "besser" angesehen als ein Film mit einer Bewertung von 8,9 von 10.000 Wählern.
Stell dir zum Beispiel vor, du willst chinesisch essen gehen und hast mehrere Möglichkeiten. Das eine Restaurant hat nur 5 Sterne, das andere Restaurant hat 4,5 Sterne von 1000 Leuten. Welches Restaurant würdest du bevorzugen? Die zweite, richtig?
Natürlich kann es eine Ausnahme sein, dass das erste Restaurant erst vor ein paar Tagen eröffnet wurde und daher weniger Leute dafür gestimmt haben, während das zweite Restaurant bereits seit einem Jahr in Betrieb ist.
Außerdem begünstigt diese Kennzahl Filme mit einer geringeren Anzahl von Wählern, die eine verzerrte und/oder extrem hohe Bewertung haben. Mit zunehmender Anzahl der Wählerinnen und Wähler reguliert sich die Bewertung eines Films und nähert sich einem Wert an, der die Qualität des Films widerspiegelt und dem Nutzer/der Nutzerin eine viel bessere Vorstellung davon gibt, welchen Film er/sie wählen sollte. Es ist zwar schwierig, die Qualität eines Films mit extrem wenigen Wählern zu beurteilen, aber du musst vielleicht externe Quellen heranziehen, um zu einem Schluss zu kommen.
Unter Berücksichtigung dieser Unzulänglichkeiten musst du eine gewichtete Bewertung erstellen, die die durchschnittliche Bewertung und die Anzahl der Stimmen, die sie angesammelt hat, berücksichtigt. Ein solches System stellt sicher, dass ein Film mit einer Bewertung von 9 von 100.000 Wählern eine (weit) höhere Punktzahl erhält als ein Film mit der gleichen Bewertung, aber nur ein paar hundert Wählern.
Da du versuchst, einen Klon der Top 250 von IMDB zu erstellen, lass uns die gewichtete Bewertungsformel als Maßstab/Score verwenden. Mathematisch lässt sich das wie folgt darstellen:
m ist die Mindestanzahl an Stimmen, die erforderlich ist, um in der Tabelle aufgeführt zu werden;
R ist die durchschnittliche Bewertung des Films;
C ist der Mittelwert der Stimmen für den gesamten Bericht.
Du hast bereits die Werte für v (vote_count) und R (vote_average) für jeden Film im Datensatz. Es ist auch möglich, C direkt aus diesen Daten zu berechnen.
Die Bestimmung eines geeigneten Wertes für m ist ein Hyperparameter, den du entsprechend wählen kannst, da es keinen richtigen Wert für m gibt. Du kannst ihn als vorläufigen Negativfilter betrachten, der einfach die Filme entfernt, deren Stimmenzahl unter einem bestimmten Schwellenwert m liegt. Die Selektivität deines Filters liegt in deinem Ermessen.
In diesem Lernprogramm verwendest du den Cutoff m als 90ste Perzentile. Mit anderen Worten: Damit ein Film in die Charts kommt, muss er mehr Stimmen haben als mindestens 90% der Filme auf der Liste. (Hättest du hingegen das 75. Perzentil gewählt, hättest du die besten 25 % der Filme in Bezug auf die Anzahl der erhaltenen Stimmen berücksichtigt. Je niedriger der Prozentsatz ist, desto mehr Filme werden berücksichtigt).
Als ersten Schritt berechnen wir den Wert C, den Mittelwert der Bewertung aller Filme, mit der Funktion .mean():
# Calculate mean of vote average column
C = metadata['vote_average'].mean()print(C)Bereitgestellt von
Aus der obigen Ausgabe kannst du ersehen, dass die durchschnittliche Bewertung eines Films auf IMDB etwa 5,6 auf einer Skala von 10 beträgt.
Als Nächstes berechnen wir die Anzahl der Stimmen, m, die ein Film im 90sten Perzentil erhält. Die pandas Bibliothek macht diese Aufgabe mit der .quantile() Methode von Pandas extrem trivial:
# Calculate the minimum number of votes required to be in the chart, m
m = metadata['vote_count'].quantile(0.90)print(m)Bereitgestellt von
Da du jetzt die m hast, kannst du einfach eine Bedingung verwenden, die größer als gleich ist, um Filme herauszufiltern, deren Stimmenzahl größer als 160 ist:
Du kannst die Methode .copy() verwenden, um sicherzustellen, dass der neu erstellte q_movies DataFrame unabhängig von deinem ursprünglichen Metadaten-DataFrame ist. Mit anderen Worten: Alle Änderungen am q_movies DataFrame haben keine Auswirkungen auf den ursprünglichen Metadaten-DataFrame.
# Filter out all qualified movies into a new DataFrame
q_movies = metadata.copy().loc[metadata['vote_count']>= m]
q_movies.shape
Bereitgestellt von
Aus der obigen Ausgabe geht hervor, dass etwa 10 % der Filme mehr als 160 Stimmen haben und sich für diese Liste qualifizieren.
Der nächste und wichtigste Schritt ist die Berechnung der gewichteten Bewertung für jeden qualifizierten Film. Um dies zu tun, musst du:
Definiere eine Funktion, weighted_rating();
Da du m und C bereits berechnet hast, gibst du sie einfach als Argument an die Funktion weiter;
Dann wählst du die Spalten vote_count(v) und vote_average(R) aus dem Datenrahmen q_movies aus;
Schließlich berechnest du den gewichteten Durchschnitt und gibst das Ergebnis zurück.
Du definierst ein neues Merkmal score, dessen Wert du berechnest, indem du diese Funktion auf deinen DataFrame mit qualifizierten Filmen anwendest:
# 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)Bereitgestellt von
# Define a new feature 'score' and calculate its value with `weighted_rating()`
q_movies['score']= q_movies.apply(weighted_rating, axis=1)Bereitgestellt von
Zum Schluss sortieren wir den DataFrame in absteigender Reihenfolge nach der Spalte score und geben den Titel, die Anzahl der Stimmen, den Durchschnitt der Stimmen und die gewichtete Bewertung (Score) der 20 besten Filme aus.
#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)Bereitgestellt von
title
vote_count
vote_average
punkten
314
Die Verurteilten - Die Erlösung
8358.0
8.5
8.445869
834
Der Pate
6024.0
8.5
8.425439
10309
Dilwale Dulhania Le Jayenge
661.0
9.1
8.421453
12481
Der dunkle Ritter
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
Schindlers Liste
4436.0
8.3
8.206639
23673
Schleudertrauma
4376.0
8.3
8.205404
5481
Weggeistert
3968.0
8.3
8.196055
2211
Das Leben ist schön
3643.0
8.3
8.187171
1178
Der Pate: Teil II
3418.0
8.3
8.180076
1152
Einer flog über das Kuckucksnest
3001.0
8.3
8.164256
351
Forrest Gump
8147.0
8.2
8.150272
1154
Das Imperium schlägt zurück
5998.0
8.2
8.132919
1176
Psycho
2405.0
8.3
8.132715
18465
Die Berührbaren
5410.0
8.2
8.125837
40251
Dein Name.
1030.0
8.5
8.112532
289
Leon: Der Profi
4293.0
8.2
8.107234
3030
Die grüne Meile
4166.0
8.2
8.104511
1170
GoodFellas
3211.0
8.2
8.077459
Anhand der obigen Ausgabe kannst du sehen, dass die simple recommender gute Arbeit geleistet hat!
Da die Tabelle viele Filme mit der IMDB-Top-250-Liste gemeinsam hat: Deine beiden Top-Filme, "Die Verurteilten" und "Der Pate", sind zum Beispiel die gleichen wie bei IMDB, und wir alle wissen, dass sie in der Tat tolle Filme sind, verdienen es eigentlich alle Top-20-Filme, in dieser Liste zu stehen, oder?
Inhaltsbasierter Empfehlungsgeber
Plotbeschreibung basierte Empfehlung
In diesem Teil des Tutorials lernst du, wie du ein System aufbaust, das Filme empfiehlt, die einem bestimmten Film ähnlich sind. Um dies zu erreichen, berechnest du paarweise cosine Ähnlichkeitswerte für alle Filme auf der Grundlage ihrer Handlungsbeschreibungen und empfiehlst Filme auf der Grundlage dieses Ähnlichkeitsschwellenwerts.
Die Grundstücksbeschreibung steht dir als Merkmal overview in deinem metadata Datensatz zur Verfügung. Schauen wir uns die Handlungen einiger Filme an:
#Print plot overviews of the first 5 movies.
metadata['overview'].head()Bereitgestellt von
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
Bereitgestellt von
Bei dem vorliegenden Problem handelt es sich um ein Problem der natürlichen Sprachverarbeitung. Daher musst du aus den oben genannten Textdaten eine Art von Merkmalen extrahieren, bevor du die Ähnlichkeit und/oder Unähnlichkeit zwischen ihnen berechnen kannst. Einfach ausgedrückt: Es ist nicht möglich, die Ähnlichkeit zwischen zwei Übersichten in ihrer Rohform zu berechnen. Dazu musst du die Wortvektoren jeder Übersicht oder jedes Dokuments, wie es von nun an heißen wird, berechnen.
Wie der Name schon sagt, sind Wortvektoren vektorisierte Darstellungen von Wörtern in einem Dokument. Die Vektoren tragen eine semantische Bedeutung mit sich. Zum Beispiel haben Mann und König Vektordarstellungen, die nahe beieinander liegen, während Mann und Frau weit voneinander entfernt dargestellt werden.
Du berechnest Term Frequency-Inverse Document Frequency (TF-IDF) Vektoren für jedes Dokument. So erhältst du eine Matrix, in der jede Spalte ein Wort aus dem Übersichtsvokabular darstellt (alle Wörter, die in mindestens einem Dokument vorkommen), und jede Spalte steht für einen Film, wie zuvor.
Im Wesentlichen ist der TF-IDF-Score die Häufigkeit, mit der ein Wort in einem Dokument vorkommt, gewichtet nach der Anzahl der Dokumente, in denen es vorkommt. Dies geschieht, um die Bedeutung von Wörtern, die häufig in Handlungsübersichten vorkommen, und damit auch ihre Bedeutung für die Berechnung der endgültigen Ähnlichkeitsbewertung zu verringern.
Zum Glück gibt es in scikit-learn eine eingebaute TfIdfVectorizer Klasse, die die TF-IDF-Matrix in ein paar Zeilen erstellt.
Importiere das Tfidf-Modul mit scikit-learn;
Entferne Stoppwörter wie "der", "eine" usw., da sie keine nützlichen Informationen über das Thema liefern;
Ersetze Nicht-eine-Zahl-Werte durch eine leere Zeichenkette;
Erstelle schließlich die TF-IDF-Matrix für die Daten.
#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
Bereitgestellt von
#Array mapping from feature integer indices to feature name.
tfidf.get_feature_names()[5000:5010]Bereitgestellt von
['avails','avaks','avalanche','avalanches','avallone','avalon','avant','avanthika','avanti','avaracious']Bereitgestellt von
Anhand der obigen Ausgabe siehst du, dass 75.827 verschiedene Vokabulare oder Wörter in deinem Datensatz 45.000 Filme haben.
Mit dieser Matrix in der Hand kannst du nun eine Ähnlichkeitsbewertung errechnen. Es gibt verschiedene Ähnlichkeitsmetriken, die du dafür verwenden kannst, wie z.B. die Manhattan-, Euklidische-, Pearson und Cosinus-Ähnlichkeitsbewertung. Auch hier gibt es keine richtige Antwort darauf, welche Punktzahl die beste ist. Unterschiedliche Werte sind in verschiedenen Szenarien gut, und es ist oft eine gute Idee, mit verschiedenen Metriken zu experimentieren und die Ergebnisse zu beobachten.
Du wirst die cosine similarity benutzen, um eine numerische Größe zu berechnen, die die Ähnlichkeit zwischen zwei Filmen angibt. Du verwendest den Cosinus-Ähnlichkeitsscore, da er unabhängig von der Größe ist und sich relativ einfach und schnell berechnen lässt (vor allem, wenn er in Verbindung mit dem TF-IDF-Score verwendet wird, der später erklärt wird). Mathematisch wird sie wie folgt definiert:
Da du den TF-IDF-Vektorisierer verwendet hast, ergibt die Berechnung des Punktprodukts zwischen den einzelnen Vektoren direkt den Cosinus-Ähnlichkeitswert. Deshalb verwendest du sklearn's linear_kernel() anstelle von cosine_similarities(), da es schneller ist.
Dies würde eine Matrix der Form 45466x45466 ergeben, was bedeutet, dass jeder Film overview eine Kosinusähnlichkeit mit jedem anderen Film overview hat. Jeder Film ist also ein 1x45466-Spalten-Vektor, bei dem jede Spalte einen Ähnlichkeitswert mit jedem Film darstellt.
# Import linear_kernelfrom sklearn.metrics.pairwise import linear_kernel
# Compute the cosine similarity matrix
cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)Bereitgestellt von
array([0.01504121,1.,0.04681953,...,0.,0.02198641,0.00929411])Bereitgestellt von
Du wirst eine Funktion definieren, die einen Filmtitel als Eingabe erhält und eine Liste mit den 10 ähnlichsten Filmen ausgibt. Dafür brauchst du erstens eine umgekehrte Zuordnung von Filmtiteln und DataFrame-Indizes. Mit anderen Worten: Du brauchst einen Mechanismus, um den Index eines Films in deinem metadata DataFrame anhand seines Titels zu ermitteln.
#Construct a reverse map of indices and movie titles
indices = pd.Series(metadata.index, index=metadata['title']).drop_duplicates()Bereitgestellt von
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
Bereitgestellt von
Jetzt bist du gut gerüstet, um deine Empfehlungsfunktion zu definieren. Das sind die folgenden Schritte, die du befolgen wirst:
Ermittelt den Index des Films anhand seines Titels.
Erhalte die Liste der Cosinus-Ähnlichkeitswerte für diesen bestimmten Film mit allen Filmen. Wandle sie in eine Liste von Tupeln um, in der das erste Element die Position und das zweite die Ähnlichkeitsbewertung ist.
Sortiere die oben genannte Liste von Tupeln nach den Ähnlichkeitswerten, d.h. nach dem zweiten Element.
Hol dir die 10 wichtigsten Elemente dieser Liste. Ignoriere das erste Element, da es sich auf dich selbst bezieht (der Film, der einem bestimmten Film am ähnlichsten ist, ist der Film selbst).
Gibt die Titel zurück, die den Indizes der obersten Elemente entsprechen.
# 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]Bereitgestellt von
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
Bereitgestellt von
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
Bereitgestellt von
Du siehst, dass dein System zwar eine gute Arbeit geleistet hat, um Filme mit ähnlichen Handlungsbeschreibungen zu finden, aber die Qualität der Empfehlungen ist nicht so gut. "The Dark Knight Rises" bringt alle Batman-Filme zurück, während es wahrscheinlicher ist, dass die Leute, die diesen Film mochten, eher geneigt sind, andere Christopher Nolan-Filme zu mögen. Das ist etwas, das dein derzeitiges System nicht erfassen kann.
Auf Credits, Genres und Schlagwörtern basierender Recommender
Die Qualität deines Empfehlungsprogramms wird durch die Verwendung besserer Metadaten und die Erfassung von mehr Details erhöht. Das ist genau das, was du in diesem Abschnitt tun wirst. Du baust ein Empfehlungssystem auf, das auf den folgenden Metadaten basiert: den 3 Top-Schauspielern, dem Regisseur, verwandten Genres und den Schlüsselwörtern zur Filmhandlung.
Die Daten zu den Stichwörtern, der Besetzung und der Crew sind in deinem aktuellen Datensatz nicht vorhanden. Der erste Schritt wäre also, sie in deinen Haupt-DataFrame metadata zu laden und zusammenzuführen.
# 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')Bereitgestellt von
# Print the first two movies of your newly merged metadata
metadata.head(2)Bereitgestellt von
Lass die Würfel rollen und entfache die Aufregung!
Jumanji
Falsch
6.9
2413.0
[{'cast_id': 1, "Zeichen": "Alan Parrish", "...
[{'credit_id': '52fe44bfc3a36847f80a7cd1', 'de...
[{'id': 10090, 'name': 'Brettspiel'}, {'id': 1...
2 Zeilen × 27 Spalten
Aus deinen neuen Merkmalen, der Besetzung, der Crew und den Schlüsselwörtern, musst du die drei wichtigsten Schauspieler, den Regisseur und die mit dem Film verbundenen Schlüsselwörter herausfiltern.
Aber das Wichtigste zuerst: Deine Daten liegen in Form von "stringifizierten" Listen vor. Du musst sie so umwandeln, dass sie für dich nutzbar sind.
# 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)Bereitgestellt von
Als Nächstes schreibst du Funktionen, die dir helfen, die benötigten Informationen aus jedem Merkmal zu extrahieren.
Zunächst importierst du das NumPy-Paket, um Zugriff auf die Konstante NaN zu erhalten. Anschließend kannst du damit die Funktion get_director() schreiben:
Hol dir den Namen des Regisseurs aus dem Crew-Feature. Wenn der Direktor nicht aufgeführt ist, schicke NaN
defget_director(x):for i in x:if i['job']=='Director':return i['name']return np.nan
Bereitgestellt von
Als nächstes schreibst du eine Funktion, die die obersten 3 Elemente oder die gesamte Liste zurückgibt, je nachdem, was mehr ist. Hier bezieht sich die Liste auf die cast, keywords, und 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[]Bereitgestellt von
# 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)Bereitgestellt von
# Print the new features of the first 3 films
metadata[['title','cast','director','keywords','genres']].head(3)Bereitgestellt von
title
gießen
director
keywords
Genres
0
Toy Story
(Tom Hanks, Tim Allen, Don Rickles)
John Lasseter
[Eifersucht, Spielzeug, Junge]
[Animation, Komödie, Familie]
1
Jumanji
[Robin Williams, Jonathan Hyde, Kirsten Dunst]
Joe Johnston
[Brettspiel, Verschwinden, basierend auf Kinder...
[Abenteuer, Fantasy, Familie]
2
Mürrische alte Männer
(Walter Matthau, Jack Lemmon, Ann-Margret)
Howard Deutch
(Angeln, bester Freund, während des Abspanns)
[Romanze, Komödie]
Der nächste Schritt wäre, die Namen und Schlüsselwortinstanzen in Kleinbuchstaben umzuwandeln und alle Leerzeichen zwischen ihnen zu entfernen.
Das Entfernen der Leerzeichen zwischen den Wörtern ist ein wichtiger Vorverarbeitungsschritt. Das wird gemacht, damit dein Vektorisierer den Johnny von "Johnny Depp" und "Johnny Galecki" nicht als denselben zählt. Nach diesem Verarbeitungsschritt werden die oben genannten Akteure als "johnnydepp" und "johnnygalecki" dargestellt und sind für deinen Vektorisierer eindeutig.
Ein weiteres gutes Beispiel, bei dem das Modell dieselbe Vektordarstellung ausgeben könnte, sind "Brotstau" und "Verkehrsstau". Daher ist es besser, alle vorhandenen Lücken zu beseitigen.
Die folgende Funktion wird genau das für dich tun:
# 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''Bereitgestellt von
# Apply clean_data function to your features.
features =['cast','keywords','director','genres']for feature in features:
metadata[feature]= metadata[feature].apply(clean_data)Bereitgestellt von
Jetzt kannst du deine "Metadatensuppe" erstellen. Das ist eine Zeichenkette, die alle Metadaten enthält, die du an deinen Vektorisierer weitergeben willst (nämlich Schauspieler, Regisseur und Schlüsselwörter).
Die Funktion create_soup verbindet einfach alle benötigten Spalten durch ein Leerzeichen. Dies ist der letzte Vorverarbeitungsschritt, und die Ausgabe dieser Funktion wird in das Wortvektormodell eingespeist.
defcreate_soup(x):return' '.join(x['keywords'])+' '+' '.join(x['cast'])+' '+ x['director']+' '+' '.join(x['genres'])Bereitgestellt von
# Create a new soup feature
metadata['soup']= metadata.apply(create_soup, axis=1)Bereitgestellt von
Eifersucht toy boy tomhanks timallen donrickles ...
1
Brettspiel "Verschwinden" nach dem Kinderbuch ...
Die nächsten Schritte sind die gleichen wie bei deinem plot description based recommender. Ein wesentlicher Unterschied besteht darin, dass du die CountVectorizer() anstelle von TF-IDF verwendest. Das liegt daran, dass du die Präsenz des Schauspielers/Regisseurs nicht abwerten willst, wenn er oder sie in relativ vielen Filmen mitgespielt oder Regie geführt hat. Es macht intuitiv nicht viel Sinn, sie in diesem Zusammenhang herunterzugewichten.
Der Hauptunterschied zwischen CountVectorizer() und TF-IDF ist die inverse Dokumentenhäufigkeit (IDF), die in der letzteren Komponente enthalten ist, in der ersteren jedoch nicht.
# 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'])Bereitgestellt von
Anhand der obigen Ausgabe kannst du sehen, dass die von dir eingegebenen Metadaten 73.881 Vokabulare enthalten.
Als Nächstes verwendest du die cosine_similarity, um den Abstand zwischen den Einbettungen zu messen.
# Compute the Cosine Similarity matrix based on the count_matrixfrom sklearn.metrics.pairwise import cosine_similarity
cosine_sim2 = cosine_similarity(count_matrix, count_matrix)Bereitgestellt von
# Reset index of your main DataFrame and construct reverse mapping as before
metadata = metadata.reset_index()
indices = pd.Series(metadata.index, index=metadata['title'])Bereitgestellt von
Du kannst jetzt deine get_recommendations() Funktion wiederverwenden, indem du die neue cosine_sim2 Matrix als zweites Argument angibst.
get_recommendations('The Dark Knight Rises', cosine_sim2)Bereitgestellt von
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
Bereitgestellt von
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
Bereitgestellt von
Toll! Du siehst, dass dein Empfehlungsprogramm aufgrund von mehr Metadaten mehr Informationen erfassen konnte und dir bessere Empfehlungen gegeben hat. Es gibt natürlich zahlreiche Möglichkeiten, mit diesem System zu experimentieren, um die Empfehlungen zu verbessern.
Einige Vorschläge:
Führe einen Beliebtheitsfilter ein: Dieser Empfehlungsgeber würde die 30 ähnlichsten Filme nehmen, die gewichteten Bewertungen berechnen (mit der IMDB-Formel von oben), die Filme nach dieser Bewertung sortieren und die 10 besten Filme zurückgeben.
Andere Teammitglieder: Die Namen anderer Teammitglieder, wie Drehbuchautoren und Produzenten, können ebenfalls aufgenommen werden.
Das zunehmende Gewicht des Regisseurs: Um dem Regisseur oder der Regisseurin mehr Gewicht zu verleihen, kann er oder sie mehrfach in der Suppe erwähnt werden, um die Ähnlichkeitswerte von Filmen mit demselben Regisseur zu erhöhen.
Kollaborative Filterung mit Python
In diesem Tutorial hast du gelernt, wie du dein eigenes einfaches und inhaltsbasiertes Filmempfehlungssystem erstellen kannst. Es gibt noch eine andere, sehr beliebte Art von Empfehlungssystemen, die sogenannten kollaborativen Filter.
Kollaborative Filter können in zwei Arten unterteilt werden:
User-based Filtering: Diese Systeme empfehlen einem Nutzer Produkte, die ähnlichen Nutzern gefallen haben. Nehmen wir zum Beispiel an, Alice und Bob haben ein ähnliches Interesse an Büchern (d.h. sie mögen und mögen nicht dieselben Bücher). Nehmen wir an, ein neues Buch ist auf den Markt gekommen, und Alice hat es gelesen und geliebt. Es ist also sehr wahrscheinlich, dass es auch Bob gefallen wird, und deshalb empfiehlt das System dieses Buch für Bob.
Item-based Filtering: Diese Systeme sind der von dir entwickelten Content Recommendation Engine sehr ähnlich. Diese Systeme erkennen ähnliche Gegenstände anhand der Bewertungen, die andere in der Vergangenheit abgegeben haben. Wenn Alice, Bob und Eva zum Beispiel 5 Sterne für Der Herr der Ringe und Der Hobbit vergeben haben, erkennt das System die Artikel als ähnlich. Wenn also jemand Der Herr der Ringe kauft, empfiehlt das System ihm oder ihr auch den Hobbit.
Ein Beispiel für kollaboratives Filtern auf der Grundlage eines Bewertungssystems:
Du wirst diese Systeme in diesem Lehrgang nicht bauen, aber du bist bereits mit den meisten Ideen vertraut, die du dafür brauchst. Ein guter Anfang für kollaborative Filter ist die Untersuchung des MovieLens-Datensatzes, den du hier findest.
Fazit
Herzlichen Glückwunsch zur Fertigstellung dieses Tutorials!
Du hast unser Tutorial über Empfehlungssysteme in Python erfolgreich durchlaufen. Du hast gelernt, wie du einfache und inhaltsbasierte Empfehlungsprogramme erstellen kannst.
Eine gute Übung für euch wäre es, kollaboratives Filtern in Python zu implementieren und dabei die Teilmenge des MovieLens-Datensatzes zu verwenden, die ihr für die Erstellung einfacher und inhaltsbasierter Empfehlungsprogramme verwendet habt.
Lerne mehr über Python-Lambda-Funktionen, wozu sie gut sind und wann man sie benutzt. Enthält praktische Beispiele und bewährte Methoden für eine effektive Umsetzung.
Mach dich mit Python-Datenstrukturen vertraut: Lerne mehr über Datentypen und primitive sowie nicht-primitive Datenstrukturen wie Strings, Listen, Stapel usw.
Erforsche Pythons match-case: eine Anleitung zu seiner Syntax, Anwendungen in Data Science und ML sowie eine vergleichende Analyse mit dem traditionellen switch-case.
Das Ziel dieses Tutorials ist es nicht, dich zu einem Experten für die Erstellung von Empfehlungssystemen zu machen. Stattdessen geht es darum, dir einen Überblick über die verschiedenen Arten von Empfehlungssystemen zu verschaffen und dir zu zeigen, wie du selbst eines aufbauen kannst.
In diesem Lernprogramm lernst du, wie du ein grundlegendes Modell für einfache und inhaltsbasierte Empfehlungssysteme erstellst. Auch wenn diese Modelle in Bezug auf Komplexität, Qualität und Genauigkeit nicht an den Industriestandard heranreichen, helfen sie dir, komplexere Modelle zu erstellen, die noch bessere Ergebnisse liefern.
Empfehlungssysteme gehören heute zu den beliebtesten Anwendungen der Datenwissenschaft. Sie werden verwendet, um die "Bewertung" oder "Präferenz" vorherzusagen, die ein Nutzer für einen Artikel abgeben würde. Fast jedes große Technologieunternehmen hat sie in irgendeiner Form eingesetzt. Amazon nutzt sie, um Kunden Produkte vorzuschlagen, YouTube nutzt sie, um zu entscheiden, welches Video als Nächstes abgespielt werden soll, und Facebook nutzt sie, um Seiten zu empfehlen, die man mögen und denen man folgen sollte.
Für einige Unternehmen wie Netflix, Amazon Prime, Hulu und Hotstar dreht sich das Geschäftsmodell und ihr Erfolg um die Wirksamkeit ihrer Empfehlungen. Netflix hat 2009 sogar eine Million Dollar für denjenigen ausgelobt, der sein System um 10% verbessern kann.
Es gibt auch beliebte Empfehlungssysteme für Bereiche wie Restaurants, Filme und Online-Dating. Empfehlungssysteme wurden auch entwickelt, um Forschungsartikel und Experten, Mitarbeiter und Finanzdienstleistungen zu finden. YouTube nutzt das Empfehlungssystem in großem Umfang, um dir Videos auf der Grundlage deines Verlaufs vorzuschlagen. Wenn du dir zum Beispiel viele Lehrvideos ansiehst, schlägt es dir diese Art von Videos vor.
Aber was sind diese Empfehlungssysteme?
Im Großen und Ganzen lassen sich Empfehlungssysteme in 3 Typen einteilen:
Einfache Empfehlungsgeber
Wie im vorigen Abschnitt beschrieben, sind einfache Empfehlungssysteme grundlegende Systeme, die die besten Artikel auf der Grundlage einer bestimmten Metrik oder Punktzahl empfehlen. In diesem Abschnitt erstellst du einen vereinfachten Klon der IMDB Top 250 Movies mit Metadaten aus der IMDB.
Im Folgenden werden die einzelnen Schritte beschrieben:
Entscheide dich für eine Metrik oder Punktzahl, nach der du Filme bewerten willst.
Berechne die Punktzahl für jeden Film.
Sortiere die Filme nach der Punktzahl und gib die besten Ergebnisse aus.
Über den Datensatz
Die Datensatzdateien enthalten Metadaten für alle 45.000 Filme, die in der
Full MovieLens Datasetaufgeführt sind. Der Datensatz besteht aus Filmen, die im Juli 2017 oder früher veröffentlicht wurden. Dieser Datensatz enthält Merkmale wie Besetzung, Crew, Stichwörter zur Handlung, Budget, Einnahmen, Plakate, Veröffentlichungstermine, Sprachen, Produktionsfirmen, Länder, TMDB-Stimmenzahlen und Stimmendurchschnitte.Mit diesen Merkmalen kannst du deine Machine-Learning-Modelle für Content und Collaborative Filtering trainieren.
Dieser Datensatz besteht aus den folgenden Dateien:
Der vollständige MovieLens-Datensatz umfasst 26 Millionen Bewertungen und 750.000 Tag-Anwendungen von 270.000 Nutzern für alle 45.000 Filme in diesem Datensatz. Du kannst sie auf der offiziellen GroupLens-Website aufrufen.
Hinweis: Der Datensatz, der im heutigen Tutorial verwendet wird, kann hier heruntergeladen werden.
Um deinen Datensatz zu laden, verwendest du die
pandasDataFrame-Bibliothek.pandaswird hauptsächlich für die Datenbearbeitung und -analyse verwendet. Sie stellt deine Daten in einem Zeilen-/Spaltenformat dar. Die Pandas-Bibliothek stützt sich auf das ArrayNumPyfür die Implementierung von Pandas-Datenobjekten.pandasbietet Standard-Datenstrukturen und -Operationen für die Bearbeitung von numerischen Tabellen, Zeitreihen, Bildern und Datensätzen zur Verarbeitung natürlicher Sprache. Grundsätzlich istpandasfür Datensätze geeignet, die sich leicht in Tabellenform darstellen lassen.Bevor du die oben genannten Schritte durchführst, laden wir deinen Film-Metadatensatz in einen
pandasDataFrame:3 Zeilen × 24 Spalten
Eine der grundlegendsten Metriken, die du dir vorstellen kannst, ist die Rangliste, um zu entscheiden, welche Filme in den Top 250 sind, basierend auf ihren jeweiligen Bewertungen.
Die Verwendung einer Bewertung als Maßstab hat jedoch ein paar Vorbehalte:
Zum einen berücksichtigt sie nicht die Popularität eines Films. Daher wird ein Film mit einer Bewertung von 9 von 10 Wählern als "besser" angesehen als ein Film mit einer Bewertung von 8,9 von 10.000 Wählern.
Stell dir zum Beispiel vor, du willst chinesisch essen gehen und hast mehrere Möglichkeiten. Das eine Restaurant hat nur 5 Sterne, das andere Restaurant hat 4,5 Sterne von 1000 Leuten. Welches Restaurant würdest du bevorzugen? Die zweite, richtig?
Natürlich kann es eine Ausnahme sein, dass das erste Restaurant erst vor ein paar Tagen eröffnet wurde und daher weniger Leute dafür gestimmt haben, während das zweite Restaurant bereits seit einem Jahr in Betrieb ist.
Unter Berücksichtigung dieser Unzulänglichkeiten musst du eine gewichtete Bewertung erstellen, die die durchschnittliche Bewertung und die Anzahl der Stimmen, die sie angesammelt hat, berücksichtigt. Ein solches System stellt sicher, dass ein Film mit einer Bewertung von 9 von 100.000 Wählern eine (weit) höhere Punktzahl erhält als ein Film mit der gleichen Bewertung, aber nur ein paar hundert Wählern.
Da du versuchst, einen Klon der Top 250 von IMDB zu erstellen, lass uns die gewichtete Bewertungsformel als Maßstab/Score verwenden. Mathematisch lässt sich das wie folgt darstellen:
\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}
In der obigen Gleichung,
v ist die Anzahl der Stimmen für den Film;
m ist die Mindestanzahl an Stimmen, die erforderlich ist, um in der Tabelle aufgeführt zu werden;
R ist die durchschnittliche Bewertung des Films;
C ist der Mittelwert der Stimmen für den gesamten Bericht.
Du hast bereits die Werte für v
(vote_count)und R(vote_average)für jeden Film im Datensatz. Es ist auch möglich, C direkt aus diesen Daten zu berechnen.Die Bestimmung eines geeigneten Wertes für
mist ein Hyperparameter, den du entsprechend wählen kannst, da es keinen richtigen Wert fürmgibt. Du kannst ihn als vorläufigen Negativfilter betrachten, der einfach die Filme entfernt, deren Stimmenzahl unter einem bestimmten Schwellenwertmliegt. Die Selektivität deines Filters liegt in deinem Ermessen.In diesem Lernprogramm verwendest du den Cutoff
mals 90ste Perzentile. Mit anderen Worten: Damit ein Film in die Charts kommt, muss er mehr Stimmen haben als mindestens 90% der Filme auf der Liste. (Hättest du hingegen das 75. Perzentil gewählt, hättest du die besten 25 % der Filme in Bezug auf die Anzahl der erhaltenen Stimmen berücksichtigt. Je niedriger der Prozentsatz ist, desto mehr Filme werden berücksichtigt).Als ersten Schritt berechnen wir den Wert C, den Mittelwert der Bewertung aller Filme, mit der Funktion
.mean():Aus der obigen Ausgabe kannst du ersehen, dass die durchschnittliche Bewertung eines Films auf IMDB etwa 5,6 auf einer Skala von 10 beträgt.
Als Nächstes berechnen wir die Anzahl der Stimmen, m, die ein Film im 90sten Perzentil erhält. Die
pandasBibliothek macht diese Aufgabe mit der.quantile()Methode von Pandas extrem trivial:Da du jetzt die
mhast, kannst du einfach eine Bedingung verwenden, die größer als gleich ist, um Filme herauszufiltern, deren Stimmenzahl größer als 160 ist:Du kannst die Methode
.copy()verwenden, um sicherzustellen, dass der neu erstellteq_moviesDataFrame unabhängig von deinem ursprünglichen Metadaten-DataFrame ist. Mit anderen Worten: Alle Änderungen am q_movies DataFrame haben keine Auswirkungen auf den ursprünglichen Metadaten-DataFrame.Aus der obigen Ausgabe geht hervor, dass etwa 10 % der Filme mehr als 160 Stimmen haben und sich für diese Liste qualifizieren.
Der nächste und wichtigste Schritt ist die Berechnung der gewichteten Bewertung für jeden qualifizierten Film. Um dies zu tun, musst du:
weighted_rating();mundCbereits berechnet hast, gibst du sie einfach als Argument an die Funktion weiter;vote_count(v) undvote_average(R) aus dem Datenrahmenq_moviesaus;Du definierst ein neues Merkmal
score, dessen Wert du berechnest, indem du diese Funktion auf deinen DataFrame mit qualifizierten Filmen anwendest:Zum Schluss sortieren wir den DataFrame in absteigender Reihenfolge nach der Spalte
scoreund geben den Titel, die Anzahl der Stimmen, den Durchschnitt der Stimmen und die gewichtete Bewertung (Score) der 20 besten Filme aus.Anhand der obigen Ausgabe kannst du sehen, dass die
simple recommendergute Arbeit geleistet hat!Da die Tabelle viele Filme mit der IMDB-Top-250-Liste gemeinsam hat: Deine beiden Top-Filme, "Die Verurteilten" und "Der Pate", sind zum Beispiel die gleichen wie bei IMDB, und wir alle wissen, dass sie in der Tat tolle Filme sind, verdienen es eigentlich alle Top-20-Filme, in dieser Liste zu stehen, oder?
Inhaltsbasierter Empfehlungsgeber
Plotbeschreibung basierte Empfehlung
In diesem Teil des Tutorials lernst du, wie du ein System aufbaust, das Filme empfiehlt, die einem bestimmten Film ähnlich sind. Um dies zu erreichen, berechnest du paarweise
cosineÄhnlichkeitswerte für alle Filme auf der Grundlage ihrer Handlungsbeschreibungen und empfiehlst Filme auf der Grundlage dieses Ähnlichkeitsschwellenwerts.Die Grundstücksbeschreibung steht dir als Merkmal
overviewin deinemmetadataDatensatz zur Verfügung. Schauen wir uns die Handlungen einiger Filme an:Bei dem vorliegenden Problem handelt es sich um ein Problem der natürlichen Sprachverarbeitung. Daher musst du aus den oben genannten Textdaten eine Art von Merkmalen extrahieren, bevor du die Ähnlichkeit und/oder Unähnlichkeit zwischen ihnen berechnen kannst. Einfach ausgedrückt: Es ist nicht möglich, die Ähnlichkeit zwischen zwei Übersichten in ihrer Rohform zu berechnen. Dazu musst du die Wortvektoren jeder Übersicht oder jedes Dokuments, wie es von nun an heißen wird, berechnen.
Wie der Name schon sagt, sind Wortvektoren vektorisierte Darstellungen von Wörtern in einem Dokument. Die Vektoren tragen eine semantische Bedeutung mit sich. Zum Beispiel haben Mann und König Vektordarstellungen, die nahe beieinander liegen, während Mann und Frau weit voneinander entfernt dargestellt werden.
Du berechnest
Term Frequency-Inverse Document Frequency(TF-IDF) Vektoren für jedes Dokument. So erhältst du eine Matrix, in der jede Spalte ein Wort aus dem Übersichtsvokabular darstellt (alle Wörter, die in mindestens einem Dokument vorkommen), und jede Spalte steht für einen Film, wie zuvor.Im Wesentlichen ist der TF-IDF-Score die Häufigkeit, mit der ein Wort in einem Dokument vorkommt, gewichtet nach der Anzahl der Dokumente, in denen es vorkommt. Dies geschieht, um die Bedeutung von Wörtern, die häufig in Handlungsübersichten vorkommen, und damit auch ihre Bedeutung für die Berechnung der endgültigen Ähnlichkeitsbewertung zu verringern.
Zum Glück gibt es in scikit-learn eine eingebaute
TfIdfVectorizerKlasse, die die TF-IDF-Matrix in ein paar Zeilen erstellt.Anhand der obigen Ausgabe siehst du, dass 75.827 verschiedene Vokabulare oder Wörter in deinem Datensatz 45.000 Filme haben.
Mit dieser Matrix in der Hand kannst du nun eine Ähnlichkeitsbewertung errechnen. Es gibt verschiedene Ähnlichkeitsmetriken, die du dafür verwenden kannst, wie z.B. die Manhattan-, Euklidische-, Pearson und Cosinus-Ähnlichkeitsbewertung. Auch hier gibt es keine richtige Antwort darauf, welche Punktzahl die beste ist. Unterschiedliche Werte sind in verschiedenen Szenarien gut, und es ist oft eine gute Idee, mit verschiedenen Metriken zu experimentieren und die Ergebnisse zu beobachten.
Du wirst die
cosine similaritybenutzen, um eine numerische Größe zu berechnen, die die Ähnlichkeit zwischen zwei Filmen angibt. Du verwendest den Cosinus-Ähnlichkeitsscore, da er unabhängig von der Größe ist und sich relativ einfach und schnell berechnen lässt (vor allem, wenn er in Verbindung mit dem TF-IDF-Score verwendet wird, der später erklärt wird). Mathematisch wird sie wie folgt definiert:Da du den TF-IDF-Vektorisierer verwendet hast, ergibt die Berechnung des Punktprodukts zwischen den einzelnen Vektoren direkt den Cosinus-Ähnlichkeitswert. Deshalb verwendest du
sklearn's linear_kernel()anstelle voncosine_similarities(), da es schneller ist.Dies würde eine Matrix der Form 45466x45466 ergeben, was bedeutet, dass jeder Film
overvieweine Kosinusähnlichkeit mit jedem anderen Filmoverviewhat. Jeder Film ist also ein 1x45466-Spalten-Vektor, bei dem jede Spalte einen Ähnlichkeitswert mit jedem Film darstellt.Du wirst eine Funktion definieren, die einen Filmtitel als Eingabe erhält und eine Liste mit den 10 ähnlichsten Filmen ausgibt. Dafür brauchst du erstens eine umgekehrte Zuordnung von Filmtiteln und DataFrame-Indizes. Mit anderen Worten: Du brauchst einen Mechanismus, um den Index eines Films in deinem
metadataDataFrame anhand seines Titels zu ermitteln.Jetzt bist du gut gerüstet, um deine Empfehlungsfunktion zu definieren. Das sind die folgenden Schritte, die du befolgen wirst:
Ermittelt den Index des Films anhand seines Titels.
Erhalte die Liste der Cosinus-Ähnlichkeitswerte für diesen bestimmten Film mit allen Filmen. Wandle sie in eine Liste von Tupeln um, in der das erste Element die Position und das zweite die Ähnlichkeitsbewertung ist.
Sortiere die oben genannte Liste von Tupeln nach den Ähnlichkeitswerten, d.h. nach dem zweiten Element.
Hol dir die 10 wichtigsten Elemente dieser Liste. Ignoriere das erste Element, da es sich auf dich selbst bezieht (der Film, der einem bestimmten Film am ähnlichsten ist, ist der Film selbst).
Gibt die Titel zurück, die den Indizes der obersten Elemente entsprechen.
Du siehst, dass dein System zwar eine gute Arbeit geleistet hat, um Filme mit ähnlichen Handlungsbeschreibungen zu finden, aber die Qualität der Empfehlungen ist nicht so gut. "The Dark Knight Rises" bringt alle Batman-Filme zurück, während es wahrscheinlicher ist, dass die Leute, die diesen Film mochten, eher geneigt sind, andere Christopher Nolan-Filme zu mögen. Das ist etwas, das dein derzeitiges System nicht erfassen kann.
Auf Credits, Genres und Schlagwörtern basierender Recommender
Die Qualität deines Empfehlungsprogramms wird durch die Verwendung besserer Metadaten und die Erfassung von mehr Details erhöht. Das ist genau das, was du in diesem Abschnitt tun wirst. Du baust ein Empfehlungssystem auf, das auf den folgenden Metadaten basiert: den 3 Top-Schauspielern, dem Regisseur, verwandten Genres und den Schlüsselwörtern zur Filmhandlung.
Die Daten zu den Stichwörtern, der Besetzung und der Crew sind in deinem aktuellen Datensatz nicht vorhanden. Der erste Schritt wäre also, sie in deinen Haupt-DataFrame
metadatazu laden und zusammenzuführen.2 Zeilen × 27 Spalten
Aus deinen neuen Merkmalen, der Besetzung, der Crew und den Schlüsselwörtern, musst du die drei wichtigsten Schauspieler, den Regisseur und die mit dem Film verbundenen Schlüsselwörter herausfiltern.
Aber das Wichtigste zuerst: Deine Daten liegen in Form von "stringifizierten" Listen vor. Du musst sie so umwandeln, dass sie für dich nutzbar sind.
Als Nächstes schreibst du Funktionen, die dir helfen, die benötigten Informationen aus jedem Merkmal zu extrahieren.
Zunächst importierst du das NumPy-Paket, um Zugriff auf die Konstante
NaNzu erhalten. Anschließend kannst du damit die Funktionget_director()schreiben:Hol dir den Namen des Regisseurs aus dem Crew-Feature. Wenn der Direktor nicht aufgeführt ist, schicke
NaNAls nächstes schreibst du eine Funktion, die die obersten 3 Elemente oder die gesamte Liste zurückgibt, je nachdem, was mehr ist. Hier bezieht sich die Liste auf die
cast,keywords, undgenres.Der nächste Schritt wäre, die Namen und Schlüsselwortinstanzen in Kleinbuchstaben umzuwandeln und alle Leerzeichen zwischen ihnen zu entfernen.
Das Entfernen der Leerzeichen zwischen den Wörtern ist ein wichtiger Vorverarbeitungsschritt. Das wird gemacht, damit dein Vektorisierer den Johnny von "Johnny Depp" und "Johnny Galecki" nicht als denselben zählt. Nach diesem Verarbeitungsschritt werden die oben genannten Akteure als "johnnydepp" und "johnnygalecki" dargestellt und sind für deinen Vektorisierer eindeutig.
Ein weiteres gutes Beispiel, bei dem das Modell dieselbe Vektordarstellung ausgeben könnte, sind "Brotstau" und "Verkehrsstau". Daher ist es besser, alle vorhandenen Lücken zu beseitigen.
Die folgende Funktion wird genau das für dich tun:
Jetzt kannst du deine "Metadatensuppe" erstellen. Das ist eine Zeichenkette, die alle Metadaten enthält, die du an deinen Vektorisierer weitergeben willst (nämlich Schauspieler, Regisseur und Schlüsselwörter).
Die Funktion
create_soupverbindet einfach alle benötigten Spalten durch ein Leerzeichen. Dies ist der letzte Vorverarbeitungsschritt, und die Ausgabe dieser Funktion wird in das Wortvektormodell eingespeist.Die nächsten Schritte sind die gleichen wie bei deinem
plot description based recommender. Ein wesentlicher Unterschied besteht darin, dass du dieCountVectorizer()anstelle vonTF-IDFverwendest. Das liegt daran, dass du die Präsenz des Schauspielers/Regisseurs nicht abwerten willst, wenn er oder sie in relativ vielen Filmen mitgespielt oder Regie geführt hat. Es macht intuitiv nicht viel Sinn, sie in diesem Zusammenhang herunterzugewichten.Der Hauptunterschied zwischen
CountVectorizer()undTF-IDFist die inverse Dokumentenhäufigkeit (IDF), die in der letzteren Komponente enthalten ist, in der ersteren jedoch nicht.Anhand der obigen Ausgabe kannst du sehen, dass die von dir eingegebenen Metadaten 73.881 Vokabulare enthalten.
Als Nächstes verwendest du die
cosine_similarity, um den Abstand zwischen den Einbettungen zu messen.Du kannst jetzt deine
get_recommendations()Funktion wiederverwenden, indem du die neuecosine_sim2Matrix als zweites Argument angibst.Toll! Du siehst, dass dein Empfehlungsprogramm aufgrund von mehr Metadaten mehr Informationen erfassen konnte und dir bessere Empfehlungen gegeben hat. Es gibt natürlich zahlreiche Möglichkeiten, mit diesem System zu experimentieren, um die Empfehlungen zu verbessern.
Einige Vorschläge:
Führe einen Beliebtheitsfilter ein: Dieser Empfehlungsgeber würde die 30 ähnlichsten Filme nehmen, die gewichteten Bewertungen berechnen (mit der IMDB-Formel von oben), die Filme nach dieser Bewertung sortieren und die 10 besten Filme zurückgeben.
Andere Teammitglieder: Die Namen anderer Teammitglieder, wie Drehbuchautoren und Produzenten, können ebenfalls aufgenommen werden.
Das zunehmende Gewicht des Regisseurs: Um dem Regisseur oder der Regisseurin mehr Gewicht zu verleihen, kann er oder sie mehrfach in der Suppe erwähnt werden, um die Ähnlichkeitswerte von Filmen mit demselben Regisseur zu erhöhen.
Kollaborative Filterung mit Python
In diesem Tutorial hast du gelernt, wie du dein eigenes einfaches und inhaltsbasiertes Filmempfehlungssystem erstellen kannst. Es gibt noch eine andere, sehr beliebte Art von Empfehlungssystemen, die sogenannten kollaborativen Filter.
Kollaborative Filter können in zwei Arten unterteilt werden:
User-based Filtering: Diese Systeme empfehlen einem Nutzer Produkte, die ähnlichen Nutzern gefallen haben. Nehmen wir zum Beispiel an, Alice und Bob haben ein ähnliches Interesse an Büchern (d.h. sie mögen und mögen nicht dieselben Bücher). Nehmen wir an, ein neues Buch ist auf den Markt gekommen, und Alice hat es gelesen und geliebt. Es ist also sehr wahrscheinlich, dass es auch Bob gefallen wird, und deshalb empfiehlt das System dieses Buch für Bob.Item-based Filtering: Diese Systeme sind der von dir entwickelten Content Recommendation Engine sehr ähnlich. Diese Systeme erkennen ähnliche Gegenstände anhand der Bewertungen, die andere in der Vergangenheit abgegeben haben. Wenn Alice, Bob und Eva zum Beispiel 5 Sterne für Der Herr der Ringe und Der Hobbit vergeben haben, erkennt das System die Artikel als ähnlich. Wenn also jemand Der Herr der Ringe kauft, empfiehlt das System ihm oder ihr auch den Hobbit.Ein Beispiel für kollaboratives Filtern auf der Grundlage eines Bewertungssystems:
Du wirst diese Systeme in diesem Lehrgang nicht bauen, aber du bist bereits mit den meisten Ideen vertraut, die du dafür brauchst. Ein guter Anfang für kollaborative Filter ist die Untersuchung des MovieLens-Datensatzes, den du hier findest.
Fazit
Herzlichen Glückwunsch zur Fertigstellung dieses Tutorials!
Du hast unser Tutorial über Empfehlungssysteme in Python erfolgreich durchlaufen. Du hast gelernt, wie du einfache und inhaltsbasierte Empfehlungsprogramme erstellen kannst.
Eine gute Übung für euch wäre es, kollaboratives Filtern in Python zu implementieren und dabei die Teilmenge des MovieLens-Datensatzes zu verwenden, die ihr für die Erstellung einfacher und inhaltsbasierter Empfehlungsprogramme verwendet habt.
Wenn du gerade erst mit Python anfängst und mehr darüber erfahren möchtest, besuche den DataCamp-Kurs Einführung in die Datenwissenschaft in Python.