(전공복습) 데이터과학 4. 시각화

차례

들어가기 전에

이 글은 컴퓨터학과 이중전공생으로서 배운 것들을 다시 한번 정리하고자 남기는 글입니다. 불완전한 기억 등의 이유로 오류가 있을 수 있으며, 참조 내지 이정표로만 사용해주세요.
본 게시글은 고려대학교의 데이터과학 강의를 기반으로 작성자의 추가적인 설명이 덧붙여진 글입니다.

시각화의 이점

오늘은 시각화(Visualization)에 대해 알아볼 것이다. 시각화는 말 그대로 눈으로 알아보기 쉽도록 데이터를 그래픽의 형태로 나타내는 것을 말한다. 일반적으로는 그래프(차트, 도표, 플롯)의 형태로 데이터를 나타내는 것을 말한다.
데이터를 시각화하는 이유가 무엇인가? 이는 데이터를 분석함에 있어서 인간의 인지 능력을 최대한으로 활용하기 위함이다. 일반적으로 제시되는 데이터들은 일련의 숫자(혹은 문자)들일 뿐이다. 거기에서 어떤 인싸이트(또는 아이디어)를 찾는 것은 어려운 일이다. 그렇지만 데이터를 시각적으로 보기 쉬운 형태로 구성한다면 그 분포 등을 보고 아이디어를 얻을 수 있을 것이다.

앤스컴 콰르텟(Anscombe’s Quartet)

시각화의 중요성을 보여주는 예시 중 하나가 바로 앤스컴 콰르텟(Anscombe’s Quartet)이라는 데이터셋이다.
이 데이터셋은 네 종류의 범주로 구분되어 있다. 각 데이터는 네 범주 중 하나에 속하며, 두 개의 값(xy)을 지닌다. 특이한 점은, 이 네 범주의 평균, 표준편차, xy의 상관계수가 모두 같다는 점이다.
그렇다면 이 네 범주의 데이터는 유사한 분포를 보일까? 그렇지 않다. 아래는 앤스컴 콰르텟에서 각 범주별 데이터의 분포이다. 보이는 것처럼 각 범주는 같은 통계량을 갖지만 매우 다르게 생긴 분포를 가지고 있다.
앤스컴 콰르텟
시각화를 하지 않고 통계량에 기반해서 데이터를 분석하게 되면 이러한 차이를 놓치게 된다. 이러한 이유로 시각화는 중요한 것이다.

시각화의 목표

시각화의 목표는 크게 두 가지라고 할 수 있다.

  1. 자신의 이해를 위해: 위 앤스컴 콰르텟의 예시처럼, EDA 등의 과정에서 스스로 데이터를 더 잘 이해하기 위해서 시각화를 할 수 있다.
  2. 타인의 이해를 위해: 분석 결과등을 제시하고 의사소통하기 위해서 시각화를 할 수 있다. 특히, 이 경우 상대가 데이터 과학이나 도메인 지식에 대해서 문외한일 수도 있다는 점을 고려하라.

특히, 잘 만든 시각화는 의사결정이라는 데이터과학의 주요 목표를 한번에 달성할 수도 있다. 백문이 불여일견이라는 말처럼 말이다. 시각화는 그만큼 중요하지만, 단순히 plot()을 호출하는 것이 시각화의 전부는 아니다. 좋은 시각화를 위해서는 많은 숙고가 필요하다.

인코딩(Encoding)

인코딩(Encoding)이란 무엇인가? 일반 용어로서 인코딩은 어떠한 정보를 규칙에 따라 부호화하는 것을 의미한다. 대표적으로 텍스트 인코딩을 생각해보자. 텍스트 인코딩은 결국 어떠한 규칙에 따라서 문자를 일련의 01들로 바꾸는 과정이다.

한편, 시각화에서 말하는 인코딩은 데이터를 시각적 요소로 부호화하는 과정을 의미한다. 데이터는 여러 개의 열(Columns), 즉 변수로 구성된다. 각 변수에서 시각적 요소로의 사상(Mapping, 매핑)이 바로 이 맥락에서의 인코딩이다.
시각화 인코딩 0
위 예시를 살펴보자. 각 데이터포인트(행)들을 선으로 나타냈다. 이때 age 변수는 선의 y좌표로 매핑되었다. 이것이 바로 인코딩이다.
시각화 인코딩 1
위 예시에서는 두 개의 변수 agefare가 존재한다. 각 데이터포인트들은 점으로 나타나 있는데, age는 x좌표, fare는 y좌표로 매핑되어 있다. 이처럼 각 열(변수)을 시각적 요소로 사상하는 것이 바로 인코딩이다.

시각화 인코딩 2
위 이미지를 살펴보자. 몇 개의 변수가 인코딩되었는가? 데이터포인트가 점(또는 원)으로 나타나 있는데, x축과 y축이 존재하므로 각 좌표로 2개의 변수가 있다. 거기에 더해, 각 데이터포인트를 나타내는 원의 색깔과 크기가 다르므로 2개의 변수가 더 있다. 즉 우리는 총 4개의 변수가 인코딩되었다는 것을 알 수 있다.

잘못된 시각화 인코딩
중요한 점 중 하나는 각 변수의 타입과 시각적 요소의 타입을 비교해볼 필요가 있다는 점이다. 위 시각화는 x축에 국가, y축에 자동차 종류가 사상된 바플롯(Barplot, 막대 그래프)이다. 정확히 말하자면, 위 시각화에서 각 데이터포인트는 막대로 나타나는데, 자동차 종류는 막대의 y축 좌표로, 국가는 막대의 x축 길이로 사상되어 있다.
막대의 길이는 주로 양적변수를 나타낸다. 하지만 국가는 명목변수에 해당한다. 이러한 불일치는 그래프를 이해하기 어렵게 만들거나 심각한 경우 잘못 이해하도록 만든다. 얼핏 이 그래프를 본 사람들은 Volvo 260과 Saab 900이 가장 좋거나 많이 팔린 차라고 오해할 수 있다(실제 시각화의 의미는 단순히 두 자동차가 스웨덴산이라는 뜻일 뿐이다).
(양적변수나 명목변수와 같은 변수 또는 척도의 종류에 대해서는 데이터과학 2. 전처리와 EDA를 참조하라.)

분포(Distribution)

시각화에서 분포(Distribution)란 범주형 변수에 대해 각 범주들이 데이터포인트에서 등장하는 빈도를 보여주는 것을 의미한다. 다만 항상 그런 것은 아니다. 말 그대로 데이터가 어디에 얼마나 존재하는지를 나타내는 경우에도 분포라는 어휘를 사용하며, 아래에서 설명할 특정한 조건을 만족하는 시각화 결과를 분포라고 부르기도 한다.

  1. 모든 데이터포인트는 하나의 범주에 속해야 한다.
  2. 모든 범주의 빈도 총합은 100%, 즉 전체 관측치 수 \(N\)이어야 한다.

분포 예시
위 이미지는 전형적인 분포의 예시인 소득분위를 나타내고 있다. 모든 사람은 소득분위 상, 중, 하 중 어딘가에는 속해야 하며, 또한 동시에 두 소득분위에 속할 수 없다. 따라서 세 소득분위의 빈도 합은 100%가 된다. 이것이 올바른 분포이다.

분포가 아닌 예시
반면, 이건 분포가 아니다. 왜냐하면 복수응답이 가능한 설문으로, 한 데이터포인트(개인)가 동시에 여러 범주에 속할 수 있기 때문이다. 이는 올바른 분포라고 하기에는 어렵다.

최빈값(Mode, 모드)

분포에서 가장 큰 값을 가진, 즉 가장 데이터가 많은 범주를 최빈값(Mode)이라 한다.
지역적인 관점에서의 최빈값, 즉 봉우리가 하나인 분포가 등장하는 경우 이를 유니모달(Unimodal)이라 한다. 마찬가지로 2개면 바이모달(Bimodal), 또는 2개 이상이면 멀티모달(Multimodal)이라 한다.

왜도(Skewness, 편포도)

분포가 치우쳐져 있는 정도를 왜도(Skewness)라 한다.

예를 들어, , , 의 3개 범주에서, 을 중심으로 분포가 대칭을 이룬다면 이를 대칭(Symmetric)이라 한다. 이 경우, 평균과 중위수(중간값)는 비슷한 값(완벽히 대칭이라면 같은 값)을 가진다.

만약, 좌측의 값, 즉 가 더 많다면, 분포의 꼬리(Tail) 부분이 오른쪽으로 가게 될텐데, 이를 우측편포(Skewed Right)라 하며, 이 경우 평균이 중위수보다 우측에 존재하게 된다. 즉, 평균이 중위수보다 더 커지게 된다.

한편, 우측의 값, 즉 이 더 많다면, 분포의 꼬리는 왼쪽으로 가게 되고, 이를 좌측편포(Skewed Left)라 하며, 이 경우 반대로 평균이 중위수보다 좌측에 존재한다. 즉, 평균이 중위수보다 작아지게 된다.

플롯(Plot)

일반적으로 우리는 데이터를 일정한 구조를 가진 이미지로 나타낸 것을 그래프(Graph)라 부른다. 다만, 이 그래프라는 용어는 몇 가지 혼동을 가져올 수 있다. 일반적으로 아래 대상들은 모두 그래프라는 이름을 지닌다.

  • 데이터를 시각화한 결과.
  • 함수를 시각화한 결과(\(y = x\)그래프와 같은).
  • 노드(정점)와 엣지(간선)로 구성된 자료구조.

따라서, 그래프라는 이름은 맥락에 따라 구별할 필요가 있다. 도표 또는 차트(Chart)라는 어휘는 더 제한적으로 사용되므로 표현하고자 하는 바를 확실히 표현할 수 있다. 우리는 플롯(Plot)이라는 어휘를 사용하기도 할 것이다. 특히 컴퓨터과학의 영역에서 그래프라는 단어는 자료구조로서의 그래프를 뜻할 때가 훨씬 많기 때문에 시각화 결과를 나타내는 말로서는 거의 사용하지 않을 것이다.

파이썬으로 플로팅하기(Plotting with Python)

우리는 데이터를 시각화한 결과를 플롯(Plot)이라 칭하기로 했다. 이렇게 플롯을 만드는 일을 플로팅(Plotting)이라 한다. 파이썬에는 플로팅을 위한 많은 시각화 라이브러리가 있다. 아래는 시각화를 할 수 있는 몇 가지 방법이다.

  • matplotlib: 기초적인 저수준(Low Level) 시각화 라이브러리이다.
  • pandas.DataFrame.plot(): pandas 데이터프레임을 바로 시각화할 수 있다. 기본적으로 위의 matplotlib을 사용한다.
  • seaborn: matplotlib 기반의 고수준(High Level) 시각화 라이브러리이다.
  • plotly: 위 라이브러리들과 다르게 인터랙티브 시각화에 초점을 맞춘 라이브러리이다.

참고로, 컴퓨터과학에서 고수준, 저수준은 완성도나 성능과는 무관한 용어이며, 인터페이스의 관점에서, 결과물을 만들기 위해 사용자가 일일히 내부적인 구현과 작동을 신경써야 한다면 저수준, 라이브러리가 그러한 것들을 알아서 결정해주고 사용자가 고민할 필요가 없다면 고수준이라 할 수 있다. 간략하게 말해, 저수준은 자유롭고, 고수준은 편리하다.

바플롯(Bar Plot)

바플롯 예제

주로 막대그래프 내지는 막대차트라고 하는 바플롯은 말 그대로 막대를 이용한 시각화이다. 일반적으로 바플롯은 x축에는 여러 개의 카테고리(범주형 변수)가, y축에는 수치형 변수가 등장한다. 다만, 이는 필수적이지는 않으며, 일반적인 수직 바플롯을 90도 회전시켜 y축에 범주, x축에 수치가 나오는 수평 바플롯 역시 가능하다.

특히, 위에서 살펴본 분포(Distribution) 역시 각 범주에 대한 비중을 수치값으로 나타내므로 바플롯을 이용해 시각화하는 것이 일반적이다.

바플롯(수직 바플롯)의 인코딩을 정리하자면 아래와 같다.

  • 막대의 x축 좌표: 범주
  • 막대의 y축 길이: 수치
  • 막대의 색상: 필요하다면, 이차 범주(Subcategory)
  • 참고로, 막대의 y축 너비는 아무런 의미가 없음에 유의하라

러그플롯(Rug Plot)

러그플롯 예제

하나의 수치형 변수에 대해 그 수치형 변수의 분포를 나타낼 때 사용한다. 단순히 단일 변수가 어떻게 분포했는지를 나타내는 간단한 플롯이므로, 일반적으로 혼자 사용되는 일은 많지 않다. 단일 변수를 나타내기에 축은 하나면 충분하며, 여러 축에 각 변수에 대한 러그플롯을 그릴 수도 있다.

  • 선분의 좌표: 수치
  • 선분의 색상: 필요하다면, 범주

히스토그램(Histogram)

히스토그램 예제

수치형 변수에서, 특정한 구간에 따른 데이터의 분포를 확인할 때 사용하는 플롯이다. 학창시절에 도수분포표(Frequency Table)를 배운 적이 있다면, 도수분포표를 특정 조건을 만족하도록 바플롯과 유사한 형태로 나타낸 것을 히스토그램이라 생각해도 된다.

히스토그램은 기본적으로 러그플롯을 부드럽게 한(Smoothing) 버전이라고 생각할 수 있다. 그말인즉슨, 러그플롯에서 구간을 나누고, 그 값들의 개수를 세어 하나의 막대(Bin)로 뭉뚱그려 나타낸 것이 히스토그램이라 할 수 있다는 것이다.

히스토그램은 위에서 언급한 분포(Distribution)이기 때문에, 분포의 조건을 만족한다. 즉, 모든 데이터는 각 막대 중 하나에 속하며, 여러 막대에 동시에 속할 수도 없다.

  • 막대의 x축 좌표: 구간의 값
  • 막대의 x축 너비: 구간의 크기
  • 막대의 y축 높이: 해당 구간 데이터들의 전체 데이터에서의 비율

프리드먼-디아코니스 규칙(Freedman-Diaconis Rule)

위에서 본 것처럼, 히스토그램은 바플롯과 달리 막대의 x축 너비가 의미를 지닌다. 막대의 너비가 크다는 것은 그 막대가 나타내는 구간이 그만큼 넓다는 것을 의미한다. 심지어 같은 히스토그램 안에서 막대마다 너비가 다른 것도 가능하기 때문에, 히스토그램에서 막대 너비는 중요한 요소이다.

히스토그램에서 최적 막대 수를 결정하기 위해 사용할 수 있는 방법 중 하나가 바로 프리드먼-디아코니스 규칙을 사용하는 것이다. 이 규칙은 아래와 같다.

  • \[\mathrm{Bin\;Width} = 2 { \mathrm{IQR}(x) \over \sqrt[3]{n}}\]

여기서, \(\mathrm{IQR}(x)\)는 사분범위(Interquartile Range, IQR)로, 구체적으로는 아래에서 설명하고 있다. 또한 여기에서 \(x\)는 표본 자체, \(n\)은 그 표본의 데이터 개수를 의미한다.

밀도곡선(Density Curve)

밀도곡선 예제

히스토그램은 각 구간별로 데이터의 개수를 나타낸다고 할 수 있다. 또한 이는 러그플롯을 특정 구간으로 뭉뚱그린 것이라 할 수 있다고도 했다. 그렇다면 전체 히스토그램을 이산적인 구간이 아니라, 하나의 곡선으로 나타낼 수는 없을까? 그것이 바로 밀도곡선(Density Curve)이다.

밀도곡선의 인코딩은 아래와 같다고 할 수 있다.

  • x좌표: 수치
  • y좌표: 해당 수치의 밀도

그렇다면 어떻게 히스토그램을 하나의 곡선으로 근사할 수 있는가? 바로 커널 밀도 추정(Kernel Density Estimation, KDE)를 이용한다.

(KDE에 관한 세부적인 내용은 아래에서도 조금 다루며, 자세한 것은 추후 작성될 기계학습 게시글에 관한 것을 참조하라.)

박스플롯(Box Plot)

박스플롯 예제

박스플롯은 상자그림 내지는 상자수염그림으로도 불린다. 주로 변수의 통계치를 간략하게 한눈에 보기 위해 사용한다. 특히, 여러 개의 데이터셋 또는 여러 범주의 데이터에서 각 범주마다 통계치가 어떻게 달라지는지 보고 싶을 때 유용하다. 이름처럼 상자 부분과 수염 부분으로 구성되어 있는데, 이를 이해하기 위해서는 사분위수를 알아야 한다.

사분위수(Quartile)

우리는 살아가면서 백분위(Percentile)라는 말을 자주 사용한다. 단어를 뜻풀이해보면 말 그대로 100개로 나눈 것 중의 위치를 의미한다. 예를 들어, 백분위에서 상위 1%는 100명 중 위에서 1번째를, 하위 10%는 100명 중 밑에서 10번째를 의미한다.
사분위(Quartile)도 이와 유사하다. 차이점이 있다면, 백분위가 전체 데이터를 100개로 나눈다면, 사분위는 전체 데이터를 4개로만 나눈다는 부분이다. 사분위 용어들은 아래와 같이 정리된다.

  • Q1: 하위 사분위로, 백분위로 따지면 하위 25%(상위 75%)를 의미한다.
    • Lower 또는 First Quartile이라고도 한다.
  • Q2: 중위 사분위로, 백분위로 따지면 50%이고, 중위수(Median, 중간값)와 같다.
    • Second Quartile이라고도 한다.
  • Q3: 상위 사분위로, 백분위로 따지면 하위 75%(상위 25%)를 의미한다.
    • Upper 또는 Third Quartile이라고도 한다.
  • IQR(Interquartile Range): 우리말로는 사분범위라 하는데, \(Q3 - Q1\)으로 정의된다. 즉 25%부터 75% 지점 사이의, 전체 데이터의 50%에 해당하는 범위를 IQR이라 한다.

박스플롯 살펴보기

박스플롯과 사분위수

박스플롯은 위에서 언급한 사분위수에 기반하여 그려진다. 우선 상자는 3개의 수평선으로 구성되어 있다. 각각 Q1, Q2, Q3이다. 즉, 상자의 범위가 IQR인 셈이다.
여기에 더해, 상자 위아래로 일정 구간이 직선으로 표시되어 있는 것을 볼 수 있다. 이를 수염(Whisker)이라 하는데, 아래와 같이 정의된다.

  • 아래쪽 수염: \(Q1 - (1.5 \times \mathrm{IQR})\)
  • 위쪽 수염: \(Q3 + (1.5 \times \mathrm{IQR})\)

수염은 일반적으로 값들이 있으리라 기대되는 범위를 2 IQR 범위를 나타낸다. 수염 바깥쪽의 값들은 아웃라이어(Outlier, 이상치)라 한다. 종합적으로, 박스플롯의 인코딩은 아래와 같다.

  • y축 좌표: 수치형 변수의 통계치
    • 상자 중심: 중위수
    • 상자 하단: Q1
    • 상자 상단: Q3
    • 상자 높이: IQR
    • 수염 범위: 중앙의 \(2 \times \mathrm{IQR}\) 구간
  • x축 좌표는 아무런 의미를 갖지 않는다.

바이올린플롯(Violin Plot)

바이올린플롯 예제

박스플롯을 응용한 형태의 시각화로, 박스플롯에서 상자를 매우 얇게 만들고, 플롯 주변으로 밀도곡선을 나타낸 모습을 지닌다. 바이올린 몸통 같이 생긴 부분은 밀도곡선을 90도 회전시켜서 대칭으로 만든 모습이고, 바이올린 내부의 선과 작은 사각형이 기존 상자와 수염이 된다.
바이올린플롯은 박스플롯에 더해 밀도곡선을 동시에 알 수 있다는 점에서 메리트를 지니며, 따라서 박스플롯과 마찬가지로 여러 집단의 분포를 한눈에 비교할 때 유용하다.

인코딩의 측면에서, y축은 박스플롯과 동일하며, x축은 밀도곡선의 y축과 동일하다.

  • y축 좌표: 수치형 변수의 통계치
    • 상자 중심: 중위수
    • 상자 하단: Q1
    • 상자 상단: Q3
    • 상자 높이: IQR
    • 수염 범위: 중앙의 \(2 \times \mathrm{IQR}\) 구간
  • x축 좌표: 해당 수치의 확률밀도

스캐터플롯(Scatter Plot, 산점도)

스캐터플롯 예제

스캐터플롯은 산점도라고도 하며, 말 그대로 점이 흩어져 있는 모양의 플롯이다. 축 개수만큼의 수치형 변수에 대하여 모든 데이터포인트를 하나의 플롯으로 나타낼 수 있다. 그러한 점에서 러그플롯과 닮은 점이 있으며, 일종의 2차원 러그플롯이라 생각할 수 있다.
스캐터플롯은 특히 변수 간 관계를 확인하고 싶을 때 매우 유용하다.

  • 점의 x축 좌표: 수치
  • 점의 y축 좌표: 또다른 수치
  • 점의 색상: 필요하다면, 범주

헥스플롯(Hex Plot)

헥스플롯 예제

Hexbin Plot이라고도 부르며, 모든 데이터포인트를 시각화하는 스캐터플롯과 달리, 축별로 히스토그램처럼 구간을 나누어 그 구간 내에 속한 데이터포인트의 수에 따라 구간의 색을 다르게 하는 방법을 이용한다. 스캐터플롯이 2차원 러그플롯이라면, 헥스플롯은 2차원 히스토그램을 위에서 내려다본 모습이라 생각할 수 있다.

  • 구간의 x축 좌표: 수치
  • 구간의 y축 좌표: 또다른 수치
  • 구간의 색상: 구간의 밀도

왜 헥스플롯에선 구간을 사각형이 아니라 육각형으로 나누는가? 사각형으로 나누면 더 간편할텐데 말이다. 여러 개의 사각형이 줄지어 있으면 마치 그 위에 선이 존재하는 것 같은 시각적인 착각이 일어날 수 있다. 이 경우 플롯의 의미를 혼동할 수 있으므로, 그러한 시각적인 편향을 피하기 위해 육각형을 이용한다고 한다.

등고선플롯(Contour Plot)

등고선플롯 예제

지도에서 볼 수 있는 등고선처럼, 밀도가 비슷한 영역을 곡선으로 묶어 색을 다르게 나타낸 플롯이다. 스캐터플롯이 2차원 러그플롯, 헥스플롯이 2차원 히스토그램이라면, 등고선플롯은 2차원 밀도곡선이라 할 수 있다.

  • 구간의 x축 좌표: 수치
  • 구간의 y축 좌표: 또다른 수치
  • 구간의 색상: 구간의 밀도

시각화의 원칙

Scale

두 변수 스케일
시각화할 때는 값들의 스케일에 유의해야 한다. 특히나 여러 변수들을 시각화할 때 유의하라. 위 시각화는 어떠한 문제가 있는가? 마치 Cancer Screening이 Abortion보다 적어진 느낌이 든다. 하지만 실제 수치는 그렇지 않다. 잘못된 직관을 호도하는 것이다. 이처럼 같은 축에 서로 다른 스케일을 사용하는 것은 오해를 낳는다.

두 변수 스케일 방법
만약, 두 변수를 함께 시각화하고 싶다면 어떻게 해야 할까? 위 사진처럼 같은 스케일을 사용할 수 있다. 하지만, 이 경우 Cancer에 비해 Abortion의 변화가 적어 전달하고자 하는 바를 직관적으로 알 수 없다. 이 경우엔 아래처럼 변화량을 바플롯으로 나타내는 것 또한 방법이다.

부분 데이터 스케일링
필요하다면, 전체 데이터에서 필요한 구간에만 집중할 수도 있다. 위쪽의 플롯은 전체 구간에서의 데이터 밀도를 나타낸다. 10 이상의 구간에서, 밀도가 사실상 0게 가깝게 나타나는 것을 볼 수 있다. 이때, 아래 플롯처럼 필요한 부분만 줌인함으로써 유용한 직관을 얻을 수도 있다. 이처럼 관심 영역(Region of Interest)을 줌인한 시각화 역시 의미를 가질 수 있다.

Conditioning

컨디셔닝 예제
Conditioning이란 말 그대로 조건(Condition)을 결정하는 것을 의미한다. 같은 데이터를 시각화한다고 하더라도, 가능한 방법은 무수히 많다.
위 이미지는 미국 25세 이상 노동자들의 성별, 학력별 주급을 시각화한 2개의 플롯이다. 두 플롯의 차이점이 무엇일까? 좌측은 바플롯을 이용했으며 두 성별을 각각 배치했고, 우측은 라인플롯을 이용했으며 두 성별을 함께 배치했다. 우측의 플롯이 조금 더 이해하기 편한 것은 자명하다.

여러 플롯을 하나의 이미지 안에 시각화할 때, 각각 옆으로 또는 위아래로 늘어놓는다면(좌측의 경우에 가깝다), 이를 Juxtaposition이라 한다. 반면, 여러 플롯을 같은 축 상에 겹치게 같이 그린다면(우측의 경우에 가깝다), 이를 Superposition이라 한다.

Perception

인간의 시각적인 인지에 있어서, 주의해야 할 부분이 있다. 몇 가지 측면에서 이를 알아보자.

색상

우선 색상에 관한 것부터 이야기해보자. 변수의 값에 따라 시각화 결과가 어떤 색을 띠게 할지 결정하는 것을 컬러맵(Colormap)이라 한다.

jet와 viridis
위 이미지는 matplotlib의 이전 기본 컬러맵 jet와 바뀐 컬러맵 viridis의 인지적 차이를 나타내고 있다. 보이는 것처럼, jet는 인지적인 밝기가 일정하지 않지만, viridis는 인지적인 밝기가 일정한 것을 볼 수 있다. 자세히 보면, jet에는 파란색과 녹색 사이의 연두색 부분과 녹색과 주황색 사이의 노랑색 부분이 다른 구간에 비해 더 밝아보이는 것을 볼 수 있다. 얼핏 보면 그 사이에 밝은 선이 있는 것처럼 보이며, 이는 시각화 결과에 허위 관계가 있는 것처럼 보이게 할 수 있다.
(이에 관한 자세한 내용은 Rainbow Colormap (Still) Considered Harmful을 참조하라.)

또한, 색각 이상자들을 위해 빨간색 + 초록색과 같은 조합은 피하는 것이 좋다. 특히 시각화를 통해 설득해야 하는 잠재적인 청중이 색각 이상자일 수 있을 때는 더더욱 그렇다. 시각화의 목적 중 하나는 다른 이들을 이해시키거나 설득하는 것임을 기억하라.

양적 변수와 질적 변수의 컬러맵
또한, 대상 변수가 양적 변수인지 질적 변수인지, 각 값들 간에 순서가 존재하는지에 따라 사용할 컬러맵이 달라진다.
예를 들어 위 이미지는 유명한 iris 데이터셋을 이용하여 붓꽃의 종별 꽃받침의 길이와 너비를 등고선으로 시각화한 것이다. virginica는 푸른색, setosa는 붉은색 계열의 색상을 사용했는데, 이는 두 종의 꽃 사이에 상하관계나 선후관계가 없기 때문이다. 한편, 데이터의 밀도에 따라 색상이 점점 어두워지는데, 이는 밀도가 순서를 가진 양적변수이기 때문에 같은 계열의 색에서 명도나 채도가 바뀌는 컬러맵을 사용하는 것이 해석하기 쉽기 때문이다.

이때, 같은 양적변수라도 구체적인 범위에 따라 다른 색을 사용할 수 있다. (앞서 본 밀도와 같이) 낮은 값에서 높은 값으로의 진행을 나타내는 경우 점점 밝아지거나 어두워지는 Sequential한 컬러맵을 사용할 수 있다. 한편, (정치성향과 같이) 중점을 기준으로 양극단을 지닌 값을 나타내는 경우 한 색에서 다른 색으로 변화하는 Diverging한 컬러맵을 사용할 수 있다.

형태

또한, 시각화 대상의 형태에 따라서 인식이 달라지기도 한다. 대표적으로, 길이는 각도보다 훨씬 비교하기 쉽다. 그것이 바로 바플롯이 파이차트(원 그래프)보다 유용한 이유이다. 비슷한 이유로, 워드클라우드처럼 한눈에 빈도를 비교하기 어려운 플롯은 특별한 이유가 있지 않는 한 피하는 것이 좋다.

기준선이 일정하지 않은 바플롯
비슷한 이유로, 바플롯 등을 그릴 때는 여러 범주를 하나의 막대로 쌓지 않는 편이 좋다. 위 이미지를 살펴보자. 전체 값의 변화와 각 범주의 비율은 알 수 있지만, 각 범주의 변화는 한눈에 들어오지 않는다. 길이를 비교할 기준선(Baseline)이 아래 범주까지의 누적값에 의해 결정되기 때문이다.

Overplotting

산점도(스캐터플롯)나 러그플롯은 모든 데이터포인트를 전부 시각화한다는 특징이 있다. 이 경우, 같은 값을 가진 데이터포인트가 겹쳐진다는 문제가 있다. 이 경우 해당 영역에 값이 몇 개 있는지 아예 알 수가 없게 된다. 이러한 문제를 해결하기 위한 몇 가지 방법이 있다.

  1. 데이터에 약간의 노이즈를 더해 위치를 변화시킨다(Jittering).
  2. 점을 반투명하게 만들어 겹쳐진 점들이 더 진하게 보이도록 한다.
  3. 히스토그램이나 헥스플롯처럼 밀도를 알 수 있는 플롯을 사용한다.

Context

백문이 불여일견이라 하지만, 그럼에도 때때로 플롯을 설명할 수 있는 맥락적 내용이 존재하는 것은 중요하다. 특히, (스스로 데이터를 이해하기 위한 것이 아니라) 타인을 설득하기 위한 시각화에는 아래와 같은 것들이 필요하다.

  • 제목(Title): 해당 플롯의 제목이다. 이때 중요한 것은, 제목은 정보를 담고 있어야 한다는 것이다(Informative Title). 가격과 나이에 관한 산점도처럼 단순히 플롯의 구조를 설명하는 제목보다는 노인들은 비행기표에 더 많은 돈을 쓴다와 같은 플롯의 내용을 요약하는 제목이 더 좋을 수 있다.
  • 축 레이블(Axis Label): x축과 y축과 같은 각 축이 어떤 의미인지를 설명하는 레이블을 의미한다.
  • 중요한 값을 표시하는 참조선(Reference Line), 표시(Marker), 레이블(Label): 참고로, 참조선이란 특정 값을 표시하기 위해 별도로 그은 선을 의미한다.
  • 범례(Legend): 필요하다면 범례를 추가할 수 있다. 범례란 플롯에서 각 요소가 어떤 데이터를 의미하는지 알려주는 칸을 의미한다.
  • 캡션(Caption): 캡션은 아래와 같은 조건을 만족하도록 달도록 하자.
    • 그 자체로 이해하기 쉬워야 함
    • 무엇이 그려졌는지 설명해야 함
    • 중요한 특징들을 언급해야 함
    • 시각화 결과를 포함해야 함

Smoothing

Smoothing은 말 그대로 부드럽게 한다는 뜻이다. 각 데이터포인트를 일일히 플로팅하는 대신, 데이터들을 요약해서 플로팅할 수 있다. 이를 Smoothing이라 한다.
이를테면, 러그플롯은 모든 데이터포인트를 일일히 플로팅한다. 이때, 구간별로 데이터의 개수를 세어 히스토그램을 그릴 수 있는데, 이것이 바로 Smoothing이다. 여러 구간의 개수를 세고 있는 히스토그램을 하나의 밀도곡선으로 요약할 수 있는데, 이것도 Smoothing이다.
Smoothing은 왜 하는가? 모든 데이터포인트를 일일히 확인할 수 있다면 그게 가장 정보량이 높지 않은가? 왜 굳이 데이터를 요약해서 보여주고 싶은가? Smoothing을 통해 우리는 각 데이터 자체보다는 전반적인 구조를 확인할 수 있다. 나무가 아닌 숲을 보기 위한 작업이 Smoothing인 셈이다.

KDE(Kernel Density Estimation)

KDE란, 히스토그램을 밀도곡선으로 변환하기 위해 확률밀도함수(Probability Density Function)를 구하는 방법이다. x축이 구간, y축이 그 구간의 비중인 히스토그램에서, 전체 막대의 넓이 합이 1인 것처럼, 밀도곡선 역시 데이터의 분포를 나타내면서 넓이가 1로 나타나는 것이 직관적일 것이다.
그렇다면 어떻게 이러한 조건을 만족하는 밀도곡선을 만들 수 있는가? 바로 KDE를 이용해서이다. KDE는 아래와 같은 순서로 이루어진다.

KDE 스텝 1
각 데이터포인트의 위치에 커널(Kernel)이라 불리는, 넓이가 1인 단위곡선(함수)을 배치한다. 커널에는 여러 종류가 있는데, 위 이미지에서는 정규분포(Normal Distribution)라고도 불리는 가우시안(Gaussian) 커널을 배치했다.

KDE 스텝 2
그 이후, 모든 커널의 넓이 합이 1이 되도록 정규화(Normalize)해야 한다. 위 예시에서는 5개 커널이 존재하는데, 각 커널의 넓이는 1이므로 모든 커널을 5로 나누어 총합이 1이 되도록 한다.

KDE 스텝 3
이제 모든 커널을 더하면 전체 넓이가 1이며 데이터의 분포를 반영하는 하나의 곡선이 등장한다. 이것이 KDE를 통해 구한 밀도곡선이 된다.

(KDE와 같은 추정 방법을 비모수적 방법이라 한다. 다양한 비모수적 방법은 추후 기계학습 게시글에서 다룰 예정이다.)

커널(Kernel)

커널(Kernel)은 원래 알맹이 내지는 핵심이라는 뜻인데, 여기에선 각 데이터포인트에 적용할 함수 정도로 이해하면 된다. CNN(Convolutional Neural Network) 따위를 알고 있다면, 거기서의 커널과 비슷한 느낌을 받을 수 있을 것이다.

커널은 그 자체로 유효한 밀도^이어야 하는데, 따라서 음수값이 존재해서는 안되고, 넓이의 총합이 1이어야 한다. 더불어 커널이 각 데이터포인트를 중심으로 한다는 것을 고려한다면, 좌우가 대칭이어야 한다.

커널에는 대역폭(Bandwidth)이 존재하는데, 대역폭이란 말 그대로 커널의 폭(너비)을 이야기한다. 대역폭이 작다는 것은 커널이 중심으로 밀집해 있다는 것을 의미하고, 대역폭이 크다는 것은 커널이 넓게 퍼져있다는 것을 의미한다. 대략적으로 첨도(Kurtosis)의 반대 개념으로 이해하면 된다.
대역폭은 KDE에서 어떤 역할을 하는가? 만약 대역폭이 작다면, 각 데이터를 더 세밀하게 반영할 것이다. 반면 대역폭이 크다면, 개별 데이터보다 대략적인 구조가 더 크게 반영된다. 지나치게 작은 대역폭은 과적합(Overfitting)이고, 지나치게 큰 대역폭은 과소적합(Underfitting)이다. 아래는 대역폭 \(\alpha\)에 따른 KDE의 변화이다.
대역폭 예제

Transformation

때로는 선형이 아닌 두 피처 사이의 관계를 선형으로 보고 싶을 때도 있을 수 있다. 특히, 이러한 과정을 통해 얼핏 관계없어 보이는 두 피처가 사실은 관계가 있음을 발견할 수도 있다. 따라서 피처의 값을 변환함으로써 피처 사이의 선형 관계를 찾는 일은 도움이 된다.
그렇게 하기 위한 방법으로 각 축 중 하나 또는 여럿에 특정한 함수를 취할 수 있는데, 대표적인 것이 바로 로그함수(\(\log\))이다. 로그함수를 이용하면 \(y = a^x\)와 같은 지수함수꼴의 관계도 \(\log y = x \log a\)와 같이 (\(\log y\)에 대한 \(x\)의) 선형으로 나타낼 수 있고, \(y = ax^k\)와 같은 다항함수도 \(\log y = \log a + k \log x\)와 같이 (\(\log y\)에 대한 \(\log x\)의) 선형으로 나타낼 수 있다.

Tukey-Mosteller Bulge Diagram

Tukey-Mosteller Bulge Diagram
물론, 그렇다고 로그함수만 사용할 수 있는 것은 아니다. 이러한 형태의 변환을 쉽게 하기 위해, Tukey-Mosteller Bulge Diagram을 활용할 수 있다.
위 이미지는 원래 그래프의 개형을 보고, 관계를 선형으로 만들기 위한 변형을 유추하는 데에 사용할 수 있다. 이를테면, 두 피처 사이의 관계가 좌측 상단의 개형과 유사하다면, \(x\)에 대해 로그나 루트를 취하거나, \(y\)에 대해 제곱이나 세제곱을 취함으로써 관계를 선형에 가깝게 만들 수 있다는 것이다.

정리

이렇게 데이터의 시각화에 대해 알아보았다. 거의 pandas편 급으로 내용이 길어졌는데, 그만큼 중요한 내용이 많았다. 특히 여러 종류의 플롯은 기초적인 내용이므로 꼭 알아두자.

다음 시간부터는 드디어 기초적인 내용에서 벗어나, 모델링의 기초와 여러가지 모델에 대해 다루게 된다.

2024

맨 위로 이동 ↑

2023

세그먼트 트리

개요 선형적인 자료구조에서는 값에 접근하는 데에 \(O(1)\)이면 충분하지만, 대신 부분합을 구하는 데에는 \(O(N)\)이 필요하다. 그렇다면 이 자료구조를 이진 트리로 구성하면 어떨까? 값에 접근하는 데에 걸리는 시간이 \(O(\lg N)\)으로 늘어나지만 대신 부분합을 구하...

벨만-포드 알고리즘

개요 다익스트라 알고리즘과 함께 Single Sourse Shortest Path(SSSP) 문제를 푸는 알고리즘이다. 즉, 한 노드에서 다른 모든 노드로 가는 최단 경로를 구하는 알고리즘이다. 다익스트라 알고리즘보다 느리지만, 음수 가중치 간선이 있어도 작동하며, 음수 가중치 사...

다익스트라 알고리즘

개요 다익스트라 알고리즘은 Single Sourse Shortest Path(SSSP) 문제를 푸는 알고리즘 중 하나이다. 즉, 한 노드에서 다른 모든 노드로 가는 최단 경로를 구하는 알고리즘이다. 단, 다익스트라 알고리즘은 음수 가중치 엣지를 허용하지 않는다. 이 경우에는 벨만-...

맨 위로 이동 ↑