부스트 캠프 ai tech 3주 2일차 Data 시각화 (6)


Text

  • 시각화에 적절한 Text는 시각적인것으로만 전달하기 힘든 설명을 추가하거나 잘못된 전달에서 생기는 오해를 방지 할 수 있다
  • 하지만 과한 Text는 오히려 방해가 될 수 있으니 주의할 필요가 있다

1. Anatomy of a Figure

  • Title : 그래프의 주제
  • Label : 축에 해당되는 데이터 정보
  • Tick Lable : 축의 grid의 스케일 정보
  • Legend : 한 그래프에서 여러개의 데이터 분류를 위한 보조 정보
  • Annotation : 그 외의 시각화를 위한 보조정보
1
코드 추가 필요

2. Text Properties

  1. font Components

    • family : 글씨체
    • size or fontsize : 사이즈
    • style or fontstyle : 스타일(기울임체 등등)
    • weight or fontweight : 두께
    • matplot Docs Fonts Demo
  2. Detail

    • color : 글씨의 색
    • linespacing : 줄간격
    • backgroundcolor : 배경색
    • alpha : 투명도
    • zorder : z축 순서
    • visible : 랜더 유무
  3. 정렬

    • ha : horizontal alignment
    • va : vertical alignment
    • rotation : 가로로 적을지 세로로 적을지 설정
    • multialignment : 추가적인 정렬
  4. 그 외 추가적인 항목

reference

data-viz-5


scatterplot

  • 점을 통해서 그리는 그래프
  • 상관관계를 확인하기위해 그리는 그래프
  • color, marker(모양), size으로 다양한 바리에이션을 주는것이 가능하다

scatterplot에서 확인해할 것

  • 군집을 판단한다
  • 값의 차이를 확인한다
    • 빈공간을 데이터를 보고 어떻게 채울지
  • 이상치를 파악하자
    • scatterplot을 통해서 이상치를 파악하고 처리할 수단을 생각한다

Overplotting

  • 점이 많아져서 분포를 파악하기 힘들 상황
    • 투명도 조절
    • jittering 점의 위치를 겹치지않게 변형
    • 2차원 히스토그램 : 히트맵으로 변화시켜서 시각화
    • Countor plot : 등고선으로 표현

점의 요소와 인지

    • 연속적인것은 gradient, 이산은 category color로
  • marker
    • 구별하기가 힘들다
    • 크기가 고르지 않다
    • 색과 병행해서 사용하자
  • 크기
    • 버블차트
    • 관계보다는 점간 비율에 초점을 두고 사용하자
    • 오용하기 쉽기때문에 조심할것!

인과관계와 상관관계

  • 인과관계와 상관관계를 구별해서 사용하자
    • 상관관계가 보인다고해서 인과관계가 있는것이 아니다
  • 항상 text를 추가해서 설명해주는것이 더 좋다

추세선

  • 상관관계가 존재할 경우에는 추세선을 추가해서 정보를 더 제공할 수 있다.
  • 대신 2개이상 사용하는것은 지양할것

그 외

  • Grid는 지양하는게 좀 더 깔끔한 시각화를 제공한다
  • Category data는 버블차트나 히트맵을 사용하는편이 좋다

reference

부스트 캠프 ai tech 3주 1일차 Data 시각화 (4)


Lineplot

  • 연속적으로 변화하는 값을 점으로 나타내고 선으로 연결한 그래프

1. 기본적인 Lineplot

  • .plot()으로 그래프를 그릴 수 있다
  • 5개 이하의 선을 사용하는것이 가독성이 좋다
    • 색상, 마커, 선의 종류 등으로 선을 구분해서 가독성을 더 끌어 올릴 수 있다.
    • color : 색상 지정
    • marker : 점의 모양 지정
    • linestyle : 선의 종류 지정(solid, dashed, dashdot, dotted, None)
  • 흐름의 파악을 원할하게 하기 위해 smoothing을 사용해서 Noise를 줄인다

2. Lineplot의 특징

1. 흐름에 집중하는 그래프

  • 데이터의 흐름을 보기위한 그래프이다
    • 그렇기에 bar와 다르게 축을 0에 맞출 필요는 없다
  • 너무 구체적인 정보는 오히려 흐름을 보는데 방해 될 수 있다
    • Grid, Annotate등을 최소한으로 사용한다
    • 디테일한 정보는 따로 표로 제공하는것도 좋다
  • 생략되지 않는 선에서 범위를 조절해서 표현한다
    • .set_ylim()을 이용하자

2. 간격

  • 축의 간격이 다를경우 기울기 정보에서 오해를 일으킬 수 있다. 또한 점과 점 사이를 선으로 연결한 것이기 때문에 실제로 데이터가 없는부분에서 있다고 오해가 가능하다
    • 수치형 데이터일 경우 matplot에서 알아서 맞추어준다
    • 데이터의 위치에 mark를 해서 오해를 줄일 수 있다

3. 보간

  • 점과 점사이를 실제 데이터가 없지만 이어서 선으로 만드는 방법
  • 데이터의 error나 Noise가 포함되어 있을경우 보간을 사용해서 어느정도 보정해 이해를 도울 수 있다.
    • scipy모듈을 이용하여 사용
  • 데이터를 분석할 경우 미세한 차이를 놓치거나, 없는데이터를 있다고 생각하게 할수 있기때문에 EDA에서는 지양하는것이 좋다.

4. 이중 축 사용

  • 한 plot에 대해서 2개의 축을 사용하는 방법
  • 같은 시간축에서 서로다른 데이터를 표현하기 위해서 쓴다.
    • .twinx()를 사용해서 구현한다
  • 보통 한 데이터에 대한 다른단위 표현을 위해 사용한다
    • .secondary_xaxis(), .secondary_yaxis()를 사용한다
  • 두 데이터에 대해서 이중 축을 사용하는것은 강제로 상관관계를 부여할 수 있으니 지양하고 2개의 plot을 사용하는쪽이 좀 더 가독성 면에서도 좋다

5.그 외 팁

  • 라인 끝에 label을 추가하면 식별에 도움이 된다
  • 주요 포인트에는 annotation을 추가하면 도움이 될 수도 있다
  • 연한색으로 uncerainty 표현이 가능하다

reference

Week3 - Day 1 Review


1. 오늘 하루 한 것

  • 강의
    • 1, 2강 완료
  • 정리
    • 1강 완료, 2강 Barplot

2. 피어세션에서 한 것

  • 피어슨 상관계수

3. 내일 할 것

  • 정리 마무리
  • 3, 4 강의

4. 하루 느낀점

  • 설연휴 좀 쉬었더니 빠르게 정리가 잘 되지 않는다
  • 쉰다고 많이 못했어….

부스트 캠프 ai tech 3주 1일차 Data 시각화 (3)


Barplot

  • 직사각형의 막대를 사용하여 데이터를 표현하는 그래프
  • category에 따른 수치값을 비교하기에 적합하다

1. 기본적인 Barplot

  • barplot은 기본적으로 bar, barh가 존재한다.
  • bar는 수직, barh는 수평으로 막대를 그린다
1
2
3
4
5
6
fig, ax = plt.subplots(1, 2, figsize=(12, 7))
x = list('ABCDE')
y = np.array([1, 2, 3, 4, 5])
ax[0].bar(x, y)
ax[1].barh(x, y)
plt.show()
subplot

2. 다양한 Barplot 기법

  • 다양한 barplot에 대해서 이야기를 할 예정이다
  • 사용하는 데이터는 Boostcamp에서 제공한 데이터를 사용하였다
  • Multiple
    • plot을 여러개 그리는 방법이다.
    • subplots의 sharey를 이용하여 y축의 범위를 공유할 수 있다.
    • 각 group의 분포를 알기 좋지만 group간 비교하기에는 쉽지 않다
1
2
3
4
fig, ax = plt.subplots(1, 2, figsize=(12, 6), sharey=True)
ax[0].bar(group['male'].index, group['male'], color='royalblue')
ax[1].bar(group['female'].index, group['female'], color='tomato')
plt.show()
subplot
  • Stack
    • 2개 이상의 그룹을 쌓아서 표현하는 방식이다
    • 맨 밑 group의 분포는 파악하기 쉽지만 그외는 파악하기 힘들다
    • bottom : bar의 시작 y좌표를 설정 할 수 있다.
1
2
3
4
5
6
7
8
fig, axes = plt.subplots(1, 2, figsize=(15, 7))
group_cnt = student['race/ethnicity'].value_counts().sort_index()
axes[0].bar(group_cnt.index, group_cnt, color='darkgray')
axes[1].bar(group['male'].index, group['male'], color='royalblue')
axes[1].bar(group['female'].index, group['female'], bottom=group['male'], color='tomato') # 각 category의 y축 시작지점을 group['male']의 수치로 지정한다
for ax in axes:
ax.set_ylim(0, 350)
plt.show()
subplot
  • Percentage Stack
    • Stack을 응용하여 만든 BarPlot
    • bal_label을 이용하여 중간에 퍼센트를 찍어주었다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fig, ax = plt.subplots(1, 1, figsize=(12, 7))

group = group.sort_index(ascending=False) # 역순 정렬
total=group['male']+group['female'] # 각 그룹별 합

for name, color in zip(['male', 'female'], ['royalblue', 'tomato']):
rects = ax.barh(group[name].index, group[name]/total,
left=group['male']/total if name == 'female' else 0,
color=color)
ax.bar_label(rects, fmt='%.2g', label_type='center')

ax.set_xlim(0, 1)
for s in ['top', 'bottom', 'left', 'right']:
ax.spines[s].set_visible(False)

plt.show()
subplot
  • Overlap
    • 2개의 그룹만 비교할때 사용하기 좋은 방식
      • 3개 이상은 파악이 어렵다
    • 같은 축을 사용하기 때문에 비교하기 쉽다
    • Bar보다는 Area에서 더 효과적이다
1
2
3
4
5
6
7
8
9
10
11
group = group.sort_index()
fig, axes = plt.subplots(1, 1, figsize=(8, 6))

axes.bar(group['male'].index, group['male'],
color='royalblue',
alpha=0.7)
axes.bar(group['female'].index, group['female'],
color='tomato',
alpha=0.7)
ax.set_ylim(0, 200)
plt.show()
subplot
  • Group
    • 그룹별 범주에 따른 막대를 이웃되게 배치하는 방법
    • Matplotlib로는 구현이 까다롭다
    • 그룹이 5~7개 이하일때 효과적이다
      • 많으면 오히려 역효과가 난다

시각화시 주의해야할점

  1. 실제값과 그래픽으로 표현되는 부분은 비례해야한다
    • 반드시 x축의 시작은 0부터 한다
    • 차이를 나타내고 싶다면 세로의 비율을 늘리자
  2. 정확한 정보를 전달하기 위해서 정렬을 하자
    • 데이터의 종류에따라 여러 기준으로 정렬을 한다.
    • 시계열 : 시간
    • 수치형 : 크기
    • 순서형 : 범주의 순서대로
    • 명목형 : 범주의 값에 따라서
    • interactive로 제공하는 것이 유용하다
  3. 여백을 잘 조절하자
    • 너무 꽉차있거나 비어있으면 가독성이 떨어진다. 적절한 조절로 가독성을 높이자
    • .set_xlim(), .set_ylim()으로 표시할 영역을 지정한다
    • .spines[pos].set_visible()을 이용해서 외곽선을 안보이게 조절한다
    • Gap, Margins을 이용해서 적절히 간격을 띄운다
  4. 복잡함을 줄이자
    • 3D는 왠만해서는 쓰지말자…
    • 축과 디테일을 조절하여 가독성과 깔끔함을 동시에 챙기자
      • text, annotate등을 이용하자

reference

부스트 캠프 ai tech 3주 1일차 Data 시각화 (2)


3. matplot.pyplot 기초

  • 이 글에서는 python 시각화 라이브러리 matplot에 대해서 다루어 본다
  • 기본적으로 가장 많이 사용하는 matplot.pyplot을 이용하여 그래프를 그린다.

들어가기전에

  • 보통 아래와 같이 많이 pyplot을 plt로 선언 한다
1
2
import numpy as np
import matplotlib.pyplot as plt

Figure & Axes

  • plt.figure로 그래프틀을 선언하고, plt.show()를 이용하여 화면에 나타낼 수 있다.
  • num : figure의 id를 지정한다. 이미 지정한 id가 존재하고 그것이 다시 정의될 경우에 원래 존재하던 figure를 반환한다
  • figsize : 그래프틀의 크기를 지정한다
  • dpi : 해상도를 설정한다
  • facecolor : 배경화면의 색을 지정한다
  • edgecolor : 가장자리 라인의 색을 지정한다
1
2
3
4
5
fig = plt.figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None)
plt.show()
==========
output
<Figure size 432x288 with 0 Axes>
  • 위의 코드에 Axes라는 subplot을 추가해야지만 제대로 그래프가 나온다
  • figure의 add_subplot()을 이용하여 Axes를 지정할 수 있다
1
2
3
fig = plt.figure()
ax = fig.add_subplot()
plt.show()
viz2

subplot

  • Axes에 추가적인 Argument 입력을 통해서 위치를 지정해 줄 수 있다.
  • suplots를 이용하여 fig와 Axes들을 동시에 정의 할 수도 있다.
1
2
3
4
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2)
plt.show()
subplot

plot

  • plot을 통해서 그래프를 그릴 수 있다.
  • x축과 y축의 수치가 1대1 대응으로 그래프가 그려진다.
  • figure, subplot에 plot을 통해 입력이 가능하다
  • 여러번 plot을 할 경우 여러개의 그래프가 그려진다
  • 직접 색을 입력해서 그래프의 색상을 지정 할 수 있다
  • x : x축이 될 데이터들
  • y : y축이 될 데이터들
1
2
3
4
5
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)
ax1.plot([1, 2], [1, 3], color = 'forestgreen')
ax1.plot([2, 3], [3, 1], color = 'r')
plt.show()
plot

text

  • label : 그래프에 label을 붙일 수 있다.
  • 단 label을 표시하기 위해서는 legend()를 이용해야 한다.
1
2
3
4
5
6
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)
ax1.plot([1, 2], [1, 3], color = 'forestgreen', label = '1')
ax1.plot([2, 3], [3, 1], color = 'r', label = '2')
ax1.legend() # 이게 없으면 label 표시가 나오지 않음
plt.show()
plot
  • 여러 메소드를 이용하여 그래프의 특정부분을 변경 시킬 수 있다.
  • set_title : title을 지정할 수 있다.
  • set_xticks : x축의 범주값을 지정할 수 있다.
  • set_ticklabels : x축을 텍스트 값으로 지정할 수 있다.
  • annotate : 그래프에 여러가지를 추가 할 수 있다.
  • 여러 메소드의 자세한 내용들은 추후에 다룰 예정이다.

reference

부스트 캠프 ai tech 3주 1일차 Data 시각화 (1)


1. Data의 종류

  • Dataset은 아래와 같이 분류가 가능하다.
    1. 정형 데이터
    2. 시계열 데이터
    3. 지리 데이터
    4. 관계형 데이터
    5. 계층적 데이터
  • 데이터는 아래와 같이 분류가 가능하다.
    • 수치형 데이터(numerical) : 수치로 표현된 데이터
      • 연속형(continuous) : 길이, 무게, 온도 등
      • 이산형(discrete) : 사람 수, 주사위 눈금 등
    • 범주형(categorical) : 문자로 표현되는 데이터
      • 명목형(norminal) : 혈액형, 종교, 주소 등
      • 순서형(ordinal) : 학년, 등급, 성적 등

1. 정형 데이터

  • 가장 기본적인 데이터 형태
  • 테이블 형태로 제공되는 데이터이다.

2. 시계열 데이터

  • 시간에 흐름에 따른 데이터
  • 기온 주가 등의 정형 데이터로 표현한 데이터와 음성, 비디오와 같이 비정형인 데이터가 존재한다.

3. 지리/지도 데이터

  • 지형과 지명이 들어가 있는 데이터
  • 위도와 경도를 이용해서 정형데이터로도 표현이 가능하다.
  • 지도 정보와 보고자하는 정보간의 조화를 잘 맞추어 주는것이 중요하다

4. 관계형 데이터

  • 객체와 객체간의 관계를 시각화 할 수 있는 데이터
  • 객체는 Node로, 관계는 Link로 표현이 가능하다
  • 크기와 색, 수 등으로 관계의 가중치를 표현 가능하다
  • 보기쉽게 하기위해 휴리스틱하게 노드의 배치를 구성할 수 있다

5. 계층적 데이터

  • 위의 관예형 데이터중에서 포함관계가 분명한 데이터
  • Tree, Treemap등의 형태의 데이터가 포함된다

2. 시각화

  • 수치와 문제로 이루어진 데이터를 점,선,면을 이용해서 한눈에 보기 쉽게 만들어준다
  • 아래의 속성들을 적절하게 사용해서 시각적으로 분리를 일으켜서 주의 깊게 보지 않아도 한눈에 알아볼수 있도록 하는것이 목표이다
    • 너무 많이 사용하면 오히려 인지하기 힘든 부작용이 나타난다
viz

reference

Garbage collection


서론

이 글에서는 Python의 Garbage Collector에 대해서 다룬다.

Garbage collection

Garbage Collector(이하 GC)는 메모리 관리 기법중 하나로 동적으로 할당했던 메모리 영역 중에 필요없게 된 부분을 해제하는 기능이다. C, C++등의 언어들은 수동메모리 관리를 전재로 설계되어 malloc, free등의 함수로 직접 메모리를 관리 해주어야 하지만, Python, Java, C# 같은 고급 언어들은 GC가 내장되어 있어 자동으로 메모리 관리를 해준다.

Python GC의 작동방식

Python의 GC는 reference count + Generational GC 방식으로 메모리를 관리한다.

reference count

1
2
3
4
5
typedef struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt; /* reference count */
struct _typeobject *ob_type;
} PyObject;

python의 객체들은 모두 reference count를 가지고 있으며 이것을 통해서 GC가 언제 메모리에서 제거할지를 판단한다. 참조가 이루어지면 reference count가 1증가하고, 참조가 끝나면 1감소한다. 최종적으로 0이 되면 GC에서 더이상 필요없는 오브젝트로 판단하고 메모리에서 삭제한다.

이러한 방식은 프로그래머가 어느정도 오브젝트의 메모리 할당 해제 시점을 유추 할 수 있고, 대부분 사용된 직후 해제되기 때문에 캐시에 저장되어 있을 확률이 높아 빠르게 할당 해제가 이루어지는 장점이 존재한다.

하지만 아래와 같은 단점 또한 존재한다. 두개 이상의 객체가 서로 가리키고 있을 경우(순환 참조) reference count가 0까지 내려가지 않는 상황이 발생 할 수 있다. 또한 Multi Thread 환경에서는 공유자원에 대한 참조가 되기 때문에 추가적인 Lock 등이 필요하거나, 지속해서 GC에서 판단하는 프로세스를 거쳐야 하기 때문에 수행 성능의 저하 등의 문제가 발생 할 수 있다.

이러한 단점들을 해결하기 위해 Python에서는 순환 참조를 탐지하는 알고리즘과, 보조적인 Generational GC를 두었고, GIL로 Multi Threading에 제한을 걸어 버렸다.

Generational GC

새롭게 할당된 오브젝트일수록 금방 메모리에서 해제될 확률이 높다는 통계에서 기반한 메모리 관리방법이다. 각각의 오브젝트가 GC가 실행하고나서 메모리에서 해제되지 않으면 다음 세대로 넘어가게 되는 방식인데 더 젊은 세대(금방 생성)일수록 자주 GC의 프로세스에서 할당 해제할 오브젝트인지 판단이 내려지게 된다.

이 과정을 보조적으로 추가하면서 python에서는 조금더 효율적으로 메모리를 관리 하고 있다.

Generational GC

reference

Global Interpritor Lock


GIL. Global Interpritor Lock.

Global Interpritor Lock(GIL)이란 Python에서 오직 하나의 Thread만 동작하도록 컨트롤하는 Lock(또는 Mutex)이다.
이 말은 타임라인상에 오직 하나의 Thread만 실행될 수 있다는 것을 말한다. Single Thread를 사용하는 코드에서는 그렇게 큰 영향을 주지 않지만, Multi-Thread를 사용하는 코드에서는 병목현상을 일으킬 수 있다.

GIL이 어떻게 동작하는지 한번 살펴보자

위에서 이야기 한 것처럼, GIL에서는 오직 하나의 Thread만 활성화되어서 코드를 실행하는데 이는 아래의 그림처럼 그려낼 수 있다.

GIL

Thread가 전환 될 경우에는 기존의 Thread의 작동이 멈추고 동작을 시작하게 된다.
기존의 하던 작업들을 멈추고 다른 Thread로 넘겨야 하기 때문에 context switch가 일어나게 된다.

그러면 왜 GIL을 사용할까?

먼저 왜 GIL을 사용하는지 알기 위해서는 Python의 Garbege Collector(GC)에 대해 알고 있어야 한다. (GC에 대한 자세한 내용은 추후에 다룰 예정이다) 고급언어인 python에서는 C언어와 다르게 자동으로 메모리 관리를 해주는 GC라는 것을 사용한다.

이 GC는 오브젝트가 얼마나 많이 참조(실행)가 되었는지를 카운팅하는 reference count 라는 것으로 메모리에서 삭제할지 유지할지를 결정한다. 하지만 동시에 여러군데에서 참조가 이루어 질 경우 Race Condition 등의 문제들이 발생 할 수 있기 때문에 이를 방지하기위해 Mutex나 Semaphore등의 Lock이 필요했는데 이것을 Python에 존재하는 수많은 Object에 전부 적용하는것은 성능상으로도 좋지 않을 뿐만 아니라, Deadlock 같은 매우 치명적인 위험상황이 발생 할 수 있었다

그래서 선택한것이 따로 Object에 Lock을 두지 않고, 타임라인에서 실행되는 Thread를 딱 하나만 두도록 Interpritor를 Mutex로 잠궈버렸다. 이렇게 되면 여러곳에서 동시 참조가 되지않으니 성능의 하락 없이 위의 동시참조의 문제를 해결하게 된것이다

그러면 python에서는 병렬화된 코드는 어떻게 써야하나

  1. Multi Process를 사용한다
    Thread를 막아버린것 이기 때문에 Multi Processing을 사용하면 잘 돌아간다. 물론 Process간에 공유자원을 가지기 위해서는 많은 작업들이 필요로 하기 때문에 context switching이 발생하여 Thread에 비해 속도가 늦을 것이다. 하지만 Windows는 OS 보안상 이유로 이걸 막아버렸다.
  2. Multi Threading을 사용한다
    아까 Multi Threading을 막아놨다고 했는데 뭔 소리냐 할 수 있지만, CPU에서 대부분의 연산이 돌아가는 코드를 제외한 I/O Bound 계열의 문제들은 file system과 Network의 하위 컴포넌트에서 돌아가기 때문에 Single보다 더 빠르게 진행 할 수 있다.
  3. 굳이 사용하고 싶다면 PyPi나 Jython 같은 다른 Python implementation으로 사용하는 방법도 존재하지만, 그 코드가 python에서와 똑같이 동작할 보장은 없다
  • 그리고 numpy나 Scipy등의 ML에서 많이 사용하는 Module들은 C기반으로 만들어져서 GIL의 굴레에서 자유롭게 연산이 된다고 한다.

reference

Week2 Homework


1. 기초과제

  • 과제 내용
    • Pytorch의 Custom Model 제작에 필요한 nn.Module 함수들에 대한 공부
    • Dataset과 Dataloader의 구현
  • 결과 및 회고

2. 심화과제

  • 과제내용
    • Transfer Learning과 weight 초기화 + Ray사용 해보기
  • 결과 및 회고
    • Transfer Learning은 익히 알던 내용이여서 어렵지 않았다
    • weight 초기화를 할때 랜덤으로 초기화 해주는것보다 특정 initialization 을 진행하는것이 더 성능이 잘 나오는것에 대해 알게 되었다
      • 이미 pytorch에서는 layer별로 내부 Method에 적용되어있다고 한다
      • 자세한 내용은 kaiming_uniform_에 대해 찾아보는것을 추천한다
    • Ray는 코드 실행은 해보았지만 colab GPU 사용량 초과로 인해서 강제 종료 당했다
    • 추후에 Linux 환경의 컴퓨터에서 다시한번 실행을 해 볼 예정이다