我们继续学习一些其他的细节

一:样本均衡问题
我们来看看在SVM中样本不均衡的情况
比如两个样本集合的数目严重不对等,我们希望模型更能识别出少数样本,比如银行贷款,预测某人会不会抵赖,我们更希望能预测出抵赖的人,防止损失吧,大多数人是不会抵赖的,递来的人就是少数。
在这样的分布下,即便我们什么都不做,全部预测是不会抵赖,那么模型的准确度也是很高的,这样是没有任何意义,我们需要重点关注的是那部分少数的样本。

我们用class_weight来改变样本的分布权重比例。
同时我们也可以用sample_weight来改变每个样本的权重比例。

我们用代码来模拟下这个过程,第一步构建出样本不均衡的数据集。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.datasets import make_blobs# ===== 第一步:构造一个样本不均衡的数据集合例子
x, y = make_blobs(n_samples=[500, 50],  # 两个簇,每个簇的样本个数分别就是元素值centers=[[2, 2], [4, 4]],  # 指定两个簇的中心cluster_std=[1.5, 0.5],  # 指定方差n_features=2,  # 样本特征是2random_state=0,shuffle=False)
print(x.shape)
print(y.shape)
plt.scatter(x[:, 0], x[:, 1], c=y, cmap='rainbow', s=10)
plt.show()

两类样本存在数据样本不均衡的现象,且有交叉重叠部分。

第二步:建立两个SVC模型,一个是不带有权重调整的,一个是有权重调整的。

# ===== 第二步:在样本不均衡的数据上进行建模
# 没有处理样本不均衡的,也就是没有设置class_weight的
svc1 = SVC(kernel='linear', C=1.0)
svc1.fit(x, y)
print(svc1.score(x, y))# 处理样本不均衡的,也就是设置class_weight的
svc2 = SVC(kernel='linear', C=1.0, class_weight={1: 10})
svc2.fit(x, y)
print(svc2.score(x, y))

输出如下:
0.9418181818181818
0.9127272727272727
可见,带有权重的话,精确度会下降,这是为什么呢?我们画出决策边界来看看。

# ===== 第三步:将SVC的决策边界画出来
plt.figure(figsize=(6, 5))
plt.scatter(x[:, 0], x[:, 1], c=y, cmap='rainbow', s=10)  # 先把样本所在的散点图画出来
ax = plt.gca()  # 获取当前画布的子图对象# 获取网格
xlim = ax.get_xlim()  # 获取x轴范围
ylim = ax.get_ylim()  # 获取y轴范围xx = np.linspace(xlim[0], xlim[1], 30)  # x轴范围平均分成30份
yy = np.linspace(ylim[0], ylim[1], 30)  # y轴范围平均分成30份YY, XX = np.meshgrid(yy, xx)  # 行成了30x30个网点,网点2 横坐标和纵坐标都在,分别用YY和XX表示了
xy = np.vstack([XX.ravel(), YY.ravel()]).T
print(xy.shape)  # 把900个点行成一个数组,放在了一起,用一个变量保存了。z_svc1 = svc1.decision_function(xy).reshape(XX.shape)  # 找到决策边界,根据决策函数,计算所有网点的值
a = ax.contour(XX, YY, z_svc1, colors='black', levels=[0], alpha=0.5, linestyles=['-'])  # levels=0表示只画距离是0的z_svc2 = svc2.decision_function(xy).reshape(XX.shape)  # 找到决策边界,根据决策函数,计算所有网点的值
b = ax.contour(XX, YY, z_svc2, colors='red', levels=[0], alpha=0.5, linestyles=['-'])  # levels=0表示只画距离是0的plt.legend([a.collections[0], b.collections[0]], ['non-weighted', 'weighted'], loc='upper right')  # 画出图例
plt.show()

我们能看到,没有经过类别权重调整的虽然精确度高,但是将少数样本拦腰截断了,对少数样本预测能力低下,但是对多数类别的样本的误差低;
经过class_weight调整的能够把少数类别样本全部分类正确,但是又误杀了一大堆多数类别样本,这就导致了准确率整体变低。

如果我们要追求总体准确率,那么不需要样本均衡,如果我们需要特别关注少数类的话,因为有时候把一个误差类分类错要比把一个多数类分类错的代价要惨痛的多啊。宁可多杀一个好人也不要错放一个坏人的这种保险思想。

比如银行贷款,潜在犯罪者,再比如新冠疫情下,宁愿相信你是疑似,高风险地区/境外回来需要集中隔离,都不能漏掉一个人传播病毒。一旦少数样本被分错,所带来的损失和代价将是巨大的。而将多数类别判断错误,顶多我们就是增加一些人为干预措施进行人为纠正排查和识别,这样的代价是可以接受的。

但是从另外的角度来看,如果我们一味追求少数类的识别正确,而把大量的多数类分类错误,这就会造成另外个问题,比如增加人为干预,成本上升,而且还带来了自己的收益反而下降了的情况,比如银行因为模型把正常客户分类错误了,就会拒绝很多交易,从而失去利润,人为增加人工排查成本也会增加。汽车召回事件,如果为了召回所有不符合标准的汽车,而把一些原本符合标准的汽车也召回,这将直接带来代价成本的提升。

因此,单纯的追求捕获少数类就会丧失一些利益和增加成本,但是不顾及少数的话,模型将失去意义,因此我们要在捕获少数的能力和将多数判断错误之间找到一个代价的平衡。
如果一个模型能在尽量鞥捕获少数类的情况下还能尽量对多数类判断正确,这就是很优秀了啊,我们需要混淆矩阵和ROC曲线来帮我们进行评估。

混淆矩阵就是:

体现在代码中就是:

A1 = (y[y == svc1.predict(x)] == 1).sum()  # 预测值是1,真实值是1。
B1 = (y[y != svc1.predict(x)] == 1).sum()  # 预测值是0,真实值是1。
C1 = (y[y != svc1.predict(x)] == 0).sum()  # 预测值是1,真实值是0。
D1 = (y[y == svc1.predict(x)] == 0).sum()  # 预测值是0,真实值是0。A2 = (y[y == svc2.predict(x)] == 1).sum()  # 预测值是1,真实值是1。
B2 = (y[y != svc2.predict(x)] == 1).sum()  # 预测值是0,真实值是1。
C2 = (y[y != svc2.predict(x)] == 0).sum()  # 预测值是1,真实值是0。
D2 = (y[y == svc2.predict(x)] == 0).sum()  # 预测值是0,真实值是0。

我们再混淆矩阵中一般有6个评估指标
1:准确率

就是预测正确的样本除以样本总数,月接近于1越好。这个值就是svc,score(x,y)的值。

# 1:准确度
accuracy1 = (A1 + D1) / (A1 + B1 + C1 + D1)
print('不带均衡的分类器的准确率是:%f' % accuracy1)
accuracy2 = (A2 + D2) / (A2 + B2 + C2 + D2)
print('带均衡的分类器的准确率是:%f' % accuracy2)

输出是:
不带均衡的分类器的准确率是:0.941818
带均衡的分类器的准确率是:0.912727
和svc.score(x,y)是一样的。样本均衡后的模型的准确率略低。

2:精确度(precision)

又叫做查准率,表示所有预测为少数的样本中,真正为少数的样本的比例。也是把多数类盘判别错后付出成本的度量。这个数值越高,表示我们越精确捕获到少数类,这个数值越低,表示我们误伤了很多多数类。

# 2:精确度
precision1 = A1 / (A1 + C1)
print('不带均衡的分类器的精确率是:%f' % precision1)
precision2 = A2 / (A2 + C2)
print('带均衡的分类器的精确率是:%f' % precision2)

输出是:
不带均衡的分类器的精确率是:0.714286
带均衡的分类器的精确率是:0.510204
样本均衡后的模型的精确度也低,原因就是误伤了很多多数类。

3:召回率(Recall)

又称为敏感度,真正率,查全率,所有真实值是1的样本中被我们预测正确的样本所占的比例。这个值越高,表示我们捕获出了越多的少数类。召回率越低,代表我们没有捕获出足够的少数类。

# 3:召回率
Recall1 = A1 / (A1 + B1)
print('不带均衡的分类器的召回率是:%f' % Recall1)
Recall2 = A2 / (A2 + B2)
print('带均衡的分类器的召回率是:%f' % Recall2)

输出是:
不带均衡的分类器的召回率是:0.600000
带均衡的分类器的召回率是:1.000000
可见,少数样本被全部捕获了。

由此引申出的一个叫做假负率(False negative rate)的指标:

4:F1 measure
为了兼顾精确率和召回率,我们提出了一个新的综合性指标。

F1-measure的取值凡是【0,1】,越接近于1越好,能保证我们精确度和召回率都很高。

# F1 measure
F1M1 = (2 * precision1 * Recall1) / (precision1 + Recall1)
print('不带均衡的分类器的F1-measure是:%f' % F1M1)
F1M2 = (2 * precision2 * Recall2) / (precision2 + Recall2)
print('不带均衡的分类器的F1-measure是:%f' % F1M2)

输出是:
不带均衡的分类器的F1-measure是:0.652174
带均衡的分类器的F1-measure是:0.675676
综合一下,带有权重的F1指标要高一些。

5:特异度
所有真实为0的样本中,被正确预测为0的样本所占比例。

# 5:特异度
specificity1 = D1 / (C1 + D1)
print('不带均衡的分类器的精确率是:%f' % specificity1)
specificity2 = D2 / (C2 + D2)
print('带均衡的分类器的精确率是:%f' % specificity2)

输出是:
不带均衡的分类器的精确率是:0.976000
带均衡的分类器的精确率是:0.904000

由此引申出的一个叫做假正率(False positive rate)的指标:

在scikit-learn中,有专门辅助类帮我们得到上面的值。
sklearn.metrics.confusion_matrix 混淆矩阵
sklearn.metrics.accuracy_score 准确率
sklearn.metrics.precision_score 精确率
sklearn.metrics.recall_score 召回率
sklearn.metrics.f1_score f1 measure
sklearn.metrics. precision_recall_curve 精确度-召回率曲线,可以展示不同阈值下的精确度召回率曲线。

《scikit-learn》SVM(二)数据不均衡相关推荐

  1. 机器学习与Scikit Learn学习库

    摘要: 本文介绍机器学习相关的学习库Scikit Learn,包含其安装及具体识别手写体数字案例,适合机器学习初学者入门Scikit Learn. 在我科研的时候,机器学习(ML)是计算机科学领域中最 ...

  2. python笔迹识别_python_基于Scikit learn库中KNN,SVM算法的笔迹识别

    之前我们用自己写KNN算法[网址]识别了MNIST手写识别数据 [数据下载地址] 这里介绍,如何运用Scikit learn库中的KNN,SVM算法进行笔迹识别. 数据说明: 数据共有785列,第一列 ...

  3. 矢量切片_数据粒度均衡的二维矢量瓦片构建方法

    作 者 信 息 应 申1,2,王子豪1,杜志强3,丁火平4, 李翔翔4 (1. 武汉大学 资源与环境科学学院,湖北 武汉 430079:2. 自然资源部城市国土资源监测与仿真重点实验室,广东 深圳 5 ...

  4. Scikit Learn: 在python中机器学习

    Warning 警告:有些没能理解的句子,我以自己的理解意译. 翻译自:Scikit Learn:Machine Learning in Python 作者: Fabian Pedregosa, Ga ...

  5. [转载]Scikit Learn: 在python中机器学习

    原址:http://my.oschina.net/u/175377/blog/84420 目录[-] Scikit Learn: 在python中机器学习 载入示例数据 一个改变数据集大小的示例:数码 ...

  6. scikit - learn 做文本分类

    文章来源: https://my.oschina.net/u/175377/blog/84420 Scikit Learn: 在python中机器学习 Warning 警告:有些没能理解的句子,我以自 ...

  7. 【Nginx那些事】nginx配置实例(二)负载均衡

    [Nginx那些事]系列 [Nginx那些事]nginx 安装及常用指令 [Nginx那些事]Nginx 配置文件说明 [Nginx那些事]nginx原理解析 [Nginx那些事]nginx配置实例( ...

  8. 如何解决回归任务数据不均衡的问题?

    摘要:现有的处理不平衡数据/长尾分布的方法绝大多数都是针对分类问题,而回归问题中出现的数据不均衡问题确极少被研究. 本文分享自华为云社区<如何解决回归任务数据不均衡的问题?>,原文作者:P ...

  9. python样本不均衡_三招提拔数据不均衡模子的机能(附python代码)

    对付深度进修而言,数据集异常主要,但在实践名目中,或多或少会遇见数据不均衡题目.甚么是数据不均衡呢?举例来说,目前有一个义务是判定西瓜是不是成熟,这是一个二分类题目--西瓜是生的照旧熟的,该义务的数据 ...

最新文章

  1. 免费网络学术资源获取
  2. C专家编程--读书笔记六 运行时数据结构
  3. 纯原生仿ES6的Object.assign,实现深度合并对象
  4. 将数据库表导入到solr索引
  5. SAP License:SAP生产订单中的统计指标运用
  6. 【视频分享】尚硅谷Java视频教程_SpringBoot视频教程
  7. 常忘知识点二-混合器
  8. c语言录制,C语言中如何录制屏幕
  9. 网安必备技能||操作系统中间件安全加固手册(附下载地址)
  10. vip.163邮箱登录指南,163vip邮箱体验分享
  11. Fabrie:PPT有风险,设计师请停用
  12. python基础 -34- 面向对象(动态生成一个类)
  13. 数学符号的意义总结(未完待续)
  14. 2021-2027全球与中国健身俱乐部和健身房管理软件市场现状及未来发展趋势
  15. 离散数学期末考试必考知识点
  16. var _ HelloServiceInterface = (*HelloServiceClient)(nil)的特殊含义
  17. 手把手教你实现聚光灯效果
  18. 软件设计师 资料 下载
  19. rabbit mq Consumer Acknowledgements and Publisher Confirms 翻译
  20. 坑爹的卓越亚马逊盗版网上书店

热门文章

  1. nm 命令 程序符号信息查看
  2. 通过sharepoint 客户脚本,验证列表添加页面上的时间
  3. OEA 中 WPF 树型表格虚拟化设计方案
  4. 清空邮件队列中的邮件
  5. 樱桃小丸子-每集标题
  6. 编写vbs脚本发送邮件
  7. 入门代码教程第六节 如何:使用客户端
  8. TypeScript 基础类型 1
  9. Nginx限制连接数和下载速度
  10. Spring 框架教程