다운로드
작성자: admin 작성일시: 2016-06-16 18:11:02 조회수: 9554 다운로드: 375
카테고리: 머신 러닝 태그목록:

나이브 베이즈 분류 모형

나이브 가정

독립 변수 $x$가 다차원이면 즉, $x = (x_1, \ldots, x_D)$이면 가능도(likelihood) $P(x \mid y = k)$로 모든 $x=(x_1, \ldots, x_D)$에 대한 결합 확률(joint probability) $P(x_1, \ldots, x_D \mid y = k)$ 을 사용해야 한다. 그러나 차원이 높아질 수록 이러한 다차원 결합 확률은 실제로 구하기 어렵기 때문에 모든 차원의 개별 독립 변수 요소들이 서로 조건부 독립(conditional independent)이라는 가정을 흔히 사용한다. 이러한 가정을 베이즈 분류 모형에 적용한 모형을 나이브 베이즈 분류 모형(Naive Bayes classification model)이라고 한다.

나이브 베이즈 분류 모형에서는 $x$ 벡터의 결합 확률이 개별 원소 $x_d$의 확률의 곱으로 나타난다.

$$ P(x_1, \ldots, x_D \mid y = k) = \prod_{d=1}^D P(x_d \mid y = k) $$$$ P(y = k \mid x) \;\; \propto \;\; \prod_{d=1}^D P(x_{d} \mid y = k)\; P(y = k) $$

가우시안 정규 분포 가능도 모형

$x$ 벡터의 원소가 모두 실수이고 클래스마다 특정한 값 주변에서 발생한다고 하면 가우시안 정규 분포 likelihood 모형을 사용한다. 각 독립 변수 $x_d$마다, 그리고 클래스 $k$마다 정규 분포의 기댓값 $\mu_{d,k}$, 표준 편차 $\sigma_{d,k}^2$가 달라진다. QDA 모형과는 달리 모든 독립 변수들이 서로 조건부 독립이라고 가정한다.

$$ P(x_d \mid y = k) = \dfrac{1}{\sqrt{2\pi\sigma_{d,k}^2}} \exp \left(-\dfrac{(x_d-\mu_{d,k})^2}{2\sigma_{d,k}^2}\right) $$

베르누이 분포 가능도 모형

베르누이 분포 가능도 모형에서는 각각의 $x = (x_1,\ldots, x_D)$의 각 원소 $x_d$가 0 또는 1이라는 값만을 가질 수 있다. 즉 독립 변수는 $D$개의 독립적인 베르누이 확률 변수, 즉 동전으로 구성된 동전 세트로 표현할 수 있다. 이 동전들의 모수 $\mu_{d}$는 동전 $d$마다 다르다.

그런데 클래스 $y = k$ $(k=1,\ldots,K)$마다도 $x_d$가 1이 될 확률이 다르다. 즉, 동전의 모수 $\mu_{d,k}$는 동전 $d$마다 다르고 클래스 $k$마다도 다르다. 즉, 전체 $D \times K$의 동전이 존재하며 같은 클래스에 속하는 $D$개의 동전이 하나의 동전 세트를 구성하고 이러한 동전 세트가 $K$개 있다고 생각할 수 있다.

$$ P(x_d \mid y = k) = \mu_{d,k}^{x_d} (1-\mu_{d,k})^{(1-x_d)} $$$$ P(x_1, \ldots, x_D \mid y = k) = \prod_{d=1}^D \mu_{d,k}^{x_d} (1-\mu_{d,k})^{(1-x_d)} $$

이러한 동전 세트마다 확률 특성이 다르므로 베르누이 분포 가능도 모형을 기반으로 하는 나이브 베이즈 모형은 동전 세트를 $N$번 던진 결과로부터 $1,\ldots,K$ 중 어느 동전 세트를 던졌는지를 찾아내는 모형이라고 할 수 있다.

다항 분포 가능도 모형

다항 분포 모형에서는 $x$ 벡터가 다항 확률 분포의 샘플이라고 가정한다. 즉, $D$개의 면을 가지는 주사위를 $\sum_{d=1}^D x_d$번 던져서 나온 결과로 본다. 예를 들어 $x$가 다음과 같다면,

$$ x = (1, 4, 0, 5) $$

4면체 주사위를 10번 던져서 1인 면이 1번, 2인 면이 4번, 4인 면이 5번 나온 결과로 해석한다.

각 클래스마다 주사위가 다르다고 가정하므로 $K$개의 클래스를 구분하는 문제에서는 $D$개의 면을 가진 주사위가 $K$개 있다고 본다.

$$ P(x_1, \ldots, x_D \mid y = k) \;\; \propto \;\; \prod_{d=1}^D \mu_{d,k}^{x_{d,k}} $$$$ N_k = \sum_{d=1}^{D} x_{d,k} $$$$ \sum_{d=1}^{D} \mu_{d,k} = 1 $$

따라서 다항 분포 가능도 모형을 기반으로 하는 나이브 베이즈 모형은 주사위를 던진 결과로부터 $1,\ldots,K$ 중 어느 주사위를 던졌는지를 찾아내는 모형이라고 할 수 있다.

Scikit-Learn에서 제공하는 나이브 베이즈 모형

Scikit-Learn의 naive_bayes 서브패키지에서는 다음과 같은 세가지 나이브 베이즈 모형 클래스를 제공한다.

이 클래스들은 다양한 속성값 및 메서드를 가진다. 우선 사전 확률과 관련된 속성은 다음과 같다.

  • classes_

    • 종속 변수 Y의 클래스(라벨)
  • class_count_

    • 종속 변수 Y의 값이 특정한 클래스인 표본 데이터의 수
  • class_prior_

    • 종속 변수 Y의 무조건부 확률 분포 $ P(Y) $ (가우시안 정규 분포의 경우에만)
  • class_log_prior_

    • 종속 변수 Y의 무조건부 확률 분포의 로그 $ \log P(Y) $ (베르누이 분포나 다항 분포의 경우에만)

가우시안 정규 분포 나이브 베이즈 모형

가우시안 나이브 베이즈 모형 GaussianNB은 가능도 추정과 관련하여 다음과 같은 속성을 가진다.

  • theta_: 가우시안 정규 분포의 기댓값 $\mu$
  • sigma_: 가우시안 정규 분포의 분산 $\sigma^2$

예를 들어 실수인 두 개의 독립 변수 $x_1, x_2$와 두 종류의 클래스 $y=0,1$을 가지는 분류 모형을 생각하자. 독립 변수는 $y$의 클래스에 따라 다음처럼 분포가 달라진다.

$$ \mu_0 = \begin{bmatrix} -2 \\ -2 \end{bmatrix}, \;\; \Sigma_0 = \begin{bmatrix} 1 & 0.9 \\ 0.9 & 2 \end{bmatrix} $$$$ \mu_1 = \begin{bmatrix} 2 \\ 2 \end{bmatrix}, \;\; \Sigma_1 = \begin{bmatrix} 1.2 & -0.8 \\ -0.8 & 2 \end{bmatrix} $$
In [45]:
np.random.seed(0)
rv0 = sp.stats.multivariate_normal([-2, -2], [[1, 0.9], [0.9, 2]])
rv1 = sp.stats.multivariate_normal([2, 2], [[1.2, -0.8], [-0.8, 2]])
X0 = rv0.rvs(40)
X1 = rv1.rvs(60)
X = np.vstack([X0, X1])
y = np.hstack([np.zeros(40), np.ones(60)])

xx1 = np.linspace(-5, 5, 100)
xx2 = np.linspace(-5, 5, 100)
XX1, XX2 = np.meshgrid(xx1, xx2)
plt.grid(False)
plt.contour(XX1, XX2, rv0.pdf(np.dstack([XX1, XX2])), cmap=mpl.cm.cool)
plt.contour(XX1, XX2, rv1.pdf(np.dstack([XX1, XX2])), cmap=mpl.cm.hot)
plt.scatter(X0[:, 0], X0[:, 1], marker="o", c='b')
plt.scatter(X1[:, 0], X1[:, 1], marker="s", c='r')
plt.axis("equal")
plt.show()

이 데이터를 가우시안 나이브 베이즈 모형으로 다음처럼 풀 수 있다.

In [2]:
from sklearn.naive_bayes import GaussianNB
model_norm = GaussianNB().fit(X, y)

y 클래스의 종류와 각 클래스에 속하는 샘플의 수, 그리고 그 값으로부터 구한 사전 확률의 값은 다음과 같다.

In [3]:
model_norm.classes_
Out:
array([0., 1.])
In [4]:
model_norm.class_count_
Out:
array([40., 60.])
In [5]:
model_norm.class_prior_
Out:
array([0.4, 0.6])

각 클래스에 따라 $x$가 이루는 확률 분포의 모수를 계산하면 다음과 같다.

In [6]:
model_norm.theta_[0], model_norm.sigma_[0]
Out:
(array([-1.96197643, -2.00597903]), array([1.02398854, 2.31390497]))
In [7]:
model_norm.theta_[1], model_norm.sigma_[1]
Out:
(array([2.19130701, 2.12626716]), array([1.25429371, 1.93742544]))
In [49]:
rv0 = sp.stats.multivariate_normal(model_norm.theta_[0], model_norm.sigma_[0])
rv1 = sp.stats.multivariate_normal(model_norm.theta_[1], model_norm.sigma_[1])

xx1 = np.linspace(-5, 5, 100)
xx2 = np.linspace(-5, 5, 100)
XX1, XX2 = np.meshgrid(xx1, xx2)
plt.grid(False)
plt.contour(XX1, XX2, rv0.pdf(np.dstack([XX1, XX2])), cmap=mpl.cm.cool)
plt.contour(XX1, XX2, rv1.pdf(np.dstack([XX1, XX2])), cmap=mpl.cm.hot)
plt.scatter(X0[:, 0], X0[:, 1], marker="o", c='b')
plt.scatter(X1[:, 0], X1[:, 1], marker="s", c='r')

x_new = [0, 0]
plt.scatter(x_new[0], x_new[1], c="g", marker="x", s=150, linewidth=5)

plt.axis("equal")
plt.show()

이 모형을 사용하여 $x_{\text{new}} = (0, 0)$인 데이터의 $y$값을 예측하자. 각 클래스값이 나올 확률은 predict_proba 메서드로 구할 수 있다. 결과는 y=0일 확률이 0.48, y=1일 확률이 0.52이다.

In [9]:
model_norm.predict_proba([x_new])
Out:
array([[0.48475244, 0.51524756]])

이 값이 나오게 된 중간 과정을 살펴보자. 우선 추정된 독립 변수의 모수와 정규 분포의 확률 밀도 함수를 사용하여 likelihood를 구할 수 있다. 나이브 베이즈 가정에 따라 두 입력 변수의 곱을 결합 확률로 계산한다.

In [10]:
likelihood = [
    (sp.stats.norm(model_norm.theta_[0][0], np.sqrt(model_norm.sigma_[0][0])).pdf(x_new[0]) * \
     sp.stats.norm(model_norm.theta_[0][1], np.sqrt(model_norm.sigma_[0][1])).pdf(x_new[1])),
    (sp.stats.norm(model_norm.theta_[1][0], np.sqrt(model_norm.sigma_[1][0])).pdf(x_new[0]) * \
     sp.stats.norm(model_norm.theta_[1][1], np.sqrt(model_norm.sigma_[1][1])).pdf(x_new[1])),
]
likelihood
Out:
[0.006615760017637307, 0.004687965595148289]

여기에 사전 확률을 곱하면 사후 확률에 비례하는 값이 나온다. 아직 정규화 상수 $p(x)$로 나누어주지 않았으므로 두 값의 합이 1이 아니다. 즉, 확률이라고 부를 수는 없다. 하지만 크기를 비교하면 y=0일 확률이 y=1일 확률보다 훨씬 크다는 것을 알 수 있다.

In [11]:
posterior = likelihood * model_norm.class_prior_
posterior
Out:
array([0.0026463 , 0.00281278])

이 값을 정규화하면 predict_proba 메서드로 구한 것과 같은 값이 나온다.

In [12]:
posterior / posterior.sum()
Out:
array([0.48475244, 0.51524756])

연습 문제 18.3.2

붓꽃 분류 문제를 가우시안 나이브 베이즈 모형을 사용하여 풀고 다음을 구하라.

  • confusion matrix
  • classification report
  • ROC curve
  • AUC

베르누이 분포 나이브 베이즈 모형

베르누이 나이브 베이즈 모형에서는 타겟 변수뿐 아니라 독립 변수도 0 또는 1의 값을 가져야 한다. 예를 들어 전자우편과 같은 문서 내에 특정한 단어가 포함되어 있는지의 여부는 베르누이 확률 변수로 모형화할 수 있으므로 스팸 필터링에 사용할 수 있다.

베르누이 분포 나이브 베이즈 모형 클래스 BernoulliNB는 가능도 추정과 관련하여 다음 속성을 가진다.

  • feature_count_: 각 클래스 $k$에 대해 $d$번째 동전이 앞면이 나온 횟수 $N_{d,k}$
  • feature_log_prob_: 베르누이 분포 모수의 로그
$$ \log \mu_k = (\log \mu_{1,k}, \ldots, \log \mu_{D, k}) = \left( \log \dfrac{N_{1,k}}{N_k}, \ldots, \log \dfrac{N_{D,k}}{N_k} \right)$$

여기에서 $N_k$은 클래스 $k$에 대해 동전을 던진 총 횟수이다. 표본 데이터의 수가 적은 경우에는 모수에 대해 다음처럼 스무딩(smoothing)을 할 수도 있다.

스무딩

표본 데이터의 수가 적은 경우에는 베르누이 모수가 0 또는 1이라는 극단적인 모수 추정값이 나올 수도 있다. 하지만 현실적으로는 실제 모수값이 이런 극단적인 값이 나올 가능성이 적다. 따라서 베르누이 모수가 0.5인 가장 일반적인 경우를 가정하여 0이 나오는 경우와 1이 나오는 경우, 두 개의 가상 표본 데이터를 추가한다. 그러면 0이나 1과 같은 극단적인 추정값이 0.5에 가까운 다음과 값으로 변한다. 이를 라플라스 스무딩(Laplace smoothing) 또는 Add-One 스무딩이라고 한다.

$$ \hat{\mu}_{d,k} = \frac{ N_{d,k} + \alpha}{N_k + 2 \alpha} $$

가중치 $\alpha$를 사용하여 스무딩의 정도를 조절할 수도 있다. 가중치 $\alpha$는 정수가 아니라도 괜찮다.

In [13]:
X = np.array([
    [0, 1, 1, 0],
    [1, 1, 1, 1],
    [1, 1, 1, 0],
    [0, 1, 0, 0],
    [0, 0, 0, 1],
    [0, 1, 1, 0],
    [0, 1, 1, 1],
    [1, 0, 1, 0],
    [1, 0, 1, 1],
    [0, 1, 1, 0]])
y = np.array([0, 0, 0, 0, 1, 1, 1, 1, 1, 1])

이 데이터는 4개의 키워드를 사용하여 정상 메일 4개와 스팸 메일 6개를 BOW 인코딩한 행렬이다. 예를 들어 첫번째 메일은 정상 메일이고 1번, 4번 키워드는 포함하지 않지만 2번, 3번 키워드를 포함한다고 볼 수 있다.

이 데이터를 베르누이 나이브 베이즈 모형으로 예측해 보자.

In [14]:
from sklearn.naive_bayes import BernoulliNB
model_bern = BernoulliNB().fit(X, y)

y 클래스의 종류와 각 클래스에 속하는 샘플의 수, 그리고 그 값으로부터 구한 사전 확률의 값은 다음과 같다.

In [15]:
model_bern.classes_
Out:
array([0, 1])
In [16]:
model_bern.class_count_
Out:
array([4., 6.])
In [17]:
np.exp(model_bern.class_log_prior_)
Out:
array([0.4, 0.6])

각 클래스 $k$ 별로, 그리고 각 독립 변수 $d$ 별로, 각각 다른 베르누이 확률 변수라고 가정하여 모두 8개의 베르누이 확률 변수의 모수를 구하면 다음과 같다.

In [18]:
fc = model_bern.feature_count_
fc
Out:
array([[2., 4., 3., 1.],
       [2., 3., 5., 3.]])
In [19]:
fc / np.repeat(model_bern.class_count_[:, np.newaxis], 4, axis=1)
Out:
array([[0.5       , 1.        , 0.75      , 0.25      ],
       [0.33333333, 0.5       , 0.83333333, 0.5       ]])

그런데 이 값은 모형 내에서 구한 값과 다르다. 모형 내에서 스무딩(smoothing)이 이루어지기 때문이다. 스무딩은 동전의 각 면 즉, 0과 1이 나오는 가상의 데이터를 추가함으로서 추정한 모수의 값이 좀 더 0.5에 가까워지도록 하는 방법이다. 이 때 사용한 스무딩 가중치 값은 다음처럼 확인할 수 있다.

In [20]:
model_bern.alpha
Out:
1.0

스무딩이 적용된 베르누이 모수값은 다음과 같다.

In [21]:
theta = np.exp(model_bern.feature_log_prob_)
theta
Out:
array([[0.5       , 0.83333333, 0.66666667, 0.33333333],
       [0.375     , 0.5       , 0.75      , 0.5       ]])

이에 모형이 완성되었으니 테스트 데이터를 사용하여 예측을 해 본다. 예를 들어 1번, 2번 키워드를 포함한 메일이 정상 메일인지 스팸 메일인지 알아보자.

In [22]:
x_new = np.array([1, 1, 0, 0])
In [23]:
model_bern.predict_proba([x_new])
Out:
array([[0.72480181, 0.27519819]])

위 결과에서 정상 메일일 가능성이 약 3배임을 알 수 있다. 이 값은 다음처럼 구할 수도 있다.

In [24]:
p = ((theta ** x_new) * (1 - theta) ** (1 - x_new)).prod(axis=1)\
    * np.exp(model_bern.class_log_prior_)
p / p.sum()
Out:
array([0.72480181, 0.27519819])

반대로 3번, 4번 키워드가 포함된 메일은 스팸일 가능성이 약 90%이다.

In [25]:
x_new = np.array([0, 0, 1, 1])
In [26]:
model_bern.predict_proba([x_new])
Out:
array([[0.09530901, 0.90469099]])
In [27]:
p = ((theta ** x_new) * (1 - theta) ** (1 - x_new)).prod(axis=1)\
    * np.exp(model_bern.class_log_prior_)
p / p.sum()
Out:
array([0.09530901, 0.90469099])

연습 문제 18.3.3

  1. MNIST Digit 분류 문제에서 sklearn.preprocessing.Binarizer로 x값을 0, 1로 바꾼다(값이 8 이상이면 1, 8 미만이면 0). 즉 흰색과 검은색 픽셀로만 구성된 이미지로 만든다. 이 이미지에 대해 베르누이 나이브 베이즈 모형을 적용하자. 분류 결과를 classification_report로 나타내라.
  2. BernoulliNB 클래스의 binarize 인수를 사용하여 같은 문제를 풀어본다.
  3. 계산된 모형의 모수 벡터 값을 각 클래스별로 8*8 이미지의 형태로 나타낸다. 이 이미지는 무엇을 뜻하는가?

다항 분포 나이브 베이즈 모형

다항 분포 나이브 베이즈 모형 클래스 MultinomialNB는 가능도 추정과 관련하여 다음 속성을 가진다.

  • feature_count_: 각 클래스 $k$에서 $d$번째 면이 나온 횟수 $N_{d,k}$
  • feature_log_prob_: 다항 분포의 모수의 로그
$$ \log \mu_k = (\log \mu_{1,k}, \ldots, \log \mu_{D, k}) = \left( \log \dfrac{N_{1,k}}{N_k}, \ldots, \log \dfrac{N_{D,k}}{N_k} \right)$$

여기에서 $N_k$은 클래스 $k$에 대해 주사위를 던진 총 횟수를 뜻한다.

스무딩 공식은

$$ \hat{\mu}_{d,k} = \frac{ N_{d,k} + \alpha}{N_k + D \alpha} $$

이다.

이번에도 스팸 메일 필터링을 예로 들어보다. 다만 BOW 인코딩을 할 때, 각 키워드가 출현한 빈도를 직접 입력 변수로 사용한다.

In [28]:
X = np.array([
    [3, 4, 1, 2],
    [3, 5, 1, 1],
    [3, 3, 0, 4],
    [3, 4, 1, 2],
    [1, 2, 1, 4],
    [0, 0, 5, 3],
    [1, 2, 4, 1],
    [1, 1, 4, 2],
    [0, 1, 2, 5],
    [2, 1, 2, 3]])
y = np.array([0, 0, 0, 0, 1, 1, 1, 1, 1, 1])
In [29]:
from sklearn.naive_bayes import MultinomialNB
model_mult = MultinomialNB().fit(X, y)

사전 확률은 다음과 같이 구한다.

In [30]:
model_mult.classes_
Out:
array([0, 1])
In [31]:
model_mult.class_count_
Out:
array([4., 6.])
In [32]:
np.exp(model_mult.class_log_prior_)
Out:
array([0.4, 0.6])

다음으로 각 클래스에 대한 likelihood 모형을 구한다. 다항 분포 모형을 사용하므로 각 클래스틑 4개의 면을 가진 주사위로 생각할 수 있다. 그리고 각 면이 나올 확률은 각 면이 나온 횟수를 주사위를 던진 전체 횟수로 나누면 된다. 우선 각 클래스 별로 각각의 면이 나온 횟수는 다음과 같다.

In [33]:
fc = model_mult.feature_count_
fc
Out:
array([[12., 16.,  3.,  9.],
       [ 5.,  7., 18., 18.]])

이 데이터에서 클래스 Y=0인 주사위를 던진 횟수는 첫번째 행의 값의 합인 40이므로 클래스 Y=0인 주사위를 던져 1이라는 면이 나올 확률은 다음처럼 계산할 수 있다.

$$ \mu_{1,Y=0} = \dfrac{12}{40} = 0.3 $$
In [34]:
fc / np.repeat(fc.sum(axis=1)[:, np.newaxis], 4, axis=1)
Out:
array([[0.3       , 0.4       , 0.075     , 0.225     ],
       [0.10416667, 0.14583333, 0.375     , 0.375     ]])

실제로는 극단적인 추정을 피하기 위해 이 값을 가중치 1인 스무딩을 한 추정값을 사용한다.

In [35]:
model_mult.alpha
Out:
1.0
In [36]:
(fc + model_mult.alpha) / \
    (np.repeat(fc.sum(axis=1)[:, np.newaxis],
               4, axis=1) + model_mult.alpha * X.shape[1])
Out:
array([[0.29545455, 0.38636364, 0.09090909, 0.22727273],
       [0.11538462, 0.15384615, 0.36538462, 0.36538462]])

이렇게 구한 모수 추정치는 다음과 같다.

In [37]:
theta = np.exp(model_mult.feature_log_prob_)
theta
Out:
array([[0.29545455, 0.38636364, 0.09090909, 0.22727273],
       [0.11538462, 0.15384615, 0.36538462, 0.36538462]])

이제 이 값을 사용하여 예측을 해 보자. 만약 어떤 메일에 1번부터 4번까지의 키워드가 각각 10번씩 나왔다면 다음처럼 확률을 구할 수 있다. 구해진 확률로부터 이 메일이 스팸임을 알 수 있다.

In [38]:
x_new = np.array([10, 10, 10, 10])
model_mult.predict_proba([x_new])
Out:
array([[0.38848858, 0.61151142]])

다항 분포의 확률 밀도 공식을 사용하면 다음처럼 직접 확률을 구할 수도 있다.

In [39]:
p = (theta ** x_new).prod(axis=1)*np.exp(model_bern.class_log_prior_)
p / p.sum()
Out:
array([0.38848858, 0.61151142])

연습 문제 18.3.4

MNIST Digit 분류 문제를 다항분포 나이브 베이즈 모형을 사용하여 풀고 Binarizing을 하여 베르누이 나이브 베이즈 모형을 적용했을 경우와 성능을 비교하라.

연습 문제 18.3.5

텍스트 분석에서 TF-IDF 인코딩을 하면 단어의 빈도수가 정수가 아닌 실수값이 된다. 이런 경우에도 다항분포 모형을 적용할 수 있는가?

뉴스 그룹 분류

다음은 20 News Group 데이터에 대해 나이브 베이즈 분류 모형을 적용한 결과이다.

In [40]:
from sklearn.datasets import fetch_20newsgroups

news = fetch_20newsgroups(subset="all")
X = news.data
y = news.target
In [41]:
from sklearn.feature_extraction.text import TfidfVectorizer, HashingVectorizer, CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline

model1 = Pipeline([
    ('vect', CountVectorizer()),
    ('model', MultinomialNB()),
])
model2 = Pipeline([
    ('vect', TfidfVectorizer()),
    ('model', MultinomialNB()),
])
model3 = Pipeline([
    ('vect', TfidfVectorizer(stop_words="english")),
    ('model', MultinomialNB()),
])
model4 = Pipeline([
    ('vect', TfidfVectorizer(stop_words="english",
                             token_pattern=r"\b[a-z0-9_\-\.]+[a-z][a-z0-9_\-\.]+\b")),
    ('model', MultinomialNB()),
])
In [42]:
%%time
from sklearn.model_selection import cross_val_score, KFold

for i, model in enumerate([model1, model2, model3, model4]):
    scores = cross_val_score(model, X, y, cv=5)
    print(("Model{0:d}: Mean score: {1:.3f}").format(i + 1, np.mean(scores)))
Model1: Mean score: 0.855
Model2: Mean score: 0.856
Model3: Mean score: 0.883
Model4: Mean score: 0.888
CPU times: user 1min 12s, sys: 3.06 s, total: 1min 15s
Wall time: 1min 15s

연습 문제 18.3.6

만약 독립변수로 실수 변수, 0 또는 1 값을 가지는 변수, 자연수 값을 가지는 변수가 섞여있다면 scikit-learn에서 제공하는 나이브 베이즈 클래스들를 사용하여 풀 수 있는가?

질문/덧글

multinomialNB에서 alpha의 의미는 무엇인가요? tada*** 2016년 7월 15일 5:26 오후

예 : 뉴스그룹에서 모델 5의 alpha=0.01을 지정했는데 그 의미는 무엇인가요?

답변: multinomialNB에서 alpha의 의미는 무엇인가요? 관리자 2016년 7월 15일 8:00 오후

smoothing factor 입니다. 문서를 참조하세요
http://scikit-learn.org/stable/modules/naive_bayes.html#multinomial-naive-bayes

pos_tagger.pos의 의미는 무엇인가요? tada*** 2016년 7월 15일 6:55 오후

감성분석에서 데이터 전처리 부분에 tokenize 함수만들때 pos_tagger.pos명령어가 나오는데
무슨 의미인가요?

또 이걸 불러올려면 무엇을 import 해야 하나요? 계속해서 NameError가 뜹니다.

답변: pos_tagger.pos의 의미는 무엇인가요? 관리자 2016년 7월 15일 8:01 오후

빠진 코드를 추가하였습니다. 지적 감사드립니다.

NMSC가 무엇을 의미하나요? toug*** 2017년 2월 28일 12:41 오후

text = nltk.Text(tokens, name='NMSC')에서 name='NMSC'가 무엇을 의미하는지 궁금합니다.

답변: NMSC가 무엇을 의미하나요? 관리자 2017년 2월 28일 3:36 오후

Text 객체에 붙인 이름입니다.

다항 분포 나이브 베이즈 모형에서 [2, 3, 5, 3] 은 어떻게 나온 것인가요? hwan*** 2017년 4월 8일 9:35 오전

fc = clf_mult.feature_count_
fc
array([[ 2., 4., 3., 1.],
[ 2., 3., 5., 3.]])

[[0 1 1 0] = 2
[1 1 1 1] = 4
[1 1 1 0] = 3
[0 1 0 0] = 1
[0 0 0 1]
[0 1 1 0]
[0 1 1 1]
[1 0 1 0]
[1 0 1 1]
[0 1 1 0]]

에서 첫번째는 [2, 4, 3, 1] 이라고 추측되는데 두번째 [2, 3, 5, 3] 은 어떻게 나온 것인가요?
24 / 4 = 6 하여 6개씩 계산하면 [2, 4, 3, 4] 가 나오는데.. 제가 잘못 이해하고 있는건지요

답변: 다항 분포 나이브 베이즈 모형에서 [2, 3, 5, 3] 은 어떻게 나온 것인가요? hwan*** 2017년 4월 8일 11:49 오전

아 스스로 해결했습니다 ^^