pythonではじめる機械学習の勉強 2.3.3.6 In[46],In[47],In[48]についてと2.3.4
2.3.6では多クラス分類をする。ここで使うデータはガウス分布に従う2次元データである。
In[46]
これはfrom sklearn.datasets import make_blobsでmake_blobsデータを使う。X,y=make_blobs(random_state=42)とする。
Xは
[[-7.72642091 -8.39495682]
[ 5.45339605 0.74230537]
[-2.97867201 9.55684617]
[ 6.04267315 0.57131862]
[-6.52183983 -6.31932507]
...
...
...
[-3.18611962 9.62596242]
[-1.4781981 9.94556625]
[ 4.47859312 2.37722054]
[-5.79657595 -5.82630754]
[-3.34841515 8.70507375]]
となり、2列のデータである。yは
[2 1 0 1 2 1 0 1 1 0 0 2 2 0 0 2 2 0 2 2 0 2 2 0 0 0 1 2 2 2 2 1 1 2 0 0 0
0 1 1 2 0 1 0 0 1 2 2 2 1 1 1 0 2 2 2 0 0 1 0 2 1 2 1 2 2 1 2 1 1 1 2 2 0
1 2 1 2 1 1 0 1 0 2 0 0 0 1 0 1 1 1 0 1 0 0 0 1 2 0]
となり、0,1,2のデータである。またmglearn.discrete_scatter(X[:,0],X[:,1],y)で書かれる図2-19は横軸が特徴量0(Xの0列目)、縦軸が特徴量1(Xの1列目)、yが0,1,2の3クラスをプロットしている。
LinearSVCで実際に分類してみる。
In[47]
linear_svm=LinearSVC().fit(X,y)で学習している。
重みの形状はlinear_svm.coef_.shapeは(3,2)となる。3は3つクラス(0,1,2)があるのでその
クラスの重み(係数)。2は特徴量(Feature 0とFeature 1)に対する重みとなる。
またlinear_svm.intercept_.shapeは切片の形状を表し(3,)となる。これは3つクラス(0,1,2)
があるのでそのクラスの切片。
重み自体を見てみるとprint(linear_svm.coef_)の結果は
[[-0.17492075 0.23140415]
[ 0.47621495 -0.06936544]
[-0.18914202 -0.20400486]]
切片はprint(linear_svm.intercept_)と出力すると
[-1.07745593 0.1314066 -0.08604993]
となる。
In[48]
line=np.linspace(-15,15)は-15から15の連続する値を出力。
plt.plot(line,-(line*coef[0]+intercept)/coef[1],c=color)はlineを横軸と-(line*coef[0]+intercept)/coef[1]の値を縦軸にプロットする。
ここで
y=w[0]*x[0]+w[1]*x[1]+b=0
より
w[1]*x[1]=-(w[0]*x[0]+b)
よって
x[1]=-(w[0]*x[0]+b)/w[1]
となる。w[0]がcoef[0]、x[0]がline、w[1]がcoef[1]、bが切片でinterceptと対応する。
2.3.4 ナイーブベイズ
ナイーブベイズクラス分類器は線形モデルよりも高速だが予測の性能が落ちる。scikit-learnではGaussianNB,BernoulliNB,MultinomialNBがあり、GaussianNBは任意の連続するデータに使える。BernoulliNBは2値(0,1など)のデータに使える。MultinomialNBはカウントデータに使える。カウントデータとは例えば文の中に出現する単語の数など何かしらカウントしている特徴量をいう。MultinomialNBはBernoulliNBよりも若干性能が良い。
ナイーブベイズは高次元の疎(スパース)なデータに対してもうまく機能する。疎なデータとは0が多くあるデータのこと。
In[53]
y=np.array([0,1,0,1])
for label in np.unique(y): のnp.unique(y)は[0 1]となる。