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축값을 넣어서 나타낸다
    •  
# - 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
반응형

+ Recent posts