강의

멘토링

로드맵

인프런 커뮤니티 질문&답변

Jongsoo Park님의 프로필 이미지
Jongsoo Park

작성한 질문수

(UPDATED) Python을 이용한 개인화 추천시스템 | 추천알고리즘 | 추천인공지능

이웃을 고려한 CF

Neighbor size를 정해서 예측치를 계산하는 함수의 코드 실행 문제

해결된 질문

작성

·

348

1

#Neighbor Size를 정해서 예측치를 계산하는 함수

def CF_knn(user_id,movie_id,neighbor_size=0):
  if movie_id in rating_matrix.columns:
    sim_scores=user_similarity[user_id].copy()
    movie_ratings=rating_matrix[movie_id].copy()
    none_rating_idx=movie_ratings[movie_ratings.isnull()].index
    movie_ratings=movie_ratings.dropna()
    sim_scores=sim_scores.drop(none_rating_idx)

    if neighbor_size==0:
      mean_rating=np.dot(sim_scores, movie_ratings)/sim_scores.sum()
    else:
      if len(sim_scores) > 1:
        neighbor_size=min(neighbor_size,len(sim_scores))
        sim_scores=np.array(sim_scores)
        movie_ratings=np.array(movie_ratings)
        user_idx=np.argsort(sim_scores)
        sim_scores=sim_scores[user_idx][-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

#정확도 계산
print(score(CF_knn,neighbor_size=30))
 
 
 
 
다음과 같이 실행을 했을 때 실행결과가 None으로 표시 됩니다.
어떤오류가 있는지 찾지를 못하겠는데 도움을 부탁 드립니다.

퀴즈

협업 필터링의 핵심 원리는 무엇인가요?

아이템의 속성을 기반으로 추천합니다.

사용자의 인구 통계 정보를 활용합니다.

비슷한 취향을 가진 사용자들이 비슷한 아이템을 선호할 것이라고 가정합니다.

아이템의 인기도 순으로 추천합니다.

답변 4

0

거친코딩님의 프로필 이미지
거친코딩
지식공유자

안녕하세요.

개인사정으로 답변이 늦어진 점 죄송합니다.

방금 학습자님이 짜주신 전체 코드 리뷰를 해봤습니다 :)

그런데 모델을 테스트 셋으로 측정하는 "score module"에 문제가 있는것을 발견하였습니다.

마지막 부분에 y_pred만 있고 실제 y_true 값을 산출하는 부분 및 RMSE를 구하는 부분이 빠져있는 것 같습니다. 

# 유사집단의 크기를 미리 정하기 위해서 기존 score 함수에 neighbor_size 인자값 추가
def score(model,neighbor_size=0):
    # 테스트 데이터의 user_id와 movie_id 간 pair를 맞춰 튜플형원소 리스트데이터를 만듬
    id_pairs = zip(x_test['user_id'],x_test['movie_id'])
    # 모든 사용자-영화 짝에 대해서 주어진 예측모델에 의해 예측값 계산 및 리스트형 데이터 생성
    y_pred = np.array([model(user,movie,neighbor_size) for (user,movie) in id_pairs])
    # 실제 평점값
    y_true = np.array(x_test['rating'])
    return RMSE(y_true, y_pred)

예시코드 같이 보내드리겠습니다.

학습자님의 성공적인 학습을 기원합니다.

질문은 언제든 환영합니다 :)

감사합니다.

-거친코딩 드림-

Jongsoo Park님의 프로필 이미지
Jongsoo Park
질문자

오 감사합니다!!해결되었습니다!!!

거친코딩님의 프로필 이미지
거친코딩
지식공유자

정말 다행입니다~!! 

늘 학습자님들에게 도움이 되는 강의로 찾아뵙겠습니다 :) 

감사합니다.

-거친코딩 드림-

0

Jongsoo Park님의 프로필 이미지
Jongsoo Park
질문자

#사용자 u.user 파일을 DataFrame으로 읽기
import os
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split

base_src='drive/MyDrive/RecoSys/Data'
u_user_src=os.path.join(base_src,'u.user')
u_cols = ['user_id','age','sex','occupation','zip_code']
users=pd.read_csv(u_user_src,
                  sep='|',
                  names=u_cols,
                  encoding='latin-1')
users=users.set_index('user_id')

u_item_src=os.path.join(base_src,'u.item')
i_cols = ['movie_id','title','release date','video release date',
'IMDB URL','unknown','Action','Adventure','Animation',
'Children\'s','Comedy','Crime','Documentary','Drama','Fantasy',
'Film-Noir','Horror','Musical','Mystery','Romance','Sci-Fi','Thriller','War','Western']
movies=pd.read_csv(u_item_src,
                  sep='|',
                  names=i_cols,
                  encoding='latin-1')
movies=movies.set_index('movie_id')
u_data_src=os.path.join(base_src,'u.data')
r_cols = ['user_id','movie_id','rating','timestamp']
ratings=pd.read_csv(u_data_src,
                  sep='\t',
                  names=r_cols,
                  encoding='latin-1')
#정확도(RMSE) 계산 함수
def RMSE(y_truey_pred):
  return np.sqrt(np.mean((np.array(y_true)-np.array(y_pred))**2))

  #유사집단의 크기를 미리 정하기 위하여 기존 Score함수에 neighbor_size 인자값을 추가
def score(model,neighbor_size=0):
  #테스트 데이터의 user_id와 movie_id간 pair를 맞춰 튜플형원소 리스트데이터를 만듬
  id_pairs=zip(x_test['user_id'],x_test['movie_id'])
  #모든 사용자-영화 짝에 대해서 주어진 예측모델에 의해 예측값 계산 및 리스트형 데이터 생성
  y_pred=np.array([model(user,movie,neighbor_size) for (user,movie) in id_pairs])
  #실제 평점값
  y_pred=np.array(x_test['rating'])
  x=ratings.copy()
y=ratings['user_id']

x_train, x_test, y_train, y_test=train_test_split(x,y,test_size=0.25,stratify=y)

rating_matrix=x_train.pivot(index='user_id',columns='movie_id',values='rating')

#train set의 모든 가능한 사용자 pair의 cosine similarities계산
#코사인 유사도를 계산하는 사이킷런의 라이브러리
from sklearn.metrics.pairwise import cosine_similarity
#코사인 유사도를 구하기 위해 rating값을 복사하고, 계산 시 NaN값 에러 대비를 위해 결측치를 0으로 대체
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)

#Neighbor Size를 정해서 예측치를 계산하는 함수

def CF_knn(user_id,movie_id,neighbor_size=0):
  if movie_id in rating_matrix.columns:
    sim_scores=user_similarity[user_id].copy()
    movie_ratings=rating_matrix[movie_id].copy()
    none_rating_idx=movie_ratings[movie_ratings.isnull()].index
    movie_ratings=movie_ratings.dropna()
    sim_scores=sim_scores.drop(none_rating_idx)

    if neighbor_size==0:
      mean_rating=np.dot(sim_scores, movie_ratings)/sim_scores.sum()
    else:
      if len(sim_scores) > 1:
        neighbor_size=min(neighbor_size,len(sim_scores))
        sim_scores=np.array(sim_scores)
        movie_ratings=np.array(movie_ratings)
        user_idx=np.argsort(sim_scores)
        sim_scores=sim_scores[user_idx][-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



#neighbor size가 10, 20, 30, 40, 50, 60인 경우에 대해서 RMSE를 계산하고 이를 출력한다
for neighbor_size in [10,20,30,40,50,60]:
  print('neighbor size = %d : RMSE = %.4f' % (neighbor_size, score(CF_knn,neighbor_size)))

 

거친코딩 선생님

아무리 봐도 찾을수가 없습니다 ㅠ ㅠ

도움을 부탁 드립니다.

 

0

Jongsoo Park님의 프로필 이미지
Jongsoo Park
질문자

빠르게 답변주셔서 감사합니다.

이웃을 고려한 cf가 정상적으로 작동하는데 이는 1~6번이 정상적으로 작동했기에 가능한 것이 아닐까 싶습니다.

송구스럽지만 코드 샘플을 송부하여 주시면 

구체적으로 비교하여 보도록 하겠습니다

 

감사합니다

 

거친코딩님의 프로필 이미지
거친코딩
지식공유자

금일 저녁에 올려드리도록 하겠습니다 :) 

감사합니다.

-거친코딩 드림-

0

거친코딩님의 프로필 이미지
거친코딩
지식공유자

안녕하세요.
올려주신 코드를 보면 강의에 나온대로 잘 짜주셨네요!

학습자님이 열심히 해주신 모델(CF_knn) 에는 아무 이상이 없네요.!

다만,   예상되는 문제라고 하면 다음과 같습니다.

1. 데이터 불러오기

2. RMSE 모듈 확인

3. score 모듈 확인

4. train set과 test set을 잘 구분 하셨는지

5. train set을 통해 rating matrix(pivot)을 잘  만드셨는지

6. rating matrix를 통해 사용자간 유사도(user_similarity)를 잘 구하셨는지

 

혹시 1~6번까지 아무 이상없는데, 동작이 안되신다고 하면 제가 샘플 코드를 보내드리겠습니다 :)

ps. 샘플코드(모델 앞 부분 코드) + 학습자님 모델은 정상적으로 잘 동작하였습니다:)

감사합니다.

 

-거친코딩 드림-

Jongsoo Park님의 프로필 이미지
Jongsoo Park

작성한 질문수

질문하기