训练集/测试集同分布检验_wangjian8976的博客-程序员宅基地

技术标签: python代码  

在数据挖掘比赛中,很重要的一个技巧就是要确定训练集与测试集特征是否同分布,这也是机器学习的一个很重要的假设。但很多时候我们知道这个道理,却很难有方法来保证数据同分布。除了KS检验、overlap rate、KL散度、KDE核密度估计外,对抗验证Adversarial validation是利用机器学习模型去检测分布是否一致
在这里插入图片描述

1. KS检验

KS是一种非参数检验方法,可以在不知道数据具体分布的情况下检验两个数据分布是否一致。当然这样方便的代价就是当检验的数据分布符合特定的分布事,KS检验的灵敏度没有相应的检验来的高。在样本量比较小的时候,KS检验作为非参数检验在分析两组数据之间是否不同时相当常用。

举个例子,对于数据集 {1.26, 0.34, 0.70, 1.75, 50.57, 1.55, 0.08, 0.42, 0.50, 3.20, 0.15, 0.49, 0.95, 0.24, 1.37, 0.17, 6.98, 0.10, 0.94, 0.38},先对其排序为 {0.08, 0.10, 0.15, 0.17, 0.24, 0.34, 0.38, 0.42, 0.49, 0.50, 0.70, 0.94, 0.95, 1.26, 1.37, 1.55, 1.75, 3.20, 6.98, 50.57}。其中比0.24小的一共有4个,占数据集的 1/5,所以0.24的累积分布值是0.2,依次类推我们可以画出累积分布图。
image

对于累积分布图取Log变换

image

通过两个数据的累积分布图直接最大垂直距离描述两数据的差异

image

实际操作可以直接调用Python scipy库中封装好的函数

from scipy.stats import ks_2samp
ks_2samp(train[col],test[col]).pvalue

ks检验一般返回两个值:D和p值
其中D表示两个分布之间的最大距离,所以D越小,因为这两个分布的差距越小,分布也就越一致
p值,也就是假设检验里面的p值,那么原假设是什么呢,原假设是“待检验的两个分布式同分布”,如果p值大于0.05(当然,你也可以选择0.01或者0.10,这都取决于你的要求),那么就不能拒绝原假设。所以p越大,越不能拒绝原假设,两个分布越是同分布.
从以上可以看出,D值小和p值大,并不矛盾

2. overlap rate

https://zhuanlan.zhihu.com/p/82435050

对于类别型变量检验同分布,我们可以对其进行编码然后KS检测,或者选择通过特征重合率来进行检测,通过特征重合率检测的思想是检测训练集特征在测试集中出现的比率,举个例子:

训练集特征:[猫,狗,狗,猫,狗,狗,狗,猫] 
测试集特征:[猫,猫,鱼,猪,鱼,鱼,猪,猪]

即使该特征在训练集表现很好,但在测试集上的用处并不大,因为重合率仅有1/4,反而会导致过拟合或者模型忽略到其他更有用的特征。
image

这个信息非常重要,通过这个观察取值个数,取值交叉,我么去判断一个特征的有用性,上述表可以看出

1- idfamd5极低特征交叉数几乎就是一个垃圾的特征了,因为训练集邮359个取值,而测试集则只有2个取值,训练集合测试集相同的取值只有一个而这个取值是empty。。。等于说两者没有交叉的取值,所以这个基本就是一个废特征;

2- adidmd5极低特征交叉率几乎又是一个垃圾的特征了,20%多的训练测试分别交叉,这样的类别特征如果不处理绝对有猫腻,要么过拟合,要么过拟合,有什么处理?要么不交叉的全部取nan,毕竟树模型在分裂的时候一般是往最优方向去分裂的;但是…nan过多,每次都最优分裂,可能也会过拟合?所以另一种可能方式是赋值 ‘-9999’,这个作用则是用来避免每个样本都去单独对待,而是在同一个维度上这个特征这些取值有了统一的特质;

3. KL散度

https://www.jianshu.com/p/43318a3dc715

KL 散度是一种衡量两个概率分布的匹配程度的指标,两个分布差异越大,KL散度越大。注意如果要查看测试集特征是否与训练集相同,P代表训练集,Q代表测试集,这个公式对于P和Q并不是对称的。
在这里插入图片描述

4. KDE 核密度估计

https://blog.csdn.net/pipisorry/article/details/53635895

KDE核密度估计,看起来好像是统计学里面一个高端的非参数估计方法。大概就是通过一个核函数把一个频率分布直方图搞成平滑的了。

在这里插入图片描述

一般都是这么用的,从seaborn中找到KDE plot这个方法,然后把测试集和训练集的特征画出来,看看图像不像,不像的直接扔了就行。

>>> import numpy as np; np.random.seed(10)
>>> import seaborn as sns; sns.set(color_codes=True)
>>> mean, cov = [0, 2], [(1, .5), (.5, 1)]
>>> x, y = np.random.multivariate_normal(mean, cov, size=50).T
>>> ax = sns.kdeplot(x)

5. 对抗验证Adversarial validation

对抗验证是模型验证的一种,通常,我们在训练模型的时候,不会将所有的数据用于训练,而是留出部分数据(验证集)用于评估模型的效果,这样做可以一定程度减少过拟合,经常会使用的到的交叉验证有:留出法 (holdout cross validation),k 折交叉验证(k-fold cross validation)。对其中的留出法作简单举例说明:

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

以上为留出法,留出20%作为验证集。

什么是对抗验证?对抗验证是什么?怎么用?如何实现?

对抗验证,通常是在发现在训练集上模型表现得非常好,AUC非常高,此时如果采用k-fold交叉验证,模型在验证集上却表现非常糟糕。一种可能性就是训练集与测试集相差非常大。就如同许多数据科学竞赛都面临着测试集与训练集明显不同的问题(这违反了“相同分布”的假设)。因此很难建立一个具有代表性的验证集。

对抗验证,选择与测试样本最相似的训练样本,并将其作为验证集。这个方法的核心思想是训练一个分类器来区分训练/测试样本。相反,理想情况下,来自同一分布的训练和测试样本,验证误差就可以很好地估计测试误差,分类器就可以很好地泛化到未发现的测试样本。

此时,你心里肯定有很多疑问,比如,这样选择的话,那岂不是过度拟合测试集了吗?

对抗验证在训练集和测试集分布“不同”的情况下,它做的选择是,宁可过拟合和测试集最相似的训练样本(用于验证),也不去过拟合那些与测试集相去甚远的样本,通过这个方法降低模型的置信度,从而降低AUC。

这么做会达到什么目的呢?这样做的结果是,我模型训练的效果可以与模型测试的效果相匹配,降低模型训练表现特别好,而测试时一团糟的情况。

实现步骤:

1.合并训练集和测试集,并且将训练集和测试集的标签分别设置为0和1;

2.构建一个分类器(CNN,RNN或者决策树等),用于学习the different between testing and training data;

3.观察AUC,理想的状况是在0.5左右(0.5说明训练集与测试集基本是同分布的,AUC越高说明训练集与测试集有很大分别)。

4.找到训练集中与测试集最相似的样本(most resemble data),作为验证集,其余的作为训练集;

5.构建一个用于训练的模型(CNN,RNN或者决策树等);

由此,我们用训练好的二分类模型对训练集进行预测,然后输出预测概率,根据这个概率为训练集设置权重(概率越接近1代表训练集分布更接近测试集),这样就可以强行过拟合到测试集上!对于非线上测试型的数据挖掘比赛应该会有比较大的提升!

Kaggle Adversarial validation
Adversarial Validation example for VSB Power Line Fault Detection
fastml

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/wangjian8976/article/details/113989063

智能推荐

【python爬虫】校园网的自动登录脚本+python+request_python 校园网自动登录_mmciel的博客-程序员宅基地

利用python爬虫实现对校园网的自动登录文章目录利用python爬虫实现对校园网的自动登录摘要准备工作思路实现步骤1. 浏览器的动作分析2. 核心代码的实现3.存储用户名密码便于下次直接使用4.小细节5.打包成exe6.关于更新微信公众号内回复关键字:’‘校园网’’ 获得下载地址摘要​ 本文介绍了如何利用python爬虫实现对zzuli校园网的自动登录。主要利用requests包,通过模..._python 校园网自动登录

【编程】C++入门:static成员——用static修饰的成员函数,称之为静态成员函数。_成员函数用static修饰_IUN_2930的博客-程序员宅基地

C++入门:static成员用static修饰的成员函数,称之为静态成员函数。静态的成员变量一定要在类外进行初始化。【静态的成员变量不能在声明、初始化列表中进行初始化。】class Date{public: // 静态成员函数 static int getdcount() { return _dcount; }private: int _year; int _month; int _day; static int _dcount;};// 静态的成员变量一定要在类_成员函数用static修饰

控制面板设置小数点和数字分组符合后容易引起的bug_muum2的博客-程序员宅基地

先了解一下通过CultureInfo.CurrentUICulture和CultureInfo.InvariantCulture与控制面板设置的关系 控制面板设置如图 public partial class Form1 : Form { public Form1() { System.Globalization.Cul...

静态方法和属性可以被继承吗?_静态函数可以继承吗_Java成长记_Camel的博客-程序员宅基地

结论:静态方法和属性可以被继承,但是不能被重写。我们将结论延伸一下:我们知道,类的是由成员变量和方法组成的,成员变量代表类的属性,而方法则代表类的行为。而具体根据静态与否,可以分为1.静态的成员变量2.非静态的成员变量3.静态的方法4.非静态的方法下边给出延伸的结论:上述的四种成员变量和方法,只有非静态的方法可以被继承并且被重写(override)而另外的三种,静态的成员变量/..._静态函数可以继承吗

王者荣耀全皮肤爬虫diamond_肤质爬_卧关的博客-程序员宅基地

危莫危于任疑。宋·张商英(世上的)危险没有比任用自己怀疑的人更危险的了。**用鼠标华开桌面创建王者荣耀文件夹 **import osimport requestsurl = 'https://pvp.qq.com/web201605/js/herolist.json'herolist = requests.get(url) herolist_json = herolist.json() hero_name = list(map(lambda x: x['cname'], herolis_肤质爬

docker同时部署mysql 5.7和mysql8.0踩坑_服务器docker上安装了mysql5.7电脑上还可以安装mysql8.0吗_仗剑天涯3334的博客-程序员宅基地

1. 启动mysql 8并进入容器内,执行登录,提示:bash: msyql: command not found解决:5.7可正常登录,尝试解决中_服务器docker上安装了mysql5.7电脑上还可以安装mysql8.0吗

随便推点

echarts4 统计图表几种样板_echarts家庭数据统计模板_jianeng_Love_IT的博客-程序员宅基地

先看效果图!直接上代码! <!DOCTYPE html"><html lang="zh-CN"><head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=Edge"> <script type="..._echarts家庭数据统计模板

CNN--卷积神经网络从R-CNN到Faster R-CNN的理解_dil1523的博客-程序员宅基地

1. 什么是CNN卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一。我..._r-cnn采用了卷积神经网络(convolutional neural networks, cnn)来自动学¥¥征

laravel修改.env不生效原因以及解决办法_weixin_34204057的博客-程序员宅基地

为什么80%的码农都做不了架构师?>>> ..._laravel 环境变量不生效

Navicat导入导出csv文件_江畔独步的博客-程序员宅基地

今日需要对一个CSV文件中的某几列,进行汇总统计(如按照省,市分组统计),文件行数在270万左右,想到在数据库中进行分组汇总统计,效率比较高。用的是MySQL数据库,刚好手头上客户端软件Navicat支持[b]大部分常用文件类型[/b]的导入导出。现将CSV类型的导入导出记录如下。一、导入。首先在mysql中创建一张表,表中字段为CSV文件中的全部列,或其中的若干列..._navicat导出csv数据分隔符

微信PC端同时登陆两个或者多个 微信双开 微信多开操作_微信客户端多开登录界面 site:blog.csdn.net_月小满的博客-程序员宅基地

1.首页找到微信目标位置:可在微信快捷键上右击-属性-目标位置 比如:“D:\Program Files (x86)\Tencent\WeChat\WeChat.exe”2.打开记事本写入:@echo offstart /d "D:\Program Files (x86)\Tencent\WeChat\" WeChat.exestart /d "D:\Program Files (x86)\Tencent\WeChat\" WeChat.exeexittips:希望打开几个微信 就写几_微信客户端多开登录界面 site:blog.csdn.net

推荐文章

热门文章

相关标签