멋쟁이사자처럼 X K-DIGITAL Training - 07.12
[github] https://github.com/ijo0r98/likelion-kdigital/tree/main/mid-project-1
ijo0r98/likelion-kdigital
멋쟁이사자처럼 & K-DIGITAL. Contribute to ijo0r98/likelion-kdigital development by creating an account on GitHub.
github.com
[이전] 2021.07.10 - [python/k-digital] - [K-DIGITAL] mid-project-1. 영화 별점 데이터 분석
[K-DIGITAL] mid-project-1. 영화 별점 데이터 분석
멋쟁이사자처럼 X K-DIGITAL Training - 07.05 [github] https://github.com/ijo0r98/likelion-kdigital/tree/main/mid-project-1 ijo0r98/likelion-kdigital 멋쟁이사자처럼 & K-DIGITAL. Contribute to ijo0r98/..
juran-devblog.tistory.com
어제 하면서 아쉬웠던 부분들 다 해결해버려따 허허
그리고 어제 하면서 궁금했던 부분들도 강사님께 질문했다.
강사님께 성능에 대해 여쭤보니 좋은 팁을 주셔서 성능을 꽤 많이 올렸다! 발표 전에 완성해서 다행이다.
역시 모르는거 있을땐 바로바로 질문하는게 최고인것 같당
에측 모델이 어느정도 성능이 올라 새로운 영화에 대한 정보가 주어졌을 때 별점을 예측하는 것도 만들어 보았다.
넘 주먹구구식이지만 모 어때 여기까지라도 한데 의미가 있는거지 모~.~
발표까지 성공리에 끝낸 기념 미드플젝1 마지막 포스팅 😇
실수형으로 모델을 학습하고 accuray 측정을 할 때 continous is not supported 라며 연속값에 관련된 오류가 발생한다.
그 이유는 멀티 클래스(여러 카테고리)를 인식할 때 카테고리 넘버 형태로 인식하기 때문이라고 한다.
float형은 연속된 변수로 인식하여 0, 1 또는 0, 1, 2처럼 클래스가 정수 형태로 되어있어야 한다 !!
그래서 이전에 내가 아무생각없이 모든 rating에 10을 곱해 int형으로 바꿨을 때 잘 작동되었던 것이다..
이유도 모르고 그냥 이렇게 하니 되네~ 하고 했었는데 이제 정확한 이유를 찾았다.
다른 예로 성별을 female / male 에서 0 / 1로 바꿔주는 것도 비슷한 느낌이지 않을까 싶은데.. 쓰고보니 좀 다른것 같기도 ..
강사님께 데이터가 너무 작기도하고 x 데이터 선택이 잘못되어 성능이 잘 안나오는걸까요? 라고 질문드렸었다.
강사님께서는 y의 범주가 너무 많다고 하셨다.
가뜩이나 이렇게 데이터가 적을때 타켓의 카테고리 수가 너무 많으면 성능이 떨어진다고 한다.
rating의 범위를 나눠 카테고리를 2~3개로 줄여보라고 하신 조언에 따라 조금 수정해보았다.
먼저 y의 카테고리 분포 확인
y_data.value_counts()
카테고리 수 축소
def rating_categorized(r):
if r >= 3.0:
return 0
else:
return 1
y_data3 = y_data.copy()
y_data3.rating = y_data3.rating.apply(rating_categorized)
y_data3.value_counts()
모델 학습 및 성능 확인
# train / test
x_train, x_test, y_train, y_test = train_test_split(X_data, y_data3, test_size=0.3, random_state=0)
# create model
model = XGBClassifier(seed = 0, n_jobs = -1, learning_rate = 0.1, n_estimators = 100, max_depth = 3)
# fit
model.fit(x_train, y_train)
# predict & accuracy
y_pred = model.predict(x_test)
accuracy_score(y_test, y_pred)
>> 0.7435530085959885
성능이 완전 대폭 상승하였다 !!!!!!! 🥳
이 기세를 몰아 귀찮아서 전처리하지 않았던 장르 데이터도 살짝 건들여보았다.
df2 = pd.merge(rating_usr, movies[['movieId','genres']], on='movieId')
전체 장르 카테고리 리스트 생성 (중복 제거)
# | 기준으로 장르 구분
def genres_split(g):
return g.split('|')
# 각 영화에 대한 장르 dict 형태로 저장 key(movieId) : value(genres)
genres_list = {}
for i in df2.index:
genres_list[df2.loc[i]['movieId']] = df2.loc[i]['genres']
# dict에 저장된 value(장르) |으로 나눠줌
for key, value in genres_list.items():
genres_list[key] = genres_split(value)
# 모든 장르 카테고리 확인
genres_all = []
for value in genres_list.values():
length = len(value)
for i in range(0, length):
genres_all.append(value[i])
genres_all = set(genres_all)
(하나의 로우안에 여러 장르가 섞여있고 중복도 있어서 처리하는데 시간이 조금 걸렸다. 살짝 필요없는 코드도 섞여있는거 같기도 하고..)
# 데이터프레임으로 바꿔 인덱스 번호 매김
genres_df = pd.DataFrame({'name': list(genres_all)})
전체 데이터프레임에 장르 정보 추가
# |로 이어진 genre 리스트에서 배열로 전환
df2['genres_list'] = df2.genres.apply(genres_split)
del df2['genres']
# one-hot vector로 사용될 genre 열들 추가
for g in genres_df.name:
df2[g] = 0 # default
# 해당되는 장르 1로 변경
for index, genres in enumerate(df2.genres_list):
for genre in genres:
df2[genre][index] = 1
# 불필요한 열 삭제
del df2['genres_list']
links_metadata (links & metadata)와 df2(ratings & moive-id & genre) 연결
# metadata 추가
df2 = pd.merge(df2, links_metadata[['title', 'budget', 'original_language', 'popularity', 'runtime', 'vote_average', 'vote_count', 'movieId']], on='movieId')
original_language 전처리
숫자형 카테고리로 바꾸기 위해 카테고리마다 인덱스값(숫자) 부여
# language 종류 확인
langs = df2.original_language.unique()
langs_df = pd.DataFrame({'lan': langs})
# 인덱스 reset
langs_df.reset_index(inplace=True)
langs_df.set_index(langs_df.lan, inplace=True)
del langs_df['lan']
문자 -> 숫자로 카테고리 변경
def lang_categorized(lan):
return langs_df.loc[lan]['index']
df2.original_language = df2.original_language.apply(lang_categorized)
X 데이터 전처리
# object -> float
df2.popularity = df2.popularity.apply(lambda x: float(x))
df2.budget = df2.budget.apply(lambda x: int(x))
# y 데이터 카테고리
df2.rating = df2.rating.apply(rating_categorized)
# 타겟 데이터
y_data3 = df2['rating']
# feature selection
columns = ['Action', 'Adventure', 'Animation', 'Children', 'Comedy', 'Crime', 'Documentary', 'Drama', 'Fantasy', 'Film-Noir', 'Horror', 'IMAX', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Thriller', 'War', 'Western', 'budget', 'popularity', 'runtime', 'vote_average', 'vote_count','original_language']
X_data2 = df2[columns]
모델 학습 및 성능 확인
x_train, x_test, y_train, y_test = train_test_split(X_data2, y_data3, test_size=0.3, random_state=10)
params = {'learning_rate': 0.01, 'max_depth': 3, 'subsample': 0.6}
xgb = XGBClassifier(**params)
xgb.fit(x_train, y_train)
accuracy_score(y_test, xgb.predict(x_test))
>> 0.7675438596491229
# 별점 예측
def predict_rating(title, genre, runtime, budget, vote_avg, vote_cnt, lang, popularity):
# 새로운 x-data 행 추가
X_data2.loc['new'] = ""
X_data2.loc['new']['runtime'] = float(runtime)
X_data2.loc['new']['budget'] = int(budget)
X_data2.loc['new']['popularity'] = float(popularity)
X_data2.loc['new']['vote_average'] = float(vote_avg)
X_data2.loc['new']['vote_count'] = float(vote_cnt)
# language
X_data2.loc['new']['original_language'] = lang_categorized(lang)
# genre
genre = list(gerne.split(' '))
for g in list(genres_all):
if g in gerne:
X_data2.loc['new'][g] = 1
else:
X_data2.loc['new'][g] = 0
x_pred = X_data2.tail(1)
X_data2.drop('new')
y_pred = xgb.predict(x_pred)
return y_pred
데이터 input
title = input('제목을 입력해 주세요: ')
gerne = input('장르를 선택해 주세요(복수 나열 가능) '+ str(genres_all) + '\n: ')
runtime = input('상영 시간을 입력해 주세요: ')
budget = input('예산을 입력해 주세요: ')
vote_avg = input('평균 별점을 입력해 주세요: ')
vote_cnt = input('별점 수를 입력해 주세요: ')
popularity = input('인지도를 입력해 주세요: ')
lang = input('언어를 선택해 주세요 ' + str(langs) + '\n: ')
예측 결과 출력
rate = predict_rating(title, gerne, runtime, budget, vote_avg, vote_cnt, lang, popularity)
if rate == 0:
print(f"영화 [{title}]의 별점은 3.0 이상으로 예측됩니다.")
else:
print(f"영화 [{title}]의 별점은 3.0 미만으로 예측됩니다.")
>> 영화 [titanic]의 별점은 3.0 이상으로 예측됩니다.
예측 서비스도 완성 !!!!
[K-DIGITAL] 딥러닝 모델 최적화 이론 (0) | 2021.07.14 |
---|---|
[K-DIGITAL] 머신러닝을 넘어 딥러닝으로 (0) | 2021.07.14 |
[K-DIGITAL] 미드프로젝트. 영화 별점 데이터 분석 (0) | 2021.07.10 |
[K-DIGITAL] 세미프로젝트2. 타이타닉 생존자 예측 모델 만들기(2) (0) | 2021.07.06 |
[K-DIGITAL] 텍스트데이터 분석 TF-IDF과 유사도 계산 (0) | 2021.07.06 |
댓글 영역