기계 학습 실습 ---- SKLearn은 SVM의 최소 분류를 구현합니다.

1. 소개

win10, 파이썬 3.6, 노트북

참고:

[머신러닝 실습] Support Vector Machine----분류 라이브러리 및 단순 학습 mnist

https://blog.csdn.net/u013597931/article/details/80076058

SVM 연구 노트(2)----필기 숫자 인식

https://blog.csdn.net/chunxiao2008/article/details/50448154

 

2. SVM 모듈에 대한 자세한 설명

기본 이론 -------알고리즘 라이브러리------속성---------방법

기본 이론:

  • 기본 아이디어는 분류에 최대 간격을 사용하는 것입니다.
  • 비선형 문제를 해결하기 위해 특징 벡터를 커널 함수를 통해 고차원 공간에 매핑함으로써 선형 분리가 가능해 지지만 연산은 저차원 공간에서 수행됩니다.
  • 데이터에 노이즈가 있을 수 있다는 점을 고려하여 여유 변수도 도입되었습니다.

 

다음 라이브러리는 sklearn.svm 모듈에서 제공됩니다. 

è¿éååå¤çæè¿°

 이는 대략적으로 다음 범주로 나뉩니다(svm_l1_min_c가 페널티 매개변수 C의 최저 경계를 반환한다는 점 제외). 

è¿éååå¤çæè¿°

 

분류 라이브러리의 주요 매개변수:

è¿éååå¤çæè¿°

다른 매개변수에 대한 소개를 보려면 공식 라이브러리( 
http://scikit-learn.org/stable/modules/classes.html#module-sklearn.svm 
)를 보거나 이 블로거의 요약을 살펴보세요(요약은 매우 좋습니다). : 
http://www.cnblogs.com/pinard/p/6117515.html
 

속성:

è¿éååå¤çæè¿°

 

방법:

훈련을 위한 fit(), 점수 매기기를 위한 Score(), 새로운 샘플 예측을 위한 예측(), 샘플 지점에서 분리 초평면까지의 거리를 계산하는 Decision_function() 등을 포함하여 일반 모델과 동일합니다.

 

3. SVM 분류의 간단한 구현

분류에는 세 가지 다른 SVC가 사용되었습니다.

  • SVC:     svm.SVC(커널='선형')
  • 선형SVC:   svm.LinearSVC()
  • NuSVC:       svm.NuSVC(커널='선형'

 

알 수있는 바와 같이:

 

  • LinearSVC 훈련으로 얻은 분리 초평면은 SVC의 것과 다릅니다.
  • NuSVC 모델의 서포트 벡터는 샘플 수의 절반을 차지하며, nu=0.01인 경우 SVC와 동일하므로 학습 오차나 서포트 벡터의 백분율에 대한 요구 사항이 있는 경우 NuSVC를 선택할 수 있습니다.

1. 데이터 세트

##用于可视化图表
import matplotlib.pyplot as plt
##用于做科学计算
import numpy as np
##用于做数据分析
import pandas as pd
##用于加载数据或生成数据等
from sklearn import datasets
##加载svm模型
from sklearn import svm
##随机生成一组特征数量为2,样本数量为80的数据集
X, y = datasets.make_blobs(n_samples=80, n_features=2, centers=2, random_state=3)
fig=plt.figure(figsize=(10,8))
plt.xlim(-8,4)  #  设置x轴刻度范围
plt.ylim(-5,8)  #  设置y轴刻度范围
plt.scatter(X[:, 0], X[:, 1], c=y, s=30)
plt.show()

 

2、 svm.SVC(kernel='선형')

##加载svm的svc模型,选择线性核linear
model_svc=svm.SVC(kernel='linear')
model_svc.fit(X,y)

print("各类的支持向量在训练样本中的索引",model_svc.support_)
print("各类所有的支持向量:\n",model_svc.support_vectors_)
print("各类各有多少个支持向量",model_svc.n_support_)
print("各特征系数",model_svc.coef_)
print("截距",model_svc.intercept_)
print("各样本点到分离超平面的距离:\n",model_svc.decision_function(X))

fig=plt.figure(figsize=(10,8))
plt.xlim(-8,4)  #  设置x轴刻度范围
plt.ylim(-5,8)  #  设置y轴刻度范围
##显示分离超平面
w1=model_svc.coef_[:,0]
w2=model_svc.coef_[:,1]
b=model_svc.intercept_
x1=np.linspace(-8,6,2) 
x2=(w1*x1+b)/(-1*w2)
x2_up=(w1*x1+b+1)/(-1*w2)
x2_down=(w1*x1+b-1)/(-1*w2)
plt.plot(x1,x2,'k-',linewidth=0.8)
plt.plot(x1,x2_up,'k--',linewidth=0.8)
plt.plot(x1,x2_down,'k--',linewidth=0.8)
##显示样本点和支持向量
plt.scatter(X[:, 0], X[:, 1], c=y,s=30)
plt.scatter(model_svc.support_vectors_[:, 0], model_svc.support_vectors_[:, 1],s=80,c='',edgecolors='b')
plt.show()
各类的支持向量在训练样本中的索引 [ 3 77 63]
各类所有的支持向量:
 [[ 0.21219196  1.74387328]
 [-1.23229972  3.89519459]
 [-2.94843418  0.3655385 ]]
各类各有多少个支持向量 [2 1]
各特征系数 [[-0.48951758 -0.32852537]]
截距 [-0.32333516]
各样本点到分离超平面的距离:
 [-1.96224709  1.96992652  1.61830594 -1.00011347 -3.03968748 -1.91355576
 -3.20222196  1.07605938  1.39390527  1.19794817 -3.09852679 -2.99356435
  1.83058651  2.46025289  1.84454041 -1.98203511  1.18207352 -2.21362739
 -1.93596757  1.5062249  -3.13955464 -1.41328098  2.11163776 -2.0100733
  1.23402066 -1.3997197   1.42460256  1.9676612   1.10767531  1.64961948
  1.95638419  1.51193805 -1.2642258   2.06733658  1.99862207  1.49307471
 -1.44123444 -1.54063897  2.21232256  3.39921728  1.08180429  1.72267793
 -3.1813601   1.61914905  1.59985133 -1.70286262 -1.94181226  1.59417872
  2.15236394 -2.64727844 -2.54908967 -1.45290411 -2.30745878 -2.58497233
  2.2307059  -2.6951711  -2.96443813 -1.73637146  2.20696118 -1.77028229
 -2.67467925 -1.60612382  2.59439321  0.99988654 -1.59570877  1.53629311
 -2.69403494  1.44783106 -2.07984685 -1.3734872   1.09058746  1.60125344
  1.76284029 -1.83576229 -1.90749178 -2.44163699  2.01923035 -0.99977302
  2.01835361 -1.9910022 ]

 

3、svm.LinearSVC()

##加载svm的LinearSVC模型
model_svc=svm.LinearSVC()
model_svc.fit(X,y)
print("各特征系数",model_svc.coef_)
print("截距",model_svc.intercept_)
print("各样本点到分离超平面的距离:\n",model_svc.decision_function(X))

fig=plt.figure(figsize=(10,8))
plt.xlim(-8,4)  #  设置x轴刻度范围
plt.ylim(-5,8)  #  设置y轴刻度范围
##显示分离超平面
w1=model_svc.coef_[:,0]
w2=model_svc.coef_[:,1]
b=model_svc.intercept_
x1=np.linspace(-8,6,2) 
x2=(w1*x1+b)/(-1*w2)
x2_up=(w1*x1+b+1)/(-1*w2)
x2_down=(w1*x1+b-1)/(-1*w2)
plt.plot(x1,x2,'k-',linewidth=0.8)
plt.plot(x1,x2_up,'k--',linewidth=0.8)
plt.plot(x1,x2_down,'k--',linewidth=0.8)

##显示样本点和支持向量
plt.scatter(X[:, 0], X[:, 1], c=y,s=30)
plt.show()
各特征系数 [[-0.43861872 -0.34666587]]
截距 [-0.17687917]
各样本点到分离超平面的距离:
 [-1.93588632  1.87233349  1.51364971 -0.87449188 -2.92992153 -1.76381697
 -3.07749808  1.04025334  1.29833361  1.11381917 -2.93977862 -2.79956624
  1.71631792  2.39358778  1.73195783 -1.92786837  1.09573885 -2.04452242
 -1.82100181  1.42159955 -2.9877508  -1.29033632  2.02059401 -1.88099763
  1.19084793 -1.30551704  1.40518201  1.87446768  0.99415791  1.64725845
  1.9009514   1.43403277 -1.1375335   1.94926655  1.87258846  1.44713253
 -1.30509778 -1.4745769   2.12237058  3.19811264  1.04509393  1.58901995
 -3.04486552  1.48196178  1.52057507 -1.59990501 -1.8120006   1.48499025
  2.06828345 -2.51227207 -2.3304399  -1.36943056 -2.11483449 -2.43410562
  2.09715535 -2.51291992 -2.80568943 -1.64868248  2.14688497 -1.69265193
 -2.59427138 -1.57782921  2.51736177  0.98963954 -1.54715292  1.50308216
 -2.61135208  1.38378795 -1.94731015 -1.30279915  0.96583083  1.58100889
  1.64279966 -1.796035   -1.8219179  -2.28425194  1.91261392 -0.98670045
  1.90619623 -1.79154379]

 

4、 svm.NuSVC(커널='선형')

##加载svm的NuSVC模型,nu为默认值0.5
model_svc=svm.NuSVC(kernel='linear')
#model_svc=svm.NuSVC(kernel='linear',nu=0.01)
model_svc.fit(X,y)
print("各类的支持向量在训练样本中的索引",model_svc.support_)
print("各类各有多少个支持向量",model_svc.n_support_)
print("各特征系数",model_svc.coef_)
print("截距",model_svc.intercept_)
print("各样本点到分离超平面的距离:\n",model_svc.decision_function(X))

fig=plt.figure(figsize=(10,8))
plt.xlim(-8,4)  #  设置x轴刻度范围
plt.ylim(-5,8)  #  设置y轴刻度范围
##显示分离超平面
w1=model_svc.coef_[:,0]
w2=model_svc.coef_[:,1]
b=model_svc.intercept_
x1=np.linspace(-8,6,2) 
x2=(w1*x1+b)/(-1*w2)
x2_up=(w1*x1+b+1)/(-1*w2)
x2_down=(w1*x1+b-1)/(-1*w2)
plt.plot(x1,x2,'k-',linewidth=0.8)
plt.plot(x1,x2_up,'k--',linewidth=0.8)
plt.plot(x1,x2_down,'k--',linewidth=0.8)

##显示样本点和支持向量
plt.scatter(X[:, 0], X[:, 1], c=y,s=30)
plt.scatter(model_svc.support_vectors_[:, 0], model_svc.support_vectors_[:, 1],s=80,c='',edgecolors='b')
plt.show()
各类的支持向量在训练样本中的索引 [ 0  3  5 18 21 25 32 36 37 45 46 51 57 59 61 64 69 73 74 77 79  2  7  8
  9 16 19 24 26 28 31 35 40 43 44 47 63 65 67 70 71]
各类各有多少个支持向量 [21 20]
各特征系数 [[-0.26852918 -0.18506518]]
截距 [-0.07402223]
各样本点到分离超平面的距离:
 [-1.00000001  1.18344728  0.98651753 -0.45373219 -1.59369374 -0.9613798
 -1.68303355  0.69021961  0.86209936  0.75377706 -1.62199582 -1.56013705
  1.10412131  1.46001562  1.11206673 -1.00846728  0.74471129 -1.12708414
 -0.97711454  0.92581127 -1.64554153 -0.68461074  1.26315788 -1.017172
  0.77771057 -0.67970603  0.886296    1.18259074  0.70066156  1.01348247
  1.17979741  0.9296235  -0.60106054  1.23592282  1.1968279   0.92205787
 -0.6989911  -0.76097669  1.31946142  1.97167963  0.69334256  1.04208873
 -1.67029696  0.98397159  0.97856961 -0.84810873 -0.97900041  0.97262943
  1.28653695 -1.3723103  -1.30974513 -0.7103885  -1.17727995 -1.33606029
  1.32568017 -1.39466306 -1.54714741 -0.86822923  1.31923904 -0.88809099
 -1.3926683  -0.80103249  1.53393157  0.65006995 -0.79334001  0.94736295
 -1.4032617   0.89512436 -1.0557987  -0.66724352  0.69008091  0.9848262
  1.0657701  -0.92815667 -0.96394481 -1.25544599  1.21013198 -0.46397868
  1.20912877 -1.        ]

 

4. 최소 데이터 세트

미니스트 공식 홈페이지:  http://yann.lecun.com/exdb/mnist/

공식 홈페이지에 있는 데이터 세트는 gz 형식인데, Windows에서는 gz 형식을 압축 해제하는 것이 더 번거롭습니다.

따라서 훈련에는 두 가지 데이터 세트가 사용됩니다.

  • 첫 번째는 압축이 풀린 공식 웹사이트 데이터 세트입니다.
  • 하나는 mnist.pkl.gz이며 비교합니다.

 

1、mnist.pkl.gz

참고: https://blog.csdn.net/chunxiao2008/article/details/50448154

scikit-learn 라이브러리에서 SVM을 직접 호출하여 기본 매개변수와 손으로 쓴 숫자 1,000장의 그림을 사용하여 정확하게 판단된 그림의 개수는 9,435장에 달합니다.

위 코드는 검증 세트로 검증되지 않습니다. 왜냐하면 이 예에서는 동일한 것을 판단하기 위해 테스트 세트와 검증 세트를 사용하고, 이를 다시 검증하기 위해 일부러 검증 세트를 사용할 필요가 없기 때문입니다.

데이터 가져오기:

# import cPickle
import _pickle as cPickle
import gzip
import numpy as np
from sklearn import svm
import time

def load_data():
    """
    返回包含训练数据、验证数据、测试数据的元组的模式识别数据
    训练数据包含50,000张图片,测试数据和验证数据都只包含10,000张图片
    """
    f = gzip.open('MNIST_data/mnist.pkl.gz', 'rb')
    # training_data, validation_data, test_data = cPickle.load(f)
    training_data, validation_data, test_data = cPickle.load(f,encoding='bytes')
    f.close()
    return (training_data, validation_data, test_data)

분류:

# 使用SVM分类器,从MNIST数据集中进行手写数字识别的分类程序


def svm_baseline():
    #print time.strftime('%Y-%m-%d %H:%M:%S') 
    print(time.strftime('%Y-%m-%d %H:%M:%S'))
    training_data, validation_data, test_data = load_data()
    # 传递训练模型的参数,这里用默认的参数
    clf = svm.SVC()
    # clf = svm.SVC(C=8.0, kernel='rbf', gamma=0.00,cache_size=8000,probability=False)
    # 进行模型训练
    clf.fit(training_data[0], training_data[1])
    # test
    # 测试集测试预测结果
    predictions = [int(a) for a in clf.predict(test_data[0])]
    num_correct = sum(int(a == y) for a, y in zip(predictions, test_data[1]))
    print("%s of %s test values correct." % (num_correct, len(test_data[1])))
    print(time.strftime('%Y-%m-%d %H:%M:%S'))

if __name__ == "__main__":
    svm_baseline()

결과:

2018-12-17 15:16:57
9435 of 10000 test values correct.
2018-12-17 15:29:36

 

2、t10k-images.idx3-ubyte等

데이터:

import numpy as np
import struct
import matplotlib.pyplot as plt
import os
##加载svm模型
from sklearn import svm
###用于做数据预处理
from sklearn import preprocessing
import time
path='MNIST_data'
def load_mnist_train(path, kind='train'):    
    labels_path = os.path.join(path,'%s-labels.idx1-ubyte'% kind)
    images_path = os.path.join(path,'%s-images.idx3-ubyte'% kind)
    with open(labels_path, 'rb') as lbpath:
        magic, n = struct.unpack('>II',lbpath.read(8))
        labels = np.fromfile(lbpath,dtype=np.uint8)
    with open(images_path, 'rb') as imgpath:
        magic, num, rows, cols = struct.unpack('>IIII',imgpath.read(16))
        images = np.fromfile(imgpath,dtype=np.uint8).reshape(len(labels), 784)
    return images, labels
def load_mnist_test(path, kind='t10k'):
    labels_path = os.path.join(path,'%s-labels.idx1-ubyte'% kind)
    images_path = os.path.join(path,'%s-images.idx3-ubyte'% kind)
    with open(labels_path, 'rb') as lbpath:
        magic, n = struct.unpack('>II',lbpath.read(8))
        labels = np.fromfile(lbpath,dtype=np.uint8)
    with open(images_path, 'rb') as imgpath:
        magic, num, rows, cols = struct.unpack('>IIII',imgpath.read(16))
        images = np.fromfile(imgpath,dtype=np.uint8).reshape(len(labels), 784)
    return images, labels   
train_images,train_labels=load_mnist_train(path)
test_images,test_labels=load_mnist_test(path)

분류:

# 标准化
X=preprocessing.StandardScaler().fit_transform(train_images)  
X_train=X[0:60000]
y_train=train_labels[0:60000]

# 模型训练
print(time.strftime('%Y-%m-%d %H:%M:%S'))
model_svc = svm.SVC()
model_svc.fit(X_train,y_train)
print(time.strftime('%Y-%m-%d %H:%M:%S'))

# 评分并预测
x=preprocessing.StandardScaler().fit_transform(test_images)
x_test=x[0:10000]
y_pred=test_labels[0:10000]
print(model_svc.score(x_test,y_pred))
y=model_svc.predict(x_test)

결과:

2018-12-17 17:20:00
2018-12-17 17:30:53

0.9657

 

요약하다:

두 개의 데이터 세트를 사용하면 실행 시간이 10분 이상이고 출력 결과에 큰 오류가 있어 매개변수 조정을 통해 조정할 수 있음을 알 수 있습니다.

중요한 매개변수:

  • C: 부동 소수점 유형, 선택 사항(기본값=1.0). 오류항에 대한 페널티 매개변수 C 
  • 커널: 문자 유형, 선택 사항(기본값='rbf'). 커널 함수 유형을 지정합니다. '선형', '폴리', 'rbf', '시그모이드' 등만 가능합니다.
  • 정도 : 정수, 선택 사항(기본값=3). 다항식 커널 함수('poly')를 사용할 때, 다른 커널 함수를 사용할 때 다항식 커널 함수의 매개변수 d를 무시할 수 있습니다. 
  • 감마 : 부동 소수점 유형, 선택 사항(기본값=0.0). 'rbf', 'poly' 및 'sigmoid' 커널 함수의 계수입니다. 감마가 0이면 피처 차원의 역수 값이 실제로 계산에 사용됩니다. 즉, 특징이 100차원이면 실제 감마는 1/100입니다. 
  • oef0: 부동 소수점 유형, 선택 사항(기본값=0.0). 커널 함수의 독립 용어는 '폴리' 및 '시그모이드' 커널에만 의미가 있습니다. 

 

머신러닝 전문가인 Andrew Ng는 SVM 분류 알고리즘과 관련하여 항상 가우스 커널 함수를 사용해 왔으며 기본적으로 다른 커널 함수는 사용한 적이 없다고 말했습니다. 이 커널 함수가 가장 널리 사용되는 것을 볼 수 있습니다. 

매핑을 위해 가우스 커널을 사용할 때 감마 매개변수를 매우 작게 선택하면 고차 특성에 대한 가중치가 실제로 매우 빠르게 감소하므로 실제로 (수치적으로 근사된) 저차원 부분공간과 동일합니다. 역으로 과거에는 감마를 매우 크게 선택하면 모든 데이터가 선형 분리 가능하도록 매핑될 수 있었습니다. 이는 매우 심각한 과잉 맞춤 문제로 쉽게 이어질 수 있습니다. 

C 매개변수는 가장 큰 마진을 가진 초평면을 찾는 것과 "데이터 포인트의 최소 편차 보장" 사이의 가중치입니다. C가 클수록 모델이 허용하는 편차는 작아집니다. 

동일한 C의 경우 감마가 클수록 분류 경계가 샘플에 더 가까워집니다. 동일한 감마에 대해 C가 클수록 분류가 더 엄격해집니다. 

 

감마가 너무 크면 C가 아무리 커도 과적합을 방지할 수 없습니다.

감마가 작으면 분류 경계는 매우 선형적입니다.

중간 값을 취하면 좋은 모델의 감마와 C는 대략 대각선 위치에 분포됩니다.

또한 감마가 중간 값을 취하는 경우 C 값이 매우 커질 수 있다는 점에 유의해야 합니다. 

추천

출처blog.csdn.net/bailixuance/article/details/85051594