构建分类模型
1 收集数据并选择合适的特征
本次使用我们比较熟悉的鸢尾花数据集。
鸢尾花数据集一共包含5个变量,其中4个特征变量,1个目标分类变量。共有150个样本,目标变量为 花的类别 其都属于鸢尾属下的三个亚属,分别是山鸢尾 (Iris-setosa),变色鸢尾(Iris-versicolor)和维吉尼亚鸢尾(Iris-virginica)。包含的三种鸢尾花的四个特征,分别是花萼长度(cm)、花萼宽度(cm)、花瓣长度(cm)、花瓣宽度(cm),这些形态特征在过去被用来识别物种。
变量 | 描述 |
---|---|
sepal length | 花萼长度(cm) |
sepal width | 花萼宽度(cm) |
petal length | 花瓣长度(cm) |
petal width | 花瓣宽度(cm) |
target 鸢尾的三个亚属类别
类别 | 数量 |
---|---|
‘setosa’(0) | 50 |
‘versicolor’(1) | 50 |
‘virginica’(2) | 50 |
## 进行简单的数据查看,我们可以利用 .head() 头部.tail()尾部
iris_features.head()
## 对于特征进行一些统计描述
iris_features.describe()
## 特征与标签组合的散点可视化
sns.pairplot(data=iris_all,diag_kind='hist', hue= 'target')
plt.show()
2 选择模型性能的度量指标
首先来了解下对分类结果进行评价的指标:
- 真阳性TP:预测值和真实值都为正例;
- 真阴性TN:预测值和真实值都为负例;
- 假阳性FP:预测值为正,实际值为负;
- 假阴性FN:预测值为负,实际值为正。
基于这四个对分类结果的评价指标,有一下几种常用的分类模型评价指标:
- 准确率ACC:分类正确的样本占总样本的比例, A C C = T P + T N T P + T N + F P + F N ACC=\frac{TP+TN}{TP+TN+FP+FN} ACC=TP+TN+FP+FNTP+TN
- 精度PRC:预测为正且分类正确的样本占预测值为正的比例, P R C = T P T P + F P PRC=\frac{TP}{TP+FP} PRC=TP+FPTP
- 召回率REC:预测为正且分类正确的样本占类别正的比例, R E C = T P T P + F N REC=\frac{TP}{TP+FN} REC=TP+FNTP
- F1值:综合衡量精度和召回率, F 1 = 2 P R E × R E C P R E + R E C F1=2\frac{PRE\times REC}{PRE+REC} F1=2PRE+RECPRE×REC
- ROC曲线:以假阳率为横轴,真阳率为纵轴画出的曲线,曲线下方面积越大越好(又称为感受性曲线,是因为曲线上各点反映着相同的感受性,它们都是对同一信号刺激的反应,只不过是在几种不同的判定标准下所得的结果而已。ROC曲线描述的其实是分类器性能随着分类器阈值的变化而变化的过程)面积越接近于1识别能力越强,面积等于1为完全识别。
- AUC曲线:ROC曲线下与坐标轴围成的面积,由于ROC曲线一般都处于y=x这条直线的上方,所以AUC的取值范围在0.5和1之间。
3 选择具体的模型
3.1 逻辑回归模型
3.1.1 逻辑回归原理
逻辑回归(Logistic regression,简称LR),虽然其中带有"回归"两个字,但逻辑回归其实是一个分类模型。主要用于两分类问题(即输出只有两种,分别代表两个类别),所以利用了Logistic函数(或称为Sigmoid函数),函数形式为:
l
o
g
i
(
z
)
=
1
1
+
e
−
z
.
logi(z) = \frac{ 1 }{1+e^{-z}}\,.
logi(z)=1+e−z1.
其图像为:
由图像可知,当z=0时,logi(z)=0.5。
而回归的基本方程为:
$ 𝑧 = 𝑤_{0}+\sum_{i}^{N} w_{i}\dot x_{i} $
那么当z>0时,p>0.5,分类为1。当z<0时,p<0.5,分类为0。
对于模型的训练而言:实质上来说就是利用数据求解出对应的模型的特定的 𝑤 。从而得到一个针对于当前数据的特征逻辑回归模型。而对于多分类而言,将多个二分类的逻辑回归组合,即可实现多分类。
对于逻辑回归而言,最为突出的两点就是其模型简单和模型的可解释性强。逻辑回归模型的优劣势:
优点:实现简单,易于理解和实现;计算代价不高,速度很快,存储资源低;
缺点:容易欠拟合,分类精度可能不高
3.1.2 逻辑回归应用
逻辑回归模型现在同样是很多分类算法的基础组件,比如 分类任务中基于GBDT算法+LR逻辑回归实现的信用卡交易反欺诈,CTR(点击通过率)预估等,其好处在于输出值自然地落在0到1之间,并且有概率意义。模型清晰,有对应的概率学理论基础。它拟合出来的参数就代表了每一个特征(feature)对结果的影响。也是一个理解数据的好工具。但同时由于其本质上是一个线性的分类器,所以不能应对较为复杂的数据情况。很多时候我们也会拿逻辑回归模型去做一些任务尝试的基线(基础水平)。
3.1.3 代码演示
首先导入基本库和数据集,并查看数据集信息
## 基础函数库
import numpy as np
import pandas as pd
## 绘图函数库
import matplotlib.pyplot as plt
import seaborn as sns
## 我们利用 sklearn 中自带的 iris 数据作为数据载入,并利用Pandas转化为DataFrame格式
from sklearn.datasets import load_iris
data = load_iris() #得到数据特征
iris_target = data.target #得到数据对应的标签
iris_features = pd.DataFrame(data=data.data, columns=data.feature_names) #利用Pandas转化为DataFrame格式
## 利用.info()查看数据的整体信息
iris_features.info()
## 进行简单的数据查看,我们可以利用 .head() 头部.tail()尾部
iris_features.head()
iris_features.tail()
导入数据成功后为数据分配训练集和测试集,以进行训练和测试,80%训练,20%测试
## 为了正确评估模型性能,将数据划分为训练集和测试集,在训练集上训练模型,在测试集上验证模型性能。
from sklearn.model_selection import train_test_split
## 选择其类别为0和1的样本 (不包括类别为2的样本)(前50个为0类,中间50为1类)
iris_features_part = iris_features.iloc[:100]
iris_target_part = iris_target[:100]
## 测试集大小为20%, 80%/20%分
x_train, x_test, y_train, y_test = train_test_split(iris_features_part, iris_target_part, test_size = 0.2, random_state = 2020)
接下来就是训练模型
## 从sklearn中导入逻辑回归模型
from sklearn.linear_model import LogisticRegression
## 定义 逻辑回归模型
clf = LogisticRegression(random_state=0, solver='lbfgs')
# 在训练集上训练逻辑回归模型
clf.fit(x_train, y_train)
## 查看其对应的w
print('the weight of Logistic Regression:',clf.coef_)
## 查看其对应的w0
print('the intercept(w0) of Logistic Regression:',clf.intercept_)
训练后利用训练得到的模型进行评估
## 在训练集和测试集上分布利用训练好的模型进行预测
train_predict = clf.predict(x_train)
test_predict = clf.predict(x_test)
## 利用accuracy(准确度)【预测正确的样本数目占总预测样本数目的比例】评估模型效果
# 打印训练准确率
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_train,train_predict))
# 打印测试准确率
print('The accuracy of the Logistic Regression is:',metrics.accuracy_score(y_test,test_predict))
## 查看混淆矩阵 (预测值和真实值的各类情况统计矩阵)
confusion_matrix_result = metrics.confusion_matrix(test_predict,y_test)
print('The confusion matrix result:\n',confusion_matrix_result)
# 利用热力图对于结果进行可视化
plt.figure(figsize=(8, 6))
sns.heatmap(confusion_matrix_result, annot=True, cmap='Blues')
plt.xlabel('Predicted labels')
plt.ylabel('True labels')
plt.show()
The accuracy of the Logistic Regression is: 1.0
The accuracy of the Logistic Regression is: 1.0
The confusion matrix result:
[[ 9 0]
[ 0 11]]
3.2 基于概率的分类模型
3.2.1 线性判别分析(LDA)
LDA的思想可以用一句话概括,就是“投影后类内方差最小,类间方差最大”。
我们要将数据在低维度上进行投影,投影后希望每一种类别数据的投影点尽可能的接近,而不同类别的数据的类别中心之间的距离尽可能的大。即:将数据投影到维度更低的空间中,使得投影后的点,会形成按类别区分,一簇一簇的情况,相同类别的点,将会在投影后的空间中更接近方法。
协方差不仅反映变量之间的相关性,同样反映多维样本分布的离散程度(一维样本使用方差),协方差越大(对于负相关来说是绝对值越大),表示数据的分布越分散。所以上面的“欲使同类样例的投影点尽可能接近,可以让同类样本点的协方差矩阵尽可能小”就可以理解为如下:
J
(
w
)
=
w
T
∣
μ
1
−
μ
2
∣
2
s
1
2
+
s
2
2
J(w)=\frac{w^T|\mu_1 - \mu_2^~|^2}{s^2_1+s^2_2}
J(w)=s12+s22wT∣μ1−μ2 ∣2
分子为投影数据后的均值只差,分母为方差之后,LDA的目的就是使得
J
J
J值最大化,那么可以理解为最大化分子,即使得类别之间的距离越远,同时最小化分母,使得每个类别内部的方差越小,这样就能使得每个类类别的数据可以在投影矩阵
w
w
w的映射下,分的越开。
3.2.2 朴素贝叶斯
可以参考我的另一篇博客朴素贝叶斯
3.3 决策树
决策树的核心思想是基于树结构对数据进行划分。构建决策树的伪代码为:
输入:训练集
D
=
{
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
…
,
(
x
n
,
y
n
)
}
D=\{(x_1,y_1),(x_2,y_2),\dots,(x_n,y_n)\}
D={(x1,y1),(x2,y2),…,(xn,yn)}
特征集
A
=
{
a
1
,
a
2
,
…
,
a
d
}
A=\{a_1,a_2,\dots,a_d\}
A={a1,a2,…,ad}
输出:以node为根节点的一颗决策树
过程:
函数
T
r
e
e
G
e
n
e
r
a
t
e
(
D
,
A
)
TreeGenerate(D, A)
TreeGenerate(D,A)
- 生成节点node
- i f if if D D D中样本全为一类 C C C, t h e n then then
- ----将node标记为 C C C类叶节点; r e t u r n return return
- i f if if A = ∅ A=\varnothing A=∅或者 D D D中样本在 A A A上取值相同, t h e n then then
- ----将node标记为叶节点,类别标记为 D D D中类别最多的一类; r e t u r n return return
- 从 A A A中选择最优划分属性 a ∗ a_* a∗
- f o r for for a ∗ a_* a∗的每一个值 a ∗ v a_*^v a∗v:
- ----为node生成一个分支,令 D v D_v Dv表示 D D D在 a ∗ a_* a∗上取值为 a ∗ v a_*^v a∗v的样本子集
- ---- i f if if D v D_v Dv为空, t h e n then then
- --------将分支节点标记为叶节点,其类别标记为 D D D中样本最多的类,then
- ----else
- --------将以 T r e e G e n e r a t e ( D , A { a ∗ } ) TreeGenerate(D, A\{a_*\}) TreeGenerate(D,A{a∗})为分支节点。
决策树的构建过程是一个递归过程。函数存在三种返回状态:(1)当前节点包含的样本全部属于同一类别,无需继续划分;(2)当前属性集为空或者所有样本在某个属性上的取值相同,无法继续划分;(3)当前节点包含的样本集合为空,无法划分。
决策树的关键在于从 A A A中选择最优划分属性 a ∗ a_∗ a∗,一般我们希望决策树每次划分节点中包含的样本尽量属于同一类别,也就是节点的“纯度”更高。
3.4 支持向量机
可以参考我的另一篇文章支持向量机