其他分享
首页 > 其他分享> > 机器学习基础—集成学习Task5(分类模型)

机器学习基础—集成学习Task5(分类模型)

作者:互联网

导语:
本次内容主要是利用sklearn处理分类任务:介绍分类模型的评价指标、基础的分类模型,最后结合数据集进行实现。本次的基础模型介绍非常详细,也有很多推导过程,由于时间关系,这里不再赘述。想要详细学习可直接查看开源项目,学习链接:
集成学习: EnsembleLearning项目-github.

1.分类任务

1.1 分类模型的度量指标

度量分类模型的指标和回归的指标有很大的差异,首先是因为分类问题本身的因变量是离散变量,因此像定义回归的指标那样,单单衡量预测值和因变量的相似度可能行不通。其次,在分类任务中,我们对于每个类别犯错的代价不尽相同
分类模型的指标

更多分类问题的评价指标请参考:
https://scikit-learn.org/stable/modules/model_evaluation.html#classification-metrics

1.2 分类模型的选择

(1)逻辑回归logistic regression
逻辑回归的基本思想是将线性回归的结果通过某一函数映射至区间[0:1]上,让连续的y标签转变成一个分类的概率,通过设定阈值,就可完成分类。这里的映射函数选择对数几率函数:
p ( X ) = e β 0 + β 1 X 1 + e β 0 + β 1 X {p(X) = \dfrac{e^{\beta_0 + \beta_1X}}{1+e^{\beta_0 + \beta_1X}}} p(X)=1+eβ0​+β1​Xeβ0​+β1​X​
在这里插入图片描述图源:西瓜书
注意:逻辑回归在实际中不太用于多分类问题,因为实际效果不是很好。

(2)基于概率的分类模型
A.线性判别分析
线性判别分析是一个比较久远的算法,可以从两个方向去描述这个算法,分别是基于贝叶斯公式降维分类的思想。
基于贝叶斯公式对线性判别分析的理解如下图,虚线是线性判别分析的决策边界,正态曲线哪边高样本就是哪一类。
在这里插入图片描述
基于降维分类的思想理解线性判别分析如下图,“类内方差小,类间方差大”。
在这里插入图片描述
B.朴素贝叶斯
在线性判别分析中,我们假设每种分类类别下的特征遵循同一个协方差矩阵,每两个特征之间是存在协方差的,因此在线性判别分析中各种特征是不独立的。但是,朴素贝叶斯算法对线性判别分析作进一步的模型简化,它将线性判别分析中的协方差矩阵中的协方差全部变成0,只保留各自特征的方差,也就是朴素贝叶斯假设各个特征之间是不相关的。在之前的偏差-方差理论中,我们知道模型的简化可以带来方差的减少但是增加偏差,因此朴素贝叶斯也不例外,它比线性判别分析模型的方差小,偏差大。虽然简化了模型,实际中使用朴素贝叶斯的案例非常多,甚至多于线性判别分析,例如鼎鼎大名的新闻分类,垃圾邮件分类等。

(3)决策树
在之前的回归问题中,我们使用决策树进行了回归分析,然而,决策树也可以用来处理分类问题。分类树的构造过程与回归树也很类似,与回归树一样,分类树也是采用递归二叉分裂。但是在分类树中,均方误差无法作为确定分裂节点的准则,只需要选择:
(1) 基尼系数
G = ∑ k = 1 K p ^ m k ( 1 − p ^ m k ) G = \sum\limits_{k=1}^{K} \hat{p}_{mk}(1-\hat{p}_{mk}) G=k=1∑K​p^​mk​(1−p^​mk​)
在基尼系数的定义中,我们发现这个指标衡量的是K个类别的总方差。不难发现,如果所有的 p ^ m k \hat{p}_{mk} p^​mk​的取值都接近0或者1,基尼系数会很小。因此基尼系数被视为衡量结点纯度的指标----如果他的取值小,那就意味着某个节点包含的观测值几乎来自同一个类别。
由基尼系数作为指标得到的分类树叫做:CART
(2) 交叉熵
可以替代基尼系数的指标是交叉熵,定义如下:
D = − ∑ k = 1 K p ^ m k l o g    p ^ m k D = -\sum\limits_{k=1}^{K} \hat{p}_{mk}log\;\hat{p}_{mk} D=−k=1∑K​p^​mk​logp^​mk​
显然,如果所有的 p ^ m k \hat{p}_{mk} p^​mk​都接近于0或者1,那么交叉熵就会接近0。因此,和基尼系数一样,如果第m个结点的纯度越高,则交叉熵越小。事实证明,基尼系数和交叉熵在数值上很接近
在这里插入图片描述
(4)支持向量机SVM
支持向量机SVM是20世纪90年代在计算机界发展起来的一种分类算法,在许多问题中都被证明有较好的效果,被认为是适应性最广的算法之一。
支持向量机的基本原理非常简单,如图所视,白色和蓝色的点各为一类,我们的目标是找到一个分割平面将两个类别分开。通常来说,如果数据本身是线性可分的,那么事实上存在无数个这样的超平面。这是因为给定一个分割平面稍微上移下移或旋转这个超平面,只要不接触这些观测点,仍然可以将数据分开。一个很自然的想法就是找到最大间隔超平面,即找到一个分割平面距离最近的观测点最远
在这里插入图片描述
非线性支持向量机
实际中的例子遇到的更多的是非线性可分的情况,这时候可以通过核技巧,在避开高维数据复杂运算量的同时对数据进行升维升维后的数据就会变得线性可分,简单示意图如下:
在这里插入图片描述
几种常用的核函数:
1)多项式核函数:
多项式核函数(Polynomial Kernel)是线性不可分SVM常用的核函数之一,表达式为:
K ( x i , x j ) = ( ⟨ x i , x j ⟩ + c ) d K\left(\mathbf{x}_{i}, \mathbf{x}_{j}\right)=\left(\left\langle\mathbf{x}_{i}, \mathbf{x}_{j}\right\rangle+c\right)^{d} K(xi​,xj​)=(⟨xi​,xj​⟩+c)d
C用来控制低阶项的强度,C=0,d=1代表无核函数。
2) 高斯核函数:
高斯核函数(Gaussian Kernel),在SVM中也称为径向基核函数(Radial Basis Function,RBF),它是非线性分类SVM最主流的核函数。libsvm默认的核函数就是它。表达式为:
K ( x i , x j ) = exp ⁡ ( − ∥ x i − x j ∥ 2 2 2 σ 2 ) K\left(\mathbf{x}_{i}, \mathbf{x}_{j}\right)=\exp \left(-\frac{\left\|\mathbf{x}_{i}-\mathbf{x}_{j}\right\|_{2}^{2}}{2 \sigma^{2}}\right) K(xi​,xj​)=exp(−2σ2∥xi​−xj​∥22​​)
使用高斯核函数之前需要将特征标准化,因此这里衡量的是样本之间的相似度。
3) Sigmoid核函数:
Sigmoid核函数(Sigmoid Kernel)也是线性不可分SVM常用的核函数之一,表达式为:
K ( x i , x j ) = tanh ⁡ ( α x i ⊤ x j + c ) K\left(\mathbf{x}_{i}, \mathbf{x}_{j}\right)=\tanh \left(\alpha \mathbf{x}_{i}^{\top} \mathbf{x}_{j}+c\right) K(xi​,xj​)=tanh(αxi⊤​xj​+c)
此时的SVM相当于没有隐藏层的简单神经网络。
4) 余弦相似度核:
常用于衡量两段文字的余弦相似度,表达式为:
K ( x i , x j ) = x i ⊤ x j ∥ x i ∥ ∥ x j ∥ K\left(\mathbf{x}_{i}, \mathbf{x}_{j}\right)=\frac{\mathbf{x}_{i}^{\top} \mathbf{x}_{j}}{\left\|\mathbf{x}_{i}\right\|\left\|\mathbf{x}_{j}\right\|} K(xi​,xj​)=∥xi​∥∥xj​∥xi⊤​xj​​

2. 模型实例对比

2.1 导入数据集

处理分类问题,收集数据集并选择合适的特征,在数据集上我们使用我们比较熟悉的IRIS鸢尾花数据集。导入IRIS数据集,并查看每个特征的含义,为方便后续模型的对比,这里先统一将数据集进行划分,75%的数据用于训练,25%的数据用于测试。

import pandas as pd
from sklearn import datasets
from sklearn.model_selection import train_test_split

iris = datasets.load_iris()
X = iris.data
y = iris.target
feature = iris.feature_names
data = pd.DataFrame(X,columns=feature)
data['target'] = y

#数据划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)
data.head()

数据集前几行:
在这里插入图片描述
各个特征的相关解释:
sepal length (cm):花萼长度(厘米)
sepal width (cm):花萼宽度(厘米)
petal length (cm):花瓣长度(厘米)
petal width (cm):花瓣宽度(厘米)

2.2 模型训练,结果对比

这里针对同样的训练集和测试集,依次使用上面五种算法进行训练:

#使用各类分类模型进行建模预测

test_score = []  #存放各模型测试集得分

#1.逻辑回归
'''
penalty       {‘l1’, ‘l2’, ‘elasticnet’, ‘none’}, default=’l2’正则化方式
dual      bool, default=False   是否使用对偶形式,当n_samples> n_features时,默认dual = False。   
C        float, default=1.0      
solver       {‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’, ‘saga’}, default=’lbfgs’     
l1_ratio         float, default=None           
'''
from sklearn.linear_model import LogisticRegression
log_iris = LogisticRegression()
log_iris.fit(X_train,y_train)
log_pred_test = log_iris.predict(X_test)

print("1.逻辑回归测试集得分:",log_iris.score(X_test,y_test))   
test_score.append(log_iris.score(X_test,y_test))


#2.线性判别分析
'''
参数:
solver:{'svd','lsqr','eigen'},默认='svd'
solver的使用,可能的值:
'svd':奇异值分解(默认)。不计算协方差矩阵,因此建议将此求解器用于具有大量特征的数据。

'lsqr':最小二乘解,可以与收缩结合使用。

'eigen':特征值分解,可以与收缩结合使用。
'''
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda_iris = LinearDiscriminantAnalysis()
lda_iris.fit(X_train,y_train)
lda_iris_test = lda_iris.predict(X_test)

print("2.线性判别测试集得分:",lda_iris.score(X_test,y_test))   
test_score.append(lda_iris.score(X_test,y_test))
   

#3.朴素贝叶斯             
from sklearn.naive_bayes import GaussianNB
NB_iris = GaussianNB()
NB_iris.fit(X_train,y_train)
NB_iris_test = NB_iris.predict(X_test)

print("3.朴素贝叶斯测试集得分:",NB_iris.score(X_test,y_test))   
test_score.append(NB_iris.score(X_test,y_test))


#4.决策树
'''
criterion:{“gini”, “entropy”}, default=”gini”
max_depth:树的最大深度。
min_samples_split:拆分内部节点所需的最少样本数
min_samples_leaf :在叶节点处需要的最小样本数。

'''
from sklearn.tree import DecisionTreeClassifier
tree_iris = DecisionTreeClassifier(min_samples_leaf=5)
tree_iris.fit(X_train,y_train)
tree_iris_test = tree_iris.predict(X_test)

print("4.决策树测试集得分:",tree_iris.score(X_test,y_test))   
test_score.append(tree_iris.score(X_test,y_test))


#5.支持向量机
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
'''
C:正则化参数。正则化的强度与C成反比。必须严格为正。惩罚是平方的l2惩罚。
kernel:{'linear','poly','rbf','sigmoid','precomputed'},默认='rbf'
degree:多项式和的阶数
gamma:“ rbf”,“ poly”和“ Sigmoid”的内核系数。
shrinking:是否软间隔分类,默认true

'''
svc_iris = make_pipeline(StandardScaler(), SVC(gamma='auto'))
svc_iris.fit(X_train,y_train)
svc_iris_test = svc_iris.predict(X_test)

print("5.支持向量机测试集得分:",svc_iris.score(X_test,y_test))   
test_score.append(svc_iris.score(X_test,y_test))


#可视化
import matplotlib
import matplotlib.pyplot as plt

plt.figure(1)
plt.plot(y_test,'g-o',label='real')
plt.plot(log_pred_test,'r-o',label='log')
plt.plot(lda_iris_test,'b-o',label='lda')
plt.plot(NB_iris_test,'k-o',label='NB')
plt.plot(tree_iris_test,'y-o',label='tree')
plt.plot(svc_iris_test,'m-o',label='svc')
plt.xlabel("test", fontsize=12)
plt.ylabel("class", fontsize=12)
plt.title("测试集表现")
plt.legend()
plt.rcParams['font.sans-serif']=['SimHei']


x_list = ["逻辑回归","线性判别","朴素贝叶斯","决策树","支持向量机"]
plt.figure(2)
plt.plot(x_list,test_score,'g-o',label='test_score')
plt.xlabel("models", fontsize=12)
plt.ylabel("R_score", fontsize=12)
plt.title('test_data R_score')
plt.legend()
plt.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus'] =False

训练结果可视化:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

从各模型测试集的 R 2 R^2 R2得分来看,逻辑回归和线性判别一致,最高;朴素贝叶斯和决策树一致,其次;支持向量机的分类结果最差。
从各模型训练集的 R 2 R^2 R2得分来看,前四种算法的预测表现相对效果与测试集一致,而SVM在训练集上表现得最高,在测试集上表现最差,可判断SVM存在过拟合现象,泛化能力差。
注意:这里的五种模型都使用的是默认参数,后续可进一步调参优化,特别是针对SVM。

标签:集成,iris,plt,mathbf,Task5,分类,学习,score,test
来源: https://blog.csdn.net/lin0cp/article/details/115272093