逻辑回归的自述
逻辑回归是另一种回归模型,它与线性回归模型存在着千丝万缕的关系,但是与之相比它属于非线性模型,专门用来解决二分类的离散性问题,该模型的最大特色就是相对于其他很多分类算法来说,具有很强的可解释性。
逻辑回归和线性回归的关系
假设X轴表示的是肿瘤体积的大小,Y轴表示肿瘤是否为恶性,其中0表示良性,1表示恶性;垂直和水平方向的虚线均属于参考线,其中水平参考线设置为Y等于0.5处,很明显,这是一个二分类问题,如果使用线性回归模型预测肿瘤状态的话,得到的不会是0,1两种值,而是实数范围内的某个值,如果以0.5为判断标准,左图呈现的回归模型,对于肿瘤的划分还是比较合理的,因为当肿瘤体积小于X₁时都能够将良性肿瘤判断出来,反之亦然;再来看右图,当恶性肿瘤在X轴上相对分散时,得到的线性模型如图所示,最终导致的后果就是错误判断出现,当肿瘤体积小于X2时,会有两种肿瘤被判断为良性肿瘤。所以直接使用线性回归模型,对于离散性的因变量建模容易导致错误的结果。线性回归模型的预测值越大,肿瘤被判为恶性的可能性就越大。如果线性回归模型做出sigmoid变化,使其能够预测值被压缩到0和1之间,那么这个范围就可以理解为恶性肿瘤的概率,所以预测值越大,转换后的概率值就越接近于从而得到肿瘤的恶性概率就会越大。那么逻辑回归就是根据该预测值对数据进行分类。
sigmoid:
损失函数,penalty和C
损失函数这个评估指标来衡量参数,在模型拟合训练级时产生的信息损失的大小,并以此衡量参数的。模型在训练集上表现良好,那么我们就说模型拟合过程损失小,损失函数就小,这一组参数相对优秀,反之如果模型在训练集上表现非常糟糕,损失函数就会越大,模型训练不足,效果比较差,那么这一组参数就比较差。也就是说在求解参数的过程中追求损失函数最小是拟合效果最优。
由于我们追求损失函数的最小值,让模型在训练基地,如果模型在训练集上表现优秀,却在测试集上表现糟糕,模型就会过拟合,虽然逻辑回归和线性回归是天生欠拟合的模型,但是我们还需要控制过拟核的技术来帮助我们调整模型,对于逻辑回归中过拟合的控制,通过正则换来变。
正则化是用来防止模型过拟合的过程,常用的有L1正则化和L2正则化两种选项,分别通过在损失函数后加上参数向量 的L1范式和L2范式的倍数来实现。这个增加的范式,被称为“正则项”,也被称为"惩罚项"。在模型使用的过程中是通过penalty参数确定。
C正则化强度的倒数,必须是一个大于0的浮点数,不填写默认1.0,是对于penalty参数正则化强度的确定。
重要参数
LogisticRegression(penalty="l2"# 目标函数添加正则化惩罚项与线性模型类似默认L2
#"l1"适合选数据较为稀疏(适用于大量数据)
#"l2"(默认)选数据较为密集
,C=1.0 # 用于指定惩罚项系数的倒数,值越小正则化越大
,solver="liblinear"#用于指定求解目标函数最优化的算法
# "liblinear" "lbfgs" "newton-cg" "sag" "saga"
# 多分类 N Y Y Y Y
# VOR Y Y Y Y Y
# 二分类 Y Y Y Y Y
#l1 or l2 l1 l2 l2 l2 l2 l2
#若用sag saga 需要标准化数据
,max_iter=100 # 最大迭代次数
,random_state
)
coef_
#显示每个回归方程中参数值
# “l1”中效果小的参数为零,“l2”中不为零,但是值较小
n_iter_#显示实际迭代次数
penalty和C对模型的影响
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression as LR
cancer=load_breast_cancer()
data=pd.DataFrame(cancer.data)
target=pd.Series(cancer.target)
Xtrain, Xtest, Ytrain, Ytest = train_test_split(data,target,test_size=0.3,random_state=420)
l1 = []
l2 = []
l1test = []
l2test = []
for i in np.linspace(0.05,1,19):
lrl1 = LR(penalty="l1",solver="liblinear",C=i,max_iter=1000)
lrl2 = LR(penalty="l2",solver="liblinear",C=i,max_iter=1000)
lrl1 = lrl1.fit(Xtrain,Ytrain)
l1.append(lrl1.score(Xtrain,Ytrain))
l1test.append(lrl1.score(Xtest,Ytest))
lrl2 = lrl2.fit(Xtrain,Ytrain)
l2.append(lrl2.score(Xtrain, Ytrain))
l2test.append(lrl2.score(Xtest, Ytest))
graph = [l1,l2,l1test,l2test]
color = ["green","black","red","pink"]
label = ["L1","L2","L1test","L2test"]
plt.figure(figsize=(6,6))
for i in range(len(graph)):
plt.plot(np.linspace(0.05,1,19),graph[i],color[i],label=label[i])
plt.xlabel("C")
plt.ylabel("score")
plt.legend()
plt.show()
print("l2训练集最佳正则化在第",l2.index(max(l2)),"个")
print("l2训练集最佳正则化程度为",l2.index(max(l2))*0.95/19+0.05)
print("l2训练集最佳正则化分数",max(l2))
l2训练集最佳正则化在第 18 个
l2训练集最佳正则化程度为 0.95
l2训练集最佳正则化分数 0.9723618090452262
嵌入法threshold值对回归的影响
在正则系数为L2时,会显示出每一个特征所贡献的贡献程度,那么我们就可以使用嵌入法对于这些特征进行过滤,保留更多有效的特征。
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
from sklearn.datasets import load_breast_cancer
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression as LR
from sklearn.feature_selection import SelectFromModel
cancer=load_breast_cancer()
data=pd.DataFrame(cancer.data)
target=pd.Series(cancer.target)
lr=LR(penalty="l2",solver="liblinear",C=0.97)
lr_=lr.fit(data,target)
previous_score=[]
embedded_score=[]
k=0
print("threshold取值", "模型分数","嵌入法使用的特征个数",)
#此时,我们使用的判断指标,就不是范数,而是逻辑回归中的系数了
threshold=np.linspace(0,abs(lr_.coef_).max(),20)
for i in threshold:
new_data=SelectFromModel(lr_ ,threshold=i).fit_transform(data,target)
previous_score.append(cross_val_score(lr_,data,target,cv=10).mean())
once=cross_val_score(lr_ ,new_data,target ,cv=10).mean()
embedded_score.append(once)
print((threshold[k],once,new_data.shape[1]))
k+=1
plt.figure(figsize=(10,5))
plt. plot(threshold,previous_score,label="previous_score")
plt. plot(threshold,embedded_score,label="embedded_score")
plt.xlabel("threshold")
plt.ylabel("score")
plt. xticks(threshold,rotation=30)
plt.legend()
plt. show()
输出:
threshold取值 模型分数 嵌入法使用的特征个数
(0.0, 0.9508145363408522, 30)
(0.10841425667042925, 0.9385338345864662, 17)
(0.2168285133408585, 0.9368107769423559, 13)
(0.32524277001128776, 0.9368107769423559, 11)
(0.433657026681717, 0.9368107769423559, 8)
(0.5420712833521463, 0.9368107769423559, 8)
(0.6504855400225755, 0.9368107769423559, 6)
(0.7588997966930048, 0.9385651629072683, 5)
(0.867314053363434, 0.9385651629072683, 5)
(0.9757283100338633, 0.9385651629072683, 5)
(1.0841425667042925, 0.9385651629072683, 5)
(1.192556823374722, 0.938533834586466, 4)
(1.300971080045151, 0.9104010025062657, 2)
(1.4093853367155802, 0.9104010025062657, 2)
(1.5177995933860096, 0.9104010025062657, 2)
(1.626213850056439, 0.8858395989974935, 1)
(1.734628106726868, 0.8858395989974935, 1)
(1.8430423633972972, 0.8858395989974935, 1)
(1.9514566200677266, 0.8858395989974935, 1)
(2.059870876738156, 0.8858395989974935, 1)
我们通过数据可以观察到,当小于1.08贡献性的特征被除掉时,只使用了5个特征就保留了几乎与之前相同的效果