Open In Colab

구글 드라이브 연동 / 기초 패키지 설치

from google.colab import drive
drive.mount('/content/drive')
path = '/content/drive/MyDrive/boostcamp/' # 데이터 저장 경로
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns

Seaborn

student = pd.read_csv(path+'StudentsPerformance.csv')
iris = pd.read_csv(path+'iris.csv')
sns.countplot(x='race/ethnicity',data=student, # 세로는 y를 씀
             hue = 'gender', # hue는 구분자
             order=sorted(student['race/ethnicity'].unique()), # 순서 정해줌
             palette= 'Set2', # 색 패턴을 정해줌, 단일색으로 하면 그라데이션 효과
             hue_order=sorted(student['gender'].unique()) # hue도 순서 정해줄 수 있음
             )
<matplotlib.axes._subplots.AxesSubplot at 0x7fbdc4da8d10>

기본적으로 seaborn은 이전 matplotlib 보다 이쁘고 사용도 간편한 것 같습니다. 다양한 툴을 알아볼건데요.

countplot 입니다. 앞으로도 비슷한 형태일텐데 사용할만한 함수 내 요소들을 다 넣었습니다. 나중에 사용할 때 불필요한 부분은 빼는 식으로 하려고 합니다.

fig, ax = plt.subplots(1,1, figsize=(10, 5))

sns.boxplot(x='race/ethnicity', y='math score', data=student,
            hue='gender',
            order=sorted(student['race/ethnicity'].unique()),
            ax=ax)
plt.show()

boxplot도 쉽게 그릴 수 있습니다.

몰랐는데 박스가 IQR 기반이긴 하지만 실제 데이터가 있는 것이 기준이 되기 때문에 정확한 IQR값과 차이가 있을 수 있습니다.

fig, ax = plt.subplots(1,1, figsize=(12, 7))
sns.violinplot(x='race/ethnicity', y='math score', data=student, ax=ax,
               order=sorted(student['race/ethnicity'].unique()),
               hue='gender',
               split=True, # 동시에 보고 싶을 때 사용하는 파라미터
               bw=0.2, cut=0
              )
plt.show()

몇번 사용해본 violinplot 입니다. 잘 모르는 요소들을 알아갑니다.

fig, axes = plt.subplots(2,2, figsize=(12, 10))
axes = axes.flatten()

sns.histplot(x='math score', data=student, hue='gender', 
             multiple='stack', bins = 20 , ax=axes[0]) # bins : 막대 개수, multiple : layer, dodge, stack, fill

sns.kdeplot(x='math score', data=student, ax=axes[1],
            fill=True, 
            hue='race/ethnicity', 
            hue_order=sorted(student['race/ethnicity'].unique()),
            multiple="layer", # layer, stack, fill
            cumulative=False, # cumulative : True이면누적분포로 바꾸는 기능
            bw_method = 0.05,  # bw_method : 얼마나 스무딩 할 지 여부, 클 수록 스무딩 많아짐
            cut=0
           )

sns.ecdfplot(x='math score', data=student, ax=axes[2],
             hue='gender',
             stat='count', # proportion
             complementary=False # 1부터 시작
            )

sns.kdeplot(x='math score', y='reading score', 
             data=student, ax=axes[3],
            fill=True,
#             bw_method=0.1
            ) # 두 변수간 밀도를 잘 구해줌


plt.show()

이외에 seaborn에서 사용하는 다양한 plot들을 모아봤습니다.

실 사용에 유용한 그래프도 많이 보이고 요소들도 알아두면 좋은 게 많은 것 같아요.

지금 바로 생각나는 건 제가 데이터 일일이 코드로 이상치 판별을 위해 ecdfplot을 그렸었는데 사용이 더 편리해질 것 같습니다.

fig, ax = plt.subplots(figsize=(7, 7))
sns.scatterplot(x='math score', y='reading score', data=student,
                hue='race/ethnicity')
plt.show()

점 그래프 scatterplot 입니다. 마찬가지로 hue을 잘 사용한 모습입니다.

flights = sns.load_dataset("flights")
fig, ax = plt.subplots(1, 1, figsize=(12, 7))
sns.lineplot(data=flights, x="year", y="passengers", hue='month', 
             style='month', markers=True, dashes=False,
             ax=ax)
plt.show()

선 그래프 lineplot 입니다. 칼럼 내 값 종류가 많아지면 직관력이 조금 떨어지는 단점이 있는 것 같아요.

fig, ax = plt.subplots(1, 1, figsize=(12, 7))
sns.lineplot(data=flights, x="year", y="passengers", ax=ax)
plt.show()

평균과 표준편차 기반의 오차범위를 시각화해줍니다. 간단히 그릴 수 있다는게 큰 장점인 것 같아요.

fig, ax = plt.subplots(figsize=(7, 7))
sns.regplot(x='reading score', y='writing score', data=student,
            logx=True # order=2, 선을 1차선이 아닌 다양하게 그릴 수 있음
           )
plt.show()

regplot를 이용하면 scatterplot에서 추정되는 선을 그릴 수 있습니다. 일차선 뿐만 아니라 다양하게 응용이 되네요.

heart = pd.read_csv(path+'heart.csv')
fig, ax = plt.subplots(1,1 ,figsize=(12, 9))
sns.heatmap(heart.corr(), ax=ax,
           vmin=-1, vmax=1, center=0,
            cmap='coolwarm',
            annot=True, fmt='.2f',
            linewidth=0.1, square=True
           )
plt.show()

EDA에서 빼놓을 수 없는 heatmap 입니다. 사용하신 인자들을 적용해보니 더 직관적으로 heatmap을 볼 수 있어 좋은 것 같아요.

sns.jointplot(x='math score', y='reading score',data=student,
              hue='gender', 
              kind='scatter', # { scatter | kde | hist | hex | reg | resid }, 
             )
<seaborn.axisgrid.JointGrid at 0x7fbdc2740110>

jointplot를 이용하면 더 풍부한 시각화가 가능합니다. 축 위에 각 값의 분포가 나오는 것을 참 편리하게 할 수 있네요.

다만 화려하다고 다 좋은 것이 아니고 전달력이 우수한지 생각해볼 필요는 있을 것 같아요.

그래도 전 무조건 이게 최고다는 아니지만 전달력 충분히 좋은 것 같습니다.

sns.pairplot(data=iris, hue='Species') #kind='hist' # kind : 외각 그래프 모양, diag_kind : 대각 그래프 모양, corner=True : 삼각행렬만 보여주기
<seaborn.axisgrid.PairGrid at 0x7fbdc2205590>

EDA시 값 분포 확인을 위해 많이 사용하는 pairplot 입니다. 2가지 변수를 사용하여 시각화 방법을 조정할 수 있는데요.

kind는 전체 서브플롯, diag_kind는 대각 서브플롯을 조정합니다. 인자의 들어가는 값들은 아래와 같습니다.

  • kind : {scatter, kde, hist, reg}
  • diag_kind : {auto, hist, kde, None}

파이차트

np.random.seed(97)

data = np.array([16, 18, 20, 22, 24])
explode = [0, 0, 0.2, 0.3, 0] # 0일 때 원래 상태, 값이 커질수록 밖으로 나감
labels = list('ABCDE')
color = plt.cm.get_cmap('tab10').colors[:5]
fig, axes = plt.subplots(2, 3, figsize=(15, 10))

for i in range(3):
    axes[0][i].pie(data, labels=labels, startangle=90, explode = explode,  # startangle : 시작 점 정해줌. 유용, explode : 강조 표시
                   shadow=True, autopct='%1.1f%%', textprops={'color':"w"}) # shadow : 그림자, autopct : 몇 %인지 보여줌.
    axes[1][i].bar(labels, data, color=color)
    np.random.shuffle(data)

plt.show()

현실세계에서 많이 쓰이는 파이차트의 간단한 응용버전 입니다. 인자들은 코드에 충분히 설명 된 것 같습니다.

다만 밑의 바 차트의 경우 갯수 비교가 훨씬 용이한 것을 볼 수 있습니다.

파이차트가 대중적으로 많이 쓰이지만 바 차트 대비 가독성이 떨어지는 부분이 있기 때문에 사용을 권장하지 않는다고 합니다.

그 외 가운데 구멍이 있는 도넛차트가 있는데 파이차트보다도 가독성이 떨어지기 때문에 권장하지 않는다고 하네요.

결측 값 시각화

import missingno as msno
titanic = sns.load_dataset('titanic')
msno.matrix(titanic, 
            sort='descending', # ascending
           )
<matplotlib.axes._subplots.AxesSubplot at 0x7fbdc1bea090>

missingno 라이브러리를 사용해서 유명한 타이타닉 데이터의 결측 값을 시각화하였습니다.

데이터마다 결측값을 확인하는 것은 필수 코스인데 EDA시 시각적으로 편하면서 코드도 간단해 앞으로 사용을 많이 할 것 같아요.

msno.bar(titanic)
<matplotlib.axes._subplots.AxesSubplot at 0x7fbdc1b77990>

결측값을 단순하게 bar 형태로도 표현 가능합니다. 이게 더 좋아보이는 측면도 있는 것 같아요.

Plotly express

import plotly
import plotly.express as px 
iris = px.data.iris()

# px.scatter : 점, px.line : 선, px.bar : 바 그림
fig = px.scatter(iris, #
                 x='sepal_length',
                 y='petal_length',
                 color='species',
                 size='sepal_length',             
                 marginal_y="violin", # 값의 분포 바깥쪽에 보여주기
                 marginal_x="box", # 값의 분포 바깥쪽에 보여주기
                 hover_data=['sepal_width', 'petal_width'], # 마우스 올릴 때 추가정보 주기
                 hover_name='species', # 추가정보 제목
                 # trendline="ols", 선을 그릴수도
                 # facet_row='species', 그래프를 종 별로 다르게 그리고 싶을때
)

fig.show()

시각화를 동적으로 하는 툴 plotly 그 중에서 사용이 용이한 express를 간단하게 살펴봤습니다.

피처가 많은 경우 동적으로 시각화 하는 것이 효과가 좋다고 합니다. 다만 CPU를 꽤 잡아먹는 점이 부담입니다.

원을 클릭하면 점의 정보가 뜨고 범례를 클릭하면 데이터가 빠지기도 하는 등 신기합니다.

scatter 이외에도 line, bar 까지 사용 가능합니다.

tips = px.data.tips()
fig = px.treemap(tips, 
                  path=['day', 'time', 'sex'], 
                  values='total_bill')
fig.show()

treemap을 간단히 소개하려고 가져왔습니다. treemap을 가장 쉽게 그릴 수 있는 방법인 것 같아요.

geo = px.data.gapminder()
fig = px.scatter_geo(geo, 
                     locations="iso_alpha",
                     color="continent", 
                     size="pop",
                     animation_frame="year",
                     projection="natural earth")
fig.show()

이 것은 활용도보다 이런 것도 가능하구나 하는 신기함에서 가져왔습니다. 몇 줄 안되는 코드로 훌륭한 대시보드를 만들었습니다.

텍스트 강조 표시

from termcolor import colored, cprint

print(colored('hello', 'red'), colored('world', 'green'))
print(colored("hello red world", 'red'))
hello world
hello red world

colored을 이용하면 출력 시 텍스트에 색깔을 간편하게 바꿀 수 있습니다.

def word_highligt(txt, word, color=None, highlight=None, attr=None):
    if isinstance(word, str):
        txt = txt.replace(word, colored(word, color, highlight))
    else : 
        if not isinstance(color, list): 
            color = [color] * len(word)
        if not isinstance(highlight, list):
            highlight = [highlight] * len(word)
        for w, c, h in zip(word, color, highlight):
            txt = txt.replace(w, colored(w, c, h))
    return txt
lyrics = """
'Cause I-I-I'm in the stars tonight
So watch me bring the fire and set the night alight
Shoes on, get up in the morn'
Cup of milk, let's rock and roll
King Kong, kick the drum, rolling on like a Rolling Stone
Sing song when I'm walking home
Jump up to the top, LeBron
Ding dong, call me on my phone
Ice tea and a game of ping pong, huh
This is getting heavy
Can you hear the bass boom? I'm ready (woo hoo)
Life is sweet as honey
Yeah, this beat cha-ching like money, huh
Disco overload, I'm into that, I'm good to go
I'm diamond, you know I glow up
Hey, so let's go
'Cause I-I-I'm in the stars tonight
So watch me bring the fire and set the night alight (hey)
Shining through the city with a little funk and soul
So I'ma light it up like dynamite, whoa oh oh
Bring a friend, join the crowd
Whoever wanna come along
Word up, talk the talk
Just move like we off the wall
Day or night, the sky's alight
So we dance to the break of dawn
Ladies and gentlemen, I got the medicine
So you should keep ya eyes on the ball, huh
This is getting heavy
Can you hear the bass boom? I'm ready (woo hoo)
Life is sweet as honey
Yeah, this beat cha-ching like money
Disco overload, I'm into that, I'm good to go
I'm diamond, you know I glow up
Let's go
'Cause I-I-I'm in the stars tonight
So watch me bring the fire and set the night alight (hey)
Shining through the city with a little funk and soul
So I'ma light it up like dynamite, whoa oh oh
Dy-na-na-na, na-na, na-na-na, na-na-na, life is dynamite
Dy-na-na-na, na-na, na-na-na, na-na-na, life is dynamite
Shining through the city with a little funk and soul
So I'ma light it up like dynamite, whoa oh oh
Dy-na-na-na, na-na, na-na, ayy
Dy-na-na-na, na-na, na-na, ayy
Dy-na-na-na, na-na, na-na, ayy
Light it up like dynamite
Dy-na-na-na, na-na, na-na, ayy
Dy-na-na-na, na-na, na-na, ayy
Dy-na-na-na, na-na, na-na, ayy
Light it up like dynamite
'Cause I-I-I'm in the stars tonight
So watch me bring the fire and set the night alight
Shining through the city with a little funk and soul
So I'ma light it up like dynamite (this is ah)
'Cause I-I-I'm in the stars tonight
So watch me bring the fire and set the night alight (alight, oh)
Shining through the city with a little funk and soul
So I'ma light it up like dynamite, whoa (light it up like dynamite)
Dy-na-na-na, na-na, na-na-na, na-na-na, life is dynamite
Dy-na-na-na, na-na, na-na-na, na-na-na, life is dynamite
Shining through the city with a little funk and soul
So I'ma light it up like dynamite, whoa oh oh
"""

print(word_highligt(lyrics,  ['to', 'I'], [None, 'cyan'], ['on_red', None])) # word_highligt(텍스트, 단어, 색깔, 강조)
'Cause I-I-I'm in the stars tonight
So watch me bring the fire and set the night alight
Shoes on, get up in the morn'
Cup of milk, let's rock and roll
King Kong, kick the drum, rolling on like a Rolling Stone
Sing song when I'm walking home
Jump up to the top, LeBron
Ding dong, call me on my phone
Ice tea and a game of ping pong, huh
This is getting heavy
Can you hear the bass boom? I'm ready (woo hoo)
Life is sweet as honey
Yeah, this beat cha-ching like money, huh
Disco overload, I'm into that, I'm good to go
I'm diamond, you know I glow up
Hey, so let's go
'Cause I-I-I'm in the stars tonight
So watch me bring the fire and set the night alight (hey)
Shining through the city with a little funk and soul
So I'ma light it up like dynamite, whoa oh oh
Bring a friend, join the crowd
Whoever wanna come along
Word up, talk the talk
Just move like we off the wall
Day or night, the sky's alight
So we dance to the break of dawn
Ladies and gentlemen, I got the medicine
So you should keep ya eyes on the ball, huh
This is getting heavy
Can you hear the bass boom? I'm ready (woo hoo)
Life is sweet as honey
Yeah, this beat cha-ching like money
Disco overload, I'm into that, I'm good to go
I'm diamond, you know I glow up
Let's go
'Cause I-I-I'm in the stars tonight
So watch me bring the fire and set the night alight (hey)
Shining through the city with a little funk and soul
So I'ma light it up like dynamite, whoa oh oh
Dy-na-na-na, na-na, na-na-na, na-na-na, life is dynamite
Dy-na-na-na, na-na, na-na-na, na-na-na, life is dynamite
Shining through the city with a little funk and soul
So I'ma light it up like dynamite, whoa oh oh
Dy-na-na-na, na-na, na-na, ayy
Dy-na-na-na, na-na, na-na, ayy
Dy-na-na-na, na-na, na-na, ayy
Light it up like dynamite
Dy-na-na-na, na-na, na-na, ayy
Dy-na-na-na, na-na, na-na, ayy
Dy-na-na-na, na-na, na-na, ayy
Light it up like dynamite
'Cause I-I-I'm in the stars tonight
So watch me bring the fire and set the night alight
Shining through the city with a little funk and soul
So I'ma light it up like dynamite (this is ah)
'Cause I-I-I'm in the stars tonight
So watch me bring the fire and set the night alight (alight, oh)
Shining through the city with a little funk and soul
So I'ma light it up like dynamite, whoa (light it up like dynamite)
Dy-na-na-na, na-na, na-na-na, na-na-na, life is dynamite
Dy-na-na-na, na-na, na-na-na, na-na-na, life is dynamite
Shining through the city with a little funk and soul
So I'ma light it up like dynamite, whoa oh oh

bts 노래 가사중 내가 원하는 부분을 색깔을 바꾸고 강조표시를 했습니다.

이를 위해서 word_highligt 함수를 간단히 작성했습니다. (사실 복사했지요.)

이 것을 잘 활용한다면 눈으로 무언가를 찾는 수고를 덜 수 있을 것 같습니다. 어느 데이터를 다루느냐에 따라 사용도가 클 수도 있을 것 같아요!

느낀점

시각화 강의를 들으면서 제 주관적으로 필요성이 느낀 부분을 정리했습니다. 필요할 때 찾아 쓰면 편리할 것 같아요.

어떻게 보면 더 열심히 해야하는데 시간이 부족하다는 핑계로 좋은 재료를 가지고 효율만을 추구하는 공부를 하는 것 같아요.

그래도 필요할 때 다시 돌아오자는 마인드로 해보는 게 좋을 것 같아요. 두마리 토끼를 다 잡는게 욕심이 큰 일이구나 깨닳습니다.

어제 밤 팀원을 구했는데 기존 팀원사람들에게 미리 얘기를 못해줘서 미안한 마음이 큽니다.

또 다른 생각으론 새 팀원 분들 다들 좋으신 분들이라 으싸으싸 잘 해보자 다짐합니다.

이번 주 5일같은 주4일 너무 고생했다고 스스로를 다독여주고 싶네요. 주말 푹 쉬고 다음주도 화이팅!

참고자료 : BERT 시각화

** 위 수식과 그림은 부스트캠프 AI Tech 교육 자료를 참고하였습니다.