Machine learning for OpenCV 学习笔记 day5

来源:互联网 发布:最新网络术语 编辑:程序博客网 时间:2024/06/04 23:22

支持向量机(SVM)

本章主要解决一下三个问题:

1.怎样使用opencv中的支持向量机

2.SVM决策边界是什么样的,为什么SVM叫最大边界分类器?

3.什么是核方法以为我们如何使用它

SVM的首次应用

首先我们要介绍3个sklearn工具包中的函数:
datasets.make_classification([n_samples, …]):这个函数可以随机产生一个的n分类问题的数据集。强调内容

datasets.make_regression([n_samples, …]):这个函数可以随机产生一个回归问题的数据集。

datasets.make_blobs([n_samples, n_features, …]):这个函数可以产生包含n个符合高斯问题的blobs,用作聚类算法。

生成数据集

我们从简单的二分类着手,首先我们需要产生一个二分类的数据集,假设我们先用100个数据。

from sklearn import datasetsX,y = datasets.make_classification(n_samples=100,n_features=2,n_redundant=0,n_classes=2,random_state=7816)print(X.shape,y.shape)

数据可视化

import matplotlib.pyplot as pltplt.style.use('ggplot')plt.set_cmap('jet')plt.figure(figsize=(10,6))plt.scatter(X[:,0],X[:,1],c=y,s=100)plt.xlabel('x')plt.ylabel('y')

X[:,0]为分类1,X[:,1]为分类2,显示如图:

这里写图片描述

数据集的预处理

我们要讲上面产生的随机数据分成训练集(80%)和测试集(20%)。并且所有的数据X必须是32位的浮点型数,标签为1和-1。

import numpy as npX = X.astype(np.float32)y = y * 2 - 1'''分离数据'''from sklearn import model_selection as msX_train, X_test, y_train, y_test = ms.train_test_split(    X, y, test_size=0.2, random_state=42)

建立支持向量机

在opencv中SVM和其他学习算法一样通过调用方法,被建立,训练,获得最后分数。

import cv2svm = cv2.ml.SVM_create()svm.setKernel(cv2.ml.SVM_LINEAR)'''开始训练'''svm.train(X_train, cv2.ml.ROW_SAMPLE, y_train);'''开始预测'''_, y_pred = svm.predict(X_test)'''用scikit-learn的metrics模块计算准确率'''from sklearn import metricsprint(metrics.accuracy_score(y_test, y_pred))

这里写图片描述
这时我们可以得到80%的准确率。

画出决策线

def plot_decision_boundary(svm, X_test, y_test):    # create a mesh to plot in    h = 0.02  # step size in mesh    x_min, x_max = X_test[:, 0].min() - 1, X_test[:, 0].max() + 1    y_min, y_max = X_test[:, 1].min() - 1, X_test[:, 1].max() + 1    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),                         np.arange(y_min, y_max, h))    X_hypo = np.c_[xx.ravel().astype(np.float32),                   yy.ravel().astype(np.float32)]    _, zz = svm.predict(X_hypo)    zz = zz.reshape(xx.shape)    plt.contourf(xx, yy, zz, cmap=plt.cm.coolwarm, alpha=0.8)    plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test, s=200)plt.figure(figsize=(10, 6))plot_decision_boundary(svm, X_test, y_test)plt.show()

可以得到如下结果:
这里写图片描述

可以看到这条决策线并没有完成的将数据点分离开。

非线性SVM

opencv提供了不同种类的SVM函数供我们使用:
cv2.ml.SVM_LINEAR:这是我们刚才用的产生线性决策线的函数。

cv2.ml.SVM_POLY:这是设置一个多项式决策线的函数(曲线),这个函数有2个参数,相关系数svm.setCoef0(通常设成0)以及svm.setDegree(函数的最高次幂)

cv2.ml.SVM_RBF:这个函数用了高斯函数

cv2.ml.SVM_SIGMOID :这个函数用了sigmoid函数,类似于逻辑斯特回归。

cv2.ml.SVM_INTER:这个函数是opencv3新添加的函数,根据数据直方图的相似性来进行分类。
所以我们可以用一个for循环来遍历这些方法看看实际效果如何:

kernels = [cv2.ml.SVM_LINEAR, cv2.ml.SVM_INTER, cv2.ml.SVM_SIGMOID, cv2.ml.SVM_RBF]'''绘出曲线'''plt.figure(figsize=(14, 8))for idx, kernel in enumerate(kernels):    svm = cv2.ml.SVM_create()    svm.setKernel(kernel)    svm.train(X_train, cv2.ml.ROW_SAMPLE, y_train)    _, y_pred = svm.predict(X_test)    plt.subplot(2, 2, idx + 1)    plot_decision_boundary(svm, X_test, y_test)    plt.title('accuracy = %.2f' % metrics.accuracy_score(y_test, y_pred))

最终结果如下图所示:
这里写图片描述
可以从上图看出:
左上角是SVM唯一一个决策线是直线的核。
右上角给出了稍复杂的决策线,但是并没有改善准确率。
左下角给出来非线性的决策线,准确率变差,只有25%。
右下角的高斯核改善了准确率,是几个中效果最好的。

原创粉丝点击