【機械学習】MNISTデータセットに基づくKNN,SVM分類器テスト

3212 ワード

前編blogではMNISTの読み取り方法について述べたが,本稿では主にMNISTデータセットを用いて分類器のテストを行う

KNN近隣分類器


KNNは怠惰学習(Lazy learning)法であり,訓練過程とは訓練データを空間に格納することである.次に、テスト時に、テスト対象データをデータ空間に投入して近隣を探し、近隣カテゴリの投票によりそのデータのカテゴリを決定する
from sklearn.neighbors import KNeighborsClassifier
import MNIST 
import numpy as np


if __name__ == '__main__':

    im = MNIST.MNIST2vector('train-images.idx3-ubyte')
    label = MNIST.decode_idx1_ubyte('train-labels.idx1-ubyte')

    neigh = KNeighborsClassifier(n_neighbors=3)
    neigh.fit(im, label) 

    test = MNIST.MNIST2vector('t10k-images.idx3-ubyte')
    test_label = MNIST.decode_idx1_ubyte('t10k-labels.idx1-ubyte')

    # res = neigh.predict(test)
    score = neigh.score(test, test_label)
    print(" score: {:.6f}".format(score))

訓練データは60 k,試験データセット10 k,分類進度97.05%でデータセットが大きい場合,いくつかの簡単なモデルが比較的良い訓練効果を実現できることが分かった.良いデータは実際にはモデルよりずっと重要です.

SVM近隣分類器


SVMは現在の分類器の中で最も効果的な1つであり、そのコア関数(kernel trick)はデータを高次元空間にマッピングすることができ、データをよく分類することができる.
しかし、私はテストの時にSVMのいくつかの欠点を発見しました:1)大規模なデータには適用されず、SVMは小規模なデータの中で特徴とデータの間の非線形関係をよくつかむことができます.しかし,データ量が大きい場合,訓練速度や分類精度はそれほど適切ではない.2)kernel選択が困難で、調整が面倒
from sklearn.svm import SVC
import MNIST 
import random


if __name__ == '__main__':

    im = MNIST.MNIST2vector('train-images.idx3-ubyte')
    label = MNIST.decode_idx1_ubyte('train-labels.idx1-ubyte')

    test = MNIST.MNIST2vector('t10k-images.idx3-ubyte')
    test_label = MNIST.decode_idx1_ubyte('t10k-labels.idx1-ubyte')

    train_idx = list(range(10000))
    random.shuffle(train_idx)
    im_sample = im[train_idx]
    label_sample = label[train_idx]

    test_idx = list(range(200))
    random.shuffle(test_idx)
    test_sample = test[test_idx]
    test_label_sample = test_label[test_idx]

    clf = SVC(kernel = 'poly')
    clf.fit(im_sample, label_sample) 

    score = clf.score(test_sample, test_label_sample)
    print(" score: {:.6f}".format(score))

この訓練時間が長すぎるため,SVMの訓練時間は複雑度が高い.私はサンプリングして訓練しました.10000個の訓練セット、200個のテストセットです.多項式核polyを選択して、精度97.5%、RBF核の精度はかなり悪くて、12%ぐらいしかありません