分类器不确定度估计,监督学习算法小结

我们之前用到的所有机器学习的算法均来自于scikit—learn库,但是这个接口还有另一个用处,就是能够给出分类器预测结果的不确定性估计。有的时候,我们不仅要关心一个测试数据点究竟属于哪个类别,还要考虑这个预测的置信区间。譬如,在最近新冠疫情中出现的无症状感染,如果是假阳性预测,那么可能只会让患者接受额外的测试,但是如果是假阴性感染却有可能导致患者没有得到治疗。机器学习的大部分算法均是建立在概率统计的基础上的,而概率等于99.9%却并不意味着事件一定会发生。

scikit—learn中有两个函数可用于获取分类器的不确定估计:decision_function和predict_proba。大多数分类器都至少有其中一个函数,很多分类器两个都有。接下来我们找一个数据集来构造一个梯度提升回归树的分类器。(这个算法之前有讲过,不了解的小伙伴可以跳转到相应的文章去了解下。)

数据来源

星星分类:https://www.kaggle.com/brsdincer/star-type-classification

在这里插入图片描述
这个数据集并不大,只有240条数据记录,其中包括表面温度,颜色等特征,一共有6种星星(0-5),而我们所需要做的就是通过这些特征值来对星星(Type)进行分类。

数据挖掘

1.导入第三方库并读取文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd
import numpy as np
import winreg
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier#梯度提升回归树
from sklearn.metrics import accuracy_score
###################
real_address = winreg.OpenKey(winreg.HKEY_CURRENT_USER,r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders',)
file_address=winreg.QueryValueEx(real_address, "Desktop")[0]
file_address+='\\'
file_origin=file_address+"\\源数据-分析\\Stars.csv"###https://www.kaggle.com/brsdincer/star-type-classification
stars=pd.read_csv(file_origin)
#设立桌面绝对路径,读取源数据文件,这样将数据直接下载到桌面上就可以了,省得还要去找
###################

老规矩,上来先依次导入建模需要的各个模块,并读取文件。

2.清洗数据

查找缺失值:

在这里插入图片描述

从上面的结果来看,数据中没有缺失值。但是数据中除了数字之外,还包括字符串,如果直接用字符串建模的话会报错,所以接下来我用数字依次替代字符串,代码如下所示:

1
2
3
4
for i in ["Color","Spectral_Class"]:
a=list(set(stars[i]))
for m in range(len(a)):
stars.loc[stars[i]==a[m],i]=m

在这里插入图片描述

好的,那么接下来我们开始构建模型。

3.建模

1
2
train=stars.drop(["Type"],axis=1)
X_train,X_test,y_train,y_test=train_test_split(train,stars["Type"],random_state=1)

划分列索引为特征值和预测值,并将数据划分成训练集和测试集。

1
2
3
4
gbcf=GradientBoostingClassifier(random_state=1)
gbcf.fit(X_train,y_train)
print("梯度提升回归树训练模型评分:"+str(accuracy_score(y_train,gbcf.predict(X_train))))
print("梯度提升回归树待测模型评分:"+str(accuracy_score(y_test,gbcf.predict(X_test))))

引入梯度提升决策树算法,并且让算法中的参数保持默认值就好。进行建模后,对测试集进行精度评分,得到的结果如下:

在这里插入图片描述

可以看到,该模型的精度为96%左右。当然,接下来我们还可以通过调参,来提高模型精度,不过本文主要讲解不确定度的问题,所以调参这部分就暂时先不讲了,有兴趣的朋友可以去决策树集成-梯度提升回归树之分类实操看一下

不确定度估计

decision_function

对于多分类的情况,decision_function的形状为(n_samples,n_classes),每一列对应每个类别的“确定度分数”,分数较高的类别可能性更大,得分较低的类别可能性较小,代码及结果如下所示:

在这里插入图片描述

这里我们只看前5个数据点,可以看到每一个用中括号包括起来的一行就是一个数据点在6个分类中的得分,分数越高,属于该类别的概率就越高。譬如,第一行:“[-10.22462681, -10.21235435, -10.24571233, -10.00954012,7.89471131, -10.32103418]”中第五个数值最高,所以第一个数据点属于类别4的星星概率最高。

当然,我们还可以利用argmax找出每个数据点的最大元素,以及这些元素所对应的索引,从而利用这些分数再现预测结果,代码及结果如下所示:

在这里插入图片描述

这一串数字就代表每个数据点所对应的类别,可以看到前五个数据分别属于类别4,1,2,3,4。

predict_proba

与decision_function不同,predict_proba的输出是每个类别的概率,通常比decision_function更容易理解。同时它的输出形状也是(n_samples,n_classes)。

在这里插入图片描述

如上图所示,每行的第一个元素是第一个类别的估计概率,第二个元素是第二个类别的估计概率,依次类推。由于predict_proba的输出是一个概率,因此总是在0到1之间,元素之和始终为1。由于概率之和为1,因此只要有一个类别的概率超过50%,那么这个类别就是模型的预测结果。(ps:由于概率是浮点数,所以二分类问题中不太可能有两个0.5000,但是如果出现了这种情况,那么预测的结果就是随机的。)

同样地,我们可以通过计算predict_proba的argmax来再现预测结果,结果如下所示:

在这里插入图片描述

一般情况下,如果你想要对比predict的结果与predict_proba或decision_function的结果,那么我们可以考虑用分类器的classes_属性来获取真实的属性名称:

在这里插入图片描述

这里可以看出gbcf的6种分类类别的真实名称0,1,2,3,4,5。(说实话在这个数据集选取的并不好,因为是以数字来当作分类类别的,不太容易区分。)

监督学习算法小结

时间过得很快,三个多月前我开始接触机器学习,并且开始坚持一周学习一个算法,找其它数据练手,并且写下文章来记录。到目前为止,一些基础的监督学习算法已经全部完结了。接下来,我们来对这些算法做一个简单地总结,并附上链接,方便及时复习:

最近邻k邻近算法分类k邻近算法回归
适用于小型数据集,是很好的基准模型,很容易解释。

线性模型最小二乘法岭回归lasso回归LogisticRegression算法
非常可靠的首选算法,适用于非常大的数据集,也适用于高维数据。

朴素贝叶斯朴素贝叶斯分类器
只适用于分类问题。比线性模型速度还快,适用于非常大的数据集和高维数据。精度通常要低于线性模型。

决策树决策树算法之讲解实操(上)决策树算法之讲解实操(下)
速度很快,不需要数据缩放,可以进行可视化,很容易解释。

随机森林决策树集成-随机森林之分类实操
几乎总是比单棵决策树的表现要好,鲁棒性很好,非常强大。不需要数据缩放。不适用于高维稀疏数据。

梯度提升决策树决策树集成-梯度提升回归树之分类实操
精度通常比随机森林略高。与随机森林相比,训练速度更慢,但预测速度更快,需要的内存也更少。比随机森林需要更多的参数调节。

支持向量机支持向量机(SVM)补充说明
对于特征含义相似的中等大小的数据集很强大。需要数据缩放,对参数敏感。

神经网络神经网络(深度学习)算法之分类实操
可以构建非常复杂的模型,特别是对于大型数据集而言。对数据缩放敏感,对参数选取敏感。大型网络需要很长的训练时间

我们之前有讨论了模型复杂度,然后讨论了泛化,或者说学习一个能够在前所未见的新数据上表现良好的模型。这就引出了欠拟合过拟合的概念,前者是指一个模型无法获取数据中的所有变化,后者是指模型过分关注训练数据,但对新数据的泛化性能不好。

在我们讨论了一系列用于分类和回归的机器学习模型之后,就会发现对于许多算法而言,设置正确的参数对模型性能至关重要。有些算法还对输入数据的表示方式很敏感,特别是特征的缩放。因此,如果盲目地将一个算法应用于数据集,而不去理解模型所做的假设以及参数设定的含义,不太可能会得到精度高的模型。

通常我们在面对新数据集的时候,最好先从简单的模型开始,比如线性模型,朴素贝叶斯或最近临分类器,看看能得到什么效果。在对数据有了进一步的了解之后,我们再进一步考虑用于构建更复杂模型的算法,比如随机森林,梯度提升决策树,SVM或神经网络。

学习分享

其实在日常生活中,博主很喜欢逛知乎,当时决定要转行学习数据分析之前,也是到知乎,论坛上找了很多资料,然后看了很多人提问题,比如说“数据分析的发展前景怎么样?”,“学数据分析需要看什么书?”,“有没有大佬说一下课程推荐,或者是学习计划?”,甚至还有“学数据分析要不要买台好一点的电脑?”这样的问题。而截至到今天我已经学习了3个多月了,每周坚持更新一篇博文,然后等到我今天再去逛知乎,论坛的时候,发现当时在问类似问题的人,现在还在问这些问题,而并没有开始行动。虽然我并不知道那些人是不是营销号,但我希望他们是。希望看到这篇文章的人可以先做再说。

最后我有一句话送给打算努力或者正在努力的人,这句话也是我目前学习的动力之一,那就是:
“心不妥协,行不受限,德智之高,莫若于知行合一。”

与君共勉