sklearn 2-支持向量机SVM

SVM用于分类和回归,目的是找到一个超平面,使得离超平面最近的点都有很大的距离,max(最小距离)的意思

SVM是一个二分类方法,但是它可以在有核的情况下分类非线性的数据

大概步骤是这样的:先将数据升维,以便进行线性的分割;接下来,对分割后的数据计算支持向量,进而得到分割线。

其数学原理之精妙,让人叹为观止。

具体原理、推导,可见Jack-Cui的文章:

https://blog.csdn.net/c406495762/article/details/78072313

https://blog.csdn.net/c406495762/article/details/78158354

下面结合示例代码,具体分析一下流程。

1、生成并可视化数据。

import numpy as np
import matplotlib.pyplot as plt
import seaborn; 
from sklearn.linear_model import LinearRegression
#from scipy import stats
#import pylab as pl
#seaborn.set()
from sklearn.datasets import make_blobs
X, y = make_blobs(n_samples=50, centers=2,
                  random_state=0, cluster_std=0.60)

xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='spring')

# 其实随意给定3组参数,就可以画出3条不同的直线,但它们都可以把图上的2类样本点分隔开
for m, b, d in [(1, 0.65, 0.33), (0.5, 1.6, 0.55), (-0.2, 2.9, 0.2)]:
    yfit = m * xfit + b
    plt.plot(xfit, yfit, '-k')
    plt.fill_between(xfit, yfit - d, yfit + d, edgecolor='none', color='#AAAAAA', alpha=0.4)#alpha for blending
plt.xlim(-1, 3.5)
plt.show()

make_blobs函数是为聚类产生数据集
产生一个数据集和相应的标签
n_samples:表示数据样本点个数,默认值100
n_features:表示数据的维度,默认值是2
centers:产生数据的中心点,默认值3
cluster_std:数据集的标准差,浮点数或者浮点数序列,默认值1.0
center_box:中心确定之后的数据边界,默认值(-10.0, 10.0)
shuffle :洗乱,默认值是True
random_state:官网解释是随机生成器的种子

***
作者:你说你要一场
链接:https://www.jianshu.com/p/069d8841bd8e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

plt.scatter具体参数可以参考https://blog.csdn.net/qi_1221/article/details/73903131

plt.plot参考https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.plot.html

 

 2 SVC分类

from sklearn.datasets import make_blobs
from sklearn.svm import SVC
import numpy as np
import matplotlib.pyplot as plt
X, y = make_blobs(n_samples=50, centers=2,random_state=0, cluster_std=0.60)

clf = SVC(kernel='linear')
clf.fit(X, y)

def plot_svc_decision_function(clf, ax=None):
    """Plot the decision function for a 2D SVC"""
    if ax is None:
        ax = plt.gca()
    x = np.linspace(plt.xlim()[0], plt.xlim()[1], 30)
    y = np.linspace(plt.ylim()[0], plt.ylim()[1], 30)
    Y, X = np.meshgrid(y, x)
    P = np.zeros_like(X)
    for i, xi in enumerate(x):
        for j, yj in enumerate(y):
            P[i, j] = clf.decision_function([[xi, yj]])
    # plot the margins
    CS = ax.contour(X, Y, P, colors='k',
               levels=[-1, 0, 1], alpha=0.5,
               linestyles=['--', '-', '--'])
    ax.clabel(CS, inline=1, fontsize=10)
plt.scatter(X[:, 0], X[:, 1], c=y, s=10, cmap='spring')
plot_svc_decision_function(clf)
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],s=200, c='r', facecolors='none');
plt.show()

clf = SVC(kernel='linear')
clf.fit(X, y)

这是重点

clf.support_vectors_[:, 0], clf.support_vectors_[:, 1]这两是支持向量

根据官方code.py,核必须是{'linear', 'poly', 'rbf', 'sigmoid', 'precomputed'}之一,或是自定义的。

核函数的选择:

1、特征数量大,和样本数量差不多:此时选LR或者线性核SVM

2、特征数量少,样本数量正常:高斯核

3、特征数量小,样本数量大:手动添加特征变为第一种情况

结果如下:

下面是一个SVM人脸识别的案例

from time import time
import logging
import matplotlib.pyplot as plt
import cv2 
#从sklearn导入相关模型和svm算法
from numpy import *
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.decomposition import PCA
from sklearn.svm import SVC
# PICTURE_PATH为图像存放目录位置,注意读者需要修改为自己电脑存放图像的目录
PICTURE_PATH = "./att_faces" 
def get_Image(): #读取图像程序
    for i in range(1,41):  #循环读取所以图片文件
        for j in range(1,11):
            path = PICTURE_PATH + "\\s" + str(i) + "\\"+ str(j) + ".pgm"   #路径
            img = cv2.imread(path)                                  #使用imread函数读取图像
#生活中大多数看到的彩色图像都是RGB类型,但是图像处理时,需要用到灰度图、二值图、HSV、HSI等颜色制式,opencv的cvtColor()函数来实现这些功能
            img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            h,w = img_gray.shape           #图像的尺寸信息赋值给变量h和w
            img_col = img_gray.reshape(h*w) #使用reshape函数对图像进行处理
            all_data_set.append(img_col)     #将图像添加到数据集all_data_set中
            all_data_label.append(i)         #确定图像对应的标签值
    return h,w 
all_data_set = []         #变量all_data_set初始化为空
all_data_label = []       # 变量all_data_label初始化为空
h,w = get_Image()       #调用定义的get_Image()函数获取图像

X =array(all_data_set)    #使用all_data_set作为参数定义数组赋值给变量X
y = array(all_data_label)  #使用all_data_ label作为参数定义数组赋值给变量y
n_samples,n_features = X.shape   #X数组中的图像信息赋值给变量n_samples,n_features
print(X.shape)
n_classes = len(unique(y))        #得到变量y的长度赋值给n_classes
#unique:对于一维数组或者列表,unique函数去除其中重复的元素,并按元素由大到小返回一个新的无元素重复的元组或者列表
target_names = []               #变量target_names初始化为空
for i in range(1,41):             #循环读取
    names = "person" + str(i)    #定义变量names,并赋值
target_names.append(names) #变量target_names不断添加信息的names
#打印输出:数据集总规模,n_samples和n_features
print("Total dataset size:")
print("n_samples: %d" % n_samples)
print("n_features: %d" % n_features)
#程序划分,一部分用于训练集,另一部分用于测试集,这里使用3/4数据用于训练,1/4数据用于测试
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42)  
n_components = 20
#打印输出信息
print("Extracting the top %d eigenfaces from %d faces"
      % (n_components, X_train.shape[0])) 
t0 = time()
pca = PCA(n_components=n_components, svd_solver='randomized', #选择一种svd方式
          whiten=True).fit(X_train)    #whiten是一种数据预处理方式,会损失一些数据信息,但可获得更好的预测结果
print("done in %0.3fs" % (time() - t0)) 
eigenfaces = pca.components_.reshape((n_components, h, w))    #特征脸 
print("Projecting the input data on the eigenfaces orthonormal basis")
t0 = time()
#这是转化后,生成【分类数量,特征数量20】的矩阵
X_train_pca = pca.transform(X_train)      #得到训练集投影系数
X_test_pca = pca.transform(X_test)        #得到测试集投影系数
print("done in %0.3fs" % (time() - t0))      #打印出来时间

接下来,就是 输出特征脸eigenface

#定义plot_gallery函数
#函数参数为:images, titles, h, w, n_row, n_col
def plot_gallery(images, titles, h, w, n_row=3, n_col=4):
    """Helper function to plot a gallery of portraits"""
    plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))     #创建自定义图像
    plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)  #对子图之间的间距进行设置
    for i in range(n_row * n_col-4):    #循环处理多个图像
        plt.subplot(n_row, n_col, i + 1) #绘制子图
        plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray)  #绘制图像
        plt.title(titles[i], size=12)        #设置图像的标题
        plt.xticks(())                  #设置x轴文本
        plt.yticks(())                  #设置y轴文本
eigenface_titles = ["eigenface %d" % i for i in range(eigenfaces.shape[0])] #定义特征脸标题
plot_gallery(eigenfaces, eigenface_titles, h, w) #调用plot_gallery函数绘制特征脸
plt.show()                              #显示图像

加上分类器SVM之后,整体如下:

from time import time
import logging
import matplotlib.pyplot as plt
import cv2
 
from numpy import *
from sklearn.model_selection import train_test_split
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.decomposition import PCA
from sklearn.svm import SVC
 
PICTURE_PATH = "att_faces"
 
def get_Image():
    for i in range(1,41):
        for j in range(1,11):
            path = PICTURE_PATH + "\\s" + str(i) + "\\"+ str(j) + ".pgm"
            img = cv2.imread(path)
            img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            h,w = img_gray.shape
            img_col = img_gray.reshape(h*w)
            all_data_set.append(img_col)
            all_data_label.append(i)
    return h,w
 
all_data_set = []
all_data_label = []
h,w = get_Image()
 
X = array(all_data_set)
y = array(all_data_label)
n_samples,n_features = X.shape
n_classes = len(unique(y))
target_names = []
for i in range(1,41):
    names = "person" + str(i)
    target_names.append(names)
 
print("Total dataset size:")
print("n_samples: %d" % n_samples)
print("n_features: %d" % n_features)
print("n_classes: %d" % n_classes)
 
# split into a training and testing set
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=42)
 
n_components = 10
print("Extracting the top %d eigenfaces from %d faces"
      % (n_components, X_train.shape[0]))
 
t0 = time()
pca = PCA(n_components=n_components, svd_solver='randomized',
          whiten=True).fit(X_train)
print("done in %0.3fs" % (time() - t0))
 
eigenfaces = pca.components_.reshape((n_components, h, w))
 
print("Projecting the input data on the eigenfaces orthonormal basis")
t0 = time()
X_train_pca = pca.transform(X_train)
X_test_pca = pca.transform(X_test)
print("done in %0.3fs" % (time() - t0))
 
print("Fitting the classifier to the training set")
t0 = time()
param_grid = {'C': [1e3, 5e3, 1e4, 5e4, 1e5],
              'gamma': [0.0001, 0.0005, 0.001, 0.005, 0.01, 0.1], }
clf = GridSearchCV(SVC(kernel='rbf', class_weight='balanced'), param_grid)#网格化搜索以上grid里面的数据
clf = clf.fit(X_train_pca, y_train)
print("done in %0.3fs" % (time() - t0))
print("Best estimator found by grid search:")
print(clf.best_estimator_)
 
print("Predicting people's names on the test set")
t0 = time()
y_pred = clf.predict(X_test_pca)
print("done in %0.3fs" % (time() - t0))

print(classification_report(y_test, y_pred, labels=[i for i in range(40)],target_names=target_names))#labels很重要
print(confusion_matrix(y_test, y_pred, labels=range(n_classes)))
 
def plot_gallery(images, titles, h, w, n_row=3, n_col=4):
    """Helper function to plot a gallery of portraits"""
    plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))
    plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)
    for i in range(n_row * n_col-4):
        plt.subplot(n_row, n_col, i + 1)
        plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray)
        plt.title(titles[i], size=12)
        plt.xticks(())
        plt.yticks(())
 
 
# plot the result of the prediction on a portion of the test set
 
def title(y_pred, y_test, target_names, i):
    pred_name = target_names[y_pred[i]-1]
    true_name = target_names[y_test[i]-1]
    return 'predicted: %s\ntrue:      %s' % (pred_name, true_name)
 
prediction_titles = [title(y_pred, y_test, target_names, i)
                     for i in range(y_pred.shape[0])]
 
plot_gallery(X_test, prediction_titles, h, w)
 
# plot the gallery of the most significative eigenfaces
 
eigenface_titles = ["eigenface %d" % i for i in range(eigenfaces.shape[0])]
plot_gallery(eigenfaces, eigenface_titles, h, w)
plt.show()

结果如下

SVM的保存与读取

import pickle
model.fit(train_X, train_y)
s=pickle.dumps(model)
f=open('svm.model', "wb+")
f.write(s)
f.close()
print ("Done\n")
模型保存
这里的model已经是生成好的模型了,注意一定要用"wb+",否则会报错
f2=open('svm.model','rb')
s2=f2.read()
model1=pickle.loads(s2)
expected = test_y
predicted = model1.predict(test_X)
模型调用,注意读取方式'rb',否则会报错
————————————————
版权声明:本文为CSDN博主「jessica218」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42595525/article/details/82979076

SVM 多分类问题

clf = svm.SVC(decision_function_shape='ovo')

要改的话 clf.decision_function_shape = "ovr"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值