利用广义线性模型实现的分类——Logistic回归
本文作者:王 歌
文字编辑:孙晓玲
技术总编:张 邯
利用广义线性模型实现线性回归以及它的正则化——岭回归和LASSO回归,它们解决的都是对连续数值进行预测的回归问题,其实我们还可以利用回归的思想来解决分类问题,这就是我们今天要介绍的Logistic回归。
一、算法原理
1.模型形式——利用Sigmoid函数
Logistic回归适用于数值型或标称型(目标变量的结果只在有限目标集中取值,而且只存在‘是’和‘否’两种不同的结果)数据,因此就需要将数值型的数据转化为类别值,如二分类问题,最终是对输出的值0或者1进行分类,这就需要引入函数来对输入的数据进行处理。在数学中,Heaviside阶跃函数(或称为单位阶跃函数)就具有这样的性质,即假设输入的值为x,则:
![ac5150c587b1d54b2e74f36f8661688e.png](https://i-blog.csdnimg.cn/blog_migrate/bb272b8bbc15c4862b2d3d6adefca1e6.png)
从上面的表达式我们可以看到阶跃函数在定义域上是不连续的,这不利于我们处理连续值并进行最优化,因此我们使用另一个数学性质更优越的函数——Sigmoid函数:
![bdceb129945f66fe496176778229cc3f.png](https://i-blog.csdnimg.cn/blog_migrate/2cf0ce19bbab6f210d6164f5fed8c2e2.png)
它也是一种阶跃函数,其不同坐标尺度下的函数图像如下图所示:
![3054f5337ecbfcbd1f29c35ae04446ff.png](https://i-blog.csdnimg.cn/blog_migrate/85c0072251afc10e041fcbe922ba30b1.jpeg)
可以看到当x为0时,Sigmoid函数值为0.5。当x>0时,随着x的增大,对应的Sigmoid值将逼近于1;而随着x的减小,Sigmoid值将逼近于0。如果横坐标刻度足够大,如第二张坐标图所示,此时Sigmoid函数的形式就很接近单位阶跃函数的取值形式了。 因此,假设我们现在面临二分类任务,类标签值为0和1,那么按照线性回归的思想,我们能够得到模型
![c415ca56665efdf8897b7f41f6bcddc8.png](https://i-blog.csdnimg.cn/blog_migrate/bf6b4439419b6654c377444b41b765e3.png)
但此时我们得到的只是预测的数值而并非类标签,因此我们就要用到刚才介绍的Sigmoid函数,即Logistic模型的形式为
![de031fe1c243ffad3ef83d620202410a.png](https://i-blog.csdnimg.cn/blog_migrate/f166399afd7c154addf16692cbb32346.png)
2.模型的优化 在得到上面的模型后,我们可以对其变形为
![39ef262a2b081a39860cc249bf26d545.png](https://i-blog.csdnimg.cn/blog_migrate/9c08ba896d50809a4025027d7b45b352.png)
y和1-y可分别看作是y取1和0时的后验概率,所以我们也将Logistic回归称为对数几率回归(简称对率回归),因此我们可以进一步得到
![8c28150bf3fe055564718d305af3b2e8.png](https://i-blog.csdnimg.cn/blog_migrate/abd41c9e0555de9e6baf57e2aa564522.png)
![1ebeaa05e211e7d238c312847ca48a6f.png](https://i-blog.csdnimg.cn/blog_migrate/425e11f49dd74a797a0282b96700e4f0.png)
所以对数似然函数为
![9f993d0665507f1e71c891fcdaeb9c20.png](https://i-blog.csdnimg.cn/blog_migrate/3f64989181b5a4c9c4288174de348803.png)
这就是我们要进行优化的目标函数,一般我们会选择梯度下降法、牛顿法、拟牛顿法、梯度上升法等方法求解,具体的过程我们就不在这里介绍了,大家感兴趣可以自行查阅资料。
依据因变量类型,可分为二分类Logistic回归模型和多分类Logistic回归模型;根据多分类因变量是否有序,又可以分为多分类有序Logistic回归模型和多分类无序Logistic回归模型。在进行多分类时,相当于是多次Logistic回归,进行多次二分类,这就需要对数据集进行拆分,如OvR(“一对多”样本)、MvM(“多对多”样本)的方式。当然Logistic 回归模型可以直接推广到多类别分类,不必组合和训练多个二分类器,称为 Softmax 回归。
二、类参数介绍
我们这里使用的是sklearn. linear_model
中的LogisticRegression()
来实现Logistic算法。那么首先我们来看看这个类中的参数:
(1)solver
确定逻辑回归损失函数的优化方法,'liblinear'使用坐标轴下降法来迭代优化损失函数。'lbfgs'是拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。'newton-cg'则是牛顿法的一种。'sag'为平均随机梯度下降算法。'saga'是sag的一类变体,它支持非平滑的L1正则选项penalty='l1'。'lbfgs', 'sag'和'newton-cg'求解器只支持L2罚项以及无罚项,对某些高维数据收敛更快。默认为'liblinear';
(2)penalty
确定惩罚项,可为'l1' 或 'l2'。'newton-cg', 'sag', 'lbfgs'只支持'l2',即L2正则化;
(3)C
表示正则化系数的倒数,取值必须为正浮点数,默认为1.0;
(4)multi_class
用来选择分类方式,默认为' one-vs-rest'即OvR方式,表示对于第K类的分类决策,我们把所有第K类的样本作为正例,除了第K类样本以外的所有样本都作为负例,然后在上面做二元逻辑回归,得到第K类的分类模型。也可以设置为'multinomial'即MvM,此时若模型有K类,每次在所有的K类样本里面选择两类样本出来,把所有输出为这两类的样本进行二元Logistic回归得到模型参数,一共需要K(K-1)/2次分类;
(5)class_weight
用来设定各类型样本的权重,默认为None,此时所有类型权重均为1,也可设为'balanced',此时按照输入样本的频率大小来调整权重;
(6)dual
选择目标函数为原始形式还是对偶形式,转化为原函数的对偶函数时更易于优化,默认为False,对偶方法通常只用在正则化项为'liblinear'的L2惩罚项上;
(7)fit_intercept
表示模型中是否含常数项,默认为True;
(8)intercept_scaling
仅在正则化项为'liblinear'且fit_intercept设置为True时有用,默认为1;
(9)max_iter
表示算法收敛的最大迭代次数,默认为100,仅在正则化优化算法为'newton-cg','sag'和'lbfgs'才有用;
(10)tol
用来设置优化算法终止的条件,当迭代前后的函数差值小于等于tol时就停止,默认为0.0001;
(11)random_state
设定随机数种子;
(12)verbose
控制是否输出训练过程,默认为0表示不输出,取1时偶尔输出,大于1时对每个子模型都输出;
(13)warm_start
表示是否使用上次训练结果作为初始化参数,默认为False;
(14)n_jobs
表示用CPU的几个内核运行程序,默认为1,当为-1的时候表示用所有CPU的内核运行程序。
三、算法实例
我们这里使用的依然是鸢尾花的数据集,参数使用默认设置,程序如下:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, mean_squared_error, r2_score
iris_sample = load_iris()
x_train, x_test, y_train, y_test = train_test_split(
iris_sample.data, iris_sample.target, test_size=0.25, random_state=123)
logclf = LogisticRegression()
logclf.fit(x_train, y_train)
print('系数为:', logclf.coef_)
print('截距为:', logclf.intercept_)
y_pre = logclf.predict(x_test)
print(y_test) #输出测试集真实数据
print(y_pre) #输出测试集预测结果
print('均方误差为:', mean_squared_error(y_test, y_pre))
print('r2为:', r2_score(y_test, y_pre))
print('测试集准确度为:', accuracy_score(y_test, y_pre))
结果如下:
![1e12e98c5c82498ce257169fb44aa5a2.png](https://i-blog.csdnimg.cn/blog_migrate/3555564668f32994eaf2f1af0ea49a46.jpeg)
可以看到准确度比较高。Logistic 回归作为被人们广泛使用的算法,具有高效且计算量小,又通俗易懂容易实现的优点,但同时也有容易欠拟合,分类精度可能不高的缺点。因此我们在选择方法时要注意自己数据的特点来选择合适的分类器。