scikit-learn 잠재요인 협업 필터링

이민기·2022년 6월 14일
0
post-thumbnail

scikit learn으로 잠재요인 협업 필터링을 구현해 보았습니다.

Scikit Learn

pip install scikit-learn

## 해당 명령어로 scikit learn 설치 가능 ##

기본적으로 임의로 데이터를 csv 에 넣어 놓았다.

rating = pd.read_csv('user_rating.csv')
store = pd.read_csv('store_info.csv')

# 상점명(store)을 기준으로 rating 와 store 를 결합함
store_ratings = pd.merge(rating, store, on='store')

미리 셋팅해둔 user 별점이 등록된 csv와 상점 데이터가 들어있는 csv를
store명 즉 store라벨 기준으로 pandas로 결합 하였다.

# user별로 상점에 부여한 rating 값을 볼 수 있도록 pivot table 사용
title_user = store_ratings.pivot_table('rating', index='userid', columns='store')

# 평점을 부여안한 상점은 그냥 0이라고 부여
title_user = title_user.fillna(0)

#  모든 유저간의 코사인 유사도를 구함
user_based_collab = cosine_similarity(title_user, title_user)

# 위는 그냥 numpy 행렬이니까, 이를 데이터프레임으로 변환
user_based_collab = pd.DataFrame(user_based_collab, index=title_user.index, columns=title_user.index)

유저별로 상점에 부여한 별점을 확인하기 위해 pivot table을 사용하였고,

평점을 부여안한 상점도 있을테니 그건 0이라고 그냥 부여 하였습니다.

유저간의 코사인 유사도를 구하고, 이것을 데이터 프레임으로 변환 하였습니다.

# 현재 유저와 가장 비슷한 유저를 뽑고
user = user_based_collab[userid].sort_values(ascending=False)[:10].index[1]
# 위에 유저의 가장높게 부여한 가게를 내림차순으로 정렬
recommand_store = title_user.query(f"userid == {user}").sort_values(ascending=False, by=user, axis=1)
# 위에꺼 리스트로 10개만 가져옴
recommand_list = recommand_store.columns.tolist()[:10]

현재 로그인된 유저를 기준으로 평점을 매긴 가장 비슷 유저를 뽑고, 그 유저중 평점을 가장 높게 부여한 가게를 평점순으로

저장 합니다. 그 이후 10개만 를 리스트 형식으로 가져 왔습니다.

해당 상점에 대하여, 예상 평점 구해보기


 user_index_list = user_based_collab[userid].sort_values(ascending=False)[:10].index.tolist()
 user_weight_list = user_based_collab[userid].sort_values(ascending=False)[:10].tolist()

    store_list = []

    for i in recommand_list:
        try:
            store = Food.objects.get(store=i)
        except:
            pass
        store_list.append(store)

    star_result = []
	#위에 10개의 상점을 돌면서 현재 유저가 부여될 평점을 예측	
    for i in store_list:
        try:
            store = i.store
        except:
            pass
        weighted_sum = []
        weighted_user = []
        for i in range(1, 10):
            # 해당 상점에 평점을 부여한 사람들의 유사도와 평점만 추가 (즉, 0이 아닌 경우에만 계산에 활용)
            if int(title_user[store][user_index_list[i]]) != 0:
                # 평점 * 유사도 추가
                weighted_sum.append(title_user[store][user_index_list[i]] * user_weight_list[i])
                # 유사도 추가
                weighted_user.append(user_weight_list[i])

        # 총 평점*유사도 / 총 유사도를 토대로 평점 예측
        result = sum(weighted_sum)/sum(weighted_user)

        star_result.append(result)

(어떤 유저와 비슷한 정도 * 그 유저가 영화에 대해 부여한 평점) 을 더해서 (유저와 비슷한 정도의 합)으로 나눠보면 됨!

평점 예측은 실무에서도 사용이 가능할것 같다. 사전 데이터만 잘 되어있다고 한다면...

profile
지나가는사람

0개의 댓글