※ 이 포스팅은 저자 'Kirthi Raman'의 도서 <Mastering Python Data Visualization> 을 공부하며 정리한 글입니다. 



Chapter 05. Financial and Statistical Models (금융과 통계 모형)


( 이전 포스팅에 이어서 .. )

An Overview of Statistical and Machine Learning (통계 및 머신러닝 개요)

머신러닝은 인간이 수행하기에 충분히 간단한 분류식들을 생성하는 것을 목표로 한다.

머신러닝은 결정 프로세스에 대한 통찰력을 제공하기 위해 인간의 추론을 충분히 모방해야만 한다.

통계와 유사하게 배경 지식은 개발 단계에서 활용될 수 있다.


통계 학습과 머신 러닝의 차이는 추론 중심이냐 예측 중심이냐의 차이라고 볼 수 있다.



#. k-최근접 이웃 (k-Nearest Neighbor)

k-NN은 훈련 데이터로부터 모델을 구축하지 않는, 알고리즘이다. 

k-NN의 접근 방법은 다음과 같다.

- 어떤 방법이든 사용해 데이터를 수집

- 거리 계산에 필요한 수치 값을 준비

- 계산된 k-NN 이웃 검색에 대한 몇 가지 작업을 수행하고, 상위 k의 가까운 이웃을 식별


from numpy import random, argsort, sqrt

from pylab import plot, show

import matplotlib.pyplot as plt


def knn_search(x, data, K) :

    ndata = data.shape[1]

    K = K if K < ndata else ndata

    # 다른 지점으로부터의 유클리드 거리

    sqd = sqrt(((data - x[:,:ndata])**2).sum(axis=0))

    idx = argsort(sqd) # 정렬

    # k-NN 인덱스 반환

    return idx[:K]


data = random.rand(2,200)   # 랜덤 데이터 셋

x = random.rand(2,1)        # 쿼리 포인트


neig_idx = knn_search(x, data, 10)


plt.figure(figsize=(12, 12))


# 데이터와 입력 포인트를 플로팅한다.

plot(data[0,:], data[1,:], 'o', x[0, 0], x[1, 0], 'o', color='#9a88a1', markersize=20)

     

# 이웃들을 하이라이팅

plot(data[0, neig_idx], data[1, neig_idx], 'o', markerfacecolor='#bbe4b4', markersize=22, markeredgewidth=1)


show()




#. 일반화 선형 모델 (Generalized Linear Models)

회귀분석은 변수들 사이의 관계를 추정하는데 쓰이는 통계 프로세스다. 구체적으로, 회귀는 독립변수 중 하나가 변화할 때 종속 변수의 전형적인 값이 어떻게 변화하는지 이해하는 데 도움이 된다.


그 중 선형 회귀분석은 보간법(interpolation)을 적용할 수 있는 고전적인 방법이나 예측력은 부족하다. 또한, 이상치와 교차 상관관계에 민감하다.

선형 회귀모형은 목표 값(y)을 입력변수(x1, x2, ... xn)의 선형결합으로 다음과 같이 추정한다.

베이즈 회귀는 분리한 추정의 일종이며, 전통적인 선형 회귀보다 더 유연하고 안정적이다.

왜 베이즈를 사용하는가? 베이즈 모델은 더 유연하고, 작은 샘플에서 더 정확하며, 이전의 정보를 포함할 수 있기 때문이다.



#. 베이즈 선형 회귀 (Bayesian Linear Regression)

먼저, 선형 회귀를 위한 그래픽 모델을 살펴보자.

주어진 값을 다음과 같이 설정한다.



목표는 이 데이터를 모델링하여 다음과 같은 함수 식을 마련하는 것이다.

여기서 w는 가중치 벡터이고, 위의 식에 나타낸 것처럼 각 Yi는 정규분포를 따르게 된다.

Yi는 랜덤변수고, 데이터로부터 랜덤변수 Yi=yi의 각 조건의 변수 x값을 바탕으로 새로운 변수 x값을 대응하는 y를 예측할 수 있다.


import numpy as np

import matplotlib.pyplot as plt

from scipy import stats


from sklearn.linear_model import BayesianRidge


np.random.seed(0)

n_samples, n_features = 200, 200


X = np.random.randn(n_samples, n_features) # 가우시안 데이터

# 정밀도 4로 가중치를 만듦

theta = 4.

w = np.zeros(n_features)


# 관심 있는 8개의 가중치만 유지

relevant_features = np.random.randint(0, n_features, 8)

for i in relevant_features :

    w[i] = stats.norm.rvs(loc=0, scale=1. / np.sqrt(theta))

    

alpha_ = 50.

noise = stats.norm.rvs(loc=0, scale=1. / np.sqrt(alpha_), size=n_samples)

y = np.dot(X, w) + noise


# 베이즈 능형 회귀 (Bayesian Ridge Regression) 에 맞춤

clf = BayesianRidge(compute_score=True)

clf.fit(X, y)


# 가중치, 예측 및 히스토그램 가중치를 시각화

plt.figure(figsize=(11, 10))

plt.title("Weights of the model", fontsize=18)

plt.plot(clf.coef_, 'b-', label="Bayesian Ridge estimate")

plt.plot(w, 'g-', label="Training Set Accuracy")

plt.xlabel("Features", fontsize=16)

plt.ylabel("Values of the weights", fontsize=16)

plt.legend(loc="best", prop=dict(size=12))


plt.figure(figsize=(11, 10))

plt.title("Histogram of the weights", fontsize=18)

plt.hist(clf.coef_, bins=n_features, log=True)

plt.plot(clf.coef_[relevant_features], 5 * np.ones(len(relevant_features)),

         'ro', label="Relevant features")

plt.ylabel("features", fontsize=16)

plt.xlabel("Values of the weights", fontsize=16)

plt.legend(loc="lower left")

plt.show()





#. 애니메이션 및 인터랙티브 플롯 작성

Bokeh, Plotly, VisPy 등의 인터랙티브한 그래프 작성 도구들이 있다.


Bokeh는 인터랙션하는 부분을 쉽게 하기 위해 자바스크립트와 D3.js로 matplotlib 객체를 시각화할 수 있으며, 큰 데이터셋에서도 좋은 성능을 제공한다.


#import bokeh

#bokeh.sampledata.download() # 이 2개 라인은 최초만 실행하면 됨


from bokeh.sampledata import us_counties, unemployment

from bokeh.plotting import figure, show, output_file

from bokeh.models import HoverTool


import collections

from collections import OrderedDict


county_coordinate_xs=[

        us_counties.data[code]['lons'] for code in us_counties.data

        if us_counties.data[code]['state'] == 'ca'

        ]

county_coordinate_ys=[

        us_counties.data[code]['lats'] for code in us_counties.data

        if us_counties.data[code]['state'] == 'ca'

        ]


colors = ["#e6f2ff", "#cce5ff", "#99cbff", "#b2d8ff", "#73abe5", "#5985b2"]

county_colors = []

for county_id in us_counties.data :

    if us_counties.data[county_id]['state'] != 'ca' :

        continue

    try :

        rate = unemployment.data[county_id]

        idx = min(int(rate/2), 5)

        county_colors.append(colors[idx])

    except KeyError :

        county_colors.append("black")


output_file("california.html", title="california.py example")


TOOLS="pan, wheel_zoom, box_zoom, reset, hover, save"

p = figure(title="California Unemployment 2009",

           width=1000, height=1000, tools=TOOLS)


p.patches(county_coordinate_xs, county_coordinate_ys,

          fill_color=county_colors, fill_alpha=0.7,

          line_color="white", line_width=0.5)


mouse_hover = p.select(dict(type=HoverTool))

mouse_hover.point_policy = "follow_mouse"

mouse_hover.tooltips = collections.OrderedDict([

        ("index", "$index"), ("(x, y)", "($x, $y)"),

        ("fill color", "$color[hex, swatch]:fill_color"),])


show(p)



Plotly는 인터랙티브한 그래프 시각화를 제공하는 또 다른 옵션이다.

그러나 참고로, 온라인상에 있어야 하고 Plotly 계정이 필요하다.


VisPy는 파이썬과 OpenGL을 사용해 만들어진 고성능 인터랙티브 도구로, 최신 GPU 성능을 제공하는 라이브러리이다.




+ Recent posts