逻辑回归

逻辑回归原理

回归与分类

在线性回归问题中,算法预期得到的结果大多都是连续的值,比如给定特征房子的面积,所处的地理位置(离市区的远近)来预测房价,换而言之,就是用于预测输入变量(自变量)和输出变量(因变量)之间的关系,回归模型正是表示从输入变量到输出变量之间映射的函数。

而对于分类,输入变量和回归中的相似,但输出变量却变成了有限的离散数值,最常见的例子就是文本分类,监督学习从数据中学习一个分类函数或者分类决策函数,也就是分类器,新的输入变量经过分类器进行输出的预测。

逻辑回归

逻辑回归虽然名字里有个回归,但却是个分类算法。逻辑回归其实是将线性回归扩展到了分类上,对于二元分类问题,类0和类1,可以通过回归两类的概率来决定输出变量。

显而易见,两者的概率相加应该为1,这与线性回归不同,它的输出分布只能在0与1之间。解决这个问题的一种方法就是找到一个函数,将原先的输出压缩进0、1之间。这种方法就是逻辑回归。而这个函数,则被称为Sigmoid函数:

                                                                                f(x)=\frac{1}{1+e^{-x}}

如下图所示:

可以直观看出,函数的定义域为全体实数,值域在(0,1)之间,大于0.5可以认为是类1,反之是类0。

对于输入变量,在线性回归中,输出变量:

h_{\theta }(x) = \theta _0 +\theta _1x_1+\theta_2x_2+\cdot \cdot \cdot +\theta_nx_n=\theta ^Tx

在逻辑回归中,变为:

h_\theta (x)=\frac{1}{1+e^{-(\theta ^Tx)}}

在线性回归中,我们定义了损失函数:

J\left ( \theta \right ) = \frac{1}{2m}\sum_{i = 0}^{m}(h(x^{i})-y^i)^2

但在逻辑回归中,如果用类似直接相减的方法,发现会出现问题,原因就在于在逻辑回归中,构造的损失函数并不是像线性回归中的“碗状”,极值点较多,难以求得最低点。

这里,构建逻辑回归模型,最常用的构建方法便是应用极大似然估计。

极大似然估计

极大似然估计,就是在已知样本满足弄个概率分布,通过若干次实验,观察结果,推算估计出这个概率分布的参数。

这正和我们先要要做的不谋而合,输入样本就是所作的实验,从中得到后验概率:

P(y|x,\theta )=(h_\theta (x))^y(1-h_\theta (x))^{1-y}         

y即可为1也可以为0,极大似然函数为:

L(\theta |x,\theta )=\prod_{i=1}^{m}(h_\theta (x^i))^y^i(1-h_\theta (x^i))^{1-y^i}

 

两边取对数:

l(\theta ) =\sum_{i=1}^{m}y^ilog(h(x^i))+(1-y^i)log(1-h(x^i))

接下来,就是求最大的l\left ( \theta \right )了。

梯度上升

与线性回归的梯度下降相似,先求偏导:

\frac{\partial l(\theta )}{\partial \theta _{j}}=y^i-h_\theta (x^i)x_j^i

之后更新\theta

\theta :=\theta +\alpha(y^i-h_\theta (x^i)x_j^i

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

数据和代码

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值