<jupyter_start><jupyter_text>Installieren aller Pakete<jupyter_code># Hier die Kaggle Credentials einfügen (ohne Anführungszeichen)

%env KAGGLE_USERNAME=openhpi
%env KAGGLE_KEY=das_ist_der_key
import numpy as np
import pandas as pd

from sklearn.metrics import mean_squared_error
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import TfidfVectorizer

from keras.layers import Input, Embedding, Reshape, Dot, Concatenate, Dense, Dropout
from keras.models import Model

from sklearn.decomposition import NMF

import tensorflow as tf
import os

tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'<jupyter_output><empty_output><jupyter_text>Methodendefinitionen<jupyter_code># Credits: https://www.kaggle.com/morrisb/how-to-recommend-anything-deep-recommender

def mf_model(df, train, test,  emb_size=20):
    # Create user- & movie-id mapping
    user_id_mapping = {id:i for i, id in enumerate(df['userId'].unique())}
    movie_id_mapping = {id:i for i, id in enumerate(df['movieId'].unique())}
    
    
    # Create correctly mapped train- & testset
    train_user_data = train['userId'].map(user_id_mapping)
    train_movie_data = train['movieId'].map(movie_id_mapping)
    
    test_user_data = test['userId'].map(user_id_mapping)
    test_movie_data = test['movieId'].map(movie_id_mapping)
    
    
    # Get input variable-sizes
    users = len(user_id_mapping)
    movies = len(movie_id_mapping)
    embedding_size = emb_size
    
    
    ##### Create model
    # Set input layers
    user_id_input = Input(shape=[1], name='user')
    movie_id_input = Input(shape=[1], name='movie')
    
    # Create embedding layers for users and movies
    user_embedding = Embedding(output_dim=embedding_size, 
                               input_dim=users,
                               input_length=1, 
                               name='user_embedding')(user_id_input)
    movie_embedding = Embedding(output_dim=embedding_size, 
                                input_dim=movies,
                                input_length=1, 
                                name='item_embedding')(movie_id_input)
    
    # Reshape the embedding layers
    user_vector = Reshape([embedding_size])(user_embedding)
    movie_vector = Reshape([embedding_size])(movie_embedding)
    
    # Compute dot-product of reshaped embedding layers as prediction
    y = Dot(1, normalize=False)([user_vector, movie_vector])
    
    # Setup model
    model = Model(inputs=[user_id_input, movie_id_input], outputs=y)
    model.compile(loss='mse', optimizer='adam')
    return train_user_data, train_movie_data, test_user_data, test_movie_data, model<jupyter_output><empty_output><jupyter_text>2.6 Recommender Systems 2:  Vorschlagssystem mit Collaborative Filtering Datensatz:  The Movies DatasetMetadaten für über 45.000 Filme. 26 Millionen Bewertungen von über 270.000 NutzerInnen.Quelle: kaggle.com  Was wir erreichen wollenIn der Theorie-Einheit haben wir die Methodik des Collaborative Filtering vorgestellt. Diese Methode nutzt Ähnlichkeiten in der Interkation zwischen NutzerInnen und den Filmen, um Filme vorzuschlagen. Beim Collaborative Filtering werden Vorschläge gegeben, wie eine Nutzerin oder ein Nutzer einen Film bewerten würde, der noch nicht gesehen wurde. Dann würde man der Person einen Film mit einer hohen vorhergesagten Bewertung vorschlagen.    Einlesen der Daten<jupyter_code>!pip3 install kaggle
!kaggle datasets download -d rounakbanik/the-movies-dataset
import zipfile
with zipfile.ZipFile("the-movies-dataset.zip", 'r') as zip_ref:
    zip_ref.extractall("")
df_film_ratings = pd.read_csv("ratings_small.csv", low_memory=False)<jupyter_output><empty_output><jupyter_text>Sehen wir uns erneut einmal ein paar Einträge aus dem Datensatz an. Hierbei fällt auf, dass wir die Spalte "Timestamp" für unseren Anwendungsfall nicht brauchen und daher verwerfen können. Wir sollten zudem noch die Bewertungen "mischen".<jupyter_code>df_film_ratings.head()
df_film_ratings = df_film_ratings.drop("timestamp", axis=1) # Entfernen der Spalte Timestamp
df_film_ratings = df_film_ratings.sample(frac=1).reset_index(drop=True) # Durchmischen der Bewertungen<jupyter_output><empty_output><jupyter_text>Wie möglicherweise direkt beim Import aufgefallen ist, importieren wir hier nur die kleine Version des Datensatzes. Für die gesamte Größe des Datensatzes ist jedoch die Trainingszeit deutlich höher, weswegen wir zunächst darauf verzichten. Wer das gesamte File einlesen will, bitte "ratings.csv" statt "ratings_small.csv" verwenden.   Train Test Split  Beim Collaborative Filtering wollen wir die Güte unserer Vorhersage prüfen. Im Gegensatz zum vorgestellten Content-based Filtering haben wir hier "Labels", da wir die Bewertungen einzelner NutzerInnen für die einzelnen Filme haben. Somit können wir einen Teil im Training dem Modell vorenthalten und darauf die Güte unseres Modells bewerten. Im Folgenden Code-Abschnitt teilen wir den Datensatz in 80% Trainingsdaten und 20% Testdaten.<jupyter_code>split_factor = 0.2
n = int(split_factor*len(df_film_ratings))

df_train = df_film_ratings[:-n]
df_test = df_film_ratings[-n:]<jupyter_output><empty_output><jupyter_text>Matrix Faktorisierung - ein BeispielIn Einheit 2.2 Einführung Recommender Systems haben wir kurz die Methode Matrix Faktorisierung vorgestellt. Hier wollen wir zunächst mal ein einfaches Beispiel geben.<jupyter_code>X = np.array([[1, 1, 5], [2, 1, 3], [3, 1.2, 8.7], [4, 1, 3], [5, 0.8, 9], [6, 1, 1.5]])
X
model = NMF(n_components=2, init='random', random_state=0, verbose=False)
W = model.fit_transform(X)
H = model.components_
print(np.subtract(X, np.dot(W,H)))<jupyter_output><empty_output><jupyter_text>Root Mean Squared ErrorDer Root Mean Squared Error (RMSE) ist ein Standardverfahren zur Messung des Fehlers eines Modells bei der Vorhersage quantitativer Daten. Formal ist er wie folgt definiert:$$ RMSE = \sqrt{ \sum_{i=1}^{n} \frac{\left ( \hat{y}_{i} - y_{i}\right )^2}{n}} $$In natürlicher Sprache ist der RMSE die Wurzel aus dem MSE (Mean Squared Error). Der Mean Squared Error beschreibt den Durchschnitt der quadrierten Abweichungen (Prediction vs. realer Wert). Nun werden wir auch einmal den RMSE für unser aktuelles Beispiel berechnen:<jupyter_code>rmse = np.sqrt(mean_squared_error(y_pred=X, y_true=np.dot(W,H)))
print("RMSE: " + str(rmse))<jupyter_output><empty_output><jupyter_text>Matrix Faktorisierung - Film Vorschlagssystem Oben haben wir die Matrix Faktorisierung anhang eines Beispiels gezeigt. Nun wollen wir die Methode auf unseren Datensatz anwenden. Hierzu nutzen wir eine [existierende Methode](https://www.kaggle.com/morrisb/how-to-recommend-anything-deep-recommender), welche wir einfach aufrufen können. Zunächst müssen wir das Modell einmal definieren.<jupyter_code>train_user_data, train_movie_data, test_user_data, test_movie_data, model = mf_model(df_film_ratings, df_train, df_test)<jupyter_output><empty_output><jupyter_text>Nachdem wir das Modell nun definiert haben, trainieren wir das Modell. Für das Training müssen wir noch einige "Stellschrauben" oder Hyperparameter setzen. So zum Beispiel die Epochen (Anzahl der Durchläufe über den gesamten Datensatz) oder die Batch-Size (Anzahl der Elemente, die trainiert werden, bevor die internen Parameter automatisch angepasst werden).<jupyter_code>model.fit([train_user_data, train_movie_data],
          df_train['rating'],
          batch_size=256, 
          epochs=10,
          shuffle=True)<jupyter_output><empty_output><jupyter_text>Nun werden wir unser Modell noch testen auf den Test-Daten. Diesen Teil der Daten hat das Modell bisher noch nicht gesehen.<jupyter_code># Test model
y_pred = model.predict([test_user_data, test_movie_data])
y_true = df_test['rating'].values

#  Berechne Root Mean Squared Error
rmse = np.sqrt(mean_squared_error(y_pred=y_pred, y_true=y_true))
print('RMSE: '+ str(rmse))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08478396994364433, 'fraction_numerical': 0.008515967438948028, 'mean_word_length': 5.0180859080633, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '282303', 'license': 'MIT', 'n_tokens_mistral': 2771, 'n_tokens_neox': 2710, 'n_words': 710, 'path': 'Woche 2/2_6_Recommender_Systems_2.ipynb', 'repo_name': 'sting-aree/openhpi-kipraxis', 'size': '7985'}