学生の備忘録なブログ

日々のことを忘れないためのブログです。一日一成果物も目標。

ゼロから作るDeep Learning ~L2正規化~

L2正規化

L2正規化について,あまり詳しく書かれていなかったので

6.4.2 Weight decay

Weight decay 荷重減衰とは 学習の過程において、大きな重みを持つことに対してペ ナルティを課すことで、過学習を抑制すること.


L2正則化,L1正規化とは

機械学習でよく用いられる正則化には、L1正則化とL2正則化がある

ノルムとは

n 次元ベクトル x→=(x1,x2,⋯,xn) および 1≤p<∞ なる p に対して $\sqrt[p]{|x_1|^p+|x_2|^p+\cdots +|x_n|^p}$ を x→ の Lp ノルムと言い,||x||p と書く.

定義

$\lambda$は正則化パラメータ(regularization parameter)

$L2=\lambda ||w||^{2}{2}=\lambda \sum ^{n}{j=1}w^{2}_{j}$ 各成分の自乗の和, 2乗ノルム     

  $L1=\lambda \left| w\right| ^{1}{1}=\lambda \sum ^{n}{j=1}\left| w_{j}\right|$ 各成分の絶対値の和

以上をペナルティ項として加える.


改めてL2正則化,L1正規化正規化とは

正規化したい対象E(w)にペナルティ項λE_1(w)を加えて, E(w)+λE_1(w)を最小化するように最適化問題を解く問題に置き換えることで,過学習を避けること.


グラフで見る

L2ノルム L2 =$\sqrt[2]{|x_1|^2+|x_2|^2+\cdots +|x_n|^2}$ normf:id:forhighlow:20180611231329j:plain


f:id:forhighlow:20180611231326p:plain 六本木で働くデータサイエンティストのブログより

ペナルティ項を付けておくことでw1,w2の定まり方が変わるというお話です。左側のL1ノルム正則化であれば尖った形の領域に接するようにしなければならないため自ずとw2の軸上に最適点が定まってw1=0となり、右側のL2ノルム正則化であれば円状の領域に接するようにしなければならないためw1,w2ともにnon-zeroな値が入る、という感じになるわけです。


グラフから分かること

重みwは正規化により円状の領域にのみ制限される. よってwを項に含む関数E(D)はある程度制限される. wの値に制約を付け加えることで,意図しない域までパラメータが行くことを防ぐことができる.


制度の比較

図より,学習済みデータとテストデータとの差が狭まっている.つまり過学習が抑制されている.

正規化のないグラフ

正規化したグラフf:id:forhighlow:20180611231443p:plain


正規化したグラフ

正規化したグラフf:id:forhighlow:20180611231321p:plain


参考

六本木で働くデータサイエンティストのブログ(https://tjo.hatenablog.com/entry/2015/03/03/190000)

過学習を防ぐ正則化 (https://www.techcrowd.jp/machinelearning/regularization/)

ゼロから作るDeepLearning

pdf埋め込み

ゼロから作るDeepLearning 第5章より誤差逆伝播法の実装 ~colaboratoryにて~

実行に際してのお願い

共有フォルダではなく,自分のgoogle drive 上でcolaboratoryで以下のノートブックを実行してください.また,依存関係は,マウントすることで解消してください. できない場合に備えて,できるだけノートブック内で"from モジュール import 関数"のような依存関係が内容にしました.

irisのデータは," from sklearn.datasets import fetch_mldata"でインポートできますから,参考書付随のデータではなくても使えます.

1.ダウンロードして配置

以下のセルを実行する前に https://github.com/oreilly-japan/deep-learning-from-scratch よりスクリプトをダウンロードして,googledriveの一番上位のマイドライブに配置してください.

drive上でファイルをマウントする

下記の実行が終わると、URLと認証コード入力フォームが表示されるのでリンクをクリックしてコピペして認証をします。二回行います. 認証したあと、!lsを実行して、driveディレクトリがあればマウントは成功です。

!apt-get install -y -qq software-properties-common python-software-properties module-init-tools
!add-apt-repository -y ppa:alessandro-strada/ppa 2>&1 > /dev/null
!apt-get update -qq 2>&1 > /dev/null
!apt-get -y install -qq google-drive-ocamlfuse fuse
from google.colab import auth
auth.authenticate_user()
from oauth2client.client import GoogleCredentials
creds = GoogleCredentials.get_application_default()
import getpass
!google-drive-ocamlfuse -headless -id={creds.client_id} -secret={creds.client_secret} < /dev/null 2>&1 | grep URL
vcode = getpass.getpass()
!echo {vcode} | google-drive-ocamlfuse -headless -id={creds.client_id} -secret={creds.client_secret}
gpg: keybox '/tmp/tmphfzufzj2/pubring.gpg' created
gpg: /tmp/tmphfzufzj2/trustdb.gpg: trustdb created
gpg: key AD5F235DF639B041: public key "Launchpad PPA for Alessandro Strada" imported
gpg: Total number processed: 1
gpg:               imported: 1
Warning: apt-key output should not be parsed (stdout is not a terminal)


WARNING:google.auth._default:No project ID could be determined. Consider running `gcloud config set project` or setting the GOOGLE_CLOUD_PROJECT environment variable



---------------------------------------------------------------------------

KeyboardInterrupt                         Traceback (most recent call last)

/usr/local/lib/python3.6/dist-packages/ipykernel/kernelbase.py in _input_request(self, prompt, ident, parent, password)
    729             try:
--> 730                 ident, reply = self.session.recv(self.stdin_socket, 0)
    731             except Exception:


/usr/local/lib/python3.6/dist-packages/jupyter_client/session.py in recv(self, socket, mode, content, copy)
    802         try:
--> 803             msg_list = socket.recv_multipart(mode, copy=copy)
    804         except zmq.ZMQError as e:


/usr/local/lib/python3.6/dist-packages/zmq/sugar/socket.py in recv_multipart(self, flags, copy, track)
    394         """
--> 395         parts = [self.recv(flags, copy=copy, track=track)]
    396         # have first part already, only loop while more to receive


zmq/backend/cython/socket.pyx in zmq.backend.cython.socket.Socket.recv()


zmq/backend/cython/socket.pyx in zmq.backend.cython.socket.Socket.recv()


zmq/backend/cython/socket.pyx in zmq.backend.cython.socket._recv_copy()


/usr/local/lib/python3.6/dist-packages/zmq/backend/cython/checkrc.pxd in zmq.backend.cython.checkrc._check_rc()


KeyboardInterrupt: 


During handling of the above exception, another exception occurred:


KeyboardInterrupt                         Traceback (most recent call last)

<ipython-input-17-75a4d519ca25> in <module>()
      9 import getpass
     10 get_ipython().system('google-drive-ocamlfuse -headless -id={creds.client_id} -secret={creds.client_secret} < /dev/null 2>&1 | grep URL')
---> 11 vcode = getpass.getpass()
     12 get_ipython().system('echo {vcode} | google-drive-ocamlfuse -headless -id={creds.client_id} -secret={creds.client_secret}')


/usr/local/lib/python3.6/dist-packages/ipykernel/kernelbase.py in getpass(self, prompt, stream)
    686             self._parent_ident,
    687             self._parent_header,
--> 688             password=True,
    689         )
    690 


/usr/local/lib/python3.6/dist-packages/ipykernel/kernelbase.py in _input_request(self, prompt, ident, parent, password)
    733             except KeyboardInterrupt:
    734                 # re-raise KeyboardInterrupt, to truncate traceback
--> 735                 raise KeyboardInterrupt
    736             else:
    737                 break


KeyboardInterrupt: 
!mkdir -p drive
!google-drive-ocamlfuse drive
fuse: mountpoint is not empty
fuse: if you are sure this is safe, use the 'nonempty' mount option
!ls
datalab  drive

5.7 誤差逆伝播法の実装

5.7.1 ニューラルネットワークの学習の全体図

前提

ステップ 1(ミニバッチ)

訓練データの中からランダムに一部のデータを選び出す。

ステップ 2(勾配の算出) <- ここで誤差逆伝播法を用いる!

各重みパラメータに関する損失関数の勾配を求める。

ステップ 3(パラメータの更新)

重みパラメータを勾配方向に微小量だけ更新する。

ステップ 4(繰り返す)

ステップ 1、ステップ 2、ステップ 3 を繰り返す。

4章まとめ

機械学習で使用するデータセットは、訓練データとテストデータに分けて 使用する。

● 訓練データで学習を行い、学習したモデルの汎化能力をテストデータで評 価する。

ニューラルネットワークの学習は、損失関数を指標として、損失関数の値 が小さくなるように、重みパラメータを更新する。

● 重みパラメータを更新する際には、重みパラメータの勾配を利用して、勾 配方向に重みの値を更新する作業を繰り返す。

● 微小な値を与えたときの差分によって微分を求めることを数値微分と 言う。

● 数値微分によって、重みパラメータの勾配を求めることができる。

誤差逆伝播法は、高速に勾配を求めることができる。

5.7.2 誤差逆伝播法に対応したニューラルネットワークの 実装

レイヤーを用いる構成にする理由

レイヤを使用することによって、認識結果を得る処理(predict())や勾配を求める処理(gradient())がレイヤの伝播だけで達成できます。

# coding: utf-8
import sys, os
# sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
import numpy as np
# from layers import *
# from gradient import numerical_gradient
from collections import OrderedDict
# OrderDict()は連想配列のキーが追加された順序を覚える.イテレータから同じ順序でキーを返す.(本来は辞書の要素はバラバラに覚えられる)
# よって,forward()メソッドを呼び出すだけで,前のレイヤを指定して処理するということができる.

# function.py
def identity_function(x):
    return x


def step_function(x):
    return np.array(x > 0, dtype=np.int)


def sigmoid(x):
    return 1 / (1 + np.exp(-x))    


def sigmoid_grad(x):
    return (1.0 - sigmoid(x)) * sigmoid(x)
    

def relu(x):
    return np.maximum(0, x)


def relu_grad(x):
    grad = np.zeros(x)
    grad[x>=0] = 1
    return grad
    

def softmax(x):
    if x.ndim == 2:
        x = x.T
        x = x - np.max(x, axis=0)
        y = np.exp(x) / np.sum(np.exp(x), axis=0)
        return y.T 

    x = x - np.max(x) # オーバーフロー対策
    return np.exp(x) / np.sum(np.exp(x))


def mean_squared_error(y, t):
    return 0.5 * np.sum((y-t)**2)


def cross_entropy_error(y, t):
    if y.ndim == 1:
        t = t.reshape(1, t.size)
        y = y.reshape(1, y.size)
        
    # 教師データがone-hot-vectorの場合、正解ラベルのインデックスに変換
    if t.size == y.size:
        t = t.argmax(axis=1)
             
    batch_size = y.shape[0]
    return -np.sum(np.log(y[np.arange(batch_size), t])) / batch_size


def softmax_loss(X, t):
    y = softmax(X)
    return cross_entropy_error(y, t)
Dclass Relu:
    def __init__(self):
        self.mask = None

    def forward(self, x):
        self.mask = (x <= 0)
        out = x.copy()
        out[self.mask] = 0

        return out

    def backward(self, dout):
        dout[self.mask] = 0
        dx = dout

        return dx


class Sigmoid:
    def __init__(self):
        self.out = None

    def forward(self, x):
        out = sigmoid(x)
        self.out = out
        return out

    def backward(self, dout):
        dx = dout * (1.0 - self.out) * self.out

        return dx


class Affine:
    def __init__(self, W, b):
        self.W =W
        self.b = b
        
        self.x = None
        self.original_x_shape = None
        # 重み・バイアスパラメータの微分
        self.dW = None
        self.db = None

    def forward(self, x):
        # テンソル対応
        self.original_x_shape = x.shape
        x = x.reshape(x.shape[0], -1)
        self.x = x

        out = np.dot(self.x, self.W) + self.b

        return out

    def backward(self, dout):
        dx = np.dot(dout, self.W.T)
        self.dW = np.dot(self.x.T, dout)
        self.db = np.sum(dout, axis=0)
        
        dx = dx.reshape(*self.original_x_shape)  # 入力データの形状に戻す(テンソル対応)
        return dx


class SoftmaxWithLoss:
    def __init__(self):
        self.loss = None
        self.y = None # softmaxの出力
        self.t = None # 教師データ

    def forward(self, x, t):
        self.t = t
        self.y = softmax(x)
        self.loss = cross_entropy_error(self.y, self.t)
        
        return self.loss

    def backward(self, dout=1):
        batch_size = self.t.shape[0]
        if self.t.size == self.y.size: # 教師データがone-hot-vectorの場合
            dx = (self.y - self.t) / batch_size
        else:
            dx = self.y.copy()
            dx[np.arange(batch_size), self.t] -= 1
            dx = dx / batch_size
        
        return dx


class Dropout:
    """
    http://arxiv.org/abs/1207.0580
    """
    def __init__(self, dropout_ratio=0.5):
        self.dropout_ratio = dropout_ratio
        self.mask = None

    def forward(self, x, train_flg=True):
        if train_flg:
            self.mask = np.random.rand(*x.shape) > self.dropout_ratio
            return x * self.mask
        else:
            return x * (1.0 - self.dropout_ratio)

    def backward(self, dout):
        return dout * self.mask


class BatchNormalization:
    """
    http://arxiv.org/abs/1502.03167
    """
    def __init__(self, gamma, beta, momentum=0.9, running_mean=None, running_var=None):
        self.gamma = gamma
        self.beta = beta
        self.momentum = momentum
        self.input_shape = None # Conv層の場合は4次元、全結合層の場合は2次元  

        # テスト時に使用する平均と分散
        self.running_mean = running_mean
        self.running_var = running_var  
        
        # backward時に使用する中間データ
        self.batch_size = None
        self.xc = None
        self.std = None
        self.dgamma = None
        self.dbeta = None

    def forward(self, x, train_flg=True):
        self.input_shape = x.shape
        if x.ndim != 2:
            N, C, H, W = x.shape
            x = x.reshape(N, -1)

        out = self.__forward(x, train_flg)
        
        return out.reshape(*self.input_shape)
            
    def __forward(self, x, train_flg):
        if self.running_mean is None:
            N, D = x.shape
            self.running_mean = np.zeros(D)
            self.running_var = np.zeros(D)
                        
        if train_flg:
            mu = x.mean(axis=0)
            xc = x - mu
            var = np.mean(xc**2, axis=0)
            std = np.sqrt(var + 10e-7)
            xn = xc / std
            
            self.batch_size = x.shape[0]
            self.xc = xc
            self.xn = xn
            self.std = std
            self.running_mean = self.momentum * self.running_mean + (1-self.momentum) * mu
            self.running_var = self.momentum * self.running_var + (1-self.momentum) * var            
        else:
            xc = x - self.running_mean
            xn = xc / ((np.sqrt(self.running_var + 10e-7)))
            
        out = self.gamma * xn + self.beta 
        return out

    def backward(self, dout):
        if dout.ndim != 2:
            N, C, H, W = dout.shape
            dout = dout.reshape(N, -1)

        dx = self.__backward(dout)

        dx = dx.reshape(*self.input_shape)
        return dx

    def __backward(self, dout):
        dbeta = dout.sum(axis=0)
        dgamma = np.sum(self.xn * dout, axis=0)
        dxn = self.gamma * dout
        dxc = dxn / self.std
        dstd = -np.sum((dxn * self.xc) / (self.std * self.std), axis=0)
        dvar = 0.5 * dstd / self.std
        dxc += (2.0 / self.batch_size) * self.xc * dvar
        dmu = np.sum(dxc, axis=0)
        dx = dxc - dmu / self.batch_size
        
        self.dgamma = dgamma
        self.dbeta = dbeta
        
        return dx


class Convolution:
    def __init__(self, W, b, stride=1, pad=0):
        self.W = W
        self.b = b
        self.stride = stride
        self.pad = pad
        
        # 中間データ(backward時に使用)
        self.x = None   
        self.col = None
        self.col_W = None
        
        # 重み・バイアスパラメータの勾配
        self.dW = None
        self.db = None

    def forward(self, x):
        FN, C, FH, FW = self.W.shape
        N, C, H, W = x.shape
        out_h = 1 + int((H + 2*self.pad - FH) / self.stride)
        out_w = 1 + int((W + 2*self.pad - FW) / self.stride)

        col = im2col(x, FH, FW, self.stride, self.pad)
        col_W = self.W.reshape(FN, -1).T

        out = np.dot(col, col_W) + self.b
        out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)

        self.x = x
        self.col = col
        self.col_W = col_W

        return out

    def backward(self, dout):
        FN, C, FH, FW = self.W.shape
        dout = dout.transpose(0,2,3,1).reshape(-1, FN)

        self.db = np.sum(dout, axis=0)
        self.dW = np.dot(self.col.T, dout)
        self.dW = self.dW.transpose(1, 0).reshape(FN, C, FH, FW)

        dcol = np.dot(dout, self.col_W.T)
        dx = col2im(dcol, self.x.shape, FH, FW, self.stride, self.pad)

        return dx


class Pooling:
    def __init__(self, pool_h, pool_w, stride=1, pad=0):
        self.pool_h = pool_h
        self.pool_w = pool_w
        self.stride = stride
        self.pad = pad
        
        self.x = None
        self.arg_max = None

    def forward(self, x):
        N, C, H, W = x.shape
        out_h = int(1 + (H - self.pool_h) / self.stride)
        out_w = int(1 + (W - self.pool_w) / self.stride)

        col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)
        col = col.reshape(-1, self.pool_h*self.pool_w)

        arg_max = np.argmax(col, axis=1)
        out = np.max(col, axis=1)
        out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)

        self.x = x
        self.arg_max = arg_max

        return out

    def backward(self, dout):
        dout = dout.transpose(0, 2, 3, 1)
        
        pool_size = self.pool_h * self.pool_w
        dmax = np.zeros((dout.size, pool_size))
        dmax[np.arange(self.arg_max.size), self.arg_max.flatten()] = dout.flatten()
        dmax = dmax.reshape(dout.shape + (pool_size,)) 
        
        dcol = dmax.reshape(dmax.shape[0] * dmax.shape[1] * dmax.shape[2], -1)
        dx = col2im(dcol, self.x.shape, self.pool_h, self.pool_w, self.stride, self.pad)
        
        return dx
  File "<ipython-input-23-2e4ec37cca83>", line 1
    Dclass Relu:
              ^
SyntaxError: invalid syntax
def im2col(input_data, filter_h, filter_w, stride=1, pad=0):
    """

    Parameters
    ----------
    input_data : (データ数, チャンネル, 高さ, 幅)の4次元配列からなる入力データ
    filter_h : フィルターの高さ
    filter_w : フィルターの幅
    stride : ストライド
    pad : パディング

    Returns
    -------
    col : 2次元配列
    """
    N, C, H, W = input_data.shape
    out_h = (H + 2*pad - filter_h)//stride + 1
    out_w = (W + 2*pad - filter_w)//stride + 1

    img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')
    col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))

    for y in range(filter_h):
        y_max = y + stride*out_h
        for x in range(filter_w):
            x_max = x + stride*out_w
            col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]

    col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)
    return col


def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):
    """

    Parameters
    ----------
    col :
    input_shape : 入力データの形状(例:(10, 1, 28, 28))
    filter_h :
    filter_w
    stride
    pad

    Returns
    -------

    """
    N, C, H, W = input_shape
    out_h = (H + 2*pad - filter_h)//stride + 1
    out_w = (W + 2*pad - filter_w)//stride + 1
    col = col.reshape(N, out_h, out_w, C, filter_h, filter_w).transpose(0, 3, 4, 5, 1, 2)

    img = np.zeros((N, C, H + 2*pad + stride - 1, W + 2*pad + stride - 1))
    for y in range(filter_h):
        y_max = y + stride*out_h
        for x in range(filter_w):
            x_max = x + stride*out_w
            img[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]

    return img[:, :, pad:H + pad, pad:W + pad]
class TwoLayerNet:

    def __init__(self, input_size, hidden_size, output_size, weight_init_std = 0.01):
        # 引数は頭から順に、入力層のニューロンの数、隠れ 層のニューロンの数、出力層のニューロンの数、重 み初期化時のガウス分布のスケール。
        # 重みの初期化
        ## インスタンス変数とその説明
        '''
        params
        ニューラルネットワークのパラメータを保持するディクショナリ変数。
        params['W1'] は 1 層目の重み、params['b1'] は 1 層目のバイアス。
        params['W2'] は 2 層目の重み、params['b2'] は 2 層目のバイアス。
        '''
        self.params = {}
        self.params['W1'] = weight_init_std * np.random.randn(input_size, hidden_size)
        self.params['b1'] = np.zeros(hidden_size)
        self.params['W2'] = weight_init_std * np.random.randn(hidden_size, output_size) 
        self.params['b2'] = np.zeros(output_size)

        # レイヤの生成
        '''
        layers
        ニューラルネットワークのレイヤを保持する順番付きディクショナリ変数。
        layers['Affine1']、layers['Relu1']、layers['Affine2'] と
        いったように順番付きディクショナリで各レイヤを保持する。
        '''
        self.layers = OrderedDict()
        self.layers['Affine1'] = Affine(self.params['W1'], self.params['b1'])
        self.layers['Relu1'] = Relu()
        self.layers['Affine2'] = Affine(self.params['W2'], self.params['b2'])
        
        self.lastLayer = SoftmaxWithLoss()
        
    def predict(self, x):
        # 引数の x は画像データ
        # 認識(推論)
        for layer in self.layers.values():
            x = layer.forward(x)
        
        return x
        
    # x:入力データ, t:教師データ
    def loss(self, x, t):
        # 損失関数の値を求める
        y = self.predict(x)
        return self.lastLayer.forward(y, t)
    
    def accuracy(self, x, t):
        # 認識精度を求める
        y = self.predict(x)
        y = np.argmax(y, axis=1)
        if t.ndim != 1 : t = np.argmax(t, axis=1)
        
        accuracy = np.sum(y == t) / float(x.shape[0])
        return accuracy
        
    # x:入力データ, t:教師データ
    def numerical_gradient(self, x, t):
        # 重みパラメータに対する勾配を数値微分によって求める
        loss_W = lambda W: self.loss(x, t)
        
        grads = {}
        grads['W1'] = numerical_gradient(loss_W, self.params['W1'])
        grads['b1'] = numerical_gradient(loss_W, self.params['b1'])
        grads['W2'] = numerical_gradient(loss_W, self.params['W2'])
        grads['b2'] = numerical_gradient(loss_W, self.params['b2'])
        
        return grads
        
    def gradient(self, x, t):
        # 重みパラメータに対する勾配を誤差逆伝播法によって求める
        # forward
        self.loss(x, t)

        # backward
        dout = 1
        dout = self.lastLayer.backward(dout)
        
        layers = list(self.layers.values())
        layers.reverse()
        for layer in layers:
            dout = layer.backward(dout)

        # 設定
        grads = {}
        grads['W1'] = self.layers['Affine1'].dW
        grads['b1'] = self.layers['Affine1'].db
        grads['W2'] = self.layers['Affine2'].dW
        grads['b2'] = self.layers['Affine2'].db

        return grads

5.7.3 誤差逆伝播法の勾配確認

誤差逆伝播法で求めた勾配の結果が一致すること――正確には、ほとんど 近い値にあること――を確認する作業を勾配確認(gradient check)と言います。

誤差逆伝播法は連鎖律を用いた解析解であり,数値的に近似された解との誤差が許容できる範囲であるかは確認する必要がある.

今回の誤差を計算する際に用いられる式

各重みパラメータの差分の絶対値の平均

$$\dfrac {1}{n}\sum {n}\left| \alpha {n}-\beta _{n}\right| $$

# ch05/gradient_check.py
# coding: utf-8
import sys, os
sys.path.append('/content/drive/deep-learning-from-scratch')
from dataset.mnist import load_mnist
from ch05.two_layer_net import TwoLayerNet
# from sklearn.datasets import fetch_mldata
# from sklearn.model_selection import train_test_split


# データの読み込み
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)

network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)

x_batch = x_train[:3]
t_batch = t_train[:3]

grad_numerical = network.numerical_gradient(x_batch, t_batch) # numerical_gradientとは数値計算で算出した勾配のこと
grad_backprop = network.gradient(x_batch, t_batch)

for key in grad_numerical.keys():
    diff = np.average( np.abs(grad_backprop[key] - grad_numerical[key]) )
    print(key + ":" + str(diff))
W1:2.8387769511474197e-13
b1:1.0329371873899624e-12
W2:1.0093874425060328e-12
b2:1.199040866595169e-10

勾配確認の結果

e-13と軒並み数値は低いことから,十分に数値微分の値と誤差逆伝播法の値が近いことがわかる.

dataset

データを* from sklearn.datasets import fetch_mldata * から取ってくるならば,以下の通り.

import sys, os

sys.path.append('/content/drive/deep-learning-from-scratch')
from dataset.mnist import load_mnist

# 最初の呼び出しは数分待ちます...
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True, normalize=False)

# それぞれのデータ形状を出力
print(x_train.shape) # (60000, 784)
print(t_train.shape) # (60000,)
print(x_test.shape) # (10000, 784)
print(t_test.shape) # (10000,)
(60000, 784)
(60000,)
(10000, 784)
(10000,)
from sklearn.datasets import fetch_mldata
from sklearn.model_selection import train_test_split
mnist = fetch_mldata('MNIST original')
x_train, x_test, t_train, t_test = train_test_split(mnist.data, mnist.target,test_size=0.142857142857143, random_state=1)
print(x_train.shape) # (60000, 784)
print(t_train.shape) # (60000,)
print(x_test.shape) # (10000, 784)
print(t_test.shape) # (10000,)
(59999, 784)
(59999,)
(10001, 784)
(10001,)
print(x_train.shape) # (60000, 784)
print(t_train.shape) # (60000,)
print(x_test.shape) # (10000, 784)
print(t_test.shape) # (10000,)
(58333, 784)
(58333,)
(11667, 784)
(11667,)

5.7.4 誤差逆伝播法を使った学習

ch05/train_neuralnet.py より 実際に学習を行います. ニューラル ネットワークが予測した答えと正解ラベルとを比較して、正解した割合を認識精度 (accuracy)とします。 実行した際に何% 正しく分類することができた、ということを表しています。

# coding: utf-8
import sys, os
# sys.path.append(os.pardir)


import numpy as np
from dataset.mnist import load_mnist
from ch05.two_layer_net import TwoLayerNet

# データの読み込み
(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)

network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)

iters_num = 10000
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.1

train_loss_list = []
train_acc_list = []
test_acc_list = []
epoch = []

iter_per_epoch = max(train_size / batch_size, 1)

for i in range(iters_num):
    batch_mask = np.random.choice(train_size, batch_size)
    x_batch = x_train[batch_mask]
    t_batch = t_train[batch_mask]
    
    # 勾配
    #grad = network.numerical_gradient(x_batch, t_batch)
    grad = network.gradient(x_batch, t_batch)
    
    # 更新
    for key in ('W1', 'b1', 'W2', 'b2'):
        network.params[key] -= learning_rate * grad[key]
    
    loss = network.loss(x_batch, t_batch)
    train_loss_list.append(loss)
    
    if i % iter_per_epoch == 0:
        train_acc = network.accuracy(x_train, t_train)
        test_acc = network.accuracy(x_test, t_test)
        train_acc_list.append(train_acc)
        test_acc_list.append(test_acc)
        epoch.append(i)
        print(i,train_acc, test_acc)
0 0.1225 0.1301
600 0.9044166666666666 0.9059
1200 0.9227 0.9269
1800 0.93595 0.9349
2400 0.9439666666666666 0.9405
3000 0.951 0.9482
3600 0.9572166666666667 0.9544
4200 0.9597333333333333 0.9576
4800 0.9618333333333333 0.9571
5400 0.9669833333333333 0.962
6000 0.9687666666666667 0.964
6600 0.97005 0.9639
7200 0.9736833333333333 0.9669
7800 0.9747833333333333 0.9653
8400 0.9769166666666667 0.9656
9000 0.9764 0.9689
9600 0.9795333333333334 0.9701

実行結果のグラフ

import numpy as np
import matplotlib.pyplot as plt
x = epoch
y = test_acc_list
y2 = train_acc_list
fig = plt.figure()
fig.patch.set_facecolor('white')

plt.plot(epoch, test_acc_list, label='test_accuracy')
plt.plot(epoch, train_acc_list, label='train_accuracy')
plt.title("accuracy ")
plt.xlabel("epoch")
plt.ylabel(" accuracy")
plt.grid(True)
plt.legend()
<matplotlib.legend.Legend at 0x7f4fd87ba630>

png f:id:forhighlow:20180605105111p:plain

5.8 まとめ

  • 計算グラフを用いれば、計算過程を視覚的に把握することができる。
  • 計算グラフのノードは局所的な計算によって構成される。局所的な計算が 全体の計算を構成する。
  • 計算グラフの順伝播は、通常の計算を行う。一方、計算グラフの逆伝播に よって、各ノードの微分を求めることができる。
  • ニューラルネットワークの構成要素をレイヤとして実装することで、勾配 の計算を効率的に求めることができる(誤差逆伝播法)。
  • 数値微分誤差逆伝播法の結果を比較することで、誤差逆伝播法の実装に 誤りがないことを確認できる(勾配確認)。

参考文献

  1. ゼロから作る Deep Learning オライリー・ジャパン発行
  2. Python機械学習プログラミング 達人データサイエンティストによる理論と実践 impress top gearシリーズ
  3. google Colaboratoryでファイルを読み込む方法https://qiita.com/uni-3/items/201aaa2708260cc790b8
  4. 「ゼロから作るDeep Learning」の実行環境を、Colaboratoryを用いて作成するhttps://qiita.com/atzu/items/8fb0cfe27dab476518f2

ターミナルのコマンドで消す方法

ターミナルのコマンドで消す方法

Macの起動音を消す方法にコマンド実行による方法があります。Finderからアプリケーションを選択し、ユーティリティを開き、ターミナルを開きます。ターミナルを開いたら「sudo nvram SystemAudioVolume=%80」と入力します。

そしてパスワードを入力し実行すれば完了です。これでMacの起動音が消音になります。もし、Macの起動音を通常通りに戻したい場合は、同じようにターミナルを開いて「sudo nvram-d SystemAudioVolume」を入力します。

sudo nvram SystemAudioVolume=%80

戻すときは

sudo nvram-d SystemAudioVolume

http://minto.tech/mac-kidouon-kesu/

統計学全体の目次

本を買った

研究室仮配属したので,興味をそそられて買った.生協10%offで.

書籍詳細 - なぜあなたの研究は進まないのか? | メディカルレビュー社

重要だと感じたこと

本の中で(全部は読めていないが)重要だと感じたのは,分野全体についての知識だ.

研究分野の全体像を知ること,これを怠れば車輪を二度発明する(すでにあるものを生み出すことに労力を使う)ことになりかねない.

統計学

以下はwikipediaを参照した.

機械学習 - Wikipedia

統計学
標本調査 標本,母集団,無作為抽出,層化抽出法 |
要約統計学 連続データ | 位置 | \multicolumn{1}{c|}{平均(算術,幾何,調和),中央値,最頻値,階級値}
| 分散 | 範囲,標準偏差,変動係数,百分率
| モーメント | 分散,歪度,尖度
カテゴリーデータ | 頻度,分割表 | 頻度,分割表
統計的推測 仮説検定 | 帰無仮説 対立仮説 有意 棄却 ノンパラメトリック手法 スチューデントのt検定 ウェルチのt検定 カイ二乗検定 イェイツのカイ二乗検定 累積カイ二乗検定 F検定 G検定 マン・ホイットニーのU検定 Z検定 フィッシャーの正確確率検定 二項検定 尤度比検定 マンテル検定 コクラン・マンテル・ヘンツェルの統計量 ウィルコクソンの符号順位検定 アンダーソン–ダーリング検定 カイパー検定 ジャック–ベラ検定 シャピロ–ウィルク検定 コルモゴロフ–スミルノフ検定 分散分析 共分散分析
区間推定 | 信頼区間,予測区間
その他 | 最尤推定 最大事後確率 ベイズ推定 尤度関数カーネル密度推定 最小距離推定 メタアナリシス
生存時間分析 生存時間関数 カプラン=マイヤー推定量 ログランク検定故障率 比例ハザードモデル |
相関 相関交絡変数 ピアソンの積率相関係数 順位相関(スピアマンの順位相関係, ケンドールの順位相関係数) |
モデル 一般線形モデル 一般化線形モデル 混合モデル一般化線形混合モデル |
回帰 線形 | 線形回帰 リッジ回帰 Lasso エラスティックネット
非線形 | k近傍法 回帰木 ランダムフォレスト ニューラルネットワーク サポートベクター回帰 射影追跡回帰
分類 線形 | 線形判別分析 ロジスティック回帰単純ベイズ分類器 単純パーセプトロン 線形サポートベクターマシン |
二次 | 二次判別分析
非線形 | 非線形k近傍法 決定木 ランダムフォレスト ニューラルネットワーク サポートベクターマシン ベイジアンネットワーク 隠れマルコフモデル
その他 | 二項分類 多クラス分類 第一種過誤と第二種過誤
教師なし学習 クラスタリング | k平均法 (k-means++法)
その他 | 主成分分析 独立成分分析 自己組織化写像(SOM)

このように思った理由

これを読んで, qiita.com ここへ飛んで Deep Learning Monitor - Find new Arxiv papers, tweets and Reddit posts for you あまりにも分野が多岐にわたっていて応用事例だけ追うことも難しいと感じた. (そりゃキュレーション全部英語だよね,,,ともなりました)

これに肉付けして頭を整理していきたい.

MindMapを書くほうが良いかと思ったけれど,先に手を動かしてみた.

ブログ再開

blogをお休みしていた理由

学校の実験講義が忙しかったため,

やる気を失っていたため,

blogを再開する理由

技術的にいろいろやってはいたけれど,残していないと忘れてしまうため,

やる気を取り戻したため,

DeepLearningにおける勾配

損失関数の出力をfとすると,出力の全てのパラメータ$w_i$に関する偏微分を計算すると,偏微分を並べたベクトルを定義することができる.このベクトル

f = f d w 1 , . . . , · f W i

を勾配と呼ぶ.

f = f d w 1 , . . . , · f W i

f = f W 1 , f W i

TeXが上手に描画できないので,一旦stop

機械学習入門_第2章 途中まで

import sys
print("Python version: {}".format(sys.version))

import pandas as pd
print("pandas version: {}".format(pd.__version__))

import matplotlib
print("matplotlib version: {}".format(matplotlib.__version__))

import numpy as np
print("NumPy version: {}".format(np.__version__))

import scipy as sp
print("SciPy version: {}".format(sp.__version__))

import IPython
print("IPython version: {}".format(IPython.__version__))

import sklearn
print("scikit-learn version: {}".format(sklearn.__version__))

import mglearn
import matplotlib.pyplot as plt

Python version: 3.6.1 |Continuum Analytics, Inc.| (default, May 11 2017, 13:04:09) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)]
pandas version: 0.20.3
matplotlib version: 2.0.2
NumPy version: 1.13.1
SciPy version: 0.19.1
IPython version: 6.1.0
scikit-learn version: 0.19.0
%matplotlib inline
from preamble import *
---------------------------------------------------------------------------

ModuleNotFoundError                       Traceback (most recent call last)

<ipython-input-10-e31a7faecc4a> in <module>()
      1 get_ipython().magic('matplotlib inline')
----> 2 from preamble import *


ModuleNotFoundError: No module named 'preamble'

教師あり学習は,ある入力に対しての特定の出力を予測したい場合で,入力出力のペアのデータが入手可能な際に用いられる.

2.1 クラス分類と回帰

教師あり機械学習問題は,2つに大別することができる. * クラス分類(classification) * 2クラス分類(binary classification) * 多クラス分類(multiclass classification) * 回帰(regression)

クラス分類問題と回帰問題を区別するには,出力に何らかの連続性があるかを考えてみれば良い.出力に連続性があるなら回帰問題である.年収を予測する場合を考えてみる.40,000ドルと40,001ドルは近似できる.しかし,webサイトの言語を認識するタスク(クラス分類問題)では,量の大小は問題ではない.言語には連続性がない.英語とフランス語の中間の言語は存在しない.

汎化,過剰適合,適合不足

非常に複雑なモデルを作ることを許せば,訓練データに対してはいくらでも正確な予測を行うようにできてしまう.

[f:id:forhighlow:20171006222712p:plain]

教師あり機械学習アルゴリズム

これから,最も一般的な機械学習アルゴリズムについて,どのようにデータから学習し,どのように予想を行うん丘を見ていく.モデルの複雑さという概念が個々のモデルで果たす役割について述べ,個々のアルゴリズムがモデルを構築する方法の概念を示す.更に,それぞれのアルゴリズムの長所と短所,適しているデータの種類について述べる.重要なパラメータとオプションについても説明する.多くのアルゴリズムは,クラス分類と回帰のバリエーションがあるので両方とも説明する.

個々のアルゴリズムの説明を詳しく読む必要はないが,モデルを理解することで個々の機械学習アルゴリズムの働き方についてより良く理解することができるだろう.本章はリファレンスガイドとしても利用できる.

サンプルデータセット

合成した2クラス分類データセットの例として,forgeデータセットを見てみる.

第1特徴量をx軸に、第2特徴量はy軸にプロットしている.

# generate dataset
X, y = mglearn.datasets.make_forge()
# plot dataset
mglearn.discrete_scatter(X[:, 0], X[:, 1], y)
plt.legend(["Class 0", "Class 1"], loc=4)
plt.xlabel("First feature")
plt.ylabel("Second feature")
print("X.shape: {}".format(X.shape))
X.shape: (26, 2)

[f:id:forhighlow:20171006222715p:plain]

X.shapeからわかるようにこのデータセットは2つの特徴量を持つ26のデータポイントで構成されている.

回帰あるを紹介する際には,合成したwaveデータセットを用いる.このwaveデータセットは入力として1つの特徴量と,モデルの対象となる連続地のターゲット変数(もしくは(response))を持つ.次のグラフは特徴量をx軸に,回帰のターゲット(出力)をy軸に取る.

X, y = mglearn.datasets.make_wave(n_samples=40)
plt.plot(X, y, 'o')
plt.ylim(-3, 3)
plt.xlabel("Feature")
plt.ylabel("Target")
<matplotlib.text.Text at 0x114641160>

[f:id:forhighlow:20171006222719p:plain]

学習にこれから用いるデータセットの一つに乳がんの腫瘍を測定したデータが有る.

from sklearn.datasets import load_breast_cancer
cancer= load_breast_cancer()
print("cancer.keys(): \n{}".format(cancer.keys()))
cancer.keys(): 
dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names'])
print("shape of cancer data: {}".format(cancer.data.shape))
shape of cancer data: (569, 30)
print("Sample counts per class:\n{}".format(
      {n: v for n, v in zip(cancer.target_names, np.bincount(cancer.target))}))
Sample counts per class:
{'malignant': 212, 'benign': 357}

212が悪性で,357が良性である.

個々の特徴量の意味を示す記述は,feature_names属性に格納されている.

print("Feature names:^n{}".format(cancer.feature_names))##特徴量名
Feature names:^n['mean radius' 'mean texture' 'mean perimeter' 'mean area'
 'mean smoothness' 'mean compactness' 'mean concavity'
 'mean concave points' 'mean symmetry' 'mean fractal dimension'
 'radius error' 'texture error' 'perimeter error' 'area error'
 'smoothness error' 'compactness error' 'concavity error'
 'concave points error' 'symmetry error' 'fractal dimension error'
 'worst radius' 'worst texture' 'worst perimeter' 'worst area'
 'worst smoothness' 'worst compactness' 'worst concavity'
 'worst concave points' 'worst symmetry' 'worst fractal dimension']
## DESCRを見れば,詳しい情報が得られる.
print("Feature names:^n{}".format(cancer.DESCR))
Feature names:^nBreast Cancer Wisconsin (Diagnostic) Database
=============================================

Notes
-----
Data Set Characteristics:
    :Number of Instances: 569

    :Number of Attributes: 30 numeric, predictive attributes and the class

    :Attribute Information:
        - radius (mean of distances from center to points on the perimeter)
        - texture (standard deviation of gray-scale values)
        - perimeter
        - area
        - smoothness (local variation in radius lengths)
        - compactness (perimeter^2 / area - 1.0)
        - concavity (severity of concave portions of the contour)
        - concave points (number of concave portions of the contour)
        - symmetry 
        - fractal dimension ("coastline approximation" - 1)

        The mean, standard error, and "worst" or largest (mean of the three
        largest values) of these features were computed for each image,
        resulting in 30 features.  For instance, field 3 is Mean Radius, field
        13 is Radius SE, field 23 is Worst Radius.

        - class:
                - WDBC-Malignant
                - WDBC-Benign

    :Summary Statistics:

    ===================================== ====== ======
                                           Min    Max
    ===================================== ====== ======
    radius (mean):                        6.981  28.11
    texture (mean):                       9.71   39.28
    perimeter (mean):                     43.79  188.5
    area (mean):                          143.5  2501.0
    smoothness (mean):                    0.053  0.163
    compactness (mean):                   0.019  0.345
    concavity (mean):                     0.0    0.427
    concave points (mean):                0.0    0.201
    symmetry (mean):                      0.106  0.304
    fractal dimension (mean):             0.05   0.097
    radius (standard error):              0.112  2.873
    texture (standard error):             0.36   4.885
    perimeter (standard error):           0.757  21.98
    area (standard error):                6.802  542.2
    smoothness (standard error):          0.002  0.031
    compactness (standard error):         0.002  0.135
    concavity (standard error):           0.0    0.396
    concave points (standard error):      0.0    0.053
    symmetry (standard error):            0.008  0.079
    fractal dimension (standard error):   0.001  0.03
    radius (worst):                       7.93   36.04
    texture (worst):                      12.02  49.54
    perimeter (worst):                    50.41  251.2
    area (worst):                         185.2  4254.0
    smoothness (worst):                   0.071  0.223
    compactness (worst):                  0.027  1.058
    concavity (worst):                    0.0    1.252
    concave points (worst):               0.0    0.291
    symmetry (worst):                     0.156  0.664
    fractal dimension (worst):            0.055  0.208
    ===================================== ====== ======

    :Missing Attribute Values: None

    :Class Distribution: 212 - Malignant, 357 - Benign

    :Creator:  Dr. William H. Wolberg, W. Nick Street, Olvi L. Mangasarian

    :Donor: Nick Street

    :Date: November, 1995

This is a copy of UCI ML Breast Cancer Wisconsin (Diagnostic) datasets.
https://goo.gl/U2Uwz2

Features are computed from a digitized image of a fine needle
aspirate (FNA) of a breast mass.  They describe
characteristics of the cell nuclei present in the image.

Separating plane described above was obtained using
Multisurface Method-Tree (MSM-T) [K. P. Bennett, "Decision Tree
Construction Via Linear Programming." Proceedings of the 4th
Midwest Artificial Intelligence and Cognitive Science Society,
pp. 97-101, 1992], a classification method which uses linear
programming to construct a decision tree.  Relevant features
were selected using an exhaustive search in the space of 1-4
features and 1-3 separating planes.

The actual linear program used to obtain the separating plane
in the 3-dimensional space is that described in:
[K. P. Bennett and O. L. Mangasarian: "Robust Linear
Programming Discrimination of Two Linearly Inseparable Sets",
Optimization Methods and Software 1, 1992, 23-34].

This database is also available through the UW CS ftp server:

ftp ftp.cs.wisc.edu
cd math-prog/cpo-dataset/machine-learn/WDBC/

References
----------
   - W.N. Street, W.H. Wolberg and O.L. Mangasarian. Nuclear feature extraction 
     for breast tumor diagnosis. IS&T/SPIE 1993 International Symposium on 
     Electronic Imaging: Science and Technology, volume 1905, pages 861-870,
     San Jose, CA, 1993.
   - O.L. Mangasarian, W.N. Street and W.H. Wolberg. Breast cancer diagnosis and 
     prognosis via linear programming. Operations Research, 43(4), pages 570-577, 
     July-August 1995.
   - W.H. Wolberg, W.N. Street, and O.L. Mangasarian. Machine learning techniques
     to diagnose breast cancer from fine-needle aspirates. Cancer Letters 77 (1994) 
     163-171.
print("Feature names:^n{}".format(cancer.data))
Feature names:^n[[  1.79900000e+01   1.03800000e+01   1.22800000e+02 ...,   2.65400000e-01
    4.60100000e-01   1.18900000e-01]
 [  2.05700000e+01   1.77700000e+01   1.32900000e+02 ...,   1.86000000e-01
    2.75000000e-01   8.90200000e-02]
 [  1.96900000e+01   2.12500000e+01   1.30000000e+02 ...,   2.43000000e-01
    3.61300000e-01   8.75800000e-02]
 ..., 
 [  1.66000000e+01   2.80800000e+01   1.08300000e+02 ...,   1.41800000e-01
    2.21800000e-01   7.82000000e-02]
 [  2.06000000e+01   2.93300000e+01   1.40100000e+02 ...,   2.65000000e-01
    4.08700000e-01   1.24000000e-01]
 [  7.76000000e+00   2.45400000e+01   4.79200000e+01 ...,   0.00000000e+00
    2.87100000e-01   7.03900000e-02]]

詳しく見てもよくわからない.

ボストン住宅価格

実世界の回帰データセットとして,boston_housingデータセットを用いる.これはボストン郊外の住宅地の住宅価格の中央世知を犯罪率チャールズ川からの距離,高速道路への利便性などから予測するものだ.

13notokutyouryouwomotu 506のデータポイントが含まれる.

from sklearn.datasets import load_boston
boston = load_boston()
print("Data shape: {}".format(boston.data.shape))
Data shape: (506, 13)

このデータセットを拡張子,13の測定結果だけを特徴量とするのではなく,特徴量間の積(交互作用(interaction)と呼ぶ)も見ることにする.つまり,犯罪率と高速道路への利便性を特徴量として見るだけでなく,それらの積も特徴量として考える.このように導出された特徴量を含めることを特徴量エンジニアリング(feature engineering)と呼ぶ.

X, y = mglearn.datasets.load_extended_boston()
print("X.shape: {}".format(X.shape))
X.shape: (506, 104)

104の特徴量とは,もとの13の特徴量に,13の特徴量から2つの特徴量を選ぶ重複ありの組合せ91を足したものである.

これから,様々な機械学習アルゴリズムの特徴を説明していく.

k-最近傍法

k-NNアルゴリズムは,最も単純な学習アルゴリズムであると言われる.新しいデータポイントに対する予測を行う際には,訓練データセットのんかから一番近い点つまり最近傍点を見つける.

k-最近傍法によるクラス分類

一番簡単な倍位には,k-NNアルゴリズムは,1つの近傍点,つまり訓練データに含まれる天の中で,予測したいデータポイントに一番近いものだけみる.予測には,この点に対する出力をそのまま用いる.

mglearn.plots.plot_knn_classification(n_neighbors=1)

f:id:forhighlow:20171006222723p:plain

ここでは,星印で示される3つの新しいデータポイントを加えている.それぞれに対して訓練データのうちで,最も近いものに印を付けた.

最近傍法アルゴリズムでの予測では,近傍店のラベルが予測されたラベルになる.(星印の色で表されている).

1つ以上の近傍店を考慮にいれる場合は,投票でラベルを決める.つまり,個々のテストする点に対して,近傍点のうちいくつがクラス0に属し,いくつが暮らすに属するのかを数える.そして最も多く現れたクラスをその点に与える.言い換えればk-最近傍点の多数はのクラスを採用する.

要は多数決的に近しいものと同じになる.朱に交われば赤くなる,ということだ.

mglearn.plots.plot_knn_classification(n_neighbors=3)

png

ここでも,予測された結果は,星印の色で示されている.左上の新しいデータポイントに対する予測は,1つの最近傍点だけを使った場合とことなっている.

scikit-learnを用いてk-最近傍点アルゴリズムが適用できるか見てみたい.まず,データを訓練セットとテストセットに分割し,汎化性能を評価可能にする.

from sklearn.model_selection import train_test_split
X, y = mglearn.datasets.make_forge()
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

次にクラスをインポートして,インスタンスを作成する.この際に,近傍店の数などのパラメータを渡すことができる.ここでは3にしている.

from sklearn.neighbors import KNeighborsClassifier
clf = KNeighborsClassifier(n_neighbors=3)

次に,訓練データセットを用いてクラス分類器を訓練する. for KNeighborsClassifier this means storing the dataset, so we can compute neighbors during prediction.

clf.fit(X_train, y_train)
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=1, n_neighbors=3, p=2,
           weights='uniform')

finds the most common class among these

clf.predict(X_test)
array([1, 0, 1, 0, 1, 0, 0])
clf.score(X_test, y_test)
0.8571428571428571

85%の正確さである.