요즘 카글 추천시스템 노트북들을 보며 코드를 깔끔하게 짜는 법과 어떤 아이디어를 이용했는지에 대해 배우고 있다.
오늘은 아마존 리뷰 데이터를 이용한 추천시스템 코드에 대해 알아보겠다.
참고 : www.kaggle.com/saurav9786/recommender-system-using-amazon-reviews
추천시스템은 사용자에게 최적의 아이템을 제안하는 시스템이다.
추천시스템이 풀 수 있는 문제로는 다음과 같다.
1. 유저가 자신에게 아이템을 찾도록 돕는다.
2. 유저의 개입을 증가시킬 수 있다. 예를 들면, 구글 뉴스의 40퍼센트의 클릭 수 증가는 추천시스템으로 인해 발생하였다.
3. 판매자가 아이템들을 올바른 유저에게 제공하도록 한다.
4. 컨텐츠가 더 개인화되도록 한다.
추천시스템 유형은 다음과 같다.
- Popularity based systems :- 가장 많이 구입되거나 높게 평가된 아이템들을 추천한다. 개인화된 추천이 아니다.
- Classification model based:- 사용자의 특성을 이해하고 분류 알고리즘을 사용하여 사용자가 특정 상품에 관심이 있는지 없는지를 결정하여 추천한다.
- Content based recommedations:- 유저의 의견보다는 아이템 콘텐츠 정보에 기반하여 추천한다. 사용자가 아이템을 좋아하면 이와 비슷한 다른 아이템도 좋아할 거라는 의견에 기반한다.
-
Collaberative Filtering:- 유저가 좋아하는 아이템과 비슷한 아이템을 좋아하고 비슷한 취향을 가진 다른사람과 비슷한 아이템을 좋아한다는 아이디어로 추천한다. 유저-유저 추천과 아이템-아이템 추천이 있다.
-
Hybrid Approaches:- Collaborative Filtering과 content-based filtering 등을 합친 방식이다. 각 방식의 단점을 커버한다.
- Association rule mining :- 거래의 동시 다발성 패턴을 이용하여 아이템들간의 관계를 파악한다.
데이터에 대한 대략적인 설명은 다음과 같다.
- userId : 각 유저의 고유한 아이디
- productId : 각 상품의 고유한 아이디
- Rating : 각 유저가 각 상품에 대해 평가한 평점
- timestamp : 평가 시간 (본 알고리즘에서는 무시함)
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import os
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
import math
import json
import time
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.model_selection import train_test_split
from sklearn.neighbors import NearestNeighbors
# from sklearn.externals import joblib
import scipy.sparse
from scipy.sparse import csr_matrix
from scipy.sparse.linalg import svds
import warnings; warnings.simplefilter('ignore')
%matplotlib inline
for dirname, _, filenames in os.walk('/kaggle/input'):
for filename in filenames:
print(os.path.join(dirname, filename))
electronics_data = pd.read_csv("ratings_Electronics (1).csv",names=['userId', 'productId','Rating','timestamp'])
electronics_data.head()
electronics_data.shape
eletronics_data = electronics_data.iloc[:1048576,0:]
eletronics_data.dtypes
eletronics_data.describe()['Rating'].T
print("max of rating : %d" %(eletronics_data.Rating.max()))
print("min of rating : %d" %(eletronics_data.Rating.min()))
Missing values 수¶
print('Number of missing values across columns: \n',electronics_data.isnull().sum())
Ratings¶
with sns.axes_style('white'):
g = sns.factorplot("Rating", data = eletronics_data, aspect = 2.0, kind = 'count')
g.set_ylabels("Total number of ratings")
print("Total data")
print("-"*50)
print("\nTotal num of ratings :", eletronics_data.shape[0])
print("Total num of Users :", len(np.unique(eletronics_data.userId)))
print("Total num of products: ", len(np.unique(eletronics_data.productId)))
eletronics_data.drop(['timestamp'],axis = 1, inplace = True)
eletronics_data.head()
Ratings 분석¶
num_of_rated_products_per_user = eletronics_data.groupby(by = 'userId')['Rating'].count().sort_values(ascending=False)
num_of_rated_products_per_user.head()
num_of_rated_products_per_user.describe()
quantiles = num_of_rated_products_per_user.quantile(np.arange(0,1.01,0.01), interpolation='higher')
quantiles
plt.figure(figsize=(10,10))
plt.title("Quantiles and their Values")
quantiles.plot()
# quantiles with 0.05 difference
plt.scatter(x=quantiles.index[::5], y=quantiles.values[::5], c='orange', label="quantiles with 0.05 intervals")
# quantiles with 0.25 difference
plt.scatter(x=quantiles.index[::25], y=quantiles.values[::25], c='m', label = "quantiles with 0.25 intervals")
plt.ylabel('No of ratings by user')
plt.xlabel('Value at the quantile')
plt.legend(loc='best')
plt.show()
print('\n No of rated product more than 50 per user : {}\n'.format(sum(num_of_rated_products_per_user >= 50)) )
Popularity Based Recommendation¶
평가가 50번이상 된 상품들을 가져옴
new_df=electronics_data.groupby("productId").filter(lambda x:x['Rating'].count() >=50)
new_df.head()
new_df.shape
num_of_ratings_per_product = new_df.groupby(by='productId')['Rating'].count().sort_values(ascending=False)
fig = plt.figure(figsize=plt.figaspect(.5))
ax = plt.gca()
plt.plot(num_of_ratings_per_product.values)
plt.title('# RATINGS per Product')
plt.xlabel('Product')
plt.ylabel('No of ratings per product')
ax.set_xticklabels([])
plt.show()
평가들을 상품 아이디로 묶고 평점의 평균을 냄
new_df.groupby('productId')['Rating'].mean().head()
new_df.groupby('productId')['Rating'].mean().sort_values(ascending=False).head()
평가된 수를 기준으로 내림차순 정렬
new_df.groupby('productId')['Rating'].count().sort_values(ascending=False).head()
ratings_mean_count = pd.DataFrame(new_df.groupby('productId')['Rating'].mean())
ratings_mean_count.head()
ratings_mean_count['rating_counts'] = pd.DataFrame(new_df.groupby('productId')['Rating'].count())
ratings_mean_count.head()
ratings_mean_count['rating_counts'].max()
plt.figure(figsize=(6,6))
plt.rcParams['patch.force_edgecolor']=True
ratings_mean_count['rating_counts'].hist(bins=50)
plt.figure(figsize=(8,6))
plt.rcParams['patch.force_edgecolor']=True
ratings_mean_count['Rating'].hist(bins=50)
plt.figure(figsize=(8,6))
plt.rcParams['patch.force_edgecolor'] = True
sns.jointplot(x='Rating', y='rating_counts', data=ratings_mean_count, alpha=0.4)
popular_products = pd.DataFrame(new_df.groupby('productId')['Rating'].count())
most_popular = popular_products.sort_values("Rating", ascending=False)
most_popular.head(30).plot(kind = "bar")
Collaborative Filtering 이용¶
# Surprise 패키지를 이용하기 위해 설치
!pip3 install surprise
from surprise import KNNWithMeans
from surprise import Dataset
from surprise import accuracy
from surprise import Reader
import os
from surprise.model_selection import train_test_split
1) Data 가져오기¶
new_df.drop(['timestamp'],axis = 1, inplace = True)
reader = Reader(rating_scale=(1,5))
data = Dataset.load_from_df(new_df,reader)
2) Trainset, Testset으로 나누기¶
trainset, testset = train_test_split(data, test_size = 0.3, random_state=10)
3) KNN을 이용 trainset에 파라미터 맞추기¶
algo = KNNWithMeans(k=5, sim_options = {'name': 'pearson_baseline', 'user_based':False})
algo.fit(trainset)
4) Test accuracy 측정¶
test_pred = algo.test(testset)
print("Item-based Model : Test Set")
accuracy.rmse(test_pred, verbose=True)
Model-based collaborative filtering system¶
# 대량의 상품, 많은 사용자들에게 추천 가능, sparse한 matrices에도 사용가능
new_df1 = new_df.head(10000)
ratings_matrix = new_df1.pivot_table(values ='Rating', index ='userId', columns ='productId',fill_value =0)
ratings_matrix.head()
ratings_matrix.shape
X = ratings_matrix.T
X.head()
X.shape
X.index
X1 = X
from sklearn.decomposition import TruncatedSVD
SVD = TruncatedSVD(n_components=10)
decomposed_matrix = SVD.fit_transform(X)
decomposed_matrix.shape
decomposed_matrix
correlation_matrix = np.corrcoef(decomposed_matrix)
correlation_matrix.shape
X.index[75]
i = X.index[75]
product_names = list(X.index)
product_ID = product_names.index(i) #index구하기
product_ID
correlation_product_ID = correlation_matrix[product_ID]
correlation_product_ID.shape
correlation_product_ID
Recommend = list(X.index[correlation_product_ID > 0.65]) #피어슨 상관계수가 0.65보다 큰 상품들의 index의 list return
Recommend.remove(i) # 이미 구입한 상품은 뺀다
Recommend[0:24] #상위 24개 추천
Recommend
'개발 > Recommender System' 카테고리의 다른 글
Embeddings에 대한 이해 -2 | 이미지 기반 유사도, 텍스트 기반 유사도에 대해, TensorFlow Hub (0) | 2020.08.11 |
---|---|
Embeddings에 대한 이해 -1 | 이미지 기반 유사도, 텍스트 기반 유사도에 대해 (2) | 2020.08.10 |
추천시스템 Collaborative Filtering - Model based approach (0) | 2020.05.31 |
추천시스템 Recommender System 정리 (0) | 2020.05.26 |
추천시스템 Collaborative Filtering(CF) Python 기반 [4] (0) | 2020.05.08 |
댓글