Python

데이터 분석 1 - 영화 흥행 요인 분석 1

retill28 2024. 7. 12. 06:10

 

데이터 프레임을 공부했던 부분을 응용해 실제적으로 영화 데이터를 분석해보려고 한다. 

우선 사용할 데이터는 2개의 csv파일로 'tmdb_5000_credits .csv ' 와 'tmdb_5000_movies.csv' 이다. 

 

 

 

1. 데이터 살펴보기

 

먼저 두 파일을 불러와 열어본다. 첫번째가 movie 데이터, 두번째가 credits 데이터이다.

movies = pd.read_csv('tmdb_5000_movies.csv')
movies.head()

credits = pd.read_csv('tmdb_5000_credits.csv')
credits.head()

 

 

 

 

각 컬럼들을 정리해보면 다음 표와 같다.

movie  credits 
  • budget: 영화 예산 (단위: 달러)
  • genres: 모든 장르
  • homepage: 공식 홈페이지
  • id: 각 영화당 unique id
  • original_language: 원 언어
  • original_title: 원 제목
  • overview: 간략한 설명
  • popularity: TMDB에서 제공하는 인기도
  • production_companies: 모든 제작사
  • production_countries: 모든 제각국가
  • release_date: 개봉일
  • revenue: 흥행 수익 (단위: 달러)
  • runtime: 상영 시간
  • spoken_language: 사용된 모든 언어
  • status: 개봉 여부
  • title: 영문 제목
  • vote_avearage: TMDB에서 받은 평점 평균
  • vote_count: TMDB에서 받은 투표수
  • movie_id: 각 영화당 unique id
  • title: 영문 제목
  • cast: 모든 출연진
  • crew: 모든 제작진

 

그렇다면 이 데이터로 알아볼 질문들을 먼저 살펴보자. 

무엇을 분석할 것인가에 따라 어떤 데이터를 사용할지, 삭제할지를 정할 수 있다. 

질문의 예시
  • 연도별 흥행 수익은?
  • 가장 흥행한 영화 TOP 10은?
  • 흥행에 가장 성공한 감독과 배우는?
  • 장르와 흥행 수익
    • 흥행 수익이 좋은 장르는?
    • 시간의 흐름에 따라 유행하는 장르가 바뀌는가?
    • 월별로 흥행하는 장르가 있는가?
  • 수익과 예산, 투표수, 평점과의 상관관계는?
  • ROI(예산 대비 수익)가 높으면서 흥행에 성공한 영화의 특징은?

 

 

 

 

 

2. 데이터 전처리 

  • 각 데이터에서 필요한 칼럼만 남긴다.
movies_df = movies[['id','budget','genres','title','release_date','revenue','vote_average','vote_count']]
credits_df = credits[['movie_id','crew','cast']]

 

 

  • merge함수를 통해 두 데이터를 결합한다. 새로 만들어진 데이터프레임은 아래와 같다.
data = pd.merge(movies_df, credits_df, left_on = 'id', right_on = 'movie_id').drop('movie_id', axis=1)
data.head()

 

 

  • 위의 질문 중 필요한 데이터인, ROI (예산 대비 수익) 이라는 컬럼을 새로 만든다. 
data['roi'] = data['revenue'] / data['budget']
data.head()

 

 

 

  • 감독 이라는 컬럼을 만든다. 이 컬럼은 crew 컬럼에서 전처리해서 만들 수 있다.  
    crew는 딕셔너리들이 있는 리스트를 문자열로 나타내고 있다.
    여기서 department 부분이 directing인 리스트의 name 부분이 감독의 이름이 된다. 
    문자열을 파이썬 딕셔너리형 리스트로 바꾸기 위해 ast라는 라이브러리를 사용했고, 
    department 부분이 directing인 리스트의 name을 반환하는 함수를 만들어 
    새로운 칼럼 director에 집어넣는다. 
import ast

print(ast.literal_eval(data['crew'][0]))
data['crew'] = data['crew'].apply(ast.literal_eval)
def get_director(x):
    for i in x:
        if i['job'] == 'Director':
            return i['name']
            
get_director(data['crew'][0])   # 출력 결과 'James Cameron'
data['director'] = data['crew'].apply(get_director)

 

 

 

  • 같은 방법으로 cast 에서 배우 이름을 뽑아 cast_name이라는 배우 칼럼을, 
    genres에서 name을 뽑아 main_genres라는 컬럼을 새로 만든다. 
#배우 컬럼 생성
data['cast_name'] = data['cast'].apply(lambda x: [i['name'] for i in ast.literal_eval(x)])
data.head()

# 메인장르 컬럼 생성
def get_genres(x):
    if len(x) > 0:
        return x[0]['name']

data['main_genre'] = data['genres'].apply(get_genres)
data.head()

 

 

 

  • 분석 중에 '시간의 흐름에 따라' 라는 기준이 있으므로 날짜 데이터가 필요하다. 
    이 날짜 데이터의 형식을 %Y-%m-%d로 바꾼 후, 년도, 월 컬럼을 만든다. 
data['release_date'] = pd.to_datetime(data['release_date'], format='%Y-%m-%d')
data['year'] = data['release_date'].dt.year
data['month'] = data['release_date'].dt.month
data.head()

 

 

 

  • id란은 숫자로 채워져있으나 영화 고유번호를 이야기하는 문자열이므로 타입을 바꿔준다.
data['id'] = data['id'].astype(str)

 

 

 

  • 필요한 종류의 컬럼들을 생성했으면 이젠 결측치를 제거한다. 
    우선 결측치를 알아보는 가장 좋은 방법은 data.info() 함수를 사용하는 것이다. 
    아래처럼 결과가 나오면 총 4803개의 데이터가 있는 것을 확인할 수 있다. 
    결측치가 없는 부분에 대하여만 분석을 진행할 예정이므로 drpona()를 사용해 간단히 제거하는 방법을 택한다. 

좌 : 제거 전 / 우 : 제거 후

 

 

 

 

 

여기까지가 분석을 위한 데이터 호출, 전처리 부분이다. 

생각보다 꼼꼼하게 신경써줘야 할 것이 많아 주의가 필요했고, 

아직 데이터프레임에 익숙하지 않아서 고민을 거듭한 부분도 있다.

이 다음글에서는 본격적인 분석을 써보도록 하겠다.