728x90
반응형
영화 데이터 전처리 및 시각화
1. 외부파일 읽어들이기
- 제목 : "title" , 평점 : "score", 리뷰 : "comment", 긍정/부정 : "label"
### 라이브러리 정의
# - 행렬데이터 처리 라이브러리
import pandas as pd
file_path = "./data/movie_reviews.txt"
df_org = pd.read_csv(file_path,
### 구분자 알려주기
delimiter = "\t",
names=["title", "score", "comment", "label"])
df_org

2. 데이터 전처리
🌳데이터 정보 확인 : 결측치 확인
df_org.info()

🌳 기초통계 확인 : 이상데이터 확인
df_org.describe()

🌳 평점(score) 현황데이터 확인
df_org["score"].value_counts()

🌳중복데이터 확인하기
- keep=False : 중복된 모든행 체크(중복이 있으면 True, 없으면 False)
df_org[df_org.duplicated(keep=False) == True]

🌳중복 데이터 추출하기
- 중복 중에 하나는 제외하고 나머지 중복만 추출
df_del = df_org[df_org.duplicated() == True]
len(df_org[df_org.duplicated() == True])

🌳중복제거하기
df_new = df_org.drop_duplicates()
len(df_new)
df_new.info()

중복된 데이터 제거로 행수가 4073에서 4033으로 줄어들었다.
3. 데이터 탐색하기
🌳영화 제목만 추출하기
df_new["title"].unique()

🌳영화 제목별 리뷰갯수 현황 확인하기
df_new["title"].value_counts()

🌳각 영화별 평점 기초통계 확인하기
- 영화제목별 평점에 대한 그룹집계하기
movie_info = df_new.groupby("title")["score"].describe()
- 기초통계 행단위 데이터 내림차순 정렬하기
movie_info = movie_info.sort_values(by=["count"], axis=0, ascending=False)
movie_info

4. 데이터 시각화
🌳 라이브러리
### 시각화 라이브러리
import matplotlib.pyplot as plt
### 폰트 설정 라이브러리
from matplotlib import font_manager, rc
### 한글폰트 설정
plt.rc("font", family="Malgun Gothic")
### 마이너스 기호 설정
plt.rcParams["axes.unicode_minus"] = False
5. 영화별 평점 평균 시각화 (1) - 막대그래프
영화별 별점 평균이 가장 큰 영화는 orange 색으로, 나머지는 lightgrey 색으로 표현
🌳 라이브러리
### 평점 평균 계산을 위해 사용
import numpy as np
🌳 영화제목을 리스트 타입으로 받아오기
- array()
- 넘파이 (numpy)에서 사용하는 배열(파이썬의 리스트와 동일)
- 단, 하나의 타입만 저장 가능하다.
- 이외 사용법은 파이썬의 리스트와 동일하다
- unique() : numpy의 배열 타입으로 반환함
movie_title = df_new["title"].unique()
movie_title

- tolist() : 파이썬의 리스트 타입으로 변환하는 함수
movie_title = df_new["title"].unique().tolist()
movie_title

🌳 영화별 평점 평균 추출하기
### 영화별 평점 평균 추출하기
# - 평점평균값을 저장할 딕셔너리 변수 선언
avg_score = {}
for m_title in movie_title:
### 평점 평균 계산하여 딕셔너리에 넣가
avg = df_new[df_new["title"] == m_title]["score"].mean()
# print(f"평점평균 : {avg}")
### 딕셔너리에 담기
# key는 제목, value는 평점평균값
avg_score[m_title] = avg
print(f"딕셔너리 최종값 : {avg_score}")

🌳 영화별 평점 평균 시각화
- 컬러값 지정하기
- array_str() : 문자열로 변환하는 함수
- where() : 파이썬에서 if문과 동일한 조건문
- where(조건, 참, 거짓) : 조건이 참이면 첫번째 값, 거짓이면 두번째 값 처리
# - 그래프 너비와 높이 지정
plt.figure(figsize=(10, 5))
# - 그래프 제목
plt.title("영화별 평점 평균 막대그래프", fontsize=17, fontweight="bold")
### 각 영화별 평점 평균 막대그래프 그리기
for k, v in avg_score.items() :
color = np.array_str(np.where(v==max(avg_score.values()), "orange", "lightgrey"))
#print(color)
### 막대 그래프 그리기
plt.bar(k, v, color=color)
### 막대 그래프 상단에 평점평균 텍스트 표시하기
plt.text(k, v, "%.2f"%v, horizontalalignment="center", verticalalignment="bottom")
### x축과 y축 제목 넣기
plt.xlabel("영화제목", fontweight="bold")
plt.ylabel("평점평균", fontweight="bold")
### x축의 값 각도 조절하기
plt.xticks(rotation = 75)
### 그래프를 이미지로 저장시키기
# - savefig() 함수는 plt.show() 전에 수행되어야 한다.
plt.savefig("./img/영화별 평점 평균 막대그래프.png")
plt.show()

6. 영화별 평점 평균 시각화 (2) - 점(분포) 그래프 그리기
🌳각 영화별 평점 분포도 그리기
- 하나의 큰 그래프 안에 10개의 그래프를 넣어서 표현 → 이를 subplot 이라고 칭한다.
- <이해를 위한 코드 설명 1>
- fig, axs = plt.subplots(5, 2, figsize=(15, 25)) : 그림(fig)과 5x2 그리드로 구성된 축(axs)을 만든다.
- axs.flatten() : 5x2 그리드를 1차원 배열로 펼친다. 이렇게 하면 단일 루프에서 각 서브플롯을 반복하는 것이 더 쉬워진다.
- avg_score.keys() 및 avg_score.values() : 나타낸 데이터 집합을 반복한다. 각 반복은 다른 영화 제목에 해당한다.
- num_reviews = len(df_new[df_new["title"] == title]) : 현재 영화 제목의 리뷰 수를 계산한다.
- x = np.arange(num_reviews) : 0에서 num_reviews - 1까지의 x값으로 이루어진 배열을 생성한다.
- y = df_new[df_new["title"] == title]["score"] : DataFrame에서 현재 영화 제목의 평점을 추출한다.
- subtitle = f"{title} ({num_reviews}명)" : 현재 서브플롯의 제목으로 영화 제목과 리뷰 수를 나타내는 부제목을 생성한다.
- ax.set_title(subtitle, fontsize=15, fontweight="bold") : 서브플롯의 제목을 설정한다.
- ax.plot(x, y, "o") : 점으로 평점을 리뷰 인덱스에 대해 나타내는 산점도를 생성한다.
- ax.axhline(avg, color="red", linestyle="--") : 영화의 평균 평점을 나타내는 수평 대시된 선을 추가한다.
- <이해를 위한 코드 설명 2>
- fig, axs = plt.subplots(5, 2, figsize=(15, 25))
→ 서브플롯 함수 사용해서 큰 그래프 하나에 작은 그래프들을 넣으려는 작업을 함
→ 작은 그래프들을 몇행 몇열로 넣을 건지 지정 해야한다. 지금 코드는 5행 2열. figsize는 전체 크기 - axs = axs.flatten()
→ for문을 사용하기 위해 flatten으로 틀 정렬 >> 이건 문법 적인 것 - for title, avg, ax in zip(avg_score.keys(), avg_score.values(), axs)
→ avg_score는 영화 제목을 키로, 해당 영화의 평균 평점을 값으로 가지는 딕셔너리로 avg_score.keys()는 딕셔너리의 키들을, avg_score.values()는 딕셔너리의 값들을 반환한다.
→ axs는 5행 2열의 subplot들을 1차원 배열로 평탄화한 것이다. 따라서 zip(avg_score.keys(), avg_score.values(), axs)는 영화 제목, 평균 평점, 그리고 subplot을 하나의 튜플로 묶어 반환한다. - df_new[df_new["title"] == title]
→ 데이터프레임 df_new에서 영화 제목이 title인 행들을 선택하는 부분이다. len(df_new[df_new["title"] == title])은 해당 영화의 리뷰 개수를 반환한다.
→ 따라서 for title, avg, ax in zip(avg_score.keys(), avg_score.values(), axs):에서 각각의 반복마다 title에는 영화 제목, avg에는 해당 영화의 평균 평점, ax에는 subplot이 할당된다. 그리고 num_reviews에는 해당 영화의 리뷰 개수가 할당된다. - x = np.arange(num_reviews), y = df_new[df_new["title"] == title]["score"]
→ x,y축을 지정해 주려는데 y는 평점이므로 0에서 10까지 범주가 정해져 있음
→ 그러나 x축은 갯수. 갯수는 데이터가 없음. 그렇기 때문에 전체 갯수를 뽑고 0부터 순차적으로 뽑아 냄
→그려진 첫번째 그래프에선 500씩 범주를 알아서 잘라냄
→ arange로 순차적인 리스트 값으로 반환 (일정한 범위로 쪼개준다)
→ x,y는 범주형 데이터 - ax.set_title
→ 해당공간(ax)의 제목 지정 - ax.plot(x, y, "o")
→ 공간에 그래프 그린다. - ax.axhline(avg, color="red", linestyle="--")
→ ax.axhline은 서브플롯 안에 또다른 그래프를 그리는 것 위에 것과 상관없음
→ avg 수평선을 기준으로 y축값을 넣어서 나타낸다
- fig, axs = plt.subplots(5, 2, figsize=(15, 25))
# - 5행 2열의 subplot 생성하여 구현하기
# - subplots(행 갯수, 열 갯수, 전체 그래프 크기)
# - fig : 큰 그래프 정보
# - axs : 5행 2열의 내부 그래프 공간 정보
fig, axs = plt.subplots(5, 2, figsize=(15, 25))
### 여러개의 그래프를 for문을 이용해서 표현하고자 할 떼 아래 먼저 수행
# - flatten() : 틀 정렬하기 - > 5행 2열의 틀을 정렬해 놓기
axs = axs.flatten()
### 각 그래프를 행렬 공간의 subplot에 넣기
for title, avg, ax in zip(avg_score.keys(), avg_score.values(), axs):
# print(f"{title} / {avg} / {ax}")
### x축에는 영화 리뷰 갯수, y축에는 평점 평균
### 리뷰 갯수 추출하기
num_reviews = len(df_new[df_new["title"] == title])
# - arange(num) : 0부터 num까지의 값을 순차적으로 만들기
x = np.arange(num_reviews)
# print(f"x ---------> {x}")
### y축에는 평점 추가
y = df_new[df_new["title"] == title]["score"]
# print(f"y ----------> {y}")
### 각 그래프에 제목 넣기
subtitle = f"{title} ({num_reviews}명)"
ax.set_title(subtitle, fontsize=15, fontweight="bold")
### 점 그래프 그리기
# - "o" : 점으로 표현하는 마커 기호
ax.plot(x, y, "o")
### 각 영화별 평점평균을 빨강색 점선으로 표시하기
# - axhline() : 각 subplot 공간에 수평선 그리기
ax.axhline(avg, color="red", linestyle="--")
plt.savefig("./img/각 영화별 평점 분포도.png")
plt.show()

728x90
반응형
'Digital Boot > Database' 카테고리의 다른 글
[데이터 수집][Crawling] 영화 긍정 / 부정 리뷰 데이터 빈도 분석 및 워드 클라우드 시각화 (4) | 2023.12.05 |
---|---|
[데이터 수집][Crawling] 영화 데이터 전처리 및 시각화 (2) (0) | 2023.12.05 |
[데이터수집][Crawling] 웹 크롤링을 이용한 영화 데이터수집 (1) | 2023.12.04 |
[Data Wrangling] 데이터 전처리 시각화 - 히트맵 / 막대그래프 / histplot / 선그래프 (1) | 2023.11.30 |
[Data Wrangling] 데이터 처리 시각화 (2) (0) | 2023.11.30 |