对数几率回归时为了使用线性回归模型来做分类任务,使用对数几率函数,把线性模型的预测值和样本的真实标记
y连接起来。
对数几率函数:
y=1+e−z1
单位阶跃函数:
f(x)=⎩⎪⎨⎪⎧10.50z>0z=0z<0
对数几率函数和单位阶跃函数图像:
使用对数几率函数是因为:
二分类任务中,需要将线性回归模型
z=wTx+b的预测值
z转换为0和1,理论上单位阶跃函数最适合,预测值
z 大于零就判为 正例,小于零则判为反例预测值为 临界值零则可任意判别。
由于单位阶跃函数不连续,不适于计算,而对数几率函数是连续函数,对单位阶跃函数的逼近比较好,输出值在
z = 0 附近变化很陡,将 z 值转化为一个接近 0 或 1 的
y值,即:
y=1+e−z1
将对数几率回归和线性回归结合起来的到:
y=1+e−(wxT+b)1
即:
ln1−yy=wTx+b
把
y看做是样本为正例的概率,
1−y则为样本为负例的概率,
1−yy为几率。对几率做对数即为对数几率回归。
通俗的讲,对数几率回归就是利用线性回归的输出值。根据线性回归的输出值
z来判断样本为正例还是负例,判断的方法是对这个输出值
z做对数几率变换。
流程为:
1、由输入
x通过线性模型得到
z;
2、由
z通过对数几率得到两个值0和1,分别对应输入
x位负例还是正例。
要得到
z就要确定
z=wTx+b中的
w和
b,我们通过极大似然法来估计
w和
b,对于
ln1−yy=wTx+b,将
y视为类后验概率估计
p(y=1∣x)(即拿出一个样本
x,这个样本为‘1’类的概率),则原式为
lnp(y=0∣x)p(y=1∣x)=wTx+b,
又因为
p(y=0∣x)+p(y=1∣x)=1,可得:
p(y=1∣x)=1+e(wxT+b)e(wxT+b)
p(y=0∣x)=1+e(wxT+b)1
此时对于二分类问题,损失函数为
cost(x,y)={−ln(1+e−(wxT+b)1)−ln(1−1+e−(wxT+b)1)y=1y=0
=
⎩⎨⎧−ln(1+e(wxT+b)e(wxT+b))−ln(1+e(wxT+b)1)y=1y=0
=
{−ln(p(y=1∣x))−ln(p(y=0∣x))y=1y=0
其中y=1表示正样本,y=0表示负样本。
对于给定的数据集
[(xi,yi)]i=1m,对率回归模型最大化对数似然(即对后验概率的对数求和)得到:
l(w,b)=∑i=1mlnp(yi∣xi;w,b)
让每个样本属于其真实标记的概率越大越好。
令
β=(w,b);
x^=(x;1) ,
wTx+b则为
βTx^,
令
p1(x^;β)=p(y=1∣x^;β),
p0(x^;β)=p(y=0∣x^;β)=1−p1(x^;β)
把
p1(x^;β)和
p0(x^;β)合并起来为:
p(x^;β) =
p(y=1∣x^;β)yip(y=0∣x^;β)1−yi
=p1(x^;β)yip0(x^;β)1−yi
该式可以看做为损失函数
则:
ln(p(yi∣xi;w,b)) =
yiln(p1(x^;β))+(1−yi)ln(p0(x^;β))
该式可看做对数损失函数
带入得:
l(β)=∑i=1m(yiln(p1(x^;β))+(1−yi)ln(p0(x^;β)))
=∑i=1m(yiln(1+e(wxT+b)e(wxT+b))+(1−yi)ln(1+e(wxT+b)1)
=∑i=1m(yi((wxT+b)−ln(1+e(wxT+b)))−(1−yi)ln(1+e(wxT+b))
=∑i=1m(yi((wxT+b)−ln(1+e(wxT+b))
=∑i=1m(yiβTxi^−ln(1+βTxi^))
该式可看做代价函数
改为求最小值:
l(β)=∑i=1m(−yiβTxi^+ln(1+βTxi^))
该式可看做目标函数
可使用不同的优化求解最小值的方法求出最优解
β∗=argminl(β)
对数几率回归的优点:
例如它是直接对分类可能性进行建模,无需事先假设数据分布?这样就避免了假设分布不准确所带来的问题;它不是仅预测出"类别",而是可得到近似概率预测,这对许多需利用概率辅助决策的任务很有用;此外,对率函数是任意阶可导的凸函数,有很好的数学性质,现有的许多数值优化算法都可直接用于求取最优解。
使用sklearn来调用逻辑回归
from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
digits = datasets.load_digits()
x_digits = digits.data
y_digits = digits.target
x_train = x_digits[:round(.9*len(x_digits))]
x_test = x_digits[round(.9*len(x_digits)):]
y_train = y_digits[:round(.9*len(y_digits))]
y_test = y_digits[round(.9*len(y_digits)):]
logistic = LogisticRegression()
print('Logistic Score: %f'%logistic.fit(x_train,y_train).score(x_test,y_test))