Ashay Pathak, Chatana Mandava, Ritesh Patel
Collaborative Filtering ist eine Technik, die in Empfehlungssystemen weit verbreitet ist und ein schnell fortschreitendes Forschungsgebiet darstellt. Die beiden am häufigsten verwendeten Methoden sind speicherbasiert und modellbasiert.
In diesem Beitrag werden wir uns nur auf (User-Based Collaborative Filtering) UB-CF konzentrieren, eine speicherbasierte Methode. Die Hauptidee hinter UB-CF ist, dass Menschen mit ähnlichen Merkmalen einen ähnlichen Geschmack haben. Wenn Sie beispielsweise unserem Freund Bob einen Film empfehlen wollen, nehmen wir an, dass Bob und ich viele Filme zusammen gesehen haben und sie fast identisch bewerten. Es macht Sinn zu denken, dass wir auch in Zukunft ähnliche Filme mögen werden und diese Ähnlichkeitsmetrik nutzen, um Filme zu empfehlen.
Lassen Sie uns versuchen, UB-CF zu implementieren und eine Liste von Filmen zu generieren, die unser Freund Bob a.k.a. aktiver Benutzer gerne sehen würde. Die Motivation, diesen Beitrag zu schreiben, besteht darin, tief in den Algorithmus einzutauchen und zu verstehen, wie UB-CF tatsächlich funktioniert. Der größte Teil des Inhalts dieses Beitrags ist von einem Kurs auf Coursera inspiriert.
User-User Collaborative Filtering
Die Methode identifiziert Benutzer, die dem abgefragten Benutzer ähnlich sind und schätzt die gewünschte Bewertung als gewichteten Durchschnitt der Bewertungen dieser ähnlichen Benutzer.
Wir würden die Empfehlungen auf dem MovieLens Dataset durchführen. Die verwendete Programmiersprache ist Python und die Datenanalyse wird hauptsächlich mit der Pandas-Bibliothek durchgeführt. Die verwendete IDE ist jupyter notebook.
Bevor wir beginnen, möchte ich die Liste der verwendeten Bibliotheken aufführen:
- Pandas
- Numpy
- sklearn
Lassen Sie uns also fortfahren und die Konzepte hinter den Empfehlungen verstehen. Zum besseren Verständnis habe ich einige Codeschnipsel und Ausgaben im Blog angehängt. Die gesamte ipynb-Datei ist am Ende des Blogs angehängt.
Score-Funktion
Es ist einfach, eine Funktion für nicht-personalisierte kollaborative Filterung zu entwickeln (d.h. wir berücksichtigen nicht die Vorlieben, Abneigungen und Bewertungen des aktiven Benutzers aus der Vergangenheit), die eine Punktzahl für den Benutzer u und den Artikel i als Eingabeparameter liefert. Die Funktion gibt eine Punktzahl aus, die angibt, wie stark ein Nutzer u den Artikel i mag/bevorzugt.
Dies geschieht also in der Regel anhand der Bewertungen anderer Personen, die dem Nutzer ähnlich sind. Dies alles wird später im Detail besprochen. Im Moment ist die Formel, die ich verwendet habe,
wobei ‘s’ der vorhergesagte Score ist, ‘u’ der Benutzer, ‘i’ der Artikel, ‘r’ die vom Benutzer abgegebene Bewertung und ‘w’ die Gewichtung ist.
In diesem Fall ist unsere Punktzahl gleich der Summe der Bewertungen, die jeder Benutzer für diesen Gegenstand abgegeben hat, abzüglich der durchschnittlichen Bewertung dieses Benutzers, multipliziert mit einer Gewichtung, die angibt, wie sehr dieser Benutzer den Vorhersagen anderer Benutzer ähnlich ist oder zu ihnen beitragen soll. Dies ist die Gewichtung zwischen Benutzer u und v. Die Punktzahl liegt zwischen 0 und 1, wobei 0 niedrig und 1 hoch ist. Alles sieht perfekt aus, aber warum haben wir dann die durchschnittlichen Bewertungen von den Bewertungen der einzelnen Nutzer abgezogen und warum haben wir den gewichteten Durchschnitt anstelle des einfachen Mittelwerts verwendet?
Das Problem liegt in den Arten von Nutzern, die wir behandeln. Es fängt damit an, dass die Leute oft auf sehr unterschiedlichen Skalen bewerten. Ich bin vielleicht ein positiver und optimistischer Nutzer, der einen Film, der ihm gefallen hat, mit 4 von 5 Punkten bewertet, aber ein anderer Nutzer, der weniger optimistisch ist oder hohe Ansprüche hat, bewertet seinen Lieblingsfilm mit 2 von 5 Punkten. Hier ist seine 2 meine 4. Wir können die Effizienz dieses Algorithmus erhöhen, wenn wir die Bewertungen der Benutzer normalisieren. Eine Möglichkeit, dies zu tun, besteht darin, s(u,i) zu berechnen, d.h. die durchschnittliche Bewertung, die der Benutzer für jeden Artikel abgibt, plus eine gewisse Abweichung, wobei die Abweichung angibt, um wie viel dieser Artikel besser oder schlechter als der Durchschnitt ist.
Ich habe die Kosinusähnlichkeit verwendet, um die Gewichtung in der obigen Formel zu berechnen. Ich habe auch den Begriff der Nachbarschaft verwendet, der in diesem Blog im weiteren Verlauf besprochen wird.
Um die Daten auf die oben beschriebene Weise zu normalisieren, ist eine Datenanalyse in Pandas erforderlich. Sie können den gesamten Code am Ende erhalten. Für den Blog werde ich mich auf die wichtigsten Konzepte konzentrieren.
import pandas as pdmovies = pd.read_csv("movies.csv",encoding="Latin1")
Ratings = pd.read_csv("ratings.csv")
Tags = pd.read_csv("tags.csv",encoding="Latin1")Mean = Ratings.groupby(by="userId",as_index=False).mean()
Rating_avg = pd.merge(Ratings,Mean,on='userId')
Rating_avg=Rating_avg-Rating_avg
Rating_avg.head()
So, jetzt sind wir fertig mit der Berechnung der normalisierten Bewertung für einen Benutzer. Die obigen Daten werden später verwendet, um die endgültige Punktzahl für den Benutzer zu berechnen.
Ab hier werden wir uns nun auf einige wichtige Konzepte im Zusammenhang mit Empfehlungssystemen konzentrieren.
Cosinusähnlichkeit
Für die obige Formel müssen wir die Benutzer finden, die ähnliche Gedanken haben. Das klingt so interessant, um einen Benutzer zu finden, der ähnliche Vorlieben und Abneigungen hat. Aber wie finden wir die Ähnlichkeit?
Um dies zu beantworten, verwenden wir die Cosinus-Ähnlichkeit und sehen, wie ähnlich sich die Nutzer sind. Sie wird normalerweise über die Bewertungen berechnet, die beide Benutzer in der Vergangenheit abgegeben haben.
In unserem Beispiel habe ich die Funktion cosine_similarity von sklearn verwendet, um die Ähnlichkeit zu berechnen. Zuvor müssen wir jedoch einige Vorverarbeitungen durchführen und die Daten bereinigen.
from sklearn.metrics.pairwise import cosine_similarityfinal=pd.pivot_table(Rating_avg,values='adg_rating',index='userId',columns='movieId')
Diese enthält viele NaN-Werte, da nicht jeder Benutzer alle Filme gesehen hat. Daher wird diese Art von Matrix als spärliche Matrix bezeichnet. Methoden wie die Matrixfaktorisierung werden verwendet, um mit dieser Spärlichkeit umzugehen, aber wir werden uns in diesem Blog nicht darauf konzentrieren. Der nächste und einer der wichtigsten Schritte besteht darin, diese NaN-Werte zu ersetzen.
Hierfür gibt es zwei Methoden, die üblicherweise verwendet werden:
- Verwenden Sie den Benutzer-Durchschnitt über die Zeile.
- Verwenden Sie den Film-Durchschnitt über die Spalte.
Ich habe beide Methoden verwendet, und Sie können sie im Code unten sehen. Aber zur Erklärung würde ich die Film-Durchschnittsmethode verwenden.
# Replacing NaN by Movie Average
final_movie = final.fillna(final.mean(axis=0))
Der nächste Schritt ist nun die Berechnung der Ähnlichkeit zwischen den Benutzern.
# user similarity on replacing NAN by item(movie) avg
cosine = cosine_similarity(final_movie)
np.fill_diagonal(cosine, 0 )
similarity_with_movie =pd.DataFrame(cosine,index=final_movie.index)
similarity_with_movie.columns=final_user.index
similarity_with_movie.head()