<jupyter_start><jupyter_text>Model creation<jupyter_code>import tensorflow as tf
n_latent_factor_user = 8
n_latent_factor_moive = 10
n_latent_factor_mf = 3
n_users, n_movies = len(dataset.userId.unique()), len(dataset.movieId.unique())
dataset.movieId.unique()
# movie_feature_column  = tf.feature_column.categorical_column_with_vocabulary_list(key='terms', vocabulary_list=dataset.movieId.unique())
from tensorflow import keras
movie_input = keras.layers.Input(shape = [1], name = 'Movie')
movie_embedding_mlp = keras.layers.Embedding(n_movies +1 , n_latent_factor_moive, name = 'Movie_embedding_MLP')(movie_input)
movie_vec_mlp = keras.layers.Flatten(name = 'FlattenMovies_MLP')(movie_embedding_mlp)
movie_vec_mlp = keras.layers.Dropout(0.2)(movie_vec_mlp)

movie_embedding_mf = keras.layers.Embedding(n_movies+1 , n_latent_factor_mf, name = 'Movie_embedding_MF')(movie_input)
movie_vec_mf = keras.layers.Flatten(name='FlattenMovies_MF')(movie_embedding_mf)
movie_vec_mf = keras.layers.Dropout(0.2)(movie_vec_mf)

user_input = keras.layers.Input(shape=[1],name='User')
user_embedding_mlp = keras.layers.Embedding(n_users +1 , n_latent_factor_user, name = 'Users_embedding_MLP')(user_input)
user_vec_mlp = keras.layers.Flatten(name = 'FlattenUser_MLP')(user_embedding_mlp)
user_vec_mlp = keras.layers.Dropout(0.2)(user_vec_mlp)

user_embedding_mf = keras.layers.Embedding(n_users +1 , n_latent_factor_mf, name = 'Users_embedding_MF')(user_input)
user_vec_mf = keras.layers.Flatten(name = 'FlattenUser_MF')(user_embedding_mf)
user_vec_mf = keras.layers.Dropout(0.2)(user_vec_mf)
(movie_embedding_mf, movie_embedding_mlp, user_embedding_mf, user_embedding_mlp)
concat = keras.layers.concatenate([movie_vec_mlp, user_vec_mlp])
concat_dropout = keras.layers.Dropout(0.2)(concat)
dense_1 = keras.layers.Dense(200, name ='FullyConnected_1')(concat_dropout)
dense_batch_1 = keras.layers.BatchNormalization(name='Batch')(dense_1)
dropout_1 = keras.layers.Dropout(0.2, name ='Dropout_1')(dense_batch_1)
dense_2 = keras.layers.Dense(100, name = 'FullyConnected_2')(dropout_1)
dense_batch_2 = keras.layers.BatchNormalization(name = 'Batch_2')(dense_2)

dropout_2 = keras.layers.Dropout(0.2, name='Dropout_2')(dense_batch_2)
dense_3 = keras.layers.Dense(50, name = 'FullyConnected_3')(dropout_2)
dense_4 = keras.layers.Dense(20, name = 'FullyConnected_4', activation='relu')(dense_3)
(movie_vec_mlp.shape , user_vec_mlp.shape)
concat.shape
(user_vec_mf.shape, movie_vec_mf.shape)
movie_vec_mf
user_vec_mf
# movie_vec_mf = keras.backend.transpose(movie_vec_mf) # movie_vec_mf shape=(?, 3) to (3,?)
movie_vec_mf
pred_mf = keras.layers.multiply([movie_vec_mf, user_vec_mf], name = 'Elemet_wise_product')
pred_mlp = keras.layers.Dense(1, activation='relu', name = 'Activation_pred')(dense_4)
(pred_mf, pred_mlp)
combine_mlp_mf = keras.layers.concatenate([pred_mf,pred_mlp],name = 'Concat_MF_MLP')
result_combine = keras.layers.Dense(100, name='Combine_MF_MLP')(combine_mlp_mf)

deep_combine = keras.layers.Dense(100, name = 'FullyConnected_5')(result_combine)
result = keras.layers.Dense(1, name='Prediction')(deep_combine)

model = keras.Model([user_input, movie_input], result)
opt = keras.optimizers.Adam(lr = 0.01)
model.compile(optimizer = 'adam', loss = 'mean_absolute_error',metrics=['mae'])
from IPython.display import SVG
# from tensorflow.keras.utils import plot_model
# SVG(plot_model(model, show_shapes=False,to_file='test_model', show_layer_names=True, rankdir='TB')) 
# SVG(plot_model(model, show_shapes=False, show_layer_names=True, rankdir='TB').create(prog='dot',format='svg'))
model.summary()
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
# cv = KFold(n_splits=10, shuffle=True, random_state=0)
# cross_val_score(model, 
#                 dataset.userId, dataset.movieId, scoring="neg_mean_absolute_error", cv=cv)

from sklearn.model_selection import train_test_split

train, test = train_test_split(dataset, test_size=0.2)
early_stopping = keras.callbacks.EarlyStopping(monitor='val_loss', min_delta = 0.0001, patience=7, verbose=1, mode='min') 
### 0.00001 이상의 변화가 없을 때 10회만큼 epoch 더 부여 후 중지
model_epoch_train = model.fit([train.userId, train.movieId], train.rating, epochs=100, verbose=1, 
                           validation_split=0.1, callbacks = [early_stopping])
from sklearn.metrics import mean_absolute_error

y_predict = np.round(model.predict([test.userId, test.movieId]), 0)
print(mean_absolute_error(test.rating, y_predict))
print(mean_absolute_error(test.rating,model.predict([test.userId, test.movieId])))
import h5py
# h5py.run_tests()
keras.models.save_model(model=model_epoch_train, filepath='./data/model/neural_MF_1_테스팅')
# tf.keras.models.save_model(model=model, filepath='./data/model/neural_MF_1_big_file.h5')
model = keras.models.load_model('./data/model/neural_MF_1.h5',)
model
# y_predict_big = np.round(model.predict([dataset.userId,dataset.movieId]), 0)

# print(mean_absolute_error(dataset.rating, y_predict_big))
# print(mean_absolute_error(dataset.rating, model.predict([dataset.userId,dataset.movieId])))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13322914631764016, 'fraction_numerical': 0.020707169369017387, 'mean_word_length': 8.24187725631769, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '23939', 'license': 'MIT', 'n_tokens_mistral': 2074, 'n_tokens_neox': 2002, 'n_words': 259, 'path': 'movie_case/Neural_Matrix_Factorization.ipynb', 'repo_name': 'JeongChanwoo/Recommend', 'size': '5119'}