데이터 과학을 위한 파이썬 머신러닝 : 5. 데이터 시각화

맷플롯립

  • 데이터 시각화(Data Visualization) : 데이터 분석 결과를 시각적으로 전달
  • matplotlib : matlab 기능을 파이썬에서 사용하도록 만든 시각화 모듈

파이플롯

  • pyplot : matplotlib을 이용할 때 가장 기본이 되는 객체
  • 바탕으로 그림(figure) 객체를 올리고 그 위로 그래프에 해당하는 축(axes)을 올림
    • 축을 여러 장 올리면 여러 개의 그래프를 만들 수 있음
import matplotlib.pyplot as plt  # matplotlib 모듈 호출

X = range(100)
Y = range(100)
plt.plot(X, Y)

import numpy as np  # numpy 모듈 호출

X_1 = range(100)
Y_1 = [np.cos(value) for value in X_1]

X_2 = range(100)
Y_2 = [np.sin(value) for value in X_1]

# pyplot 객체 내부에 cos과 sin 그래프를 그림
plt.plot(X_1, Y_1)
plt.plot(X_2, Y_2)

plt.show()  # 그래프 출력

그림과 축

  • figure(그림, fig) : 그래프를 작성하는 밑바탕
  • axes(축, ax) : 그래프를 그리는 공간
fig, ax = plt.subplots()  # figure와 axes 객체 할당

X_1 = range(100)
Y_1 = [np.cos(value)
       for value in X_1]

ax.plot(X_1, Y_1)  # plot 함수를 사용하여 그래프 생성
ax.set(title='cos graph',  # 그래프 제목, X축 라벨, Y축 라벨 설정
       xlabel='X',
       ylabel='Y')

plt.show()

fig = plt.figure()  # figure 반환
fig.set_size_inches(10, 10)  # figure의 크기 지정

# 두 개의 그래프 생성
ax_1 = fig.add_subplot(1, 2, 1)
ax_2 = fig.add_subplot(1, 2, 2)

# 두 개의 그래프 설정
ax_1.plot(X_1, Y_1, c="b")
ax_2.plot(X_2, Y_2, c="g")

plt.show()

서브플롯

  • 축을 여러 개 만들 때 서브플롯으로 공간 확보
  • plt.subplots() : plot 객체에서 서브플롯 공간 생성
fig, ax = plt.subplots(nrows=1, ncols=2)  # nrows : 행, ncols : 열
print(ax)
print(type(ax))  # ax의 축 객체가 넘파이 배열 타입으로 되어있음

  • 서브플롯 그래프 생성 방법
    • figure 객체 생성 후 축에 대한 행, 열 접근을 통한 그래프 생성
    • plt.subplot(행, 열, 순서)를 통한 그래프 생성
# np.linspace(시작점, 끝점, 구간 내 숫자 개수)
x = np.linspace(-1, 1, 100)  # x 값과 y_n 값 생성
y_1 = np.sin(x)
y_2 = np.cos(x)
y_3 = np.tan(x)
y_4 = np.exp(x)

# 2행 2열 figure 객체를 생성
fig, ax = plt.subplots(2, 2)

# ax[헹, 열]에 그래프 생성
ax[0, 0].plot(x, y_1)
ax[0, 1].plot(x, y_2)
ax[1, 0].plot(x, y_3)
ax[1, 1].plot(x, y_4)

plt.show()

# 행_열로 이루어진 공간에 순서 번째에 대한 그래프 생성
ax1 = plt.subplot(321)
plt.plot(x, y_1)
ax2 = plt.subplot(322)
plt.plot(x, y_1)
ax3 = plt.subplot(312)
plt.plot(x, y_2)
ax4 = plt.subplot(325)
plt.plot(x, y_1)
ax5 = plt.subplot(326)
plt.plot(x, y_1)

plt.show()

matplotlib 색상

  • color 또는 c 매개변수로 색상 변경 : #RGB 값을 입력하거나 약어를 통해 색상 표현
X_1 = range(100)
Y_1 = [value for value in X]

X_2 = range(100)
Y_2 = [value + 100 for value in X]

# 색상 설정
plt.plot(X_1, Y_1, color="#000000")  # 검정색
plt.plot(X_2, Y_2, c="c")  # 청록색

plt.show()

matplotlib 선의 형태

  • linestyle 또는 ls로 선의 형태 정의
    • solid : 실선 형태
    • dashed : 절취선 형태
    • dotted : 점선 형태
    • dash-dot : 절취선+점선 형태
plt.plot(X_1, Y_1, c="b",
         linestyle="dashed")  # 절취선
plt.plot(X_2, Y_2, c="r",
         ls="dotted")  # 점선

plt.show()

matplotlib figure 구조

plt.plot(X_1, Y_1,
         color="b",
         linestyle="dashed",
         label='line_1')
plt.plot(X_2, Y_2,
         color="r",
         linestyle="dotted",
         label='line_2')
plt.legend(  # 범례 설정
    shadow=True,  # 그림자 효과
    fancybox=False,
    loc="upper right")  # 범례 위치, best로 지정 시 적절한 위치에 놓임

plt.title('$y = ax+b$')  # 그래프 제목
plt.xlabel('$x_line$')  # x축 라벨 이름
plt.ylabel('y_line')  # y축 라벨 이름
Text(0, 0.5, 'y_line')

맷플롯립 그래프 종류

  • 산점도(scatter plot) : 데이터 분포를 2차원 평면에 표현
data_1 = np.random.rand(512, 2)
data_2 = np.random.rand(512, 2)

# scatter(표시할 데이터, c="포인트 색상", marker="포인트 모양", size=포인트 크기, alpha=포인트 불투명도)
plt.scatter(data_1[:, 0],
            data_1[:, 1],
            c="b", marker="x")
plt.scatter(data_2[:, 0],
            data_2[:, 1],
            c="r", marker="o")

plt.show()

N = 50
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)  # 색깔도 랜덤 설정
area = np.pi * (  # 원 크기 랜덤 설정
        15 * np.random.rand(N)) ** 2

plt.scatter(x, y,
            s=area, c=colors,
            alpha=0.5)
plt.show()

  • 막대 그래프(bar graph) : 데이터의 개수나 크기를 비교
data = [[5., 25., 50., 20.],
        [4., 23., 51., 17],
        [6., 22., 52., 19]]

# X 좌표 시작점
X = np.arange(0, 8, 2)  # array([0, 2, 4, 6])

# 3개의 막대 그래프 생성
plt.bar(X + 0.00, data[0], color='b', width=0.50)
plt.bar(X + 0.50, data[1], color='g', width=0.50)
plt.bar(X + 1.0, data[2], color='r', width=0.50)

# X축에 표시될 이름과 위치 설정
plt.xticks(X + 0.50, ("A", "B", "C", "D"))

# 막대 그래프 출력
plt.show()

  • 누적 막대 그래프(stacked bar graph) : 데이터를 밑에서부터 쌓아올려 데이터를 표현
data = np.array([[5., 25., 50., 20.],
                 [4., 23., 51., 17],
                 [6., 22., 52., 19]])

color_list = ['b', 'g', 'r']
data_label = ["A", "B", "C"]
X = np.arange(data.shape[1])

data = np.array([[5., 5., 5., 5.],
                 [4., 23., 51., 17],
                 [6., 22., 52., 19]])

# for문을 통해 누적 막대 그래프 생성
for i in range(3):
    plt.bar(X, data[i],
            bottom=np.sum(data[:i], axis=0),
            color=color_list[i],
            label=data_label[i])

plt.legend()
plt.show()

  • 히스토그램(histogram) : 데이터의 분포를 표현
N = 1000
X = np.random.normal(size=N)

# hist(표시할 데이터, bins=막대 개수)
plt.hist(X, bins=100)
plt.show()

  • 상자그림(boxplot) : 사분위수를 시각화하여 데이터의 분포와 밀집 정도를 표현
    • 데이터를 작은 데이터부터 큰 데이터까지 정렬
    • Q1(25%)부터 Q3(75%)까지 박스 형태로 위치시킴
    • IQR(InterQuatile Range) : Q1 - Q3
    • Q1 - 1.5×IQR 을 하단 값으로, Q3 + 1.5×IQR 을 상단 값으로 설정
    • 이상치(outlier) : 상단 값과 하단 값을 넘어가는 값들
data = np.random.randn(100, 5)
plt.boxplot(data)
plt.show()

시본

  • seaborn : 맷플롯립을 바탕으로 다양한 함수 사용을 돕는 wrapper 모듈
  • 맷플롯립과 동일한 결과물이 나오며, 작성 과정이 간단함
    • 그림 객체나 축 객체 같은 개념이 없음
    • xticks 설정하지 않아도 각 축에 라벨 자동으로 생성
    • 데이터프레임과 x, y에 해당하는 열 이름만 지정해 생성
import seaborn as sns  # seaborn 모듈 호출

# fmri 데이터셋 : 환자별(subject) 시가점마다의 fmri signal 값을 담고 있는 데이터
fmri = sns.load_dataset("fmri")
fmri.head()

fmri 데이터는 연속형 값 외에도 다양한 범주형 값 가지기 때문에 matplotlib으로 표현하기는 상당히 복잡하고, seaborn은 hue 매개변수만 추가하면 그래프를 그릴 수 있음

sns.set_style("whitegrid")  # 기본 스타일 적용
sns.lineplot(x="timepoint", y="signal", data=fmri)  # 선 그래프 작성

fmri.sample(n=10, random_state=1)
sns.lineplot(x="timepoint", y="signal", hue="event", data=fmri)

시본 그래프 종류

  • 회귀 그래프(regression plot) : 회귀식을 적용해 선형회귀 추세선을 그래프에 함께 작성
    • 선형회귀 추세선 : 데이터를 기반으로 데이터의 x값 대비 y값 변화를 예측하는 직선
# tips 데이터셋 : 레스토랑에 방문한 손님이 팁을 얼마나 주는지에 대한 정보를 담고 있는 데이터
tips = sns.load_dataset("tips")

# regplot : 회귀 그래프 함수
sns.regplot(x="total_bill", y="tip", data=tips, x_ci=95)  # x_ci는 신뢰구간의 비율

  • 산점도(scatter plot) : x, y를 기준으로 데이터 분포 표현
# scatterplot : 산점도 함수
tips = sns.load_dataset("tips")
sns.scatterplot(x="total_bill", y="tip", hue="time", data=tips)

  • 비교 그래프(counter plot) : 범주형 데이터의 항목별 개수
# countplot : 비교 그래프 함수
tips = sns.load_dataset("tips")
sns.countplot(x="smoker", hue="time", data=tips)

  • 막대 그래프 : y 값이 연속형 값일 경우 해당 값들의 평균을 나타냄
    • 데이터의 신뢰구간을 검은색 막대로 표현
# barplot : 막대 그래프 함수
sns.barplot(x="day", y="total_bill", data=tips)

사전 정의된 그래프

  • 맷플롯립 관점에서 여러 그래프들을 합쳐 정보를 추출한 그래프로 범주형 데이터에 유용함

  • 바이올린 플롯(Violin Plot) : 분포를 나타내는 그래프로, 상자그림과 분포도를 한 번에 나타낼 수 있음

    • x축에는 범주형 데이터, y축에는 연속형 데이터
# violinplot : 바이올린 플롯 함수
sns.violinplot(x="day", y="total_bill", hue="smoker",
               data=tips, palette="muted")

  • 스웜 플롯(swarm plot) : 분포를 나타내는 그래프로, 산점도로 데이터 분포를 나타냄
    • 매개변수 hue로 두 개 이상의 범주형 데이터를 점이 겹치지 않게 정리해, 영역별 데이터 양을 직관적으로 보여줌
# swarmplot : 스웜 플롯 함수
sns.swarmplot(x="day", y="total_bill", hue="smoker",
              data=tips, palette="muted")

  • 패싯그리드(FacetGrid) : 다양한 범주형 데이터를 나타내는 그래프로, 그래프의 틀만 제공하여 적당한 그래프를 그려주는 클래스
    • 그리드가 생성된 후 맵(map)을 사용하여 그래프 만듦
    • 각 FacetGrid에 있는 개별 그래프 영역에 그래프를 집어넣는 구조
    • 전체 데이터를 범주형 데이터의 다양한 관점에서 나눠서 볼 수 있음
# FacetGrid : 패싯그리드 함수
g = sns.FacetGrid(tips,
                  col="time",
                  row="sex")

g.map(sns.scatterplot,
      "total_bill", "tip")

g = sns.FacetGrid(tips, col="time",
                  row="sex")

g.map_dataframe(sns.histplot,
                x="total_bill")

플롯리

  • plotly : 비즈니스 인텔리전스(Business Intelligence) 대시보드로 개발된 도구
    • 비즈니스 인텔리전스(BI 도구) : 사내 여러 데이터들을 정리하여 의사 결정을 도움
  • 애플리케이션으로, 사용자에게 그래프를 제공
    • 맷플롯립이나 시본은 데이터 분석가들이 데이터의 형태나 분포를 살피기 위해 코드로 사용하는 도구
  • 인터랙션 그래프 : 그래프 생성 이후 사용자가 마우스 커서를 올리면 데이터를 볼 수 있으며, 인터페이스를 통해 조절 가능
import plotly.express as px

df = px.data.iris()  # iris : 판다스 데이터프레임 데이터셋
fig = px.scatter(df, x="sepal_width", y="sepal_length")
fig.show()

  • 좌표 그래프(coordinates plot) : 데이터 간 관계를 표현
fig = px.parallel_coordinates(
    df, color="species_id",
    labels={"species_id": "Species",
            "sepal_width": "Sepal Width",
            "sepal_length": "Sepal Length",
            "petal_width": "Petal Width",
            "petal_length": "Petal Length", },
    color_continuous_scale=px.colors.diverging.Tealrose,
    color_continuous_midpoint=2)
fig.show()


참고문헌

최성철, 『데이터 과학을 위한 파이썬 머신러닝』, 초판, 한빛아카데미, 2022

이 글이 도움이 되었나요?

0 minutes ago
작성된 댓글이 없습니다. 첫 댓글을 달아보세요!
    댓글을 작성하려면 로그인이 필요합니다.