Ashay Pathak, Chatana Mandava, Ritesh Patel
Collaborative Filtering is een techniek die veel wordt gebruikt in aanbevelingssystemen en is een snel voortschrijdend onderzoeksgebied. De twee meest gebruikte methoden zijn geheugen-gebaseerd en model-gebaseerd.
In deze post zullen we ons alleen richten op (User-Based Collaborative Filtering) UB-CF dat een geheugen-gebaseerde methode is. Het belangrijkste idee achter UB-CF is dat mensen met vergelijkbare kenmerken een vergelijkbare smaak delen. Bijvoorbeeld, als je een film wil aanbevelen aan onze vriend Bob, stel dat Bob en ik samen veel films hebben gezien en dat we ze bijna identiek beoordelen. Het is logisch om te denken dat we ook in de toekomst soortgelijke films leuk zullen vinden en dat we deze gelijkenis gebruiken om films aan te bevelen.
Laten we proberen om UB-CF te implementeren en een lijst van films te genereren die onze vriend Bob a.k.a actieve gebruiker zou kunnen interesseren om te bekijken. De motivatie achter het schrijven van deze post is om diep in het algoritme te duiken en te begrijpen hoe UB-CF eigenlijk werkt. Het grootste deel van de inhoud van deze post is geïnspireerd door een cursus op Coursera.
User-User Collaborative Filtering
De methode identificeert gebruikers die vergelijkbaar zijn met de opgevraagde gebruiker en schat de gewenste beoordeling in als het gewogen gemiddelde van de beoordelingen van deze vergelijkbare gebruikers.
Nu zijn we dus klaar met het berekenen van de genormaliseerde rating voor een gebruiker. De bovenstaande gegevens worden later gebruikt om de eindscore voor de gebruiker te berekenen.
Van hieruit gaan we ons nu richten op enkele belangrijke concepten met betrekking tot aanbevelingssystemen.
Cosineovereenkomst
Voor de bovenstaande formule moeten we de gebruikers vinden die vergelijkbare gedachten hebben. Dit klinkt zo interessant om een gebruiker te vinden die gelijksoortige sympathieën en antipathieën heeft. Maar de vraag is hoe vinden we de gelijkenis?
Om dit te beantwoorden, zullen we Cosine Gelijkenis gebruiken en zien hoe gelijk de gebruikers zijn. Deze wordt gewoonlijk berekend over de beoordelingen die beide gebruikers in het verleden hebben gegeven.
In ons voorbeeld heb ik de cosine_similarity-functie van sklearn gebruikt om de gelijkenis te berekenen. Maar daarvoor moeten we eerst wat voorbewerken en de gegevens opschonen.
from sklearn.metrics.pairwise import cosine_similarityfinal=pd.pivot_table(Rating_avg,values='adg_rating',index='userId',columns='movieId')
Dit bevat een aantal veel NaN-waarden omdat niet elke gebruiker alle films heeft gezien en daarom wordt dit type matrix sparse matrix genoemd. Methoden zoals matrix factorisatie worden gebruikt om met deze karigheid om te gaan, maar daar zullen we ons in deze blog niet op richten. De volgende stap en een van de belangrijkste stappen is het vervangen van deze NaN waarden.
Er zijn twee methoden die hier vaak voor worden gebruikt :
- Gebruik het gebruikersgemiddelde over de rij.
- Gebruik het filmgemiddelde over de kolom.
Ik heb beide methoden gebruikt en je kunt het in de onderstaande code vinden. Maar voor de uitleg zou ik de methode van het filmgemiddelde gebruiken.
# Replacing NaN by Movie Average
final_movie = final.fillna(final.mean(axis=0))
Nu is de volgende stap het berekenen van de gelijkenis tussen de gebruikers.
# 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()
Laten we eens kijken of wat we berekend hebben ook echt zin heeft !
a = get_user_similar_movies(370,86309)
a = a.loc]
a.head()
Van bovenstaande afbeelding kunnen we zien dat de overeenkomst die we hebben gegenereerd waar is aangezien beide gebruikers (370,86309) bijna dezelfde beoordelingen en likings hebben.
Dus we zijn klaar met het berekenen van de overeenkomsten tussen de gebruikers, maar ik ben nog niet tevreden. Ik zou de reden hiervoor in de volgende stap bespreken.
Neighborhood for User (K)
Zo uit het bovenstaande kunnen we zien dat we de overeenkomsten voor alle gebruikers hebben berekend. Maar sinds ik een Big Data student ben, drijft de complexiteit van het probleem me altijd. Hiermee bedoel ik dat het aanbevelingssysteem werkt met de enorme gegevens en dus wordt het erg belangrijk om alleen de belangrijke en noodzakelijke hoogtepunten uit de gegevens te behouden en vast te leggen.
Om dit uit te leggen met behulp van ons voorbeeld van filmaanbevelingssysteem, de matrix die we hierboven hebben verkregen is (862*862), omdat er 862 unieke gebruikers in de gegevens zijn. Dit aantal is nog steeds klein in vergelijking met de gegevens waar het originele systeem mee zou werken. Laten we eens denken aan Amazon. Het zou meer dan miljoenen gebruikers in zijn database hebben en dus zou het bij het berekenen van de score voor een item geen goede oplossing of methode zijn om de hele tijd naar alle andere gebruikers te kijken. Om dit te ondervangen genereren we een notie van buurt. Dit omvat alleen de set van (K) vergelijkbare gebruikers voor een bepaalde gebruiker.
Nu laten we verdere stappen nemen om het idee uit te voeren. In ons voorbeeld heb ik de waarde van k als 30 genomen. Dus we zouden 30 naaste buren hebben voor alle gebruikers.
Ik heb mijn aangepaste functie find_n_neighbours gebruikt, die de gelijkenismatrix en de waarde van n als invoer neemt en de dichtstbijzijnde n-buren voor alle gebruikers retourneert. U kunt de code vinden in de notebook aan het einde van de blog.
# top 30 neighbours for each user
sim_user_30_m = find_n_neighbours(similarity_with_movie,30)
sim_user_30_m.head()
Dus als u nu denkt dan hebben we het aantal onnodige berekeningen serieus verminderd. Nu zijn we klaar om de score voor een item te berekenen.
Het genereren van de eindscore S(u,i)
Wow! We zijn klaar met het proces. Ik weet dat we door een aantal echte technische dingen zijn gegaan, maar de tijd die we hebben besteed is de moeite waard omdat we de laatste stap hebben bereikt.
Hier zullen we proberen de score te voorspellen voor de film die de gegeven gebruiker niet heeft gezien.
score = User_item_score(320,7371)
print(score)
Dus ons systeem voorspelde dat de score 4,25 zou zijn, wat erg goed is. Ik denk dat gebruiker (370) de film leuk zou kunnen vinden met id (7371).
Nu nog een finishing touch geven aan ons systeem. Ik denk dat de meesten van ons zou hebben gebruikt Netflix of Hotstar. Dus wanneer we de app openen het toont het item dat u maakt like.
Ik altijd gefascineerd door de aanbeveling als ze blijken te zijn de films die ik leuk vind. Dit gebeurt allemaal door het aanbevelingssysteem zelf. We gaan nu hetzelfde doen en proberen de top 5 films te voorspellen die de gegeven gebruiker leuk zou kunnen vinden.
De logica is niet zo moeilijk. We hebben de score voor één item al gegenereerd. Op dezelfde manier kunnen we de score voor de andere items met dezelfde gebruiker genereren.
Maar, nu opnieuw rekening houdend met Big Data, heeft het zin om de score voor alle andere items te genereren?
Ik denk NOOOOOOOOOOOOOOOOOO!!!
Laten we eens kijken naar gebruiker (U) en gebruiker (K). Stel nu dat K niet in de buurt van U is, is het dan mogelijk voor gebruiker U om een film leuk te vinden die K heeft gezien en beoordeeld. Meestal niet.
Ik denk dat je de truc doorhebt. Ja, we zijn gewoon geïnteresseerd in het berekenen van de scores voor de items die hun buurman gebruikers hebben gezien.
We zijn echt succesvol. We hebben de berekening teruggebracht van 2500 naar N (waarbij N de reeks films is die mijn buurt leuk vond) en dat is heel wat minder dan 2500.
Dus laten we eindelijk de films aanbevelen.
User_item_score1 is mijn aangepaste functie die gebruik maakt van onze bovenstaande discussie om voorspellingen te berekenen
user = int(input("Enter the user id to whom you want to recommend : "))
predicted_movies = User_item_score1(user)
print(" ")
print("The Recommendations for User Id : ",user)
print(" ")
for i in predicted_movies:
print(i)
Eindelijk!!!! Het is ons gelukt. We hebben ons eigen aanbevelingssysteem.
De weergave van de code hieronder is misschien niet erg gemakkelijk te lezen, dus ga naar mijn GitHub-repository om toegang te krijgen tot de code.
De benodigde Datasets kunnen hier worden verkregen.
Ik hoop dat je de blog leuk vond. Voor eventuele vragen kunt u mij mailen. Blijf op de hoogte voor meer blogs, want dit is een van mijn interessegebieden en ik zou zeker posten wat nieuwe stuff.
Dank je wel..!!