본문 바로가기
데이터 사이언스 공부/Competition

영화 관객수 예측 모델 실습 (feat. 데이콘 대회)

by 아인슈페너먹고싶다 2022. 9. 16.

요즘 개념 정리만 많이해서 

 

실습 욕구가 땡겨 오랜만에 데이콘에 들어갔다. 

 

난이도 중급, 교육용 대회가 마감 2주 남았길래 얼른 신청하고 바로 문제를 풀어보았다!

 

첫 시작은 맛보기로 다른사람들이 공유해준 코드들에 내 사견을 곁들여 간단히 모델을 만들어 보았다.

 

 

 

 

빠르게 꼬꼬


 

1. 먼저 데이터를 살펴 보았다.

 

1
2
3
4
import pandas as pd
train = pd.read_csv('C:/Users/비밀/dacon/movie/movies_train.csv')
test = pd.read_csv('C:/Users/비밀/dacon/movie/movies_test.csv')
train.head(10)
cs

 

1
train.info()
cs

 

Column의 정보는 다음과 같다.

 

 

title : 영화의 제목
distributor : 배급사
genre : 장르
release_time : 개봉일
time : 상영시간(분)
screening_rat : 상영등급
director : 감독이름
dir_prev_bfnum : 해당 감독이 이 영화를 만들기 전 제작에 참여한 영화에서의 평균 관객수
(단 관객수가 알려지지 않은 영화 제외)
dir_prev_num : 해당 감독이 이 영화를 만들기 전 제작에 참여한 영화의 개수
(단 관객수가 알려지지 않은 영화 제외)
num_staff : 스텝수
num_actor : 주연배우수
box_off_num : 관객수

 


 

2. 간단한 전처리를 진행했다.

 

 

결측치를 찾아보았다.

 

1
train.isna().sum()
cs

 

 

330개? 어림도 없지!

 

 

 

1
2
3
4
#결측치 절반이나 있어서 바로! 제거
train = train.drop(['dir_prev_bfnum'],axis = 1)
test =  test.drop(['dir_prev_bfnum'],axis = 1)
 
cs

 

 

 

1
2
3
#제목은 예측에 필요하지 않아 제거
train = train.drop(['title'],axis= 1)
test = test.drop(['title'],axis= 1)
cs

 

 

 

 

감독명 또한 다양하고 COUNT 수가 설명할 만큼 충분하지 않다고 생각해서 제거

 

 

 

 

1
2
3
train.director.value_counts().head(10)
train = train.drop(['director'],axis = 1)
test = test.drop(['director'],axis = 1)
cs

 

 

 

 

배급사 또한 다양했지만 배급사별 표본수가 많은 탑 6는 남겨두고 

나머지는 '기타'로 처리 후 각각을 count rank대로 수로 변형 시켜주었다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
train.distributor.value_counts().head(10)
distributor_list = train.distributor.value_counts()[:6]
def func(distributor):
    if distributor in distributor_list:
        return distributor
    else:
        return '기타'
 
train['distributor'= train['distributor'].apply(lambda x : func(x))
test['distributor'= test['distributor'].apply(lambda x : func(x))
train['distributor_rank'= train.distributor.map({'CJ 엔터테인먼트' : 1'롯데엔터테인먼트' : 2'(주)NEW' : 3'(주)마운틴픽쳐스' : 4'(주)쇼박스' : 5,
                                      '인디스토리' : 6'기타' : 7})
test['distributor_rank'= test.distributor.map({'CJ 엔터테인먼트' : 1'롯데엔터테인먼트' : 2'(주)NEW' : 3'(주)마운틴픽쳐스' : 4'(주)쇼박스' : 5,
                                      '인디스토리' : 6'기타' : 7})
cs

 

 

 

 

장르도 마찬가지로 장르별 평균 관객수를 나열한 후 랭크를 먹여주었다.

 

1
2
3
4
5
train.groupby('genre').box_off_num.mean().sort_values()
train['genre_rank'= train.genre.map({'뮤지컬' : 1'다큐멘터리' : 2'서스펜스' : 3'애니메이션' : 4'멜로/로맨스' : 5,
                                      '미스터리' : 6'공포' : 7'드라마' : 8'코미디' : 9'SF' : 10'액션' : 11'느와르' : 12})
test['genre_rank'= test.genre.map({'뮤지컬' : 1'다큐멘터리' : 2'서스펜스' : 3'애니메이션' : 4'멜로/로맨스' : 5,
                                      '미스터리' : 6'공포' : 7'드라마' : 8'코미디' : 9'SF' : 10'액션' : 11'느와르' : 12})
cs

 

 

 

물론 새로 만들고 나서의 기존 Column들은 제거해주었다.

 

 

1
2
3
4
train = train.drop(['distributor'],axis= 1)
train = train.drop(['genre'],axis= 1)
test = test.drop(['distributor'],axis= 1)
test = test.drop(['genre'],axis= 1)
cs

 

 

 

 

날짜는 개봉일 기준으로 년도 별, 월 별 변수를 생성해 지정해주었다.

 

 

1
2
3
4
5
6
7
train['년'= train['release_time'].apply(lambda x: int(x[:4]))
train['월'= train['release_time'].apply(lambda x: int(x[5:7]))
train =  train.drop(['release_time'],axis = 1)
 
test['년'= test['release_time'].apply(lambda x: int(x[:4]))
test['월'= test['release_time'].apply(lambda x: int(x[5:7]))
test =  test.drop(['release_time'],axis = 1)
cs

 

 

 

 

마지막으로 남은 범주형 Column(상영등급 등)은 더미변수화 해주어 전처리를 마무리하였다.

 

 

1
2
train = pd.get_dummies(train)
test = pd.get_dummies(test)
cs

 


 

3. 모델링

 

 

 

 

관객 수와 나머지 Column을 분리해주었다. 

 

(train, test로 split은 나중에... 오늘은 일단 바로)

 

1
2
train_x = train.drop(['box_off_num'],axis= 1)
train_y = train['box_off_num']
cs

 

 

 

 

 

제일 무난하고 간단한!!

 

갓갓 랜덤포레스트 모델을 사용해서 모델링을 해주었다.

 

 

1
2
3
4
from sklearn.ensemble import RandomForestRegressor
model=RandomForestRegressor(n_estimators=100)
model.fit(train_x,train_y)
pred =model.predict(test)
cs

 

 

 

그렇게 생성하고 학습시킨 모델을 test 데이터셋에 적용하였고

 

 

 

결과물을 데이콘에 제출하였다.

 

두구두구두구 

 

결과는?

 

 

 

 

4..76등!

 

제출인원이 1000명 정도 되니까 첫 제출에 절반권은 들어온거 같다.

 

 

 

 


 

 

 

 

전처리도 잘 하지 못하였고

 

사용한 모델도 제일 간단한 랜덤포레스트 모델에 하이퍼파리미터 조정도 하지 않아서 

 

점수가 높지 않은 것 같다.

 

 

다음엔 더 다양한 모델도 사용하고 

 

train, test split 및 교차검증 또한 진행하여 

 

점수를 높여봐야겠다. 

 

 

 

 

간단 test 꿑!

댓글