はじめに †
ここでは,Rを使ってNaïve Bayes(ナイーブ・ベイズ)による学習を行います.
準備 †
Rのインストールについては,次のページを見てください.
Naïve Bayesは,e1071パッケージに含まれています. そこで,e1071パッケージをインストールします. install.packagesコマンドを実行すると,パッケージをダウンロードするサーバーを聞かれますので,リストからJapanのどれかを選択します.
> install.packages("e1071") > library("e1071")
ここでは,標準で使用できるirisデータセットを使います.
> data(iris)
このデータセットは,アヤメの種類(Species)をがく片の長さ(Sepal.Length),幅(Lepal.Width),花びらの長さ(Petal.Length),幅(Petal.Width)によって分類する問題です. 長さと幅は連続値,種類はsetosa, versicolor, virginicaのいずれかをとる離散値です.
このデータセットには,setosa, versicolor, virginicaという3種類のアヤメについて,それぞれ50個ずつ,合計150個のデータが含まれています. ランダムに10個のデータを選択して,見てみましょう.
> iris[sort(sample(1:150,10)),] Sepal.Length Sepal.Width Petal.Length Petal.Width Species 4 4.6 3.1 1.5 0.2 setosa 22 5.1 3.7 1.5 0.4 setosa 65 5.6 2.9 3.6 1.3 versicolor 97 5.7 2.9 4.2 1.3 versicolor 100 5.7 2.8 4.1 1.3 versicolor 108 7.3 2.9 6.3 1.8 virginica 116 6.4 3.2 5.3 2.3 virginica 122 5.6 2.8 4.9 2.0 virginica 136 7.7 3.0 6.1 2.3 virginica 146 6.7 3.0 5.2 2.3 virginica
最初は,離散値属性のNaïve Bayesについて説明しますので,このデータを二値化したものを用意します.
まずは,データフレームごとコピーします.
> iris.bi <- data.frame(iris)
各属性の平均を求め,平均より大きければ1,そうでなければ0とします. ベクトルの平均を求めるにはmean関数,ベクトルの二値化にはcut関数,データフレームの値を入れ替えるにはtransform関数を使います.
> mu <- mean(iris.bi$Sepal.Length) > bi <- cut(iris.bi$Sepal.Length, breaks=c(-Inf, mu, Inf), labels=c(0, 1)) > iris.bi <- transform(iris.bi, Sepal.Length = bi)
これを他の属性にも行います.
> mu <- mean(iris.bi$Sepal.Width) > bi <- cut(iris.bi$Sepal.Width, breaks=c(-Inf, mu, Inf), labels=c(0, 1)) > iris.bi <- transform(iris.bi, Sepal.Width = bi)
> mu <- mean(iris.bi$Petal.Length) > bi <- cut(iris.bi$Petal.Length, breaks=c(-Inf, mu, Inf), labels=c(0, 1)) > iris.bi <- transform(iris.bi, Petal.Length = bi)
> mu <- mean(iris.bi$Petal.Width) > bi <- cut(iris.bi$Petal.Width, breaks=c(-Inf, mu, Inf), labels=c(0, 1)) > iris.bi <- transform(iris.bi, Petal.Width = bi)
ランダムに10個サンプリングして,二値化されたデータを確認しましょう.
> iris.bi[sort(sample(1:150,10)),] Sepal.Length Sepal.Width Petal.Length Petal.Width Species 23 0 1 0 0 setosa 49 0 1 0 0 setosa 59 1 0 1 1 versicolor 72 1 0 1 1 versicolor 75 1 0 1 1 versicolor 84 1 0 1 1 versicolor 108 1 0 1 1 virginica 116 1 1 1 1 virginica 123 1 0 1 1 virginica 125 1 1 1 1 virginica
これをランダム・サンプリングして80%を訓練データとし,のこりの20%をテスト・データとします.
> idx <- sample(nrow(iris.bi), as.integer(nrow(iris.bi)*0.8)) > iris.bi.train <- iris.bi[idx,] > iris.bi.test <- iris.bi[-idx,]
Naïve Bayes †
Naïve Bayesはスパム・メール・フィルターなどで用いられている機械学習の手法です.
Naïve Bayesでは,それぞれの特徴が独立に出現することを仮定して,Bayesの定理に基づいて分類規則を生成します.
Naïve Bayesを式で書くと,次のようになります. \[ \hat{c}_i = \mathrm{argmax}_{c_k} P(c_k)\Pi_{j=1}^{m}P(v_{i,j}|c_k) \]
ここで,[math]\hat{c}_i[/math] は [math]i[/math] 番目の事例のクラスの予測値,[math]v_{i,j}[/math] は [math]i[/math] 番目の事例の [math]j[/math] 番目の属性の値,[math]P(v_{i,j}|c_k)[/math] はクラス [math]c_k[/math] の中で [math]j[/math] 番目の属性の値が [math]v_{i,j}[/math] となる確率(条件付き確率),[math]P(c_k)[/math] は全事例の中でクラスが [math]c_k[/math] となる確率(クラスの事前確率)を表します.
Naïve Bayesは,ベイズの定理 \[ P(Y|X_1,X_2,...,X_m) = \frac{P(X_1,X_2,...,X_m|Y)P(Y)}{P(X_1,X_2,...,X_m)} \] を用いて,各属性の値が [math]x_1,x_2,...,x_m[/math] のときに [math]P(y|x_1,x_2,...,x_m)[/math] の値が最大となるような [math]Y[/math] の値を予測クラスとして出力します.
このとき,[math]X_1,X_2,...,X_m[/math] が独立であると仮定すると,分子の [math]P(X_1,X_2,...,X_m|Y)[/math] はそれぞれの条件付き確率の積で表すことができます. \[ P(X_1,X_2,...,X_m|Y) = P(X_1|Y) P(X_2|Y) \dots P(X_m|Y) = \Pi_{j=1}^m P(X_j|Y) \]
これによって,Bayesの定理の式は \[ P(Y|X_1,X_2,...,X_m) = \frac{P(Y)\Pi_{j=1}^m P(X_j|Y)}{P(X_1,X_2,...,X_m)} \] と変形できるので,この右辺を最大化する [math]Y[/math] の値を調べます.
ここで,この右辺の分母 [math]P(X_1,X_2,...,X_m)[/math] はどのクラス [math]Y[/math] に対しても同じ値なので,この右辺を最大化する [math]Y[/math] を調べるには,この右辺の分子を最大化する [math]Y[/math] を調べればいいことになります.
このようにして,Naïve Bayesの式 \[ \hat{Y} = \mathrm{argmax}_Y P(Y)\Pi_{j=1}^m P(X_j|Y) \] が導かれます.
Naïve Bayesで学習する †
Naïve Bayesを使うには,e1071パッケージのnaiveBayes関数を用います.
> NB.model <- naiveBayes(Species~., iris.bi.train)
naiveBayes関数の第1引数には,モデルの式を「被説明変数 ~ 説明変数1+説明変数2+,...,説明変数k」という形で与えます. 説明変数を列挙する替わりに,被説明変数以外の全ての変数という意味の .(ドット)を使うこともできます. 第2引数には訓練データを与えます.
学習したモデルの中身を見てみると次のようになっています.
> NB.model Naive Bayes Classifier for Discrete Predictors Call: naiveBayes.default(x = X, y = Y, laplace = laplace) A-priori probabilities: Y setosa versicolor virginica 0.3416667 0.3500000 0.3083333 Conditional probabilities: Sepal.Length Y 0 1 setosa 1.0000000 0.0000000 versicolor 0.4285714 0.5714286 virginica 0.1081081 0.8918919 Sepal.Width Y 0 1 setosa 0.1707317 0.8292683 versicolor 0.8095238 0.1904762 virginica 0.6216216 0.3783784 Petal.Length Y 0 1 setosa 1.0000000 0.0000000 versicolor 0.1190476 0.8809524 virginica 0.0000000 1.0000000 Petal.Width Y 0 1 setosa 1.0000000 0.0000000 versicolor 0.1904762 0.8095238 virginica 0.0000000 1.0000000
クラスの事前確率(A-priori prob.),各属性値の条件付き確率(Conditional prob.)が計算されていることがわかります.
テスト・データのクラスを予測する †
学習したモデルを用いてクラスを予測するには,predict関数を使います.
> NB.predict <- predict(NB.model, iris.bi.test)
中身を見ると,予測値が出力されていることがわかります.
> NB.predict [1] setosa setosa setosa setosa setosa [6] setosa setosa setosa setosa versicolor [11] virginica virginica setosa versicolor setosa [16] versicolor versicolor virginica virginica virginica [21] virginica versicolor virginica virginica virginica [26] virginica virginica versicolor virginica virginica Levels: setosa versicolor virginica
この予測クラスを真のクラスと照らし合わせてみます.
> result <- table(NB.predict, iris.bi.test$Species) > result NB.predict setosa versicolor virginica setosa 9 2 0 versicolor 0 4 2 virginica 0 2 11
ここから,setosaと予測した11個のうち真のクラスがsetosaだったのは9個で,2個のversicolorをsetosaと予測してしまっていることがわかります.
対角要素の和が正解数なので,ここから正解率を求めます.
> sum(diag(result))/nrow(iris.bi.test) [1] 0.8
正解率は80%でした.
Gaussian Naïve Bayes †
ここまではNaïve Bayesを理解しやすいように属性の値は離散値としてきました.
しかし,属性の値が正規分布に従って発生していると仮定することで,Naïve Bayesを連続値の属性に拡張することができます. これをGaussian Naïve Bayesといいます.
離散化したirisデータと同じ番号を用いて,連続値のirisデータの事例を訓練データとテスト・データに分けます.
> iris.train <- iris[idx,] > iris.test <- iris[-idx,]
NaiveBayes関数を用いて学習します.
> NB.model <- naiveBayes(Species~., iris.train)
学習したモデルを見てみます.
> NB.model Naive Bayes Classifier for Discrete Predictors Call: naiveBayes.default(x = X, y = Y, laplace = laplace) A-priori probabilities: Y setosa versicolor virginica 0.3416667 0.3500000 0.3083333 Conditional probabilities: Sepal.Length Y [,1] [,2] setosa 5.009756 0.3541221 versicolor 5.966667 0.5135561 virginica 6.664865 0.6684211 Sepal.Width Y [,1] [,2] setosa 3.439024 0.4110219 versicolor 2.797619 0.3024196 virginica 3.021622 0.3250087 Petal.Length Y [,1] [,2] setosa 1.475610 0.1699713 versicolor 4.285714 0.4791107 virginica 5.621622 0.5826830 Petal.Width Y [,1] [,2] setosa 0.2487805 0.1120758 versicolor 1.3380952 0.1987183 virginica 2.0594595 0.2722942
条件付き確率(Conditional prob.)のところには,正規分布のパラメーターである平均と不偏標準偏差が出ています.
テスト・データのラベルを予測し,正解と照らし合わせてから予測精度を求めます.
> NB.predict <- predict(NB.model, iris.test) > result <- table(NB.predict, iris.test$Species) > result NB.predict setosa versicolor virginica setosa 9 0 0 versicolor 0 8 1 virginica 0 0 12 > sum(diag(result))/nrow(iris.test) [1] 0.9666667
正解率は97%でした.
まとめ †
Naïve Bayesは,Bayes統計に基づく分類手法です.
説明変数の値が独立に発生するという現実的でないことを仮定していますが,それでも高い分類精度を得ることができます.