본 내용은 Building a Recommendation System with R 내용을 기반으로 작성 되었다.
콘텐츠 기반 추천 시스템 : 사용자들 간에 유사도를 고려하여 사용자들에게 아이템을 추천하는 시스템
따라서, 사용자가 과거에 좋아했던 아이템들과 비슷한 제품을 추천
ex) 영화추천
추천과정에서 주변 사용자들의 선호도를 고려하지 않고 사용자의 과거 선호도와 아이템의 속성 및 특징을 중점으로 추천한다.
추천하기 전에 아이템의 특징과 명시적 질문을 통해 획득한 사용자 선호도와 추천 범위 등에서 정보를 고려해 추천
모델의 정확도는 추천된 아이템이 얼마나 사용자에게 유용한가를 기반으로 평가
사용자들의 구매 이력이 적은 경우 사용.
대부분의 데이터들은 고차원이며 희소한 데이터이므로 이를 바로 분석모델에 적용할 경우 예측능력이 현저하게 낮아지는 현상이 발생하는데 이를 차원의 저주(THe cusse of dimensionality)라 한다.
이를 해소하는 방법중 하나로 차원축소(Dimensionality Reduction)를 사용한다. 차원 축소 기법들의 종류로는 Principal component analysis(PCA), Non-negative Matrix factorization(NMF), Topological Data Analysis(TDA), auto encoder ,t-Stochastic Neighbor Embedding(T-SNE) 등이 있다.
추천 시스템은 자료간 유사도를 고려하여 작동
유사도의 3가지 조건과 거리의 3가지 조건
유사도는 양수이어야하며 \(d(x,y)=d(y,x)\)를 만족하고 \(s(x,y)\le s(x,x)\)를 만족하여야 한다.
양수이어야하며, \(d(x,y)=d(y,x)\) 즉, 대칭성을 만족하며, 동일성 즉, 오직\(d(x,y)=0\)때만 \(x=y\)를 만족하여야 한다.
\(Dist(x,y)=[\sum(x_{ri}-x_{si})^p]^{1/p}\)
두 점 간의 차이의 절대값을 합한 값, r=1일 때의 민코우스키의 거리와 같음. \(Dist(x,y)=\sum|x_i-y_i|\)
민코우스키거리의 특별 경우(r=2) 자료의 분포적 특성을 고려할 수 없으며, 단위 또한 같아야한다는 단점이 존재.
\(Dist(x,y)=\sqrt{\sum(x_{ri}-x_{si})^2}=\sqrt{[X_r-X_s]^T[X_r-X_s]}\)
두 집단에서 가장 긴 지점에서의 거리
\(max(|x_1-y_1|,\cdots,|x_p-y_p|\)
유클리드 거리를 공분산으로 나눈 거리
\([(X_r-X_s)^TD^{-1}(X_r-X_s)]^{1/2} , D=diag(S_{11},\cdots,S_{pp})\)
공분산 구조를 함께 고려한 통계적 거리, 자료의 분포적 특성을 고려하기 위한 방법.
참고:공분산이 단위행렬이 되면 유클리드거리와 같아지는데 이러한 변환을 화이트닝변환이라 한다.
\([(X_r-X_s)^TS^{-1}(X_r-X_s)]^{1/2} , S=표본공분산행렬\)
맨하튼 거리에 가중치를 적용한 거리의 개념
\(dist(x,y)=\sum\frac{|x_i-y_i|}{x_i-y_i}\)
method에 euclidean, maximum, manhattan, canbera, minkowski 등이 들어갈 수 있다.
x1=rnorm(30)
x2=rnorm(30)
dist(rbind(x1,x2),method='euclidean')
x1
x2 8.225788
\(cos(X_r,X_s)=\frac{X_r\times X_s}{|X_r||X_s|}\)
코사인 유사도는 무게나 크기는 전혀 고려하지 않고 벡터 사이의 각도만으로 측정하는 것과 유사
library('lsa')
x1=sample(c(0,1),30,replace = T)
x2=sample(c(0,1),30,replace = T)
cosine(x1,x2)
[,1]
[1,] 0.571662
피어슨 상관계수의 범위가 -1~1이므로 1에서 피어슨 상관계수를 뺀 값을 거리로 사용
PCA
축을 변환하여 행렬을 새로운 형태로 변환하는 기법. 자체로는 차원이 줄어들지 않는다. 선형 분석방식이므로 비선형성을 고려하지 못한다는 단점이 존재
Propertion of Variance: 분산비율, 각 주성분의 차지하는 비율을 말하며 클 수록 영향을 많이 미친다는 것을 의미한다. Cumulative Proportion: 분산의 누적 합계
prcomp 의 경우 SVD(특이값 분해)를 사용하고, princomp의 경우 스팩트럼 분해를 사용한다는 측면에서 prcomp의 수치 정확도가 더 높다.
data(USArrests)
Warning message:
In strsplit(code, "\n", fixed = TRUE) :
input string 1 is invalid in this locale
rownames(USArrests)
[1] "Alabama" "Alaska" "Arizona"
[4] "Arkansas" "California" "Colorado"
[7] "Connecticut" "Delaware" "Florida"
[10] "Georgia" "Hawaii" "Idaho"
[13] "Illinois" "Indiana" "Iowa"
[16] "Kansas" "Kentucky" "Louisiana"
[19] "Maine" "Maryland" "Massachusetts"
[22] "Michigan" "Minnesota" "Mississippi"
[25] "Missouri" "Montana" "Nebraska"
[28] "Nevada" "New Hampshire" "New Jersey"
[31] "New Mexico" "New York" "North Carolina"
[34] "North Dakota" "Ohio" "Oklahoma"
[37] "Oregon" "Pennsylvania" "Rhode Island"
[40] "South Carolina" "South Dakota" "Tennessee"
[43] "Texas" "Utah" "Vermont"
[46] "Virginia" "Washington" "West Virginia"
[49] "Wisconsin" "Wyoming"
names(USArrests)
[1] "Murder" "Assault" "UrbanPop" "Rape"
head(USArrests)
#변수별 분산
apply(USArrests,2,var)
Murder Assault UrbanPop Rape
18.97047 6945.16571 209.51878 87.72916
pca=prcomp(USArrests,scale=T)
summary(pca)
Importance of components:
PC1 PC2 PC3 PC4
Standard deviation 1.5749 0.9949 0.59713 0.41645
Proportion of Variance 0.6201 0.2474 0.08914 0.04336
Cumulative Proportion 0.6201 0.8675 0.95664 1.00000
biplot(pca)
plot(pca)
t-SNE
library(Rtsne)
tsne=Rtsne(USArrests,dim=2, perplexity=10, verbose=TRUE, max_iter = 500)
Read the 50 x 4 data matrix successfully!
Using no_dims = 2, perplexity = 10.000000, and theta = 0.500000
Computing input similarities...
Normalizing input...
Building tree...
- point 0 of 50
Done in 0.00 seconds (sparsity = 0.698400)!
Learning embedding...
Iteration 50: error is 51.184210 (50 iterations in 0.01 seconds)
Iteration 100: error is 47.904857 (50 iterations in 0.01 seconds)
Iteration 150: error is 53.147732 (50 iterations in 0.01 seconds)
Iteration 200: error is 50.765835 (50 iterations in 0.01 seconds)
Iteration 250: error is 48.690994 (50 iterations in 0.01 seconds)
Iteration 300: error is 1.383360 (50 iterations in 0.00 seconds)
Iteration 350: error is 0.819592 (50 iterations in 0.00 seconds)
Iteration 400: error is 0.393121 (50 iterations in 0.01 seconds)
Iteration 450: error is 0.251557 (50 iterations in 0.00 seconds)
Iteration 500: error is 0.131463 (50 iterations in 0.01 seconds)
Fitting performed in 0.06 seconds.
library(tsne)
data(iris)
iris_tsne = tsne::tsne(as.matrix(iris[1:4]))
sigma summary: Min. : 0.486505661043274 |1st Qu. : 0.587913800179832 |Median : 0.614872437640536 |Mean : 0.623051089344394 |3rd Qu. : 0.654914112723525 |Max. : 0.796707932771489 |
Epoch: Iteration #100 error is: 13.2837229048556
Epoch: Iteration #200 error is: 0.266909913372238
Epoch: Iteration #300 error is: 0.265050123836646
Epoch: Iteration #400 error is: 0.26471624264499
Epoch: Iteration #500 error is: 0.264477221499082
Epoch: Iteration #600 error is: 0.264232266607102
Epoch: Iteration #700 error is: 0.263976211815421
Epoch: Iteration #800 error is: 0.263792910643845
Epoch: Iteration #900 error is: 0.263675732682757
Epoch: Iteration #1000 error is: 0.263605324162608
df_iris_tsne = iris_tsne %>%
as.data.frame() %>%
tbl_df() %>%
mutate(species = iris$Species)
df_iris_tsne %>%
ggplot(aes(x = V1, y = V2, color = species)) +
geom_point() +
scale_color_brewer(palette = 'Paired') +
ggtitle('t-SNE result : iris dataset (Real Species)') +
theme(axis.title.x = element_blank(),
axis.title.y = element_blank())
NMF
1개의 데이터 행렬을 2개로 분리
library(NMF)
res=nmf(USArrests,3)
V.hat <- fitted(res)
w <- basis(res)
TDA
# install_version('phom')
library(phom) # phom 설치 확인
Warning message:
In strsplit(code, "\n", fixed = TRUE) :
input string 1 is invalid in this locale
data = as.matrix(iris[,-5])
head(data)
Sepal.Length Sepal.Width Petal.Length Petal.Width
[1,] 5.1 3.5 1.4 0.2
[2,] 4.9 3.0 1.4 0.2
[3,] 4.7 3.2 1.3 0.2
[4,] 4.6 3.1 1.5 0.2
[5,] 5.0 3.6 1.4 0.2
[6,] 5.4 3.9 1.7 0.4
max_dim = 0
max_f = 1
irisInt0 = pHom(data, dimension=max_dim,# maximum dimension of persistent homology computed
max_filtration_value=max_f, # maximum dimension of filtration complex
mode="vr", # type of filtration complex
metric="euclidean")
plotBarcodeDiagram(irisInt0, max_dim, max_f, title="H0 Barcode plot of Iris Data")
지도학습
계층적 군집, k-means cluster, partitioning around medoids(PAM), 혼합분포 군집, 밀도기반 군집,서포트 벡터 머신 등이 있으며 추후 업데이트 예정
library(recommenderlab)
data_package=data(package='recommenderlab')
data_package$results[,'Item']
[1] "Jester5k"
[2] "JesterJokes (Jester5k)"
[3] "MSWeb"
[4] "MovieLense"
[5] "MovieLenseMeta (MovieLense)"
data("MovieLense")
a=as(MovieLense,'matrix')
aa <- as(as(a, "matrix"), "realRatingMatrix")
head(a[1,1:5])
Toy Story (1995) GoldenEye (1995) Four Rooms (1995)
5 3 4
Get Shorty (1995) Copycat (1995)
3 3
유사도 행렬 계산
witch는 users 와 items를 지원하며, method는 cosine, pearson,jaccard를 지원한다.
similarity_users=similarity(MovieLense[1:4,],method='cosine',which='users')
as.matrix(similarity_users)
1 2 3 4
1 0.0000000 0.9605820 0.8339504 0.9192637
2 0.9605820 0.0000000 0.9268716 0.9370341
3 0.8339504 0.9268716 0.0000000 0.9130323
4 0.9192637 0.9370341 0.9130323 0.0000000
image(as.matrix(similarity_users))
추천 item에 대한 유사도 계산
similarity_items=similarity(MovieLense[,1:4],method='cosine',which='items')
as.matrix(similarity_items)
Toy Story (1995) GoldenEye (1995)
Toy Story (1995) 0.0000000 0.9487374
GoldenEye (1995) 0.9487374 0.0000000
Four Rooms (1995) 0.9132997 0.9088797
Get Shorty (1995) 0.9429069 0.9394926
Four Rooms (1995) Get Shorty (1995)
Toy Story (1995) 0.9132997 0.9429069
GoldenEye (1995) 0.9088797 0.9394926
Four Rooms (1995) 0.0000000 0.8991940
Get Shorty (1995) 0.8991940 0.0000000
image(as.matrix(similarity_items))
적용 가능한 모델 확인과 설명
recommender_models=recommenderRegistry$get_entries(dataType='realRatingMatrix')
names(recommender_models)
[1] "ALS_realRatingMatrix"
[2] "ALS_implicit_realRatingMatrix"
[3] "IBCF_realRatingMatrix"
[4] "POPULAR_realRatingMatrix"
[5] "RANDOM_realRatingMatrix"
[6] "RERECOMMEND_realRatingMatrix"
[7] "SVD_realRatingMatrix"
[8] "SVDF_realRatingMatrix"
[9] "UBCF_realRatingMatrix"
lapply(recommender_models,'[[','description')
$`ALS_realRatingMatrix`
[1] "Recommender for explicit ratings based on latent factors, calculated by alternating least squares algorithm."
$ALS_implicit_realRatingMatrix
[1] "Recommender for implicit data based on latent factors, calculated by alternating least squares algorithm."
$IBCF_realRatingMatrix
[1] "Recommender based on item-based collaborative filtering."
$POPULAR_realRatingMatrix
[1] "Recommender based on item popularity."
$RANDOM_realRatingMatrix
[1] "Produce random recommendations (real ratings)."
$RERECOMMEND_realRatingMatrix
[1] "Re-recommends highly rated items (real ratings)."
$SVD_realRatingMatrix
[1] "Recommender based on SVD approximation with column-mean imputation."
$SVDF_realRatingMatrix
[1] "Recommender based on Funk SVD with gradient descend."
$UBCF_realRatingMatrix
[1] "Recommender based on user-based collaborative filtering."
매개변수에 대한 설명
data.frame(recommender_models$IBCF_realRatingMatrix$parameters)
모델을 좀더 대중적으로 일반화 해보자.
평점 분포
vector_ratings=as.vector(MovieLense@data)
table_ratings=table(vector_ratings)
table_ratings
vector_ratings
0 1 2 3 4 5
1469760 6059 11307 27002 33947 21077
vector_ratings2=vector_ratings[vector_ratings!=0]
vector_ratings2=factor(vector_ratings2)
qplot(vector_ratings2)
조회수 상위랭킹 영화
views_per_movie=colCounts(MovieLense)
table_views=data.frame(movie=names(views_per_movie),views=views_per_movie)
table_views2=table_views[order(table_views$views,decreasing = T),]
ggplot(table_views[1:6,],aes(x=movie,y=views))+geom_bar(stat='identity')+
theme(axis.text.x=element_text(angle=45,hjust=1))+
ggtitle('Number of views of the top movies')
평균 영화 평점 분포와 조회수 100이상의 평균 평점 분포
average_ratings=colMeans(MovieLense)
qplot(average_ratings)+stat_bin(binwidth = .1)
average_ratings_relevant=average_ratings[views_per_movie>100]
qplot(average_ratings_relevant)+stat_bin(binwidth = .1)
결측 분포를 보여주는 히트맵
image(MovieLense)
영화를 많이 본 사용자와 많은 사용자가 본 영화를 시각화
min_n_movies=quantile(rowCounts(MovieLense),.99)
min_n_users=quantile(colCounts(MovieLense),.99)
image(MovieLense[rowCounts(MovieLense)>min_n_movies,
colCounts(MovieLense)>min_n_users])
시청 횟수가 적은 영화는 정보부족으로 인해 평점에 편향을 미칠 수 있고, 거의 평점을 매기지 않은 사용자는 등급에 편향을 미칠 수 있다.
따라서, 영화를 50편 이상 이용한 사용자이고 적어도 100번 이상 시청된 영화를 추출하여 시각화
ratings_movies=MovieLense[rowCounts(MovieLense)>50,colCounts(MovieLense)>100]
ratings_movies=MovieLense[rowCounts(MovieLense)>50,colCounts(MovieLense)>100]
min_n_movies=quantile(rowCounts(ratings_movies),.98)
min_n_users=quantile(colCounts(ratings_movies),.98)
image(ratings_movies[rowCounts(ratings_movies)>min_n_movies,
colCounts(ratings_movies)>min_n_users])
평균 평점은 여러 사용자마다 크게 다름을 볼 수 있다.
average_ratings_per_user=rowMeans(ratings_movies)
qplot(average_ratings_per_user)+stat_bin(binwidth = .1)+ggtitle('Distribution of the average rating per user')
모든 영화에 높은 평점을 부여하는 고객은 결과를 왜곡시킬 수 있으므로 평균 평점이 0이되도록 변환(정규화)
ratings_movies_norm=normalize(ratings_movies)
image(ratings_movies_norm[rowCounts(ratings_movies_norm)>min_n_movies,
colCounts(ratings_movies_norm)>min_n_users])
데이터의 이진화
이진화의 방법 영화 평점을 매기면1, 아니면 0 상세 평점에 대한 정보가 손실되는게 단점.
평점이 일정 기준 이상인 경우 1, 아니면 0 이경우 나쁜 평점이 부여된 영화를 평가 대상에서 제외하는 효과
case1)
ratings_movies_watched=binarize(ratings_movies,minRating=1)
min_movies_binary=quantile(rowCounts(ratings_movies),.95)
min_users_binary=quantile(colCounts(ratings_movies),.95)
image(ratings_movies_watched[rowCounts(ratings_movies)>min_movies_binary,
colCounts(ratings_movies)>min_users_binary])
case2)
ratings_movies_good=binarize(ratings_movies,minRating=3)
image(ratings_movies_good[rowCounts(ratings_movies)>min_movies_binary,
colCounts(ratings_movies)>min_users_binary])
아이템 기반 협업 필터링
협업필터링 이란 : 여러 사용자에 대한 정보를 고려한 추천 형태
아이템을 추천하기 위해 서로 협력한다는 뜻에서 협업 필터링이라 표현
학습 알고리즘
which_train=sample(x=c(T,F),size=nrow(ratings_movies),replace=T,prob=c(.7,.3))
train=ratings_movies[which_train,]
test=ratings_movies[!which_train,]
which_set=sample(x=1:5,size=nrow(ratings_movies),replace=T)
for(i_model in 1:5){
which_train=which_set==i_model
train<-ratings_movies[which_train,]
test<-ratings_movies[!which_train,]
}
method는 유사도 함수를 나타내며 k는 유사한 아이템의 개수를 의미
head(apply(model_details$sim,1,function(x)sum(x>0)))
Toy Story (1995) GoldenEye (1995)
30 30
Get Shorty (1995) Twelve Monkeys (1995)
30 30
Babe (1995) Dead Man Walking (1995)
30 30
Warning message:
In strsplit(code, "\n", fixed = TRUE) :
input string 1 is invalid in this locale
예측 알고리즘
recc_predicted=predict(model,newdata=test,n=n_recommended)
t(data.frame(recc_predicted@items))
[,1] [,2] [,3] [,4] [,5] [,6]
X2 56 73 96 109 127 152
X3 38 249 229 7 163 13
X5 34 62 99 168 186 251
X6 52 178 212 207 216 292
X7 171 158 209 81 252 198
X8 66 106 149 217 319 327
X10 130 181 109 325 305 314
X11 120 108 228 118 329 265
X14 5 139 280 33 7 208
X15 177 306 174 239 161 178
X16 17 20 22 40 44 55
X18 34 143 329 33 189 282
X21 213 319 315 101 7 253
X23 68 263 199 243 271 172
X24 1 23 29 34 48 87
X25 10 12 21 39 48 60
X26 208 228 246 296 47 52
X28 6 125 128 196 201 220
X37 31 40 56 83 91 99
X38 5 14 24 28 29 31
X43 228 44 222 194 121 68
X44 52 89 184 188 209 106
X48 11 58 79 168 206 242
X49 314 190 316 204 110 167
X56 14 304 232 309 255 276
X57 177 191 219 228 247 316
X58 71 145 188 52 39 326
X60 320 246 17 167 146 131
X63 298 249 148 28 72 194
X64 219 304 282 15 162 267
X65 14 17 34 61 71 72
X69 12 42 63 78 156 168
X70 51 9 33 31 295 146
X72 174 265 240 282 108 66
X73 31 56 179 330 210 55
X75 11 165 247 308 223 161
X77 9 21 28 40 44 70
X79 6 10 13 17 19 25
X81 10 11 47 295 32 9
X83 282 275 80 265 210 150
X84 38 162 192 269 66 159
X85 318 290 215 174 322 63
X87 28 180 121 289 80 244
X89 8 30 34 36 40 67
X90 209 327 47 216 206 95
X91 44 45 36 117 100 221
X94 190 219 327 81 65 186
X95 304 249 295 219 265 3
X96 3 6 15 16 18 32
X97 3 7 10 22 25 27
X99 31 183 289 108 161 282
X101 27 32 40 52 224 226
X102 92 101 292 59 158 66
X104 74 228 83 153 14 329
X106 25 235 251 304 263 228
X109 160 206 211 221 149 332
X110 4 14 80 162 128 229
X115 2 16 19 59 66 74
X116 229 104 209 46 108 13
X117 18 22 31 34 38 47
X118 3 9 20 21 23 30
X121 51 122 140 145 151 156
X122 25 40 42 58 63 68
X125 102 235 34 330 186 275
X128 93 328 79 320 190 183
X130 292 167 46 42 175 49
X135 2 3 4 14 16 29
X138 12 13 19 21 22 25
X144 80 301 282 283 91 157
X148 3 6 9 10 11 12
X151 202 187 251 162 34 219
X152 13 23 27 40 51 52
X154 13 88 101 181 303 79
X161 14 45 55 93 113 114
X167 13 28 29 33 35 49
X168 9 60 80 144 239 49
X174 42 44 45 55 59 110
X176 40 63 64 280 133 213
X178 81 318 249 215 33 276
X180 2 5 7 13 15 20
X181 127 108 99 198 199 134
X183 51 74 131 138 153 167
X184 52 184 327 281 321 290
X186 66 73 162 196 208 205
X188 79 145 188 174 160 206
X189 56 40 292 179 246 304
X190 12 50 168 266 194 237
X193 80 32 187 206 222 68
X195 134 52 46 206 229 160
X197 171 80 53 289 153 14
X198 38 206 212 325 17 5
X200 316 174 173 292 213 191
X201 79 314 282 326 269 52
X206 79 232 249 24 175 65
X207 51 80 251 132 162 229
X210 92 180 219 241 329 229
X214 152 217 15 314 143 136
X215 14 31 49 119 216 324
X216 22 240 246 36 149 192
X217 5 14 21 47 49 74
X218 30 54 74 78 107 116
X221 57 282 315 222 221 187
X227 55 100 275 323 314 226
X232 11 104 123 137 140 195
X233 17 40 44 45 66 75
X234 314 158 188 172 65 167
X235 172 283 315 51 124 230
X236 324 246 204 42 33 76
X239 11 85 90 98 112 113
X243 43 151 223 259 265 92
X244 162 233 157 190 263 208
X246 219 238 75 186 84 303
X248 65 74 133 201 265 286
X249 32 304 269 178 216 63
X251 3 43 65 158 188 232
X254 259 66 62 47 219 226
X255 12 314 141 319 196 1
X256 14 49 51 167 219 263
X262 158 208 173 141 157 145
X264 2 30 41 55 67 75
X267 51 106 329 80 251 167
X268 304 80 231 216 233 178
X269 186 222 25 304 192 289
X270 70 74 84 104 143 158
X271 162 137 38 301 328 228
X274 29 38 39 55 132 136
X275 32 43 94 131 135 158
X276 255 320 323 183 269 208
X277 57 75 10 118 105 34
X279 130 194 5 210 293 146
X280 14 235 167 308 269 178
X283 4 7 13 15 18 41
X286 188 329 67 80 158 186
X287 29 39 40 72 81 152
X288 45 54 68 101 112 116
X290 207 283 232 65 219 316
X292 88 241 171 325 8 134
X293 167 332 318 212 51 53
X294 121 233 322 7 321 37
X295 25 60 65 168 215 152
X296 32 72 217 289 222 317
X297 134 69 231 106 260 270
X298 185 251 272 298 311 328
X299 219 251 208 288 295 289
X301 250 200 148 119 198 199
X303 187 319 212 216 80 134
X305 115 282 283 231 147 40
X307 93 99 120 135 182 185
X308 178 317 233 222 205 289
X311 237 219 153 323 81 171
X312 46 50 133 206 220 332
X313 131 304 179 167 181 171
X314 59 157 162 208 219 222
X315 48 55 65 93 207 218
X316 164 172 186 214 273 275
X318 70 63 149 331 139 206
X320 144 102 215 305 190 163
X323 208 32 109 229 232 186
X324 58 64 178 206 16 220
X325 122 223 297 145 246 33
X327 290 185 219 222 205 318
X328 15 188 320 168 24 232
X330 20 24 46 51 92 102
X331 13 16 24 36 44 74
X332 236 178 107 9 131 3
X334 171 211 65 63 215 226
[ reached getOption("max.print") -- omitted 295 rows ]
recc_user_1=recc_predicted@items[[1]]
movies_user_1=recc_predicted@itemLabels[recc_user_1]
recc_matrix=sapply(recc_predicted@items,function(x){colnames(ratings_movies)[x]})
number_of_items=factor(table(recc_matrix))
qplot(number_of_items)
number_of_items_sorted=sort(number_of_items,decreasing = T)
number_of_items_top=head(number_of_items_sorted,4)
사용자 기반
같은 사람들이 구매한 것과 유사한 아이템 선별 새 사용자에게 구매했던 것과 비슷한 아이템 추천
알고리즘
각 사용자와 새로운 사용자와의 유사도 측정 가장 유사한 사용자들을 선별(k nn 사용) 가장 유사한 사용자가 구매한 아이템들에 평점을 매긴다. 평점은 유사도를 가중치로 하는 가중평점이나 평균평점을 사용
nn은 유사한 사용자의 수를 의미(디폴트 =25)
model2=Recommender(data=train,method='UBCF')
model2
model_details=getModel(model2)
n_recommended=6
recc_predicted=predict(model2,test,n_recommended)
유저기반 협업필터링은 초기 데이터에 접근해야 하므로 사후학습모델에 해당된다. 또한 전체 데이터베이스에 리소스 소모가 심하다.
일반적으로 UBCF가 IBCF보다 좀 더 정확하다고 입증되었으므로 UBCF를 추천.
이진데이터에 대한 협업필터링
\(distance(item_1,item_2)=\frac{item_1 \cap item_2}{item_2 \cup item_2}\)
이럴 때 사용 가능 어떤 아이템을 구매했는지 알지만 평점을 모른다. 각 사용자에 대한 구매한 아이템을 알지 못하지만 좋아하는 아이템은 알고 있다.
아이템 기반
ratings_movies_watched=binarize(ratings_movies,minRating=1)
qplot(rowSums(ratings_movies_watched))+stat_bin(binwidth=10)
model=Recommender(train,method='IBCF',parameter=list(method='Jaccard'))
model_details=getModel(model)
n_recommended=6
recc_predicted=predict(model,test,n=n_recommended)
recc_matrix=sapply(recc_predicted@items,function(x){colnames(ratings_movies)[x]})
사용자기반
model=Recommender(train,method='UBCF',parameter=list(method='Jaccard'))
model_details=getModel(model)
n_recommended=6
recc_predicted=predict(model,test,n=n_recommended)
recc_matrix=sapply(recc_predicted@items,function(x){colnames(ratings_movies)[x]})
협업 필터링의 문제점
새로운 사용자가 아직 영화를 보지 못했으면 사용 불가능. IBCF의 경우 구매 아이템을 알아야 하며, UBCF는 기존 사용자가 새로운 사용자와 유사한 선호도를 가졌는지 알아야 한다.
새 아이템을 다른사람이 구매하지 않은 경우에는 절대로 추천되지 않음.
또한 평점 매트릭스만 고려하며, 사용자의 정보를 고려하지 못함.
콘텐츠 기반 필터링 아이템에 대한 세부정보로 시작되며 다른 사용자들을 고려할 필요가 없다. 각 사용자에 대해 알고리즘은 과거 구매와 유사한 아이템을 추천
하이브리드 추천 시스템
병렬 하이브리드 시스템 : 추천 모듈을 병렬로 각각 실행하고 그 결과를 결합한다. 각 사용자에 대한 추천 결과를 결합
파이프라인 하이브리드 시스템 : 서로 다른 추천 시스템을 차래대로 수행
모놀리식 하이브리드 시스템 : 동일한 추천 알고리즘 내에서 다양한 방식으로 수행한 결과를 통합.