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

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

작성한 질문수

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

이웃을 고려한 CF

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

해결된 질문

작성

·

275

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

작성한 질문수

질문하기