سیستمهای توصیهگر (Recommender Systems) با تحلیل رفتار کاربر، اقدام به پیشنهاد مناسبترین اقلام (داده، اطلاعات، کالا و…) میکنه. این سیستم کمک زیادی به مشکلات سیستمهای دارای حجم زیاد اطلاعات میکنه و به کاربرش کمک میکنه تا در بین حجم زیاد اطلاعات سریعتر به هدفش نزدیک بشه.
مقدمه:
فرض کنید یک سایت شبیه GoodReads داریم که کاربران میتونند در مورد کتاب های مختلف در سایت نظرشونو بنویسند. ما اطلاعاتی در مورد اینکه هر کاربر به چه کتابی چه امتیازی داده داریم، فرض کنید کاربر الف به کتاب های a , b , c رای بالا داده، و ما میخوایم پیشبینی کنیم این کاربر به کتاب d احتمالا چه امتیازی میده، برای اینکار با تحلیل دادههای بقیه کاربرهایی که امتیازشون به a, b , c شبیه کاربر الف بوده میشه فهمید احتمالا کاربر الف به کتاب d چه امتیازی میده.
به یک مثال دیگه توجه کنید:
فرض کنید این اطلاعات یک سایت پیشنهاد فیلمه و این جدول رای هر کاربر به هر فیلمو نشون میده. همونطوری که میبینید بعضی از خانه های جدول خالیه و هدف حدس زدن خانه های خالی جدوله. برای اینکار ابتدا برای مثال ۵ ویژگی برای هر فیلم در نظر میگیریم، مثلا تخیلی بودن ، درام بودن ، علمی بودن و… ، و ۵ ویژگی هم برای کاربر مثلا دوست داشتن فیلم تخیلی، دوست داشتن فیلم درام و…
حالا به صورت تصادفی به هر کدام از این ویژگی ها یک عدد نسبت میدیم:
حالا حاصل ضرب نقطهای تمام عدد ویژگی های یک کاربر و یک فیلم به ما یک عدد میده که توی خونه مربوط به همون کاربر و فیلم مینویسم. برای خانههای خالی هم فعلا عدد -۰- میذاریم(تا وقتی که وزنها به صورت درستی در بیاد -از تصادفی بودن در بیاد- ).
خب همونطوری که میبینید اعدادی که بدست اومده با اعداد واقعی رای هر کاربر بسیار تفاوت داره. حالا ما بر اساس دیتای درستی که داریم و بدست آوردن اختلافش با اعدادی که حدس زده شده ۵ ویژگی که اعدادش به صورت تصادفی تولید شده بود را بهبود میدیم(در این مثال بسیار ساده با استفاده از افزونه solver نرمافزار اکسل اینکار انجام شده) :
خب همونطوری که مشاهده میکنید بعد از آپدیت شدن وزنهای ویژگیها اعداد پیشبینی خیلی به اعدادی که واقعا هر کاربر رای داده بود نزدیک شد.
حالا همین اگر روش با کتابخانه Keras پیادهسازی بشه بر روی دیتاهای بزرگ و واقعیتر قابل استفاده است و دقت بسیار بالایی هم داره.
___________________________________________________________________
پیاده سازی یک سیستم توصیهگر کتاب با استفاده از Keras
با تشکر از Tanner Gilbert و برگرفته از گیت
برای پیادهسازی این سیستم ابتدا دیتاست استفاده شده که از وبسایت Kaggle گرفته شده دانلود کنید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
from IPython.display import SVG import numpy as np import pandas as pd import matplotlib.pyplot as plt import os import warnings warnings.filterwarnings('ignore') %matplotlib inline from keras.layers import Input, Embedding, Flatten, Dot, Dense from keras.models import Model from keras.utils.vis_utils import model_to_dot |
1 2 3 4 5 6 7 |
dataset = pd.read_csv('ratings.csv') from sklearn.model_selection import train_test_split train, test = train_test_split(dataset, test_size=0.2, random_state=42) n_users = len(dataset.user_id.unique()) n_books = len(dataset.book_id.unique()) |
با دستور dataset.head() میتونید تعدادی از دادهها را مشاهده کنید.
ساخت مدل
مدلی که خواهیم داشت از اجزای اصلی زیر تشکیل میشه:
- Input: Input for both books and users
- Embedding Layers: Embeddings for books and users
- Dot: combines embeddings using a dot product
در یک embedding مدل ، embeddings ها وزنهایی هستند که در طول training یادگرفته میشوند. برای ساده شدن کار هیچ لایه fully-connected در آخر اضافه نشده اگرچه اینکار احتمالا دقت مدلو بالا میبره.
کدهای برای ساخت مدل :
1 2 3 4 5 6 7 8 9 10 11 |
book_input = Input(shape=[1], name="Book-Input") book_embedding = Embedding(n_books, 5, name="Book-Embedding")(book_input) book_vec = Flatten(name="Flatten-Books")(book_embedding) user_input = Input(shape=[1], name="User-Input") user_embedding = Embedding(n_users, 5, name="User-Embedding")(user_input) user_vec = Flatten(name="Flatten-Users")(user_embedding) prod = Dot(name="Dot-Product", axes=1)([book_vec, user_vec]) model = Model([user_input, book_input], prod) model.compile('adam', 'mean_squared_error') |
مرحله train
حالا ما برای train کردن مدل آمادهایم.
اول یه شرط میذاریم که اگر قبلا مدل train و ذخیره شده بود نیاز به train نیست همون مدل قبلی load بشه.
در غیراینصورت مدل train میشه.
1 2 3 4 5 6 7 8 9 10 |
from keras.models import load_model if os.path.exists('regression_model.h5'): model = load_model('regression_model.h5') else: history = model.fit([train.user_id, train.book_id], train.rating, epochs=10, verbose=1) model.save('regression_model.h5') plt.plot(history.history['loss']) plt.xlabel("Epochs") plt.ylabel("Training Error") |
برای ارزیابی مدل:
1 |
model.evaluate([test.user_id, test.book_id], test.rating) |
تست کردن پیشبینی مدل :
1 2 3 |
predictions = model.predict([test.user_id.head(10), test.book_id.head(10)]) [print(predictions[i], test.rating.iloc[i]) for i in range(0,10)] |
که همچین خروجی مشاهده میکنید(مثلا اولین مورد کاربر ۵ رای داده و سیستم ۴.۹۲ پیشبینی کرده) :
مصور کردن embedding ها
برای اینکه بتونیم این مفاهیم را مصور کنیم چون چشم ما قادر به درک بیش از ۳بعد نیست باید با استفاده از یک سری روش های کاهش دیمانسیون مثل PCA یا t-SNE پیش پردازش اینکار را انجام بدیم.
اول یه لایه را میگیریم ( لایه -embedding- رو در book_em میگیره و وزنهاش در book_em_weights):
1 2 3 |
# Extract embeddings book_em = model.get_layer('Book-Embedding') book_em_weights = book_em.get_weights()[0] |
برای کاهش دیمانسیون از PCA استفاده میکنیم:
1 2 3 4 5 6 |
from sklearn.decomposition import PCA import seaborn as sns pca = PCA(n_components=2) pca_result = pca.fit_transform(book_em_weights) sns.scatterplot(x=pca_result[:,0], y=pca_result[:,1]) |
نتیجه به صورت شکل زیر نمایش داده میشود
همینکار با روش TSNE نیز قابل انجامه:
1 2 3 4 |
from sklearn.manifold import TSNE tsne = TSNE(n_components=2, verbose=1, perplexity=40, n_iter=300) tnse_results = tsne.fit_transform(book_em_weights) |
مرحله هیجان انگیز: توصیه سیستم به کاربر!
برای استفاده از سیستم کافیه یک کاربر انتخاب کنیم تا کتابهایی که بیشترین احتمال اینکه کاربر دوستشون داشته باشه رو نشون بده، برای اینکار:
1 2 3 4 5 6 7 8 9 10 11 |
# Creating dataset for making recommendations for the first user book_data = np.array(list(set(dataset.book_id))) user = np.array([1 for i in range(len(book_data))]) predictions = model.predict([user, book_data]) predictions = np.array([a[0] for a in predictions]) recommended_book_ids = (-predictions).argsort()[:5] print(recommended_book_ids) print(predictions[recommended_book_ids]) |
که خروجی این کد به صورت :
که آرایه اول نشاندهنده آیدی کتاب ها و آرایه دوم نشاندهنده میزان علاقه کاربر به کتاب هست. که از این طریق میشه مثلا ۳ کتابی که احتمال خریدش توسط کاربر بالاهست به کاربر پیشنهاد داده بشه.
با آیدی کتابهای بدست اومده میشه اطلاعات کامل هر کتاب را هم بدست آورد. با کد زیر:
1 2 |
books = pd.read_csv(‘books.csv’) books.head() |
ابتدا کل کتابهای دیتاست را در متغییر books میریزیم و سپس head آن را چاپ میکنیم. نتیجه:
برای مشاهده کتاب های توصیه شده به کاربر کد زیر را اجرا کنید
1 |
print(books[books[‘id’].isin(recommended_book_ids)]) |
نتیجه:
البته این آموزش هرگز یک آموزش کامل و بهینه در این زمینه نبوده و فقط مثال ساده و نقطه شروعی برای یادگیری بوده است.
برای بهبود عملکرد این آموزش کارهای زیادی از جمله :
اضافه کردن لایه fully-connected
افزایش ایپاک های train
و… میشه انجام داد.
شبکه های اجتماعی