逻辑回归属于监督学习算法中,分类算法的一种,主要应用在二分类场景中,也可应用在多分类场景。
概述
简单点说,Logistic回归模型就是将线性回归的结果输入一个Sigmoid函数,将回归值映射到0~1区间,表示输出的类别“1”的概率。
模型
线性回归的表达式如下:
y
i
=
w
x
i
+
b
y_i=wx_i+b
yi=wxi+b
Sigmoid函数:
σ
(
z
)
=
1
1
+
e
−
z
\sigma(z)=\frac{1}{1+e^{-z}}
σ(z)=1+e−z1
其中,
z
z
z是自变量,
e
e
e是自然常熟。该函数图像如下图所示:
将线性回归的结果输入Sigmoid函数,就能得到Logistic回归的结果,即:
σ
(
y
i
)
=
1
1
+
e
−
y
i
=
1
1
+
e
−
(
w
x
i
+
b
)
\sigma(y_i)=\frac{1}{1+e^{-y_i}}=\frac{1}{1+e^{-(wx_i+b)}}
σ(yi)=1+e−yi1=1+e−(wxi+b)1
如果我们将
y
i
=
1
y_i=1
yi=1视为
x
i
x_i
xi作为正例的可能性,可以得到:
P
(
y
i
=
1
∣
x
i
)
=
1
1
+
e
−
(
w
x
i
+
b
)
=
e
(
w
x
i
+
b
)
1
+
e
(
w
x
i
+
b
)
P(y_i=1 \mid x_i) = \frac{1}{1+e^{-(wx_i+b)}}=\frac{e^{(wx_i+b)}}{1+e^{(wx_i+b)}}
P(yi=1∣xi)=1+e−(wxi+b)1=1+e(wxi+b)e(wxi+b)
P ( y i = 0 ∣ x i ) = 1 − P ( y i = 1 ∣ x i ) = 1 1 + e ( w x i + b ) P(y_i=0 \mid x_i) =1-P(y_i=1 \mid x_i) =\frac{1}{1+e^{(wx_i+b)}} P(yi=0∣xi)=1−P(yi=1∣xi)=1+e(wxi+b)1
定义两者的比值
P
(
y
i
=
1
∣
x
i
)
P
(
y
i
=
0
∣
x
i
)
\frac{P(y_i=1 \mid x_i) }{P(y_i=0 \mid x_i) }
P(yi=0∣xi)P(yi=1∣xi)为“概率”,对其取对数得到“对数概率”,可得:
l
n
P
(
y
i
=
1
∣
x
i
)
1
−
P
(
y
i
=
1
∣
x
i
)
=
w
x
i
+
b
ln\frac{P(y_i=1 \mid x_i)}{1-P(y_i=1 \mid x_i)}=wx_i+b
ln1−P(yi=1∣xi)P(yi=1∣xi)=wxi+b
上面定义的“对数概率”结果正好是线性回归的预测结果。由此可知,Logistic回归的本质其实就是用线性回归的预测结果 w x i + b wx_i+b wxi+b 去逼近真实标记的对数概率 l n y 1 − y ln\frac{y}{1-y} ln1−yy ,这也是逻辑回归被称为“对数概率回归”的原因。
策略
对于二元分类问题,我们希望模型预测的标签(是/否)与真实值越接近越好。用数学语言表达:我们希望模型的预测集合
A
A
A,与真实集合
B
B
B 的交集越大越好。
但根据这个描述,很难直接定义出一个数学上方便处理的损失函数。于是借鉴统计学中最大似然估计的思想。
已知
y
i
y_i
yi 的概率分布函数为:
P
(
y
i
)
=
P
(
y
i
=
1
)
y
i
P
(
y
i
=
0
)
1
−
y
i
P(y_i)=P(y_i=1)^{y_i}P(y_i=0)^{1-y_i}
P(yi)=P(yi=1)yiP(yi=0)1−yi
构造似然函数:
L
=
∏
[
P
(
y
i
=
1
∣
x
i
)
]
y
i
[
1
−
P
(
y
i
=
1
∣
x
i
)
]
1
−
y
i
L=\prod\limits_{}\left[P(y_i=1 \mid x_i)\right]^{y_i} \left[1-P(y_i=1 \mid x_i)\right]^{1-y_i}
L=∏[P(yi=1∣xi)]yi[1−P(yi=1∣xi)]1−yi
取对数,得到对数似然函数:
l
n
L
=
∑
{
y
i
⋅
l
n
P
(
y
i
=
1
∣
x
i
)
+
(
1
−
y
i
)
⋅
l
n
[
1
−
P
(
y
i
=
1
∣
x
i
)
]
}
=
∑
{
y
i
⋅
l
n
e
(
w
x
i
+
b
)
1
+
e
(
w
x
i
+
b
)
+
(
1
−
y
i
)
⋅
l
n
1
1
+
e
(
w
x
i
+
b
)
}
=
∑
{
y
i
⋅
(
w
x
i
+
b
)
−
y
i
⋅
l
n
(
1
+
e
w
x
i
+
b
)
+
(
y
i
−
1
)
⋅
l
n
(
1
+
e
w
x
i
+
b
)
}
=
∑
{
y
i
⋅
(
w
x
i
+
b
)
−
l
n
(
1
+
e
w
x
i
+
b
)
}
\begin{aligned} lnL & = \sum \left\{y_i \cdot lnP(y_i=1 \mid x_i)+(1-y_i) \cdot ln \left[1-P(y_i=1 \mid x_i)\right] \right\} \\ &= \sum \left\{y_i \cdot ln\frac{e^{(wx_i+b)}}{1+e^{(wx_i+b)}}+(1-y_i) \cdot ln\frac{1}{1+e^{(wx_i+b)}} \right\} \\&= \sum \left\{y_i \cdot (wx_i+b)-y_i \cdot ln(1+e^{wx_i+b})+(y_i-1) \cdot ln(1+e^{wx_i+b})\right\} \\&= \sum \left\{y_i \cdot (wx_i+b)- ln(1+e^{wx_i+b})\right\} \end{aligned}
lnL=∑{yi⋅lnP(yi=1∣xi)+(1−yi)⋅ln[1−P(yi=1∣xi)]}=∑{yi⋅ln1+e(wxi+b)e(wxi+b)+(1−yi)⋅ln1+e(wxi+b)1}=∑{yi⋅(wxi+b)−yi⋅ln(1+ewxi+b)+(yi−1)⋅ln(1+ewxi+b)}=∑{yi⋅(wxi+b)−ln(1+ewxi+b)}
我们只需要使每个样本属于其真实标记的概率越大越好,即:
m
a
x
w
,
b
∑
{
y
i
⋅
(
w
x
i
+
b
)
−
l
n
(
1
+
e
w
x
i
+
b
)
}
max_{w,b} \sum \left\{y_i \cdot (wx_i+b)- ln(1+e^{wx_i+b})\right\}
maxw,b∑{yi⋅(wxi+b)−ln(1+ewxi+b)}
参数求解
同样使用梯度下降法来求解上述优化问题,分别对 w w w, b b b求一阶偏导数:
∂ ∂ w l n L = ∂ ∂ w ∑ { y i ⋅ ( w x i + b ) − l n ( 1 + e w x i + b ) } = ∂ ∂ w ∑ ( y i x i − x i e w x i + b 1 + e w x i + b ) = ∂ ∂ w ∑ ( y i − e w x i + b 1 + e w x i + b ) x i \begin{aligned} \frac{\partial}{\partial_w}lnL &=\frac{\partial}{\partial_w}\sum \left\{y_i \cdot (wx_i+b)- ln(1+e^{wx_i+b})\right\} \\& = \frac{\partial}{\partial_w}\sum (y_ix_i - \frac{x_ie^{wx_i+b}}{1+e^{wx_i+b}}) \\&= \frac{\partial}{\partial_w}\sum (y_i- \frac{e^{wx_i+b}}{1+e^{wx_i+b}})x_i \end{aligned} ∂w∂lnL=∂w∂∑{yi⋅(wxi+b)−ln(1+ewxi+b)}=∂w∂∑(yixi−1+ewxi+bxiewxi+b)=∂w∂∑(yi−1+ewxi+bewxi+b)xi
∂ ∂ b l n L = ∂ ∂ b ∑ { y i ⋅ ( w x i + b ) − l n ( 1 + e w x i + b ) } = ∂ ∂ b ∑ ( y i − e w x i + b 1 + e w x i + b ) \begin{aligned} \frac{\partial}{\partial_b}lnL &=\frac{\partial}{\partial_b}\sum \left\{y_i \cdot (wx_i+b)- ln(1+e^{wx_i+b})\right\} \\& = \frac{\partial}{\partial_b}\sum (y_i- \frac{e^{wx_i+b}}{1+e^{wx_i+b}}) \end{aligned} ∂b∂lnL=∂b∂∑{yi⋅(wxi+b)−ln(1+ewxi+b)}=∂b∂∑(yi−1+ewxi+bewxi+b)
得到
w
w
w,
b
b
b的迭代公式如下:
w
⟵
w
+
η
(
y
i
−
e
w
x
i
+
b
1
+
e
w
x
i
+
b
)
x
i
w \longleftarrow w+\eta(y_i- \frac{e^{wx_i+b}}{1+e^{wx_i+b}})x_i
w⟵w+η(yi−1+ewxi+bewxi+b)xi
b
⟵
b
+
η
(
y
i
−
e
w
x
i
+
b
1
+
e
w
x
i
+
b
)
b \longleftarrow b+\eta(y_i- \frac{e^{wx_i+b}}{1+e^{wx_i+b}})
b⟵b+η(yi−1+ewxi+bewxi+b)
其中, η \eta η为学习率,即学习的步长,取值范围在 [ 0 , 1 ] [0,1] [0,1]之间。
Logistic回归的scikit-learn实现
Logistic回归在scikit-learn中通过 sklearn.linear_model.LogisticRegression 类进行实现:
class sklearn.linear_model.LogisticRegression(penalty=‘l2’, dual=False, tol=0.0001, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver=‘liblinear’, max_iter=100, multi_class=‘ovr’, verbose=0)[source]¶
参数:
- penalty:添加正则化项
- c:指定正则化项权重,c越小,正则化越大
- fit_intercept:计算偏置常数
- class_weight:指定各类别权重,当样本不均衡时,可以设为balanced
- solver:指定求解参数的算法
- max_iter:最大迭代次数
- tol:迭代收敛的阈值
- multi_class:指定多分类的策略
- n_jobs:指定CPU核数
属性:
- coef_:输出权重向量
- intercept_:输出偏置项
- n_iter_:输出迭代次数
方法:
- fit(X_train, y_train):训练模型
- score(X_test, y_test):模型得分,同线性回归
- predict(X):返回结果标签
- predict_proba(X):返回类别概率
我们使用kaggle泰坦尼克数据进行模型示例,代码如下:
# 导入数据集
import pandas as pd
data_train = pd.read_csv(r"C:\Users\chih-cheng\Desktop\Train.csv")
data_test = pd.read_csv(r"C:\Users\chih-cheng\Desktop\Test.csv")
#############缺失值处理############
#缺失值处理(使用随机森林预测填充)
from sklearn.ensemble import RandomForestRegressor
#将要填充的特征和其他无缺失的特征取出,这里先处理Age特征
age_df = data_train[['Age','Fare','Parch','SibSp','Pclass']]
#将乘客分为年龄已知和年龄未知两部分,分别作为训练集和测试集
age_know = age_df[age_df['Age'].notnull()].as_metrix()
age_unknow = age_df[age_df['Age'].isnull()].as_metrix()
#获取训练集特征和结果标签
X = age_know[:,1:]
y = age_know[:,0]
#建立随机森林回归预测模型
RF_clf = RandomForestRegressor(n_estimators=2000, n_jobs=-1)
RF_clf.fit(X, y)
#预测年龄未知的样本
age_predicted = RF_clf.predict(age_unknow[:, 1:])
#用预测结果填补原缺失数据
data_train.loc[(data_train.Age.isnull()), 'Age'] = age_predicted
#将Cabin特征直接去掉
data_train = data_train.drop(['Cabin'], axis=1)
#将剩下的还有缺失值的样本直接去掉
data_train = data_train.dropna(axis=0)
#############特征处理############
# 将类别型特征取出并进行one-hot编码
cate_df = data_train[['Pclass','Sex','Embarked']]
cate_onehot_df = pd.get_dummies(cate_df)
cate_onehot_df.head(3)
#将数值型特征取出并标准化
cont_df = data_train[['Age','Fare','SibSp','Parch']]
import sklearn.preprocessing as preprocessing
scaler = preprocessing.StandardScaler()
#Age特征
age_scale = scaler.fit(cont_df['Age'])
cont_df['Age_scaled'] = scaler.fit_transform(cont_df['Age'], age_scale)
#Fare特征
fare_scale = scaler.fit(cont_df['Fare'])
cont_df['Fare_scaled'] = scaler.fit_transform(cont_df['Fare'], fare_scale)
#Sibsip特征
SibSp_scale = scaler.fit(cont_df['SibSp'])
cont_df['SibSp_scaled'] = scaler.fit_transform(cont_df['SibSp'], SibSp_scale)
#Parch特征
Parch_scale = scaler.fit(cont.df['Parch'])
cont_df['Parch_scaled'] = scaler.fit_transform(cont_df['Parch'], Parch_scale)
#删除原来的特征
cont_df.drop(['Age','Fare','SibSp','Parch'], axis=1, inplace=True)
#将结果标签、one-hot编码后的类别特征、标准化后的数值特征拼接到一起形成新的训练集
df_train = pd.concat([data_train['Survived'], cate_onehot_df, cont_df], axis=1)
#############模型训练################
#导入逻辑回归模型
from sklearn.linear_model import LogisticRegression
#将训练集转换为矩阵格式
df_train_mat = df_train.as_metrix()
#分割训练集特征和结果标签
X = df_train_mat[:, 1:]
y = df_train_mat[:, 0]
#划分训练集和验证集
from sklearn.model_selection import train_test_split
X_train, y_train, X_test, y_teset = train_test_split(X, y)
#训练模型
LR_clf = LogisticRegression()
LR_clf.fit(X_train, y_train)
#在验证集上验证
y_predict = LR_clf.predict(X_test)
y_predict_prob = LR_clf.predict_proba(X_test)[:, 1]
from sklearn.metrics import classification_report
print('查准率、查全率、F1值')
print(classification_report(y_test, y_predict, target_names=None))
from sklearn.metrics import roc_auc_score
print('AUC值:')
print(roc_auc_score(y_test, y_predict_prob))
from sklearn.metrics import confusion_matrix
print('混淆矩阵')
print(confusion_matrix(y_test, y_predict, labels=None))
#############结果分析############
#输出特征标签
feature_list = list(df_train.columns[1:])
print(feature_list)
#输出LR模型中各特征权重值
weight_array LR_clf.coef_
weight = weight_array[0]
print(weight)
逻辑回归优缺点
优点:
- 直接对分类的可能性进行建模,无需事先假设数据满足某种分布类型。
- 不仅可以预测出样本类别,还可以得到近似概率,可解释性较强。
- 对数损失函数是任意阶可导的凸函数,可避免局部最小值问题。
缺点:
- 本质还是线性模型,只能做线性分类,不适合处理非线性的情况,一般需要结合较多的人工特征处理使用。
- 对正负样本的分布比较敏感,所以要注意样本的平衡性。
与线性回归模型的区别:
- 逻辑回归用于分类任务,线性回归用于回归任务。
- 线性回归采用均方误差损失,而逻辑回归不能使用均方误差损失。如果采用均方误差损失,那么逻辑回归模型的决策函数代入均方误差函数后,得到的损失函数是非凸的,而非凸函数的极值点不唯一,因此最终可能得到一个局部极值点。