在ks上训练集和测试集相差不大,但在auc上却相差较大,这是为啥?

2020-08-03 10:34发布

6条回答
卡卡
2楼 · 2020-08-03 16:51



转载自这篇文章



本文结构:

学习曲线是什么?怎么解读?怎么画?

学习曲线是什么?


学习曲线就是通过画出不同训练集大小时训练集和交叉验证的准确率,可以看到模型在新数据上的表现,进而来判断模型是否方差偏高或偏差过高,以及增大训练集是否可以减小过拟合。


怎么解读?




当训练集和测试集的误差收敛但却很高时,为高偏差。 

左上角的偏差很高,训练集和验证集的准确率都很低,很可能是欠拟合。 

我们可以增加模型参数,比如,构建更多的特征,减小正则项。 

此时通过增加数据量是不起作用的。


当训练集和测试集的误差之间有大的差距时,为高方差。 

当训练集的准确率比其他独立数据集上的测试结果的准确率要高时,一般都是过拟合。 

右上角方差很高,训练集和验证集的准确率相差太多,应该是过拟合。 

我们可以增大训练集,降低模型复杂度,增大正则项,或者通过特征选择减少特征数。


理想情况是是找到偏差和方差都很小的情况,即收敛且误差较小。


怎么画?


在画学习曲线时,横轴为训练样本的数量,纵轴为准确率。




例如同样的问题,左图为我们用 naiveBayes 分类器时,效果不太好,分数大约收敛在0.85,此时增加数据对效果没有帮助。


右图为 SVM(RBFkernel),训练集的准确率很高,验证集的也随着数据量增加而增加,不过因为训练集的还是高于验证集的,有点过拟合,所以还是需要增加数据量,这时增加数据会对效果有帮助。


上图的代码如下:


模型这里用GaussianNB和SVC做比较, 

模型选择方法中需要用到learning_curve和交叉验证方法ShuffleSplit。

importnumpyasnp

importmatplotlib.pyplotasplt


fromsklearn.naive_bayesimportGaussianNB

fromsklearn.svmimportSVC


fromsklearn.datasetsimportload_digits

fromsklearn.model_selectionimportlearning_curve

fromsklearn.model_selectionimportShuffleSplit123456789123456789

首先定义画出学习曲线的方法, 

核心就是调用了sklearn.model_selection的learning_curve, 

学习曲线返回的是train_sizes,train_scores,test_scores, 

画训练集的曲线时,横轴为train_sizes,纵轴为train_scores_mean, 

画测试集的曲线时,横轴为train_sizes,纵轴为test_scores_mean:

defplot_learning_curve(estimator,title,X,y,ylim=None,cv=None,

n_jobs=1,train_sizes=np.linspace(.1,1.0,5)):

~~~

train_sizes,train_scores,test_scores=learning_curve(

estimator,X,y,cv=cv,n_jobs=n_jobs,train_sizes=train_sizes)

train_scores_mean=np.mean(train_scores,axis=1)

test_scores_mean=np.mean(test_scores,axis=1)

~~~1234567812345678

在调用plot_learning_curve时,首先定义交叉验证cv和学习模型estimator。


这里交叉验证用的是ShuffleSplit,它首先将样例打散,并随机取20%的数据作为测试集,这样取出100次,最后返回的是train_index,test_index,就知道哪些数据是train,哪些数据是test。


estimator用的是GaussianNB,对应左图:

cv=ShuffleSplit(n_splits=100,test_size=0.2,random_state=0)

estimator=GaussianNB()

plot_learning_curve(estimator,title,X,y,ylim=(0.7,1.01),cv=cv,n_jobs=4)123123

再看estimator是SVC的时候,对应右图:

cv=ShuffleSplit(n_splits=10,test_size=0.2,random_state=0)

estimator=SVC(gamma=0.001)

plot_learning_curve(estimator,title,X,y,(0.7,1.01),cv=cv,n_jobs=4)123123

资料: http://scikit-learn.org/stable/modules/learning_curve.html#learning-curve http://scikit-learn.org/stable/auto_examples/model_selection/plot_learning_curve.html#sphx-glr-auto-examples-model-selection-plot-learning-curve-py


推荐阅读 历史技术博文链接汇总 

也许可以找到你想要的



曾为
3楼 · 2020-09-28 09:15



一、ROC曲线和AUC值

在逻辑回归、随机森林、GBDT、XGBoost这些模型中,模型训练完成之后,每个样本都会获得对应的两个概率值,一个是样本为正样本的概率,一个是样本为负样本的概率。把每个样本为正样本的概率取出来,进行排序,然后选定一个阈值,将大于这个阈值的样本判定为正样本,小于阈值的样本判定为负样本,然后可以得到两个值,一个是真正率,一个是假正率。

真正率即判定为正样本且实际为正样本的样本数/所有的正样本数,假正率为判定为正样本实际为负样本的样本数/所有的负样本数。每选定一个阈值,就能得到一对真正率和假正率,由于判定为正样本的概率值区间为[0,1],那么阈值必然在这个区间内选择,因此在此区间内不停地选择不同的阈值,重复这个过程,就能得到一系列的真正率和假正率,以这两个序列作为横纵坐标,即可得到ROC曲线了。而ROC曲线下方的面积,即为AUC值。









image



二、KS曲线

K-S曲线其实数据来源和本质和ROC曲线是一致的,只是ROC曲线是把真正率和假正率当作横纵轴,而K-S曲线是把真正率和假正率都当作是纵轴,横轴则由选定的阈值来充当。

KS(Kolmogorov-Smirnov):KS用于模型风险区分能力进行评估,指标衡量的是好坏样本累计分部之间的差值。好坏样本累计差异越大,KS指标越大,那么模型的风险区分能力越强。

KS的计算步骤如下:

计算每个评分区间的好坏账户数。计算每个评分区间的累计好账户数占总好账户数比率(good%)和累计坏账户数占总坏账户数比率(bad%)。计算每个评分区间累计坏账户占比与累计好账户占比差的绝对值(累计good%-累计bad%),然后对这些绝对值取最大值即得此评分卡的KS值。









image



三、AUC和KS的关系

要弄明白ks值和auc值的关系首先要弄懂roc曲线和ks曲线是怎么画出来的。其实从某个角度上来讲ROC曲线和KS曲线是一回事,只是横纵坐标的取法不同而已。拿逻辑回归举例,模型训练完成之后每个样本都会得到一个类概率值(注意是类似的类),把样本按这个类概率值排序后分成10等份,每一份单独计算它的真正率和假正率,然后计算累计概率值,用真正率和假正率的累计做为坐标画出来的就是ROC曲线,用10等分做为横坐标,用真正率和假正率的累计值分别做为纵坐标就得到两个曲线,这就是KS曲线。AUC值就是ROC曲线下放的面积值,而ks值就是ks曲线中两条曲线之间的最大间隔距离。

ROC值一般在0.5-1.0之间。值越大表示模型判断准确性越高,即越接近1越好。ROC=0.5表示模型的预测能力与随机结果没有差别。KS值表示了模型将+和-区分开来的能力。值越大,模型的预测准确性越好。一般,KS>0.2即可认为模型有比较好的预测准确性。KS值一般是很难达到0.6的,在0.2~0.6之间都不错。一般如果是如果负样本对业务影响极大,那么区分度肯定就很重要,此时K-S比AUC更合适用作模型评估,如果没什么特别的影响,那么用AUC就很好了。

四、混淆矩阵


查准率(准确率):在被识别为正类别的样本中,确实为正类别的比例是多少?查全率(召回率):在所有正类别样本中,被正确识别为正类别的比例是多少?










image



查准率和查全率的计算









image



查准率和查全率是一对矛盾的度量。一般来说,查准率高时,查全率往往偏低;而查全率高时,查准率往往偏低。例如,若希望将好瓜尽可能多地选出来(查全率高),则可通过增加选瓜的数量来实现,如果将所有西瓜都选上,那么所有的好瓜也必然都被选上了,但这样查准率就会较低;若希望选出的瓜中好瓜比例尽可能高(查准率高),则可只挑选最有把握的瓜,但这样就难免会漏掉不少好瓜,使得查全率较低。

五、P-R曲线

根据样例是正例的可能性进行排序,排在前面的是学习器认为"最可能“是正例的样本,排在最后的则是学习器认为"最不可能"是正例的样本。这样,分类过程就相当于在这个排序中以某个"截断点”(cutpoint)将样本分为两部分,前一部分判作正例,后一部分则判作反例。

这个截断点就相当于阈值(threshold),设置不同的threshold计算出当前的查全率、查准率。即根据不同threshold来绘制曲线,曲线A上的每个点都对应不同的阈值。A,B,C是三个学习器,也可以说是三个模型。









image



如何度量学习器性能?

若一个学习器的P-R曲线被另一个学习器的曲线完全包住,则后者的性能优于前者,A优于C若两个学习器的P-R曲线相交,则可根据平衡点和F1度量。

(1)平衡点(Break-eventPoint,简称BEP):即查全率=查准率时的取值。平衡点取值A>B,即A优于B(2)F1度量

Fl是基于查准率与查全率的调和平均(harinonicmean)定义的:









image



六、模型稳定度指标PSI

群体稳定性指标PSI(PopulationStabilityIndex)是衡量模型的预测值与实际值偏差大小的指标。









image



举例:

比如训练一个logistic回归模型,预测时候会有个概率输出p。测试集上的输出设定为p1吧,将它从小到大排序后10等分,如0-0.1,0.1-0.2,......。现在用这个模型去对新的样本进行预测,预测结果叫p2,按p1的区间也划分为10等分。实际占比就是p2上在各区间的用户占比,预期占比就是p1上各区间的用户占比。

意义就是如果模型跟稳定,那么p1和p2上各区间的用户应该是相近的,占比不会变动很大,也就是预测出来的概率不会差距很大。一般认为PSI小于0.1时候模型稳定性很高,0.1-0.25一般,大于0.25模型稳定性差,建议重做。

PS:除了按概率值大小等距十等分外,还可以对概率排序后按数量十等分,两种方法计算得到的psi可能有所区别但数值相差不大。



征戰撩四汸
4楼 · 2021-09-15 17:12

1. 构建测试集时的数据分布跟实际预测所使用的数据分布差别较大。比如产品有了新的用户群体,行为发生了较大变化。

2. 测试集用来进行了model selection,导致模型在测试集上过拟合。

3. 实际预测中的feature engineering pipeline跟验证集测试集中的出现了不一致,导致了数据上的bug。

4. 验证集测试集数据量过小,指标置信度低。




回答: 2021-11-03 14:37

如果train auc 和test auc 差距比较大,有可能是欠拟合了,不是说模型那种特别欠拟合,只是没有拟合那么完美,可以让模型更好的拟合,


可以通过画学习曲线 能看出一点


解决方案:


一:看看是不是特征有问题,特征过少,增加特征,或者做特征多项式特征


二:调模型参数让模型更好的拟合


三:减少正则化参数(因为正则化是解决过拟合的)


小新没有蜡笔
5楼 · 2021-09-18 14:22

特征分布不同

验证集和真实的测试集之间的特征分布不同。总结了一下,特征分布不同主要有几种典型的问题:


  • 特征构造:特征穿越是其中重要的一种情况。在训练模型时特别是时间序列相关的模型,我们会有很多和时间相关的统计特征。如过去7天某个资源的点击率,此时一定要保证生成特征所用的数据是在这条样本发生之前的。特征穿越往往会导致线下效果很好,但是在线上效果会很差,而且随着时间的推移,模型的效果会持续变差。

  • 特征分布:特征分布不同对效果影响很大。特别是在时序相关的问题中,有些特征随着时间的推移,分布发生了很大的变化。此时模型更适合训练集的特征分布,自然会导致预测的效果很差。解决这个办法,关键还是要看特征的业务含义,是否能够通过一些特征变换使分布保持一致。


freediandianer
6楼 · 2021-10-21 13:30

1.换个更大的数据集

2.根据特征分布细致一些划分数据集

3.Pseudo-labeling建模


希希
7楼 · 2021-10-30 16:15

ROC曲线和AUC值

在逻辑回归、随机森林、GBDT、XGBoost这些模型中,模型训练完成之后,每个样本都会获得对应的两个概率值,一个是样本为正样本的概率,一个是样本为负样本的概率。把每个样本为正样本的概率取出来,进行排序,然后选定一个阈值,将大于这个阈值的样本判定为正样本,小于阈值的样本判定为负样本,然后可以得到两个值,一个是真正率,一个是假正率。

真正率即判定为正样本且实际为正样本的样本数/所有的正样本数,假正率为判定为正样本实际为负样本的样本数/所有的负样本数。每选定一个阈值,就能得到一对真正率和假正率,由于判定为正样本的概率值区间为[0,1],那么阈值必然在这个区间内选择,因此在此区间内不停地选择不同的阈值,重复这个过程,就能得到一系列的真正率和假正率,以这两个序列作为横纵坐标,即可得到ROC曲线了。而ROC曲线下方的面积,即为AUC值。




相关问题推荐

  • 回答 3

    换行。比如,print hello\nworld效果就是helloworld\n就是一个换行符。\是转义的意思,'\n'是换行,'\t'是tab,'\\'是,\ 是在编写程序中句子太长百,人为换行后加上\但print出来是一整行。...

  • 回答 42

    十种常见排序算法一般分为以下几种:(1)非线性时间比较类排序:a. 交换类排序(快速排序、冒泡排序)b. 插入类排序(简单插入排序、希尔排序)c. 选择类排序(简单选择排序、堆排序)d. 归并排序(二路归并排序、多路归并排序)(2)线性时间非比较类排序:...

  • 回答 70
    已采纳

    前景很好,中国正在产业升级,工业机器人和人工智能方面都会是强烈的热点,而且正好是在3~5年以后的时间。难度,肯定高,要求你有创新的思维能力,高数中的微积分、数列等等必须得非常好,软件编程(基础的应用最广泛的语言:C/C++)必须得很好,微电子(数字电...

  • 回答 28

    迭代器与生成器的区别:(1)生成器:生成器本质上就是一个函数,它记住了上一次返回时在函数体中的位置。对生成器函数的第二次(或第n次)调用,跳转到函数上一次挂起的位置。而且记录了程序执行的上下文。生成器不仅记住了它的数据状态,生成器还记住了程序...

  • 回答 9

    python中title( )属于python中字符串函数,返回’标题化‘的字符串,就是单词的开头为大写,其余为小写

  • 回答 6

    第一种解释:代码中的cnt是count的简称,一种电脑计算机内部的数学函数的名字,在Excel办公软件中计算参数列表中的数字项的个数;在数据库( sq| server或者access )中可以用来统计符合条件的数据条数。函数COUNT在计数时,将把数值型的数字计算进去;但是...

  • 回答 1

    head是方法,所以需要取小括号,即dataset.head()显示的则是前5行。data[:, :-1]和data[:, -1]。另外,如果想通过位置取数据,请使用iloc,即dataset.iloc[:, :-1]和dataset.iloc[:, -1],前者表示的是取所有行,但不包括最后一列的数据,结果是个DataFrame。...

  • Python入门简单吗2021-09-23 13:21
    回答 45

    挺简单的,其实课程内容没有我们想象的那么难、像我之前同学,完全零基础,培训了半年,直接出来就工作了,人家还在北京大公司上班,一个月15k,实力老厉害了

  • 回答 4

    Python针对众多的类型,提供了众多的内建函数来处理(内建是相对于导入import来说的,后面学习到包package时,将会介绍),这些内建函数功用在于其往往可对多种类型对象进行类似的操作,即多种类型对象的共有的操作;如果某种操作只对特殊的某一类对象可行,Pyt...

  • 回答 8

     相当于 ... 这里不是注释

  • 回答 4

    还有FIXME

  • 回答 3

    python的两个库:xlrd和xlutils。 xlrd打开excel,但是打开的excel并不能直接写入数据,需要用xlutils主要是复制一份出来,实现后续的写入功能。

  • 回答 8

    单行注释:Python中的单行注释一般是以#开头的,#右边的文字都会被当做解释说明的内容,不会被当做执行的程序。为了保证代码的可读性,一般会在#后面加一两个空格然后在编写解释内容。示例:#  单行注释print(hello world)注释可以放在代码上面也可以放在代...

  • 回答 2

    主要是按行读取,然后就是写出判断逻辑来勘测行是否为注视行,空行,编码行其他的:import linecachefile=open('3_2.txt','r')linecount=len(file.readlines())linecache.getline('3_2.txt',linecount)这样做的过程中发现一个问题,...

  • 回答 4

    或许是里面有没被注释的代码

  • 回答 26

    自学的话要看个人情况,可以先在B站找一下视频看一下

没有解决我的问题,去提问