TigerCow.Door

'데이터분석 관련'에 해당되는 글 4건

안녕하세요. 문범우입니다.

이번 포스팅에서는 나이브 베이즈 분류(Naive Bayesian Classification)에 대해서 알아보도록 하겠습니다.

나이브 베이즈 분류는 스팸 필터나 문서 분류등에서도 많이 사용되는 분류 방법으로써, 분류 문제에 있어서 현재도 많이 이용되는 방법입니다.


1. 확률 이론 - 조건부 확률


나이브 베이즈 분류에 대해서 알아보기 전에 확률 이론중 조건부 확률에 대해 알아야 합니다.

크게 어려운 내용은 아니니 간단하게 짚고 넘어가보도록 하겠습니다.


먼저 간단하게, 확률은 다음과 같이 나타냅니다.

위의 그림과 같이, 파란색 구슬3개, 빨간색 구슬 2개로 총 5개의 구슬이 있을때,

P(파란색 구슬) = 3/5

P(빨간색 구슬) = 2/5

입니다.


즉,

P( A ) = A 의 경우의 수 / 전체 경우의 수

로 생각할 수 있습니다.


그럼 바로, 조건부 확률에 대해서 알아보도록 하겠습니다.

조건부 확률에서는 몇가지 가정이 필요합니다.

A와 B라는 두 가지 경우(상황)가 있을때, 이 두 경우는 서로 영향을 미치지 않는 상황을 먼저 생각해 볼게요.

예시를 들어본다면, 제가 오늘 아침에 일어나서 바로 물을 마시는 확률과 저녁에 게임을 하는 확률로 생각할 수 있습니다.

이러한 두 상황은 서로에게 영향을 미치지는 않지만, 충분히 둘 다 발생하는 경우는 존재할 수 있습니다.


위와 같이, 파란색, A 경우의 확률은 10%이고 B의 경우는 50%라고 생각해 봅시다. 이때 다음과 같은 식으로 나타낼 수 있습니다.


P(A) = 0.1

P(B) = 0.5

P(A  B) = P(A) * P(B) = 0.1 * 0.5 = 0.05


 B 는, A와 B가 동시에 일어날 확률이므로 서로의 확률을 곱해줌으로써 구해줄 수 있습니다. 그럼, 조건부 확률은 어떻게 나타내고, 어떻게 구할까요?

먼저 식으로 살펴보면 다음과 같습니다.


P(A|B) = P(A) = 0.1

P(B|A) = P(B) = 0.5


A|B 는 B의 경우에 A의 확률 입니다. 그런데 위의 식을 보면 P(A|B) = P(A) 로 되어 있습니다. 왜 그럴까요?

우리가 위에서, A와 B는 서로 영향을 미치지 않는다고 가정하였습니다.

즉, 오늘 제가 저녁에 게임을 하던 안하던, 아침에 일어나서 바로 물을 마실 확률은 그대로인 것입니다.

같은 개념으로, 그 반대인, P(B|A) = P(B) 로 도출됩니다.


그럼 조금 다른 가정을 생각해보도록 할게요.

만약에 A와 B가 서로에게 영향을 미치는 상황이라면 어떨까요?

그림은 위에서 사용한 동일한 그림을 이용하겠습니다.

이제는 A와 B가 서로에게 영향을 끼칩니다.

그러므로 조건부 확률의 식이 달라지게 되는데, 이때의 조건부 확률은 다음과 같습니다.


P(A|B) = P(A ∩ B) / P(A)

P(B|A) = P(A ∩ B) / P(B)


위와 같은 식을 이용하여 베이즈 정리를 통해 우리는 다양하게 변형 해볼 수 있습니다.


P(A B) = P(A|B) * P(A) = P(B|A) * P(B)

P(A|B) = P(B|A) * P(B) / P(A)

P(B|A) = P(A|B) * P(A) / P(B)


즉, 베이즈 정리는 위와 같이, 사전 확률(A경우에서의 B)를 통해 사후 확률(B경우에서의 A)을 알 수 있다는 것을 말합니다.

위와 같이 변형된 식들을 이용하면, 우리가 알고있는 정보를 통해 새로운 정보를 얻을 수 있습니다.

또한 본격적으로 알아볼 나이브 베이즈 분류에서 위의 개념들이 사용됩니다.



2. 나이브 베이즈 분류

(Naive Bayesian Classification)


그럼 실제로 나이브 베이즈 분류가 어떤 것인지 예제를 통해 알아보도록 하겠습니다.

처음에 말씀드렸듯이, 나이브 베이즈 분류는 스팸 필터에서도 많이 사용되는 분류기이기 때문에, 이와 같은 예제를 사용해보도록 하겠습니다.

우리가 사전에 알고 있는 정보는 다음과 같습니다.


총 이메일: 100개

(spam 이메일의 확률) = P(spam) = 30/100

(money라는 단어가 포함된 이메일의 확률) = P(money) = 50/100

(spam 이메일 중 money를 포함한 이메일의 확률) = P(money | spam) = 2/5


이러한 정보들을 바탕으로, 우리는 money를 포함한 이메일이 spam일 확률을 구하고 싶어합니다.

즉, P(spam | money) 의 값을 구하고 싶은 것이죠.

우리가 위에서 알아본 베이즈 정리를 통해 아래와 같은 수식으로 쉽게 구할 수 있습니다.


P(spam | money) = P(money | spam) * P(money) / P(spam)

=(2/5) * (50/100) / (30/100) = 2/3


위와 같이 쉽게 구할 수 있습니다.


하지만 위와 같은 예제는 아주 복잡한 상황을 매우 단순하게 축약했을 뿐 입니다.

실제로는 훨씬 더 복잡하기에 우리는 분류기 등을 실제로 설계하고 제작하여 사용합니다.


단순히 하나의 단어가 아니고, 수십개, 수백개의 단어를 통해 분류를 하기에 우리가 하나하나 손으로 계산하기가 불가능하다고 볼 수 있습니다.


블로그 이미지

Tigercow.Door

Data-Analysis / AI / back-end / Algorithm / DeepLearning / etc

Matplotlib_clear

안녕하세요. 문범우입니다.

이번 포스팅에서는 파이썬 기반 시각화 라이브러리인 matplotlib에 대해서 알아보도록 하겠습니다.


해당 내용은 flearning의 김길호님의 강의를 바탕으로 작성되었습니다.

https://www.flearning.net/courses/6


1. Matplotlib 이란?


matplotlib은 다양한 데이터를 많은 방법으로 도식화 할 수 있도록 하는 파이썬 라이브러리로써, 우리는 matplotlib의 pyplot을 이용하게 됩니다.

이는 mathworks에서 개발한 매트랩(MATLAB)과 비슷한 형태를 가지고 있습니다.

matplotlib을 이용하면 우리가 이전에 알아본 numpy나 pandas에서 사용되는 자료구조를 쉽게 시각화 할 수 있습니다.


matplotlib을 사용하기 위해서는 먼저 matplotlib을 설치하고 아래와 같이 import를 해주어야 합니다.


import matplotlib

import matplotlib.pyplot as plt


또한 jupyter notebook에서 그래프를 제대로 확인하기 위해서는 아래와 같은 매직 커맨드를 작성해주셔야 합니다.


%matplotlib inline


이러한 매직커맨드는 맨 뒤에 inline 이외에도 우리가 아래에서 사용하는 nbagg 등의 다양한 속성이 있습니다.


Matplotlib 기초

1. Matplotlib 이란?

In [11]:
import matplotlib
import matplotlib.pyplot as plt
%matplotlib nbagg
#위와 같은 것이 %로 시작하는 것을 jupyter notebook의 magic command라고 한다.
# %who는 변수명의 리스트를 보여주고 %magic 은 모든 매직명령어를 보여준다.
# 전체적인 magic 명령어에 대해서는 다음 블로그를 참고
# http://studymake.tistory.com/601
# matplotlib 을 jupyter notebook에서 사용할 때, plot의 이미지를 보여주기 위해 magic command를 사용하는데,
# 이때 우리가 사용하는 nbagg 이외에도 다음과 같은 요소를 사용할 수 있다.
# Available matplotlib backends: ['osx', 'qt4', 'qt5', 'gtk3', 'notebook', 'wx', 'qt', 'nbagg','gtk', 'tk', 'inline']
# 사용되는 명령어에 대한 차이점이 정리되어 있는 사이트는 따로 찾지 못했지만
# 각각에 대해서는 matplotlib의 공식문서에서 참고 할 수 있는듯 하며,
# 우리가 사용하는 nbagg에 대해서는 다음 링크에서 확인할 수 있다.
# https://matplotlib.org/users/prev_whats_new/whats_new_1.4.html#the-nbagg-backend
import numpy as np
import pandas as pd

2. Plot의 종류

Line plot 그리기

In [12]:
# Series를 통한 line plot 그리기
s = pd.Series(np.random.randn(10).cumsum(), index=np.arange(0, 100, 10))
s
Out[12]:
0    -0.722984
10   -1.830547
20   -0.592063
30   -1.320894
40   -1.849281
50   -1.570039
60   -3.052119
70   -2.698092
80   -2.722053
90   -2.735229
dtype: float64
In [13]:
# 위에서 정의한 s라는 시리즈에 대해서 line plot을 그리고 싶다면?
s.plot()
Out[13]:
<matplotlib.axes._subplots.AxesSubplot at 0x108ef0c88>

s 라는 Series에서의 index와 value를 통해 그래프가 그려졌다.

그래프 우측상단의 전원버튼을 누르기 전까지 우리는 해당 그래프를 interactive하게 조작할 수 있다.

In [14]:
# DataFrame을 통한 line plot 그리기
df = pd.DataFrame(np.random.randn(10, 4).cumsum(axis=0),
                  columns=["A", "B", "C", "D"],
                  index=np.arange(0, 100, 10))
df
Out[14]:
A B C D
0 -0.278464 1.680385 0.711803 -0.216933
10 -0.239848 2.527778 1.558551 1.006354
20 -2.112968 1.384759 2.648977 -0.124528
30 -2.461009 -0.023573 2.145466 -0.253936
40 -4.098926 -0.191797 1.583091 -1.285248
50 -2.224330 0.036316 -0.053839 0.045480
60 -4.346708 0.467878 0.877064 -1.018642
70 -5.083230 2.082973 2.360633 0.942955
80 -5.860602 4.372568 2.506778 0.312459
90 -4.651125 5.932881 1.437739 -1.382153
In [16]:
df.plot()
Out[16]:
<matplotlib.axes._subplots.AxesSubplot at 0x109df6710>
In [17]:
# 하나의 열에 대해서만 보고 싶다면?
df['B'].plot()
Out[17]:
<matplotlib.axes._subplots.AxesSubplot at 0x10a859b38>

Bar plot 그리기

In [18]:
s2 = pd.Series(np.random.rand(16), index=list("abcdefghijklmnop"))
s2
Out[18]:
a    0.571031
b    0.225421
c    0.210635
d    0.247162
e    0.850638
f    0.300911
g    0.485898
h    0.573721
i    0.223882
j    0.248352
k    0.163142
l    0.977120
m    0.615089
n    0.376035
o    0.618324
p    0.374877
dtype: float64
In [19]:
s2.plot(kind='bar')
Out[19]:
<matplotlib.axes._subplots.AxesSubplot at 0x10b26a208>
In [21]:
# 가로방향의 bar plot그리기
s2.plot(kind='barh')
Out[21]:
<matplotlib.axes._subplots.AxesSubplot at 0x10c6f0908>
In [22]:
df2 = pd.DataFrame(np.random.rand(6, 4), 
                   index=["one", "two", "three", "four", "five", "six"],
                   columns=pd.Index(["A", "B", "C", "D"], name="Genus"))
df2
Out[22]:
Genus A B C D
one 0.832213 0.165459 0.385868 0.300776
two 0.937578 0.576798 0.175512 0.690425
three 0.473119 0.690937 0.844016 0.542061
four 0.974779 0.911599 0.880104 0.155459
five 0.421689 0.168038 0.637749 0.181037
six 0.921647 0.069688 0.143649 0.033414
In [23]:
df2.plot(kind='bar')
Out[23]:
<matplotlib.axes._subplots.AxesSubplot at 0x10d17e7f0>
In [28]:
df2.plot(kind='barh', stacked=True)