-
[2월 2주차-2/14]🎬 넷플릭스 데이터 분석 프로젝트Why Not SW CAMP 5기/수업 기록 2025. 2. 14. 15:34
📌 개요
넷플릭스 데이터 분석 프로젝트는 넷플릭스의 콘텐츠 데이터를 탐색하고, 데이터 전처리 과정을 거쳐 다양한 시각화를 통해 인사이트를 도출하는 것을 목표로 합니다. 이 분석을 통해 콘텐츠의 트렌드를 파악하고, 사용자 맞춤형 추천 시스템 개선을 위한 기초 자료를 제공합니다.
🛠 사용 라이브러리
- 넘파이 (NumPy): 수치 해석 및 배열 연산
- 판다스 (Pandas): 데이터 분석 및 전처리
- 맷플롯립 (Matplotlib) / 시본 (Seaborn): 데이터 시각화
- 워드클라우드 (WordCloud): 텍스트 데이터 강조
🎯 데이터 분석 목표
- 데이터를 빠르게 파악하고 이해하기
- 데이터 전처리를 수행하여 분석 가능한 형태로 변환
- 다양한 시각화 기법을 활용하여 인사이트 도출
- 넷플릭스의 콘텐츠 트렌드 및 사용자 선호도 분석
🔍 데이터 전처리
1. 데이터 로드 및 파악
넷플릭스 데이터셋 (netflix_titles.csv)을 로드한 후 컬럼을 확인하면 아래와 같습니다:
''' csv 로드 ''' netflix = pd.read_csv('./data/netflix_titles.csv') netflix.head(3) ''' 데이터 내용 확인 : 컬럼 확인 ''' netflix.columns ''' Index(['show_id', 'type', 'title', 'director', 'cast', 'country', 'date_added', 'release_year', 'rating', 'duration', 'listed_in', 'description'], dtype='object') ''' ''' 열에 대한 요약 정보 확인 ''' netflix.info() ''' RangeIndex: 8807 entries, 0 to 8806 -> 총 8807개 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 show_id 8807 non-null object 1 type 8807 non-null object 2 title 8807 non-null object 3 director 6173 non-null object -> 결측치가 있음 4 cast 7982 non-null object -> 결측치가 있음 5 country 7976 non-null object -> 결측치가 있음 6 date_added 8797 non-null object -> 결측치가 있음 7 release_year 8807 non-null int64 8 rating 8803 non-null object -> 결측치가 있음 9 duration 8804 non-null object -> 결측치가 있음 10 listed_in 8807 non-null object 11 description 8807 non-null object dtypes: int64(1), object(11) '''nfo()를 통해 데이터의 결측치 및 타입을 확인한 결과, 일부 컬럼에 결측치가 존재함을 확인할 수 있었습니다.
2. 🏗 결측치 처리
결측치 비율을 확인한 후 아래 기준에 따라 처리했습니다:
- 5% 미만: 해당 행 삭제
- 5% ~ 20%: 평균/중간값/최빈값 등으로 대체
- 20% 이상: 열 전체 삭제 고려
''' 넷플릭스 데이터셋 결측치 처리 ''' ''' 결측치 개수 : isna().sum() 결측치 비율: isna().sum() / len() * 100 ''' for i in netflix.columns: missingValueRate = netflix[i].isna().sum() / len(netflix) * 100 if missingValueRate > 0 : print(f'{i} null rate: {round(missingValueRate,2)}') ''' director null rate: 29.91 <- 제거(컬럼) : 대체 cast null rate: 9.37 <- 대체 country null rate: 9.44 <- 대체 date_added null rate: 0.11 <- 제거(해당 행) rating null rate: 0.05 <- 제거(해당 행) duration null rate: 0.03 <- 제거(해당 행) ''' ''' country 결측치(9.44%) 대체 ''' netflix['country'] = netflix['country'].fillna('No Data') ''' director/cast 대체 ''' netflix['director'] = netflix['director'].replace(np.nan, 'No Data') netflix['cast'] = netflix['cast'].replace(np.nan, 'No Data') ''' 결측지를 가진 행 제거 ''' netflix = netflix.dropna(subset = ['date_added', 'rating', 'duration']) netflix.info() ''' 결측치 갯수로 재확인 ''' netflix.isna().sum()3. 🏷 피처 엔지니어링
🎭 시청 등급(age_group) 생성
- rating 변수를 활용하여 시청 등급을 다음과 같이 분류:
- ALL (모두 시청 가능): G, TV-G, TV-Y
- Older Kids (어린이): PG, TV-Y7, TV-Y7-FV, TV-PG
- Teens (청소년 초반): PG-13
- Young Adults (청소년 후반): TV-14
- Adults (성인): R, TV-MA, NC-17, NR, UR
''' 넷플릭스 시청 등급 변수 ''' ''' 넷플릭스 데이터 프레임에서 rating 변수를 이용하여 age_grop(시청등급) ALL(모든) / Older Kids(어린이) / Teens(청소년초반) / Young Adults(청소년후반) / Aaults(성인) ''' age_group_dic = {'G': 'ALL', # 전체 'TV-G': 'ALL', 'TV-Y': 'ALL', 'PG': 'Older Kids', # 7세 이상 'TV-Y7': 'Older Kids', 'TV-Y7-FV': 'Older Kids', 'TV-PG': 'Older Kids', 'PG-13': 'Teens', # 13세 이상 'TV-14': 'Young Adults', # 16세 이상 'NC-17': 'Adults', # 18세 이상 'NR': 'Adults', # 등급 보류 'UR': 'Adults', # 무삭제 등급 'R': 'Adults', 'TV-MA': 'Adults' } # map()을 이용하여 age_group에 저장 netflix['age_group'] = netflix['rating'].map(age_group_dic) ''' 전처리가 완료된 데이터를 csv 파일로 저장 ''' netflix.to_csv('./result/netflix_prepro.csv', index =False) ''' 전처리된 데이터 읽기 ''' netflix = pd.read_csv('./result/netflix_prepro.csv')변환된 데이터를 netflix_prepro.csv 파일로 저장했습니다.
📊 데이터 시각화
1. 🎨 브랜드 색상 설정
넷플릭스 브랜드 색상을 활용한 데이터 시각화:

sns.palplot(['#221f1f','#b20710','#e50914','#f5f5f1']) plt.title('Netflix Brand Palette', loc='left', fontfamily='serif', fontsize=15, y=1.2) plt.show()2. 🍿 영화 vs TV 쇼 비율 (파이 차트)

type_counts = netflix['type'].value_counts() plt.figure(figsize=(5,5)) plt.pie(type_counts, labels=type_counts.index, autopct='%0.f%%', startangle=100, explode=[0.05, 0.05], shadow=True, colors=['#b20710','#221f1f']) plt.suptitle('Netflix', fontfamily='serif', fontsize=15) plt.title('Movies & TV Shows', fontfamily='serif', fontsize=11) plt.show()3. 📺 인기 장르 분석 (막대 그래프)

genres = netflix['listed_in'].str.split(', ', expand=True).stack().value_counts() plt.figure(figsize=(10,7)) sns.barplot(x=genres.values, y=genres.index, hue=genres.index, palette='RdGy') plt.suptitle('Netflix', fontfamily='serif', fontsize=15) plt.title('Popular Genres', fontfamily='serif', fontsize=11) plt.xlabel('Count', fontsize=14) plt.ylabel('Genre', fontsize=14) plt.grid(axis='x') plt.show()4. 🌍 국가별 시청층 분석 (히트맵 활용)
국가별 특정 연령대 콘텐츠 비율을 분석하여 시청 트렌드를 도출할 수 있습니다. 이를 활용하여 넷플릭스의 콘텐츠 기획 전략을 수립할 수 있습니다.
각 나라의 콘텐츠 수를 집계한 후 각 나라에서 어느 나이 그룹이 어떤 콘텐츠를 소비하는지 분석하겠습니다
# 쉼표로 country 열의 값을 파이썬 리스트로 netflix['country'] = netflix['country'].str.split(', ')- netflix['country'] 열에는 국가 정보가 쉼표(,)로 구분되어 있는 경우가 있음.
- .str.split(', ')을 사용하여 문자열을 쉼표 기준으로 분할하고 리스트 형태로 변환함.
- 예를 들어, "United States, Canada" → ['United States', 'Canada']로 변환됨.
# 파이썬 리스트로 바꾼 것을 explode함수를 적용하여 개별 행으로 분리 netflix_age_country = netflix.explode('country')- .explode('country')를 사용하여 country 열의 리스트 값을 개별 행으로 확장함.
- 즉, 여러 개의 국가에 속한 콘텐츠를 각 국가별로 따로 저장하는 방식으로 변환.
- 예제:
before_explode = pd.DataFrame({'title': ['Movie A', 'Movie B'], 'country': [['US', 'UK'], ['France']]}) print(before_explode)title country 0 Movie A [US, UK] 1 Movie B [France]after_explode = before_explode.explode('country') print(after_explode)title country 0 Movie A US 0 Movie A UK 1 Movie B France - 따라서, 각 콘텐츠가 포함된 모든 국가에 대해 개별 행을 생성함.
# 5. 각 나이 그룹에 따른 국가별 넷플릭스 콘텐츠 수? netflix_age_country_unstack = netflix_age_country.groupby('age_group')['country'] \ .value_counts().unstack()- groupby('age_group')['country'].value_counts():
- age_group을 기준으로 country별 개수를 계산.
- 즉, 각 나이 그룹별로 국가별 콘텐츠 개수를 세는 작업.
- .unstack():
- value_counts() 결과를 가로로 펼쳐서(행 → 열) 테이블 형태로 변환.
- 그룹화된 데이터를 풀어서 다시 데이터프레임으로 변환하는 것
- 결과 예시:
country US UK France Canada age_group Kids 10 5 3 4 Teens 20 10 7 8 Adults 30 15 10 12
- 즉, 각 연령대(age_group)별로 국가(country)별 넷플릭스 콘텐츠 수를 분석하는 표를 생성.
특정 나이 그룹에 따른 특정 나라별 콘텐츠로 필터링
# 연령 age_order = ['ALL', 'Older Kids', 'Teens', 'Adults'] # 국가 country_order = ['United States', 'India', 'United Kingdom', 'Canada', 'Japan', 'France', 'South Korea', 'Spain', 'Mexico', 'Turkey'] # 필터링 # 행: age_order / 열: country_order netflix_age_country_unstack = netflix_age_country_unstack.loc[age_order, country_order] # 결측치 처리 0 netflix_age_country_unstack=netflix_age_country_unstack.fillna(0) ''' country United States India United Kingdom ... Spain Mexico Turkey age_group ... ALL 255.0 16.0 63.0 ... 9.0 3.0 1.0 Older Kids 694.0 169.0 145.0 ... 15.0 20.0 9.0 Teens 433.0 11.0 84.0 ... 5.0 4.0 0.0 Adults 1803.0 278.0 408.0 ... 185.0 120.0 71.0 '''각 국가별 콘텐츠 비율을 구하기
netflix_age_country_unstack = netflix_age_country_unstack\ .div(netflix_age_country_unstack.sum(axis=0), axis=1)
즉, 국가별 전체 콘텐츠 수 대비 각 연령대별 비율을 계산하는 작업입니다.
netflix_age_country_unstack.sum(axis=0)
- netflix_age_country_unstack는 각 연령대(age_group)별 국가(country)별 콘텐츠 개수를 나타내는 데이터프레임
- .sum(axis=0)은 각 국가별 전체 콘텐츠 개수를 계산
- 예를 들어 netflix_age_country_unstack이 아래와 같다고 가정하면:.sum(axis=0)의 결과:즉, 각 국가에서 제공되는 전체 콘텐츠 수를 계산한 것.
country US UK France Canada age_group Kids 10 5 3 4 Teens 20 10 7 8 Adults 30 15 10 12 US 60 UK 30 France 20 Canada 24
2. .div(..., axis=1)
- .div()는 나눗셈 연산을 수행하는 메서드
- axis=1을 설정하면 각 열(column, 즉 국가별) 기준으로 나눗셈을 수행합니다.
- 즉, 각 연령대의 콘텐츠 개수를 해당 국가의 전체 콘텐츠 수로 나누어 **비율(%)**을 계산하는 것.예시해석:
- 예를 들어, 미국(US)에서 Kids 콘텐츠의 비율은 10 / 60 = 0.1667 (16.67%)
- Teens는 20 / 60 = 33.33%
- Adults는 30 / 60 = 50%
- 이렇게 각 연령대의 콘텐츠가 해당 국가에서 차지하는 비율을 계산한 것.
country US UK France Canada age_group Kids 0.1667 0.1667 0.1500 0.1667 Teens 0.3333 0.3333 0.3500 0.3333 Adults 0.5000 0.5000 0.5000 0.5000
시각화
plt.figure(figsize =(15,5)) cmap = plt.matplotlib.colors.LinearSegmentedColormap.from_list('', ['#221f1f','#b20710','#f5f5f1']) sns.heatmap(netflix_age_country_unstack, cmap = cmap, linewidths=2.5, annot=True, # 각 셀에 데이터 값 표시 fmt = '.0%' ) plt.suptitle('netflix', fontfamily='serif', fontsize=15) plt.title('Percentage of content by country by age group', fontfamily='serif', fontsize=11) plt.show()
5. 📝 콘텐츠 설명 워드클라우드
pip install wordcloud 설치
from wordcloud import WordCloud from PIL import Image plt.figure(figsize=(15,5)) # netflix['description']을 list로 변환시킨 후 str로 변환 text = str(list(netflix['description'])) # logo image 갖고오고 Image.open() # image를 넘파이 배열로 변환해줘야됨 np.array() mask = np.array(Image.open('C:/work_python0203~/20250214/data/netflix_logo.jpg')) # mask = : 단어를 그릴 위치 설정, 흰색 항목은 마스킹 된 것으로 간주 # 색상맵 cmap = plt.matplotlib.colors.LinearSegmentedColormap.from_list('', ['#221f1f','#b20710']) # 워드클라우드 생성 wordcloud = WordCloud(background_color='white', width = 1400, height = 1400, max_words = 170, mask = mask, colormap=cmap).generate(text) plt.suptitle('Movies and TV shows', fontweight='bold', fontfamily='serif', fontsize=15) # 워드클라우드 결과를 plots 창에 나타내기 plt.imshow(wordcloud) plt.axis('off') # 축 감추기 plt.show()
🔎 결론 및 인사이트
넷플릭스 데이터 분석을 통해 다음과 같은 인사이트를 얻을 수 있었습니다:
- 🎬 영화와 TV 쇼 비율: 영화 콘텐츠가 TV 쇼보다 약 2배 많음.
- 📌 인기 장르 분석: 국제 영화(International Movies)와 드라마(Dramas)가 가장 많이 등장함.
- 📈 국가별 시청층 분석: 국가별 인기 콘텐츠 유형 및 타겟 연령층을 확인 가능.
- 🔍 주요 테마 분석 (워드클라우드 활용): 콘텐츠 설명에서 자주 등장하는 키워드를 분석하여 주요 트렌드 파악 가능.
이러한 분석 결과는 넷플릭스의 마케팅 전략, 콘텐츠 기획, 사용자 맞춤 추천 시스템을 개선하는 데 활용할 수 있습니다. 🚀
'Why Not SW CAMP 5기 > 수업 기록' 카테고리의 다른 글
[2월 3주차-2/17(2)]📊 파이썬 웹 스크래핑으로 삼성전자 주가 데이터 분석하기 (1) 2025.02.17 [2월 3주차-2/17(1)]📊 심부전 데이터 분석: 데이터 전처리부터 시각화까지! (0) 2025.02.17 [2월 2주차-2/13(3)]🍻음주 빈도가 삶의 만족도와 건강 상태에 미치는 영향 분석 (0) 2025.02.13 [2월 2주차-2/13(2)]🌟 인터랙티브 시각화: HTML 파일로 저장하여 웹 브라우저에서 실행하기 (1) 2025.02.13 [2월 2주차-2/13(1)]📊 통계 분석 기법을 이용한 가설 검정 (0) 2025.02.13