支持向量机原理

支持向量机要解决的问题其实就是寻求最优分类边界。且最大化支持向量间距,用直线或者平面,分隔分隔超平面。

基于核函数的升维变换

通过名为核函数的特征变换,增加新的特征,使得低维度空间中的线性不可分问题变为高维度空间中的线性可分问题。

线性核函数linear,不通过核函数进行维度提升,仅在原始维度空间中寻求线性分类边界。

基于线性核函数的SVM分类相关API:

import sklearn.svm as svm
model = svm.SVC(kernel='linear')
model.fit(train_x, train_y)

案例:对multiple2.txt中的数据进行分类。

import numpy as np
import sklearn.model_selection as ms
import sklearn.svm as svm
import sklearn.metrics as sm
import matplotlib.pyplot as mp
x, y = [], []
data = np.loadtxt('../data/multiple2.txt', delimiter=',', dtype='f8')
x = data[:, :-1]
y = data[:, -1]
train_x, test_x, train_y, test_y = \
ms.train_test_split(x, y, test_size=0.25, random_state=5)
# 基于线性核函数的支持向量机分类器
model = svm.SVC(kernel='linear')
model.fit(train_x, train_y)
n = 500
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
grid_x = np.meshgrid(np.linspace(l, r, n),
np.linspace(b, t, n))
flat_x = np.column_stack((grid_x[0].ravel(), grid_x[1].ravel()))
flat_y = model.predict(flat_x)
grid_y = flat_y.reshape(grid_x[0].shape)
pred_test_y = model.predict(test_x)
cr = sm.classification_report(test_y, pred_test_y)
print(cr)
mp.figure('SVM Linear Classification', facecolor='lightgray')
mp.title('SVM Linear Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y, cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1], c=test_y, cmap='brg', s=80)
mp.show()

多项式核函数:poly,通过多项式函数增加原始样本特征的高次方幂

$$y = x_1+x_2 \\
y = x_1^2 + 2x_1x_2 + x_2^2 \\
y = x_1^3 + 3x_1^2x_2 + 3x_1x_2^2 + x_2^3$$

案例,基于多项式核函数训练sample2.txt中的样本数据。

# 基于线性核函数的支持向量机分类器
model = svm.SVC(kernel='poly', degree=3)
model.fit(train_x, train_y)

径向基核函数:rbf,通过高斯分布函数增加原始样本特征的分布概率

案例,基于径向基核函数训练sample2.txt中的样本数据。

# 基于径向基核函数的支持向量机分类器
# C:正则强度
# gamma:正态分布曲线的标准差
model = svm.SVC(kernel='rbf', C=600, gamma=0.01)
model.fit(train_x, train_y)

样本类别均衡化

样本类别均衡化:通过类别权重的均衡化,使所占比例较小的样本权重较高,而所占比例较大的样本权重较低,以此平均化不同类别样本对分类模型的贡献,提高模型性能。

样本类别均衡化相关API:

model = svm.SVC(kernel='linear', class_weight='balanced')
model.fit(train_x, train_y)

案例:修改线性核函数的支持向量机案例,基于样本类别均衡化读取imbalance.txt训练模型。

import numpy as np
import sklearn.model_selection as ms
import sklearn.svm as svm
import sklearn.metrics as sm
import matplotlib.pyplot as mp data = np.loadtxt('../machine_learning_date/imbalance.txt', delimiter=',', dtype='f8')
x = data[:, :-1]
y = data[:, -1]
# 选择svm做分类
train_x, test_x, train_y, test_y = ms.train_test_split(x, y, test_size=0.25, random_state=5)
model = svm.SVC(kernel='linear', class_weight='balanced')
# model = svm.SVC(kernel='linear', class_weight={0:10,1:1}) # 0类别权重为10,1类别权重为1.
model.fit(train_x, train_y)
pred_test_y = model.predict(test_x)
print(sm.classification_report(test_y, pred_test_y)) # 绘制分类边界线
n = 500
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
grid_x = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
flat_x = np.column_stack((grid_x[0].ravel(), grid_x[1].ravel()))
flat_y = model.predict(flat_x)
grid_y = flat_y.reshape(grid_x[0].shape) mp.figure('Class Balanced', facecolor='lightgray')
mp.title('Class Balanced', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y, cmap='gray')
mp.scatter(x[:, 0], x[:, 1], c=y, cmap='brg', s=80)
mp.show() # precision recall f1-score support
#
# 0.0 0.29 0.76 0.42 42
# 1.0 0.95 0.70 0.80 258
#
# avg / total 0.86 0.71 0.75 300

置信概率

置信概率:根据样本与分类边界的距离远近,对其预测类别的可信程度进行量化,离边界越近的样本,置信概率越低,反之,离边界越远的样本,置信概率高。

获取每个样本的置信概率相关API:

# 在获取模型时,给出超参数probability=True
model = svm.SVC(kernel='rbf', C=600, gamma=0.01, probability=True)
预测结果 = model.predict(输入样本矩阵)
# 调用model.predict_proba(样本矩阵)可以获取每个样本的置信概率矩阵
置信概率矩阵 = model.predict_proba(输入样本矩阵)

置信概率矩阵格式如下:

  类别1 类别2
样本1 0.8 0.2
样本2 0.9 0.1
样本3 0.5 0.5

案例:修改基于径向基核函数的SVM案例,新增测试样本,输出每个测试样本的执行概率,并给出标注。

# 新增样本
prob_x = np.array([[2, 1.5], [8, 9], [4.8, 5.2], [4, 4], [2.5, 7], [7.6, 2], [5.4, 5.9]])
pred_prob_y = model.predict(prob_x)
probs = model.predict_proba(prob_x)
print(probs)
# [[3.00000090e-14 1.00000000e+00]
# [3.00000090e-14 1.00000000e+00]
# [9.73038186e-01 2.69618143e-02]
# [5.65786038e-01 4.34213962e-01]
# [2.77725531e-03 9.97222745e-01]
# [2.91704904e-11 1.00000000e+00]
# [9.43796673e-01 5.62033274e-02]] # 绘制分类边界线
n = 500
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
grid_x = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
flat_x = np.column_stack((grid_x[0].ravel(), grid_x[1].ravel()))
flat_y = model.predict(flat_x)
grid_y = flat_y.reshape(grid_x[0].shape) mp.figure('Probability', facecolor='lightgray')
mp.title('Probability', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y, cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1], c=test_y, cmap='brg', s=80)
mp.scatter(prob_x[:, 0], prob_x[:, 1], c=pred_prob_y, cmap='jet_r', s=80, marker='D')
# 绘制每个测试样本,并给出标注
for i in range(len(probs)):
mp.annotate(
'{}% {}%'.format(
round(probs[i, 0] * 100, 2),
round(probs[i, 1] * 100, 2)),
xy=(prob_x[i, 0], prob_x[i, 1]),
xytext=(12, -12),
textcoords='offset points',
horizontalalignment='left',
verticalalignment='top',
fontsize=9,
bbox={'boxstyle': 'round,pad=0.6', 'fc': 'orange', 'alpha': 0.8})
mp.show()

网格搜索

获取一个最优超参数的方式可以绘制验证曲线,但是验证曲线只能每次获取一个最优超参数。如果多个超参数有很多排列组合的话,就可以使用网格搜索寻求最优超参数组合。

针对超参数组合列表中的每一个超参数组合,实例化给定的模型,做cv次交叉验证,将其中平均f1得分最高的超参数组合作为最佳选择,实例化模型对象。

网格搜索相关API:

import sklearn.model_selection as ms
model = ms.GridSearchCV(模型, 超参数组合列表, cv=折叠数)
model.fit(输入集,输出集)
# 获取网格搜索每个参数组合
model.cv_results_['params']
# 获取网格搜索每个参数组合所对应的平均测试分值
model.cv_results_['mean_test_score']
# 获取最好的参数
model.best_params_ # 最优超参数组合
model.best_score_ # 最优得分
model.best_estimator_ # 最优模型对象

案例:修改置信概率案例,基于网格搜索得到最优超参数。

import numpy as np
import sklearn.model_selection as ms
import sklearn.svm as svm
import sklearn.metrics as sm
import matplotlib.pyplot as plt data = np.loadtxt('../machine_learning_date/multiple2.txt', delimiter=',', dtype='f8')
x = data[:, :-1]
y = data[:, -1]
# 选择svm做分类
train_x, test_x, train_y, test_y = ms.train_test_split(x, y, test_size=0.25, random_state=5)
model = svm.SVC(probability=True)
# 根据网格搜索选择最优模型
# 整理网格搜索所需要的超参数列表
params = [{'kernel': ['linear'], 'C': [1, 10, 100, 1000]},
{'kernel': ['poly'], 'C': [1], 'degree': [2, 3]},
{'kernel': ['rbf'], 'C': [1, 10, 100, 1000], 'gamma': [1, 0.1, 0.01, 0.001]}]
model = ms.GridSearchCV(model, params, cv=5)
model.fit(train_x, train_y) # 获取得分最优的的超参数信息
print(model.best_params_) # {'C': 1, 'gamma': 1, 'kernel': 'rbf'} # 获取最优得分
print(model.best_score_) # 0.96 # 获取最优模型的信息
print(model.best_estimator_)
# SVC(C=1, cache_size=200, class_weight=None, coef0=0.0,
# decision_function_shape='ovr', degree=3, gamma=1, kernel='rbf',
# max_iter=-1, probability=True, random_state=None, shrinking=True,
# tol=0.001, verbose=False) # 输出每个超参数组合信息及其得分
for param, score in zip(model.cv_results_['params'], model.cv_results_['mean_test_score']):
print(param, '->', score)
# {'C': 1, 'kernel': 'linear'} -> 0.5911111111111111
# {'C': 10, 'kernel': 'linear'} -> 0.5911111111111111
# ...
# ...
# {'C': 1000, 'gamma': 0.01, 'kernel': 'rbf'} -> 0.9555555555555556
# {'C': 1000, 'gamma': 0.001, 'kernel': 'rbf'} -> 0.92 pred_test_y = model.predict(test_x)
print(sm.classification_report(test_y, pred_test_y))
# precision recall f1-score support
# 0.0 0.95 0.93 0.94 45
# 1.0 0.90 0.93 0.92 30
# avg / total 0.93 0.93 0.93 75 # 新增样本
prob_x = np.array([[2, 1.5], [8, 9], [4.8, 5.2], [4, 4], [2.5, 7], [7.6, 2], [5.4, 5.9]])
pred_prob_y = model.predict(prob_x)
probs = model.predict_proba(prob_x) # 获取每个样本的置信概率矩阵
print(probs) # 绘制分类边界线
n = 500
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
grid_x = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
flat_x = np.column_stack((grid_x[0].ravel(), grid_x[1].ravel()))
flat_y = model.predict(flat_x)
grid_y = flat_y.reshape(grid_x[0].shape) plt.figure('Probability')
plt.title('Probability')
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
plt.pcolormesh(grid_x[0], grid_x[1], grid_y, cmap='gray')
plt.scatter(test_x[:, 0], test_x[:, 1], c=test_y, cmap='brg', s=80)
plt.scatter(prob_x[:, 0], prob_x[:, 1], c=pred_prob_y, cmap='jet_r', s=80, marker='D')
for i in range(len(probs)):
plt.annotate('{}% {}%'.format(
round(probs[i, 0] * 100, 2),
round(probs[i, 1] * 100, 2)),
xy=(prob_x[i, 0], prob_x[i, 1]),
xytext=(12, -12),
textcoords='offset points',
horizontalalignment='left',
verticalalignment='top',
fontsize=9,
bbox={'boxstyle': 'round,pad=0.6', 'fc': 'orange', 'alpha': 0.8})
plt.show()

事件预测

加载event.txt,预测某个时间段是否会出现特殊事件。

import numpy as np
import sklearn.preprocessing as sp
import sklearn.model_selection as ms
import sklearn.svm as svm
import sklearn.metrics as sm class DigitEncoder:
# 模拟LabelEncoder编写的数字编码器
# 非数字字符串的特征需要做标签编码,
# 数字字符串的特征需要做转换编码 def fit_transform(self, y):
return y.astype('i4') def transform(self, y):
return y.astype('i4') def inverse_transform(self, y):
return y.astype('str') # 加载并整理数据集
# data = np.load('../machine_learning_date/events.txt', delimiter=",", dtype='U15') data = []
with open('../machine_learning_date/events.txt', 'r') as f:
for line in f.readlines():
data.append(line.split(','))
data = np.array(data)
data = np.delete(data, 1, axis=1)
cols = data.shape[1] # 获取一共有多少列
x, y = [], []
encoders = []
for i in range(cols):
col = data[:, i]
# 判断当前列是否是数字字符串
if col[0].isdigit():
encoder = DigitEncoder()
else:
encoder = sp.LabelEncoder()
# 使用编码器对数据进行编码
if i < cols - 1:
x.append(encoder.fit_transform(col))
else:
y = encoder.fit_transform(col)
encoders.append(encoder) x = np.array(x).T # (5040,4)
y = np.array(y) # (5040,) # 拆分测试集与训练集
train_x, test_x, train_y, test_y = ms.train_test_split(x, y, test_size=0.25, random_state=7) # 构建模型
model = svm.SVC(kernel='rbf', class_weight='balanced')
model.fit(train_x, train_y)
# 测试
pred_test_y = model.predict(test_x)
print(sm.classification_report(test_y, pred_test_y)) # 业务应用
data = [['Tuesday', '13:30:00', '', '']]
data = np.array(data).T
x = []
for row in range(len(data)):
encoder = encoders[row]
x.append(encoder.transform(data[row]))
x = np.array(x).T
pred_y = model.predict(x)
print(encoders[-1].inverse_transform(pred_y)) # ['eventA\n']

交通流量预测(回归)

加载traffic.txt,预测在某个时间段某个交通路口的车流量。

"""车流量预测"""
import numpy as np
import sklearn.preprocessing as sp
import sklearn.model_selection as ms
import sklearn.svm as svm
import sklearn.metrics as sm class DigitEncoder:
def fit_transform(self, y):
return y.astype(int) def transform(self, y):
return y.astype(int) def inverse_transform(self, y):
return y.astype(str) data = []
# 回归
data = np.loadtxt('../machine_learning_date/traffic.txt', delimiter=',', dtype='U20')
data = data.T
encoders, x = [], []
for row in range(len(data)):
if data[row][0].isdigit():
encoder = DigitEncoder()
else:
encoder = sp.LabelEncoder()
if row < len(data) - 1:
x.append(encoder.fit_transform(data[row]))
else:
y = encoder.fit_transform(data[row])
encoders.append(encoder)
x = np.array(x).T
train_x, test_x, train_y, test_y = \
ms.train_test_split(x, y, test_size=0.25, random_state=5)
# 支持向量机回归器
model = svm.SVR(kernel='rbf', C=10, epsilon=0.2)
model.fit(train_x, train_y)
pred_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pred_test_y)) # 0.6379517119380995 # 业务应用
data = [['Tuesday', '13:35', 'San Francisco', 'yes']]
data = np.array(data).T
x = []
for row in range(len(data)):
encoder = encoders[row]
x.append(encoder.transform(data[row]))
x = np.array(x).T
pred_y = model.predict(x)
print(int(pred_y)) #

回归:线性回归、岭回归、多项式回归、决策树、正向激励、随机森林、SVR。

分类:逻辑分类、朴素贝叶斯、决策树、随机森林、SVC。

机器学习——支持向量机(SVM)的更多相关文章

  1. 机器学习——支持向量机SVM

    前言 学习本章节前需要先学习: <机器学习--最优化问题:拉格朗日乘子法.KKT条件以及对偶问题> <机器学习--感知机> 1 摘要: 支持向量机(SVM)是一种二类分类模型, ...

  2. 吴裕雄 python 机器学习——支持向量机SVM非线性分类SVC模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import datasets, linear_model,svm fr ...

  3. 机器学习——支持向量机(SVM)之拉格朗日乘子法,KKT条件以及简化版SMO算法分析

    SVM有很多实现,现在只关注其中最流行的一种实现,即序列最小优化(Sequential Minimal Optimization,SMO)算法,然后介绍如何使用一种核函数(kernel)的方式将SVM ...

  4. coursera机器学习-支持向量机SVM

    #对coursera上Andrew Ng老师开的机器学习课程的笔记和心得: #注:此笔记是我自己认为本节课里比较重要.难理解或容易忘记的内容并做了些补充,并非是课堂详细笔记和要点: #标记为<补 ...

  5. 机器学习-支持向量机SVM

    简介: 支持向量机(SVM)是一种二分类的监督学习模型,他的基本模型是定义在特征空间上的间隔最大的线性模型.他与感知机的区别是,感知机只要找到可以将数据正确划分的超平面即可,而SVM需要找到间隔最大的 ...

  6. 机器学习支持向量机SVM笔记

    SVM简述: SVM是一个线性二类分类器,当然通过选取特定的核函数也可也建立一个非线性支持向量机.SVM也可以做一些回归任务,但是它预测的时效性不是太长,他通过训练只能预测比较近的数据变化,至于再往后 ...

  7. 机器学习——支持向量机(SVM)之核函数(kernel)

    对于线性不可分的数据集,可以利用核函数(kernel)将数据转换成易于分类器理解的形式. 如下图,如果在x轴和y轴构成的坐标系中插入直线进行分类的话, 不能得到理想的结果,或许我们可以对圆中的数据进行 ...

  8. 机器学习——支持向量机(SVM)之Platt SMO算法

    Platt SMO算法是通过一个外循环来选择第一个alpha值的,并且其选择过程会在两种方式之间进行交替: 一种方式是在所有数据集上进行单遍扫描,另一种方式则是在非边界alpha中实现单遍扫描. 所谓 ...

  9. 机器学习:Python中如何使用支持向量机(SVM)算法

    (简单介绍一下支持向量机,详细介绍尤其是算法过程可以查阅其他资) 在机器学习领域,支持向量机SVM(Support Vector Machine)是一个有监督的学习模型,通常用来进行模式识别.分类(异 ...

随机推荐

  1. java并发编程(十九)----(JUC集合)总体框架介绍

    本节我们将继续学习JUC包中的集合类,我们知道jdk中本身自带了一套非线程安全的集合类,我们先温习一下java集合包里面的集合类,然后系统的看一下JUC包里面的集合类到底有什么不同. java集合类 ...

  2. 记我的一次 Java 服务性能优化

    背景 前段时间我们的服务遇到了性能瓶颈,由于前期需求太急没有注意这方面的优化,到了要还技术债的时候就非常痛苦了. 在很低的 QPS 压力下服务器 load 就能达到 10-20,CPU 使用率 60% ...

  3. pythonday01计算机初步认识

    1.计算机的初步认识 常见的操作系统: win:xp,win7,win8,win10,windows server linux:centos图形化界面差,ubuntu个人开发,图形界面好,redhat ...

  4. (十七)c#Winform自定义控件-基类窗体

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  5. unsqueeze 和 squeeze

    squeeze压缩的意思 就是在第几维为1 去掉 unsqueeze 解缩 在第几维增加 变成*1 squeeze用法 c = b.view(1, 1, 1, 2, 3) c.squeeze(0) # ...

  6. 大白话5分钟带你走进人工智能-第35节神经网络之sklearn中的MLP实战(3)

    本节的话我们开始讲解sklearn里面的实战: 先看下代码: from sklearn.neural_network import MLPClassifier X = [[0, 0], [1, 1]] ...

  7. maven学习(1)下载和安装和初步使用(手动构建项目和自动构建项目)

    1:背景 关于项目的搭建,有些人使用开发工具搭建项目,然后将项目所依赖第三方jar 复制到类路径下面,上述搭建方式没有第三方类库的依赖关系,在导入一个jar包的时候,这个jar包还可能依赖其他jar包 ...

  8. ‎Cocos2d-x 学习笔记(21) ScrollView (CCScrollView)

    1. 简介 CCScrollView.cpp文件内的滚动视图ScrollView直接继承了Layer+ActionTweenDelegate. 滚动视图能在屏幕区域内,用户通过触摸拖动屏幕,实现大于屏 ...

  9. property修饰关键字

    修饰符按作用区分:线程安全相关,内存相关,读写权限相关,set=和get=,是否可为空, class 一.默认值 @property NSArray *dataArray; 默认的是:atomic,s ...

  10. 剑指Offer(十八):二叉树的镜像

    剑指Offer(十八):二叉树的镜像 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu ...