推奨システム1)推奨システムの概要、コラボレーションフィルタリング
28650 ワード
推奨システムとは?
ユーザの過去の行動データまたはその他のデータに基づいて、ユーザに必要な情報または製品を提供するシステム.
従来のビジネス推奨
:お客様を興味の近いグループ(マーケティングの細分化市場)、各グループに適した製品、サービス推薦に分ける
グループのサイズを縮小し、グループのサイズを最小にすることができます.各グループ->一人
ユーザーごとにカスタマイズされた推奨およびサービスを提供する->カスタマイズされた推奨システム
1)連携フィルタリング
購入・消費製品の各消費者に対する評価により,評価モデルが類似した消費者を集約する.
消費者の興味を利用した技術
Ex)Aの消費者や製品評価モデルに似ている人を選び,これらの人が共通に好む製品の中からAがまだ触れていない製品を選び,提案する技術.
人々の好みを明確に区別する製品(映画、音楽、ファッション)などの推薦には高い精度がある
限界:消費者の評価情報を入手するのは難しい
消費者に製品を購入した後、評価情報の提供を要求すると、提供が困難になる.
これらの制限を克服するために間接情報を使用する
買い物かごの中の製品などのオンラインショッピング中のクリックフロー(Clickstream)を収集、分析することで、消費者の好みや好みを理解し、ex)アマゾン製品推薦、Netflix映画推薦システム
2)コンテンツベースのフィルタリング
製品の内容を分析し、推奨するテクノロジー
消費者が消費する製品の中でテキスト情報の多い製品(ex)ニュース、書籍などを分析し、推薦する際によく使う
テキスト中の形態素を抽出する->肝心なキーワードを抽出した後の消費者への興味の分析
3)知識ベースのフィルタリング(知識ベースのフィルタリング)
コラボレーションフィルタリング、コンテンツベースフィルタリングの共通の欠点:完全な画像がない
つまり、どの消費者がどの製品が好きなのかを分析することができますが、「なぜどの製品が好きなのか」ということです.についての答え
特定の分野(domain)の専門家の助けの下で、その分野の全体的な知識構造を作成し、利用する方法
全体的な知識構造の多様な表現
通常、ドメイン内の重要な概念に基づいてアーキテクチャ図(ontology)を作成します.
このアーキテクチャ図に基づいて、購入した興味のある製品に関連する製品を推奨する場合は、このアーキテクチャ図を参照してください.
4)深さ学習推奨技術
異なるユーザとプロジェクトのフィーチャー値(feature)を使用し、得られた出力を各ユーザの各プロジェクトに対する予想されるプリファレンスとして使用する->各ユーザに対して複数のプロジェクトの予想されるプリファレンスを計算する->推奨されるプリファレンスの高い製品
利点:複数の入力変数を使用可能
Butは,連続値(ex)1~5と表示される項目の好みをユーザが深く学習する場合,他のアルゴリズムよりも精度が高くない.
5)混合(Hybrid)
以上の2つのアルゴリズムを組み合わせた形状
各アルゴリズムには明らかな利点と欠点があるため,それらを適切に結合すると良好な効果が得られ,それらをどのように結合するかが重要な解決策である.
1)連携フィルタリング
2)コンテンツベースのフィルタリング
3)知識ベースのフィルタリング(知識ベースのフィルタリング)
4)深さ学習推奨技術
5)混合(Hybrid)
似たような人(隣人)の集団が存在すると仮定する
この組織の人々が共に好む製品とサービスを推薦する.
コラボレーションアルゴリズムの順序
1)すべてのユーザ間の評価類似度の計算(適切な類似度評価式を使用)
# train set의 모든 가능한 사용자 pair의 Cosine similarities 계산
from sklearn.metrics.pairwise import cosine_similarity
matrix_dummy = rating_matrix.copy().fillna(0)
user_similarity = cosine_similarity(matrix_dummy, matrix_dummy)
user_similarity = pd.DataFrame(user_similarity, index=rating_matrix.index, columns=rating_matrix.index)
2)現在の推奨オブジェクトと他のユーザとの類似度の抽出def CF_simple(user_id, movie_id):
if movie_id in rating_matrix:
# 현재 사용자와 다른 사용자 간의 similarity 가져오기
sim_scores = user_similarity[user_id].copy()
# 현재 영화에 대한 모든 사용자의 rating값 가져오기
movie_ratings = rating_matrix[movie_id].copy()
# 현재 영화를 평가하지 않은 사용자의 index 가져오기
none_rating_idx = movie_ratings[movie_ratings.isnull()].index
# 현재 영화를 평가하지 않은 사용자의 rating (null) 제거
movie_ratings = movie_ratings.dropna()
# 현재 영화를 평가하지 않은 사용자의 similarity값 제거
sim_scores = sim_scores.drop(none_rating_idx)
# 현재 영화를 평가한 모든 사용자의 가중평균값 구하기
mean_rating = np.dot(sim_scores, movie_ratings) / sim_scores.sum()
else:
mean_rating = 3.0
#print(movie_ratings)
return mean_rating
3)現在のユーザが評価していないすべての項目について、現在のユーザの推定評価値を導出する.->現在のユーザーとの類似性に基づいて、他のユーザーの評価を加重平均する
# 전체 데이터로 full matrix와 cosine similarity 구하기
rating_matrix = ratings.pivot_table(values='rating', index='user_id', columns='movie_id')
from sklearn.metrics.pairwise import cosine_similarity
matrix_dummy = rating_matrix.copy().fillna(0)
user_similarity = cosine_similarity(matrix_dummy, matrix_dummy)
user_similarity = pd.DataFrame(user_similarity, index=rating_matrix.index, columns=rating_matrix.index)
4)推奨品のうち推定評価値が最も高いN個def recom_movie(user_id, n_items, neighbor_size=30):
# 현 사용자가 평가한 영화 가져오기
user_movie = rating_matrix.loc[user_id].copy()
for movie in rating_matrix:
# 현 사용자가 이미 평가한 영화는 제외 (평점을 0으로)
if pd.notnull(user_movie.loc[movie]):
user_movie.loc[movie] = 0
# 현 사용자가 평가하지 않은 영화의 예상 평점 계산
else:
user_movie.loc[movie] = cf_knn(user_id, movie, neighbor_size)
# 영화를 예상 평점에 따라 정렬해서 제목을 뽑아서 돌려 줌
movie_sort = user_movie.sort_values(ascending=False)[:n_items]
recom_movies = movies.loc[movie_sort.index]
recommendations = recom_movies['title']
return recommendations
recom_movie(user_id=2, n_items=5, neighbor_size=30)
隣人のCFを考えると
二つの注意事項
1) K Nearest Neighbor(KNN)
2)Thresholding(類似度基準に適合するユーザを隣接者として選択)
# Neighbor size를 정해서 예측치를 계산하는 함수
def cf_knn(user_id, movie_id, neighbor_size=0):
if movie_id in rating_matrix:
# 현재 사용자와 다른 사용자 간의 similarity 가져오기
sim_scores = user_similarity[user_id].copy()
# 현재 영화에 대한 모든 사용자의 rating값 가져오기
movie_ratings = rating_matrix[movie_id].copy()
# 현재 영화를 평가하지 않은 사용자의 index 가져오기
none_rating_idx = movie_ratings[movie_ratings.isnull()].index
# 현재 영화를 평가하지 않은 사용자의 rating (null) 제거
movie_ratings = movie_ratings.drop(none_rating_idx)
# 현재 영화를 평가하지 않은 사용자의 similarity값 제거
sim_scores = sim_scores.drop(none_rating_idx)
##### (2) Neighbor size가 지정되지 않은 경우
if neighbor_size == 0:
# 현재 영화를 평가한 모든 사용자의 가중평균값 구하기
mean_rating = np.dot(sim_scores, movie_ratings) / sim_scores.sum()
##### (3) Neighbor size가 지정된 경우
else:
# 해당 영화를 평가한 사용자가 최소 2명이 되는 경우에만 계산
if len(sim_scores) > 1:
# 지정된 neighbor size 값과 해당 영화를 평가한 총사용자 수 중 작은 것으로 결정
neighbor_size = min(neighbor_size, len(sim_scores))
# array로 바꾸기 (argsort를 사용하기 위함)
sim_scores = np.array(sim_scores)
movie_ratings = np.array(movie_ratings)
# 유사도를 순서대로 정렬
user_idx = np.argsort(sim_scores)
# 유사도를 neighbor size만큼 받기
sim_scores = sim_scores[user_idx][-neighbor_size:]
# 영화 rating을 neighbor size만큼 받기
movie_ratings = movie_ratings[user_idx][-neighbor_size:]
# 최종 예측값 계산
mean_rating = np.dot(sim_scores, movie_ratings) / sim_scores.sum()
else:
mean_rating = 3.0
else:
mean_rating = 3.0
return mean_rating
評価傾向を考慮したCF
2人のプレイヤーの映画採点ベクトル(5,5,5),(1,1)のコサイン類似度を算出すると,1
プレイヤーの映画に対する評価は明確であるが,このような類似度では各プレイヤーの個人評価傾向を反映できないという欠点がある.
ピルソン類似度(Pearson Simility)を用いてこれを補完する
あるユーザのスコア基準が非常に低いか高すぎると、類似度に大きく影響するため、相関係数を使用してこのような状況の発生を阻止する.
各ユーザの平均値を求め、その値を減算し、コサイン類似度を計算します.
# train 데이터의 user의 rating 평균과 영화의 평점편차 계산
rating_mean = rating_matrix.mean(axis=1)
rating_bias = (rating_matrix.T - rating_mean).T
def CF_knn_bias(user_id, movie_id, neighbor_size=0):
if movie_id in rating_bias:
# 현 user와 다른 사용자 간의 유사도 가져오기
sim_scores = user_similarity[user_id].copy()
# 현 movie의 평점편차 가져오기
movie_ratings = rating_bias[movie_id].copy()
# 현 movie에 대한 rating이 없는 사용자 삭제
none_rating_idx = movie_ratings[movie_ratings.isnull()].index
movie_ratings = movie_ratings.drop(none_rating_idx)
sim_scores = sim_scores.drop(none_rating_idx)
##### (2) Neighbor size가 지정되지 않은 경우
if neighbor_size == 0:
# 편차로 예측값(편차 예측값) 계산
prediction = np.dot(sim_scores, movie_ratings) / sim_scores.sum()
# 편차 예측값에 현 사용자의 평균 더하기
prediction = prediction + rating_mean[user_id]
##### (3) Neighbor size가 지정된 경우
else:
# 해당 영화를 평가한 사용자가 최소 2명이 되는 경우에만 계산
if len(sim_scores) > 1:
# 지정된 neighbor size 값과 해당 영화를 평가한 총사용자 수 중 작은 것으로 결정
neighbor_size = min(neighbor_size, len(sim_scores))
# array로 바꾸기 (argsort를 사용하기 위함)
sim_scores = np.array(sim_scores)
movie_ratings = np.array(movie_ratings)
# 유사도를 순서대로 정렬
user_idx = np.argsort(sim_scores)
# 유사도와 rating을 neighbor size만큼 받기
sim_scores = sim_scores[user_idx][-neighbor_size:]
movie_ratings = movie_ratings[user_idx][-neighbor_size:]
# 편차로 예측치 계산
prediction = np.dot(sim_scores, movie_ratings) / sim_scores.sum()
# 예측값에 현 사용자의 평균 더하기
prediction = prediction + rating_mean[user_id]
else:
prediction = rating_mean[user_id]
else:
prediction = rating_mean[user_id]
return prediction
類似度測定関数
1) Euclidean distance
2) Cosine distance
Euclidean distanceとCosine distanceの違い
Ex)本A:ゲーム、アクション各1語、2語、本B:ゲーム、アクション各1000語、2000語
距離->(1,1)(2000,000)に基づく大きな違い->類似度が低い?
角度基準->傾斜が同じで方向が同じなので類似度が高い
3) Tanimoto coefficient
データにバイナリ値がある場合に使用できます(特定の単語、フィーチャーが含まれているかどうか、アイテムを購入しているかどうかなど)
simil(x,y) = c/a + b – c
a:ユーザxが1を有する(購入またはクリック)物品の数
b:ユーザyが1値(購入またはクリック)を有する物品の数
c:ユーザx,yの合計1値の項目数
4) Jaccard’s distance
タニモト係数と提花係数の違いは?
5)相関係数(相関係数)
相関係数は分かりやすい類似性測定値であるが,連携フィルタリングに用いるとよい結果をもたらすことはできない.
潜在変数(lurking variable):相関性が高いことは、2つの変数間の関連性が高いことを意味し、因果関係を意味しない->したがって、それらを正しく理解し、適用するために、この分野の専門的な解釈が必要である.
2つのユーザーが重複するアイテムの数を考慮しない
1)2人のユーザのアイテム嗜好のうち1つだけが重なる場合,計算方式をどのように定義するかわからないため,相関計算X
2)好み値のすべての列が一致しても判断できない
Reference
この問題について(推奨システム1)推奨システムの概要、コラボレーションフィルタリング), 我々は、より多くの情報をここで見つけました https://velog.io/@eclat12450/추천시스템-1-추천시스템-개요-Collaborative-Filteringテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol