da-analysis / asac_5_dataanalysis

ASAC 5기 Data Analysis Project (google map recommendation system)
0 stars 1 forks source link

유저 추천 모델 컨셉 잡기 #28

Open syleeie2310 opened 4 months ago

syleeie2310 commented 4 months ago

유저 추천 모델 컨셉 잡기

soojeonglim commented 4 months ago

https://cuboid-pound-a57.notion.site/665f093ee7084d9aa6c43494480e7937?pvs=4

syleeie2310 commented 4 months ago

방법

Spark MLlib

syleeie2310 commented 4 months ago

유저 -> 클러스터링 ㄴ 이름 가지고 국가를 분류 (1번) ㄴ 어떤 피쳐 사용해서 클러스터링 할지? 성향을 어떤 식으로 알 수 있을지? (2) ㄴ 해당 유저가 방문한 gmap_id의 메타 성질에 따라 해당 유저를 나눌 수 있음 (카테고리...!?, 전체 지역 : 내지인/외지인)

유저를 3개로 쪼갠다면 -> 내지인 - 중국 - 레스토랑 주로 방문하는 사람

soojeonglim commented 4 months ago

@syleeie2310 멘토님..! 모델 돌려 보기 전에 데이터 셋을 review_data에 meta_data를 INNER JOIN이나
LEFT OUTER JOIN 한 후 돌려보면 될까요?

syleeie2310 commented 4 months ago

질문의 내용을 제대로 이해 못하긴 했는데.. 조인해서 원하는 형태의 데이터가 있다면, 데이터부터 만들고 하시긴 해야겠죠?

FM 모델 만들 때는 피쳐가 필요할테니 조인해야 될듯?

soojeonglim commented 4 months ago

넵 궁금했던 부분 해결 됐습니다..! 감사합니다

syleeie2310 commented 4 months ago

어제 말한 카테고리 해시태그 고민해봤는데, 직접 눈으로 발라보긴 힘들고

차라리 나중에 시간될 때 LLM한테 카테고리 전체 데이터를 넘겨주고 대/중/소 분류로 나눠달라고 하면 잘 정리해줄거 같아요.

그걸 기반으로 클러스터링 할 때 고민해보면 좋을 듯. 토요일날 이야기 해봐요.

soojeonglim commented 4 months ago

아하..! 그런 방법이 있었군요.. 넵! 고민해봐주셔서 감사합니다..! :)

soojeonglim commented 4 months ago

@syleeie2310 멘토님.. ALS 모델 돌리는 중 오류가 해결되지 않아 comment 남깁니다.. 도와주세요....

1차 시도 1 [data encoding] encoder = DatasetLabelEncoder() train_dataset = encoder.fit_transform(train_dataset) test_dataset = encoder.transform(test_dataset)

NotImplementedError: LabelEncodingRule is not implemented for File , line 3 1 # data encoding 2 encoder = DatasetLabelEncoder() ----> 3 train_dataset = encoder.fit_transform(train_dataset) 4 test_dataset = encoder.transform(test_dataset) File /local_disk0/.ephemeral_nfs/envs/pythonEnv-0215a8ff-2fc6-426c-acd1-17682e89bf6e/lib/python3.10/site-packages/replay/preprocessing/label_encoder.py:208, in LabelEncodingRule.fit(self, df) 206 else: 207 msg = f"{self.__class__.__name__} is not implemented for {type(df)}" --> 208 raise NotImplementedError(msg) 209 self._inverse_mapping = self._make_inverse_mapping() 210 self._inverse_mapping_list = self._make_inverse_mapping_list() 2차시도 https://spark.apache.org/docs/latest/api/python/reference/api/pyspark.mllib.recommendation.ALS.html (위의 링크를 참조함) rdd가 사용되는 코드.. ![image](https://github.com/user-attachments/assets/b9a6cbac-af10-442e-aada-8ae21aa2a4cf)
syleeie2310 commented 4 months ago

from pyspark.ml.feature import IndexToString, StringIndexer

review_indexer = StringIndexer(inputCol="reviewerID", outputCol="reviewerIDIndex") asin_indexer = StringIndexer(inputCol="asin", outputCol="asinIndex") review_model = review_indexer.fit(all_amazon_data_proc) asin_model = asin_indexer.fit(all_amazon_data_proc) als_df_reviewindex = review_model.transform(all_amazon_data_proc) als_df_reviewasinindex = asin_model.transform(als_df_reviewindex)

als 예제(replay) https://tacademykr-asacanalysis.cloud.databricks.com/?o=3001521127938963#notebook/2311048449669918/command/2311048449669919

als 예제 (recommender) https://tacademykr-asacanalysis.cloud.databricks.com/?o=3001521127938963#notebook/2311048449669855/command/2311048449669856

syleeie2310 commented 4 months ago
syleeie2310 commented 4 months ago
syleeie2310 commented 4 months ago
syleeie2310 commented 4 months ago
syleeie2310 commented 4 months ago

그리고 10개 이상으로 필터링 했을 때 너무 데이터가 없으면, 5개 이상으로 다시 바꿔서 해도 되요. (혹시 너무 오래걸릴까봐 10개 이상 중에서 하라고 한거라서, 실제 나중에 성능까지 보면서 조절해도 될듯)

soojeonglim commented 3 months ago

멘토님 질문 2가지가 있어서 comment 남깁니다..!

1. slim 모델로 훈련은 완료했는데, 평가하는 부분에서 Replay ALS model support only spark 3.1-3.4 versions 현재 spark 버전이 3.5여서 버전이 맞지 않아서 오류가 났습니다. replay는 spark 다운그레이드를 해야만 사용 가능할까요?

2. replay 사용이 불가능해서 implicit로 시도했는데 같은 부분에서 아래와 같은 오류가 계속 나고 있습니다..ㅜ AttributeError: module 'implicit.nearest_neighbours' has no attribute 'SlimElasticNet'

syleeie2310 commented 3 months ago

spark 3.4 version만 가능하다고 하면 runtime 버전을 낮추시면 될듯 해요. 현재 사용하는 개인 클러스터에서 runtime 버전이 세팅해두신 클러스터가 14.3LTS이면 > 13.3 LTS로 낮추심 됩니다. @soojeonglim 런타임 버전 별로 사용 가능한 스파크 버전이 약간 다른데 너무 최신이라서 패키지에서 반영이 안되었나 보네요. https://docs.databricks.com/en/release-notes/runtime/index.html

implicit는 제가 사용해보지 않아서 피드백 드리기가 좀 어렵네요. spark가 아니라 python에서 가능한 패키지가 Surprise 있긴한데 이것도 안써보긴 했어요. 저는 als 쪽은 spark만 해봐서 recommender 라이브러리 사용하거나 mllib에 있는 예제만 해봤어요.

직접 구현하는거 아니면 라이브러리 의존성이 있을 수밖에 없어서, 결국 안되었을 때 해결책 찾는게 늘 어려운일인것 같지만 어쩔수 없지요.

als, fm까지 진도 나가는게 목표인데 als 잘 안되면 fm 부터 해봐도 되긴 합니다.

syleeie2310 commented 3 months ago
soojeonglim commented 3 months ago
syleeie2310 commented 3 months ago

import mlflow

mlflow.autolog( log_input_examples=False, log_model_signatures=True, log_models=True, disable=False, exclusive=False, disable_for_unsupported_versions=True, silent=False )

syleeie2310 commented 3 months ago

- als implicitPrefs false 로 실험해보기 -> 수요일까지 als가 rmse 가 낮은 이유를 한번 확인해주세요~ FM이 rmse 값이 더 낮을 수는 있는데 als 모델에서 RMSE 값이 3이 넘기는 상황은 이상하긴 해요. (너무 값이 높음) -> rmse, MAE, R2, Explained variance 는 모델 하이퍼 파라미터 실험할 때 비교하면 일반적으로 맞습니다. (예를 들면 als에서 RANK, regParam 파라미터, FM에선 factorSize, regParam 파라미터) 자세한건 als 경우에는 아래 문서 보심 됩니다. https://spark.apache.org/docs/latest/ml-collaborative-filtering.html

  • 각 모델 별로 als, fm, slim 3개 랭킹 평가를 수요일까지 부탁드려요. (slim은 als랑 컨셉이 거의 비슷해서, 정 시간이 없으면 빼도 되긴 해요) -> 랭킹 평가는 (map, precision, recall, ndcg, hit ratio, coverage ratio) 모델(ALS, SLIM, FM)끼리 비교하는 목적으로 정리해주시면 됩니다. (모델 별로 생성하는 추천 데이터가 달라져도 상관 없어요. 예를 들면 ALS, SLIM는 생성하는 추천 데이터가 유저 X 아이템 조합 갯수만큼 나오는게 이론적으로 가능하므로 추천 데이터가 클 것이고 FM은 훈련 데이터에 있는 조합만 가지고 추천 데이터를 만약 만들면 생성되는 데이터가 적을 거에요, 그럼 당연히 테스트 데이터랑 recall 비교하면 그 부분에서 차이가 있을거에요)

제대로 하려면 학습한 FM 모델에서 prediction 할때 더 다양한 조합을 넣어서 추천 데이터를 만들 수도 있는데 그건 어떤 피쳐를 사용하냐에 따라서 가능할수도 안될수도 있을것 같네요.

그리고 Two-Tower Stage 모델 (https://docs.databricks.com/en/machine-learning/train-recommender-models.html) 를 나중에 해봤으면 좋겠는데.. 가능할지 저도 잘 몰라서 이건 수요일에 이야기 해보시죠!

syleeie2310 commented 3 months ago
  1. 테스트 데이터 동일하게 세팅한다.
  2. 2개 모델 prediction은 적당하게 줄여서 생성한다.
  3. 생성한 데이터를 테스트 데이터의 RANK 평가한다.
  4. 생성한 데이터를 저장하면 나중에 streamlit 활용할 수 있도록 가지고 있기
  5. 모델 더 리서치 해서 쉽게 할 수 있는 (KNN, 수정님이 할 수 있는 scikit-learn에 있는것 중에 사용)
soojeonglim commented 3 months ago

@syleeie2310

멘토님, als, fm 모델 랭킹평가 정리한 내용 공유 드립니다. 이상한 부분이나 빠진부분 있으면 피드백 부탁드립니다..!

https://www.notion.so/010425b7fad14803b695c9bc2ec78fc1?pvs=4

syleeie2310 commented 3 months ago

@soojeonglim 랭킹 평가 방식이 좀 이상한데 이렇게 한번 확인해보시겠어요? 숫자가 두 방식 극단적이라.. ALS 경우에 학습한 모델에 userID를 넣는거잖아요.근데 dfs_pred에서 gmap_id가 리뷰가 5개 이상 작성된것만 가지고 썼는데 그게 너무 빠진거 같아요. -> 13611 X 1935개 = 26,337,285개.

1935개가 아니라 최소 5천개 정도로 해서 5천만개는 확보한 다음에 평가해야 되지 않을까 싶어요. 넘 적어서 전체적으로 성능이 낮은건지.. user_id 13611개도 test 데이터에서 찾는게 아니라 train에서 선정하는게 좋을거 같긴 하지만요. 2번째 방식인 dfs_test_pred(정답지)와 동일한 데이터로 하는 방식은 정답을 알고 하는거니깐, 랭킹 평가와는 맞지 않을 듯 해요.

그리고 FM에서 evaluation RSME 0.65903이라고 중간에 나와 있는건 오타죠?

image

RMSE 값이 traindata 에도 성능이 낮은지가 궁금하긴 해요. (FM 경우)

오늘까지만 한번 더 성능 평가 제대로 마무리 해서 내일 이야기 해보시죠. !!

이거 정리 끝나면 텍스트 리뷰 요약 하는거 LLM 으로 해보는거 수정님이 해봤으면 좋겠는데, 내일 이야기 해보시죠. ~ 설하님/수정님 두분 중에 한분이 아래 이슈 맡고, 나머지 한분이 streamlit ui 이슈 맡아야 될듯 해요.

https://github.com/da-analysis/asac_4_dataanalysis/blob/main/4.%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85/pages/%EB%A6%AC%EB%B7%B0%EC%9A%94%EC%95%BD%26%ED%82%A4%EC%9B%8C%EB%93%9C.py

soojeonglim commented 3 months ago

@syleeie2310 1. dfs_pred의 user_id는 모두 train에 있는 데이터를 포함하고 있습니다!

dfs_pred에서 gmap_id가 리뷰가 5개 이상 작성된것만 가지고 썼는데 그게 너무 빠진거 같아요.

-> 아하 그럴 수 있겠군요..! 아마존 als 코드 랭킹 평가 결과 부분에서 비슷한 성능이 출력되어 있어서 이렇게 나오는 것이 맞는 건가 하면서도 좀 의문이었어요.. 그럼, train에 있는 user_id들로만 testdata를 구성한 것처럼 train에 있는 gmap_id들로만 리뷰가 n개 이상 작성된 것으로 필터링해서 dfs_pred를 구성해도 될까요? 아니면 train에 없는 gmap_id들도 섞어서 dfs_pred를 구성하는 것이 맞는 건가요?

2. 2번째 방식인 dfs_test_pred(정답지)와 동일한 데이터로 하는 방식은 정답을 알고 하는거니깐, 랭킹 평가와는 맞지 않을 듯 해요.

-> dfs_test_pred는 회귀 평가만 dfs_pred는 랭킹 평가만 진행하는 것이 맞는 건가요?

3. 그리고 FM에서 evaluation RSME 0.65903이라고 중간에 나와 있는건 오타죠?

-> 앗 네..! 오타입니다;;ㅎㅎ 다시 수정해 뒀어요!

FM RMSE값은 아래와 같이 나왔습니다. 성능 괜찮게 나오지만 회귀 평가에서는 여전히 als모델이 더 좋은 성능을 보입니다.

[FM] image

[ALS] image

syleeie2310 commented 3 months ago
  1. 네, 방식은 본인이 결정하면 되는데 traindata에서 gmap_id는 다시 선택해서 해보세요. traindata에 없는 gmap_id로 돌리면 아마 안나올 수도 있어서 기준만 잘 정해주세요 (데이터가 많을테니 모두 다 만들수 없을테니 그것만 주의해서..)
  2. dfs_test_pred는 회귀 평가만 dfs_pred는 랭킹 평가만 진행하는 것이 맞는 건가요? -> 네. 그렇게 하심 될듯 합니다.
  3. FM RMSE 값이 ALS보다 낮은게 아직 잘 모르겠는데 파라미터 어떻게 했는지 알 수 있을까요? 파라미터/변수가 문제라면 그거부터 먼저 변경하면 ALS보다 나아지는지 궁금해요. (+변수가 너무 많은게 더 문제일 수도 있음, 아래에서 변수 제외했을 때 어떻게 바뀌는지? 몇가지 케이스 테스트 해보는게 맞겠죠?) -> features_list : "review_count", "avg_rating", "price" (meta), category_features : "first_main_category" (meta)
syleeie2310 commented 3 months ago

ALS보다 FM이 RMSE값이 낮아진것 확인. 랭킹 평가 재확인 FM만 랭킹 평가한 다음에 마무리 하고. FM데이터만 저장해서 화면 상으로 보여줄 때

syleeie2310 commented 3 months ago

데이터 저장 -> streamlit (1->5위까지) -> user_id(index), gmap_id(jndex)

ALS / FM 닉네임을 위한 추천 과거 입력. 네이밍 / 텍스트 리뷰 / 방문날짜 / 평점 / 카테고리 / 장소명.

syleeie2310 commented 3 months ago

랜덤 유저 선택 랜덤 유저 다시 선택

닉네임을 위한 추천 아이템 Rank1, Rank2, Rank3, Rank4, Rank5 -> 카테고리, 장소명, 예상 별점, 해싱 태그

uesr item -> 한국어로 직관적으로 써주면 좋은듯. 닉네임 입력 랜덤유저 선택