逻辑回归原理
回归与分类
在线性回归问题中,算法预期得到的结果大多都是连续的值,比如给定特征房子的面积,所处的地理位置(离市区的远近)来预测房价,换而言之,就是用于预测输入变量(自变量)和输出变量(因变量)之间的关系,回归模型正是表示从输入变量到输出变量之间映射的函数。
而对于分类,输入变量和回归中的相似,但输出变量却变成了有限的离散数值,最常见的例子就是文本分类,监督学习从数据中学习一个分类函数或者分类决策函数,也就是分类器,新的输入变量经过分类器进行输出的预测。
逻辑回归
逻辑回归虽然名字里有个回归,但却是个分类算法。逻辑回归其实是将线性回归扩展到了分类上,对于二元分类问题,类0和类1,可以通过回归两类的概率来决定输出变量。
显而易见,两者的概率相加应该为1,这与线性回归不同,它的输出分布只能在0与1之间。解决这个问题的一种方法就是找到一个函数,将原先的输出压缩进0、1之间。这种方法就是逻辑回归。而这个函数,则被称为Sigmoid函数:
如下图所示:
可以直观看出,函数的定义域为全体实数,值域在(0,1)之间,大于0.5可以认为是类1,反之是类0。
对于输入变量,在线性回归中,输出变量:
在逻辑回归中,变为:
在线性回归中,我们定义了损失函数:
但在逻辑回归中,如果用类似直接相减的方法,发现会出现问题,原因就在于在逻辑回归中,构造的损失函数并不是像线性回归中的“碗状”,极值点较多,难以求得最低点。
这里,构建逻辑回归模型,最常用的构建方法便是应用极大似然估计。
极大似然估计
极大似然估计,就是在已知样本满足弄个概率分布,通过若干次实验,观察结果,推算估计出这个概率分布的参数。
这正和我们先要要做的不谋而合,输入样本就是所作的实验,从中得到后验概率:
y即可为1也可以为0,极大似然函数为:
两边取对数:
接下来,就是求最大的了。
梯度上升
与线性回归的梯度下降相似,先求偏导:
之后更新:
python实现
直接贴代码
# -*- coding: utf-8 -*-
"""
Created on Tue Jul 31 07:51:45 2018
@author: 96jie
"""
import numpy as np
#数据集
label = []
feature = np.zeros([32561,123])
f = open(r'D:\python_test\test\test\样本\train.txt')
line = f.readline()
a = 0
while line:
data = []
for i in line.split( ):
data.append(i);
for i in data[1:]:
j = i.split(":")
feature[a][int(j[0]) - 1] = int(j[1])
if data[0] in '+1':
label.append(1)
else:
label.append(0)
line = f.readline()
a += 1
f.close
n = len(label)
label = np.mat(label)
#构建训练集和测试集
label1 = label[:,20001:32561]
label = label[:,0:20000]
feature1 = feature[20001:32561]
feature = feature[0:20000]
one1 = np.ones(len(feature1))
one = np.ones(len(feature))
feature1 = np.insert(feature1, 0, values=one1, axis=1)
feature = np.insert(feature, 0, values=one, axis=1)
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def Optimization(feature,label,theta,learning_rate):
for i in range(iter):
theta = Updata(feature,label,theta,learning_rate)
return theta
def Updata(feature,label,theta,learning_rate):
h = 0
alpha = learning_rate
h = sigmoid(np.dot(feature , theta))
theta += alpha * np.dot((label.transpose()-h).transpose(),feature).transpose()
return theta
def acc(theta,feature,label):
la = sigmoid(np.dot(feature,theta))
la = la.tolist()
m = len(la)
label2 = []
label = label[0].tolist()
num = 0
for c in range(len(la)):
d = float(la[c][0])
if d < 0.5:
label2.append(0)
else:
label2.append(1)
if(int(label[0][c]) != int(label2[c])):
num += 1
acc = 1-(num/m)
return acc
learning_rate = 0.0001
theta = np.ones([124,1])
iter = 1000
theta = Optimization(feature,label,theta,learning_rate)
a = acc(theta,feature,label)
b = acc(theta,feature1,label1)
print(a)
print(b)
最后训练集和测试集的准确率为:
0.84895
0.8476114649681529