SVM 代码实现展示

相关模块引入

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats import seaborn as sns;sns.set() # 使用seaborn的默认设置

数据集

这里自己生成一些随机数据

#随机来点数据
from sklearn.datasets.samples_generator import make_blobs
X, y = make_blobs(
n_samples=50, # 样本点数量
centers=2, # 簇堆数量
random_state=0, # 随机种子
cluster_std=0.60 # 簇离散程度
)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')

切分数据

xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plt.plot([0.6], [2.1], 'x', color='red', markeredgewidth=2, markersize=10) for m, b in [(1, 0.65), (0.5, 1.6), (-0.2, 2.9)]:
plt.plot(xfit, m * xfit + b, '-k') plt.xlim(-1, 3.5);

如图所示分开有很多种方式, 看哪种更好呢?

最小化雷区

xfit = np.linspace(-1, 3.5)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn') 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) plt.xlim(-1, 3.5);

画出来他的决策边界即可看出宽度

训练一个基本的SVM

from sklearn.svm import SVC # "Support vector classifier"
model = SVC(kernel='linear')
model.fit(X, y)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape=None, degree=3, gamma='auto', kernel='linear',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)

绘图展示

#绘图函数
def plot_svc_decision_function(model, ax=None, plot_support=True):
"""Plot the decision function for a 2D SVC"""
if ax is None:
ax = plt.gca()
xlim = ax.get_xlim()
ylim = ax.get_ylim() # create grid to evaluate model
x = np.linspace(xlim[0], xlim[1], 30)
y = np.linspace(ylim[0], ylim[1], 30)
Y, X = np.meshgrid(y, x)
xy = np.vstack([X.ravel(), Y.ravel()]).T
P = model.decision_function(xy).reshape(X.shape) # plot decision boundary and margins
ax.contour(X, Y, P, colors='k',
levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--']) # plot support vectors
if plot_support:
ax.scatter(model.support_vectors_[:, 0],
model.support_vectors_[:, 1],
s=300, linewidth=1, facecolors='none');
ax.set_xlim(xlim)
ax.set_ylim(ylim)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(model);

这条线就是我们希望得到的决策边界啦

观察发现有3个点做了特殊的标记,它们恰好都是边界上的点

它们就是我们的support vectors(支持向量)

在Scikit-Learn中, 它们存储在 support_vectors_ 属性中

model.support_vectors_
array([[0.44359863, 3.11530945],
[2.33812285, 3.43116792],
[2.06156753, 1.96918596]])

观察可以发现,只需要支持向量我们就可以把模型构建出来

样本密闭程度不同对决策影响

接下来我们尝试一下,用不同多的数据点,看看效果会不会发生变化

分别使用60个和120个数据点

def plot_svm(N=10, ax=None):
X, y = make_blobs(n_samples=200, centers=2,
random_state=0, cluster_std=0.60)
X = X[:N]
y = y[:N]
model = SVC(kernel='linear', C=1E10)
model.fit(X, y) ax = ax or plt.gca()
ax.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
ax.set_xlim(-1, 4)
ax.set_ylim(-1, 6)
plot_svc_decision_function(model, ax) fig, ax = plt.subplots(1, 2, figsize=(16, 6))
fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1)
for axi, N in zip(ax, [60, 120]):
plot_svm(N, axi)
axi.set_title('N = {0}'.format(N))

左边是60个点的结果,右边的是120个点的结果

观察发现,只要支持向量没变,其他的数据怎么加无所谓!

引入核函数的 SVM

对比线性核展示

首先我们先用线性的核来看一下在下面这样比较难的数据集上还能分了吗?

from sklearn.datasets.samples_generator import make_circles
X, y = make_circles(100, factor=.1, noise=.1) # 二维圆形数据 factor 内外圆比例 (0,1) clf = SVC(kernel='linear').fit(X, y) plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(clf, plot_support=False);

可以看出完全分不开的

核变换空间展示原理

相当于将二维的数据引入三维, 然后在新加入的维度中提升位置, 然后在切, 即可以分开了

#加入了新的维度r
from mpl_toolkits import mplot3d
r = np.exp(-(X ** 2).sum(1))
def plot_3D(elev=30, azim=30, X=X, y=y):
ax = plt.subplot(projection='3d')
ax.scatter3D(X[:, 0], X[:, 1], r, c=y, s=50, cmap='autumn')
ax.view_init(elev=elev, azim=azim) # 设置3D视图的角度  一般都为45
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('r') plot_3D(elev=45, azim=45, X=X, y=y)

实际操作 - 引入径向基函数

#加入径向基函数
clf = SVC(kernel='rbf', C=1E6)
clf.fit(X, y)
SVC(C=1000000.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape=None, degree=3, gamma='auto', kernel='rbf',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(clf)
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],
s=300, lw=1, facecolors='none');

调节 SVM 参数 - Soft Margin 问题

C 参数调整

软间隔设置的 C 参数调整

当C趋近于无穷大时:意味着分类严格不能有错误

当C趋近于很小的时:意味着可以有更大的错误容忍

这里将数据的离散程度稍微大一点, 让决策边界的难度更高一些

X, y = make_blobs(n_samples=100, centers=2,
random_state=0, cluster_std=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn');
X, y = make_blobs(n_samples=100, centers=2,
random_state=0, cluster_std=0.8) fig, ax = plt.subplots(1, 2, figsize=(16, 6))
fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1) for axi, C in zip(ax, [10.0, 0.1]):
model = SVC(kernel='linear', C=C).fit(X, y)
axi.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(model, axi)
axi.scatter(model.support_vectors_[:, 0],
model.support_vectors_[:, 1],
s=300, lw=1, facecolors='none');
axi.set_title('C = {0:.1f}'.format(C), size=14)

设定 C 为 10 和 0.1 的时候的对比, 可以看出比较严格的时候, 泛化能力较差

伽玛值参数调整

伽玛值在这里的意义是限制你模型的映射维度, 伽玛值这个参数是只有 SVM 中才有的

越大映射维度越高, 越小则维度越小

维度影响到模型的复杂程度,  越不复杂的模型得出的结果也就越平稳

X, y = make_blobs(n_samples=100, centers=2,
random_state=0, cluster_std=1.1) fig, ax = plt.subplots(1, 2, figsize=(16, 6))
fig.subplots_adjust(left=0.0625, right=0.95, wspace=0.1) for axi, gamma in zip(ax, [10.0, 0.1]):
model = SVC(kernel='rbf', gamma=gamma).fit(X, y)
axi.scatter(X[:, 0], X[:, 1], c=y, s=50, cmap='autumn')
plot_svc_decision_function(model, axi)
axi.scatter(model.support_vectors_[:, 0],
model.support_vectors_[:, 1],
s=300, lw=1, facecolors='none');
axi.set_title('gamma = {0:.1f}'.format(gamma), size=14)

取值依旧是 10 和 0.1

可以看出 10 的时候的决策边界相当的负责且严格

而 0.1 的时候更加柔和平稳, 但是也分错了很多数据点

应用人脸识别实例

数据集

还是个分类任务, 判定人脸是谁, 数据集需要下载, 大概大小在 200M 左右

from sklearn.datasets import fetch_lfw_people
faces = fetch_lfw_people(min_faces_per_person=60)
print(faces.target_names)
print(faces.images.shape)

首先过筛了一遍数据, 少于 60 个的都过滤掉

['Ariel Sharon' 'Colin Powell' 'Donald Rumsfeld' 'George W Bush'
'Gerhard Schroeder' 'Hugo Chavez' 'Junichiro Koizumi' 'Tony Blair']
(1348, 62, 47)

展示数据集内容

fig, ax = plt.subplots(3, 5)
for i, axi in enumerate(ax.flat):
axi.imshow(faces.images[i], cmap='bone')
axi.set(xticks=[], yticks=[],
xlabel=faces.target_names[faces.target[i]])

每个图的大小是 [62×47]

创建 SVM 模型

在这里我们就把每一个像素点当成了一个特征,但是这样特征太多了,用 PCA 降维后创建模型

from sklearn.svm import SVC
#from sklearn.decomposition import RandomizedPCA
from sklearn.decomposition import PCA
from sklearn.pipeline import make_pipeline pca = PCA(n_components=150, whiten=True, random_state=42)
svc = SVC(kernel='rbf', class_weight='balanced')
model = make_pipeline(pca, svc)

切分训练 / 测试集

from sklearn.model_selection import train_test_split
Xtrain, Xtest, ytrain, ytest = train_test_split(faces.data, faces.target,
random_state=40)

选择最佳参数

使用 grid search cross-validation来选择参数

from sklearn.model_selection import GridSearchCV
param_grid = {'svc__C': [1, 5, 10],
'svc__gamma': [0.0001, 0.0005, 0.001]}
grid = GridSearchCV(model, param_grid) %time grid.fit(Xtrain, ytrain)
print(grid.best_params_)
Wall time: 51.5 s
{'svc__C': 5, 'svc__gamma': 0.001}

选出的 C = 5 , gamma = 0.001

预测

model = grid.best_estimator_
yfit = model.predict(Xtest)
yfit.shape
(337,)

画图展示

预测成功的就用黑色, 不成功用 红色表示

fig, ax = plt.subplots(4, 6)
for i, axi in enumerate(ax.flat):
axi.imshow(Xtest[i].reshape(62, 47), cmap='bone')
axi.set(xticks=[], yticks=[])
axi.set_ylabel(faces.target_names[yfit[i]].split()[-1],
color='black' if yfit[i] == ytest[i] else 'red')
fig.suptitle('Predicted Names; Incorrect Labels in Red', size=14);

个人结果展示

详细的对每个人的预测结果展示

from sklearn.metrics import classification_report
print(classification_report(ytest, yfit,
target_names=faces.target_names))
                  precision    recall  f1-score   support

     Ariel Sharon       0.50      0.50      0.50        16
Colin Powell 0.69 0.81 0.75 54
Donald Rumsfeld 0.83 0.85 0.84 34
George W Bush 0.94 0.88 0.91 136
Gerhard Schroeder 0.72 0.85 0.78 27
Hugo Chavez 0.81 0.72 0.76 18
Junichiro Koizumi 0.87 0.87 0.87 15
Tony Blair 0.85 0.76 0.80 37 avg / total 0.83 0.82 0.82 337
  • 精度(precision) = 正确预测的个数(TP)/被预测正确的个数(TP+FP)
  • 召回率(recall)=正确预测的个数(TP)/预测个数(TP+FN)
  • F1 = 2精度召回率/(精度+召回率)

混淆矩阵展示

通过混淆矩阵可以看出那些人容易被认错成什么人

from sklearn.metrics import confusion_matrix
mat = confusion_matrix(ytest, yfit)
sns.heatmap(mat.T, square=True, annot=True, fmt='d', cbar=False,
xticklabels=faces.target_names,
yticklabels=faces.target_names)
plt.xlabel('true label')
plt.ylabel('predicted label');

机器学习 - 算法 - SVM 支持向量机 Py 实现 / 人脸识别案例的更多相关文章

  1. 机器学习 - 算法 - SVM 支持向量机

    SVM 原理引入 支持向量机( SVM,Support Vector Machine ) 背景 2012年前较为火热, 但是在12年后被神经网络逼宫, 由于应用场景以及应用算法的不同, SVM还是需要 ...

  2. 机器学习实战:用nodejs实现人脸识别

    机器学习实战:用nodejs实现人脸识别   在本文中,我将向你展示如何使用face-recognition.js执行可靠的人脸检测和识别 . 我曾经试图找一个能够精确识别人脸的Node.js库,但是 ...

  3. Python3+Dlib实现简单人脸识别案例

    Python3+Dlib实现简单人脸识别案例 写在前边 很早很早之前,当我还是一个傻了吧唧的专科生的时候,我就听说过人脸识别,听说过算法,听说过人工智能,并且也出生牛犊不怕虎般的学习过TensorFl ...

  4. 跟我学算法-svm支持向量机算法推导

    Svm算法又称为支持向量机,是一种有监督的学习分类算法,目的是为了找到两个支持点,用来使得平面到达这两个支持点的距离最近. 通俗的说:找到一条直线,使得离该线最近的点与该线的距离最远. 我使用手写进行 ...

  5. 数学之路(3)-机器学习(3)-机器学习算法-SVM[7]

    SVM是新近出现的强大的数据挖掘工具,它在文本分类.手写文字识别.图像分类.生物序列分析等实际应用中表现出非常好的性能.SVM属于监督学习算法,样本以属性向量的形式提供,所以输入空间是Rn的子集. 图 ...

  6. 机器学习算法 --- SVM (Support Vector Machine)

    一.SVM的简介 SVM(Support Vector Machine,中文名:支持向量机),是一种非常常用的机器学习分类算法,也是在传统机器学习(在以神经网络为主的深度学习出现以前)中一种非常牛X的 ...

  7. 数学之路(3)-机器学习(3)-机器学习算法-SVM[9]

    我们应用SVM的非线性分类功能对手写数字进行识别,我们在这应用poly做为非线性核 svm = mlpy.LibSvm(svm_type='c_svc', kernel_type='poly',gam ...

  8. 跟我学算法-SVM(支持向量机)

    支持向量机是一个点离决策边界越近,离决策面越远的问题 求解的过程主要是通过拉格朗日乘子法,来求解带约束的优化问题,在问题中涉及两个方面,一个是线性的,一个是非线性的,非线性的有 我们平时比较常见的高斯 ...

  9. 数学之路(3)-机器学习(3)-机器学习算法-SVM[5]

    svm小结 1.超平面 两种颜色的点分别代表两个类别,红颜色的线表示一个可行的超平面.在进行分类的时候,我们将数据点  x 代入  f(x)  中,如果得到的结果小于 0 ,则赋予其类别 -1 ,如果 ...

随机推荐

  1. C++——virtual function

    无论是pure virtual还是impure virtual,都允许子类override他.但是真两种方式还是有一点差别,如果是pure virtual,那么父类是十分强烈希望子类override他 ...

  2. 【20191118会议】针对华为云CCE 问题总结

    针对华为云CCE问题总结 如何购买CCE集群 可以分为测试环境和生产环境,针对使用范围进行购买集群. 测试环境 可以进行公用 生产环境建议使用单独集群 尤其针对部门大 耦合性不高 ,生产环境 建议使用 ...

  3. nginx基础概述

    为什么选择nginx     nginx非常轻量     互联网公司都选择nginx nginx技术成熟,具备的功能时企业最常用使用而且最需要的 适合当前主流架构趋势,微服务.云架构.中间层 统一技术 ...

  4. 虚拟dom应用

    vdom如何应用,核心api是什么 1.介绍snabbdom(开源社区用的多,vue2用的是他) 首先回顾下之前的vdom格式 真实的dom <body> <ul id=" ...

  5. Codeforces #366 (Div. 2) D. Ant Man (贪心)

    https://blog.csdn.net/liangzhaoyang1/article/details/52215276  原博客 原来好像是个dp题,不过我看了别人的博客使用贪心做的 复杂度(n^ ...

  6. Jenkins构建自动化--实例一

    1.新建任务 2.配置任务 3.构建任务 5.构建完成后,可以点击任务名称查看结果

  7. keil mdk 菜单 “project” 崩溃问题解决

    今天发现我的 Keil MDK5.28z win10系统上面,点击 Project 菜单立即崩溃.网上找到了解决方法 简单粗暴的处理方法:重装keil ,但是依然点击 project 崩溃. 通过搜索 ...

  8. 怎么才能零基础彻底学会Java

    21世纪进入信息时代,信息科技给人类的生产和生活方式带来了深刻的变革,信息产业已成为推动国家经济发展的主导产业之一,Java编程语言作为含金量极高的一门IT技术,很多人希望从事这个行业,那么想学好Ja ...

  9. 数位DP【模板】

    经典题型 数位 DP 问题往往都是这样的题型,给定一个闭区间 $[l, r]$,让你求这个区间中满足 某种条件 的数的总数. 强烈推荐 OI Wiki——数位DP 例题 BZOJ 1026 题目:wi ...

  10. 学到了林海峰,武沛齐讲的Day16完

    函数嵌套 foo()()() ====  foo()>>>gxr   gxr()>>>wsb    wsb()>>执行wsb函数 lambda   一行 ...