Python逻辑回归
逻辑回归也被称为广义线性回归模型,它与线性回归模型的形式基本上相同,最大的区别就在于它们的因变量不同,如果是连续的,就是多重线性回归;如果是二项分布,就是Logistic回归。
二分类问题的概率与自变量之间的关系图形往往是一个S型曲线,如图3-8所示,采用sigmoid函数实现,函数形式为:
对于线性边界的情况,边界形式如下:
最佳参数:
构造预测函数为:
sigmoid的函数输出是介于(0,1)之间的,中间值是0.5,公式hθ(x)的含义就很好理解了,因为hθ(x)输出是介于(0,1)之间,也就表明了数据属于某一类别的概率。例如,hθ(x)<0.5则说明当前数据属于A类;hθ(x)>0.5则说明当前数据属于B类。所以可以将sigmoid函数看成样本数据的概率密度函数。函数h(x)的值有特殊的含义,它表示结果取1的概率,因此对于输入x分类结果为类别1和类别0的概率分别为:
使用概率论中极大似然估计的方法去求解损失函数:
首先得到概率函数为:
因为样本数据(m个)独立,所以它们的联合分布可以表示为各边际分布的乘积,取似然函数为:
取对数似然函数:
最大似然估计就是要求得使l(θ)取最大值时的θ,这里可以使用梯度上升法求解,求得的θ就是要求的最佳参数:
基于最大似然估计推导得到Cost函数和J函数如下:
θ更新过程可以写成:
正则化后的梯度下降算法θ的更新变为:
代码部分:
使用如下所示数据100条
数据加载
class Logistic_regression():
#初始化
def __init__(self):
self.xmat = list();
self.ymat = list();
#数据加载处理
def loadData(self,filename):
file = open(filename);
lines = file.readlines();
#print(lineArry);
for line in lines:
lineArry = line.strip().split();# split 用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列
dataline = [1.0];
for i in range(len(lineArry)):
dataline.append(float(lineArry[i]));
#print("dataline",dataline);
label = dataline.pop();
self.ymat.append(int(label));#删除最后一个 并返回
self.xmat.append(dataline);
self.xmat = np.mat(self.xmat); # mat()函数 转换为矩阵
self.ymat = np.mat(self.ymat).transpose();
#print("len",len(self.xmat));
#print(self.xmat);
sigmoid函数
定义sigmoid函数
def sigmod(self,X):
return 1/(1-np.exp(-X));
梯度下降
# 梯度下降计算权重0
def stocGradAscent0(self,maxCycles=1000,alpha=0.001):
m,n = np.shape(self.xmat);
weights = np.ones((n,1));
for i in range(maxCycles):
h = self.sigmod(self.xmat*weights);
error = self.ymat-h;
#print("error",np.shape(error))
#print("xmat",np.shape(self.xmat.transpose()))
weights+=alpha*self.xmat.transpose()*error; #ranspose()转置
return weights;
画图
#画出最终分类图
def plotBestfit(self,weights):
xcord1 = [];
xcord2 = [];
ycord1 = [];
ycord2 = [];
for i in range(len(self.xmat)):
label = self.ymat[i];
#print(int(label))
#用x1 代表x坐标 x2 代表y坐标
if int(label) == 1:
xcord1.append(self.xmat[i,1]);
ycord1.append(self.xmat[i,2]);
else:
xcord2.append(self.xmat[i,1]);
ycord2.append(self.xmat[i,2]);
#print(xcord1,xcord2,ycord1,ycord2)
plt.figure();
#定义线条颜色
plt.scatter(xcord1,ycord1,s=30,c='red',marker='s');
plt.scatter(xcord2,ycord2,s=30,c='green');
#坐标轴
x = np.arange(-3.0,3.0,0.1); # 从-3.0 到 3.0 步长为0.1
y = (-weights[0]-weights[1]*x)/weights[2]; #决策边界 z=w0+w1*x1+w2*x2 z=0 x1代表横坐标 x2代表纵坐标 和点坐标对应 所以可以求出x2 即y
plt.plot(x,y);
plt.xlabel('X1');
plt.ylabel('Y1');
plt.legend();
plt.show();
展示
if __name__ == '__main__':
lr = Logistic_regression();
lr.loadData("data\\data.txt");#加载数据
# 更新权重
weights0 = lr.stocGradAscent0(maxCycles=700000);
#weights0 = lr.stocGradAscent(maxCycles=500);
print("weights0",weights0);
lr.plotBestfit(weights0);
结果图
蓝色线为拟合曲线