前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python 逻辑回归

python 逻辑回归

作者头像
bear_fish
发布2018-09-14 10:02:24
1.2K0
发布2018-09-14 10:02:24
举报

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1338376

逻辑回归模型所做的假设是:

相应的决策函数为: y=1,if P(y=1|x)>0.5 (实际应用时特定的情况可以选择不同阈值,如果对正例的判别准确性要求高,可以选择阈值大一些,对正例的召回要求高,则可以选择阈值小一些)

那么,给定一个逻辑回归模型,如何来调整参数θ?首先我们假设:

上面两个公式是为了,方便后面的计算。

假设我们有n个独立的训练样本{(x1, y1) ,(x2, y2),…, (xn, yn)},y={0, 1}。那每一个观察到的样本(xi, yi)出现的概率是:

当y=1的时候,后面那一项没有了(为1),那就只剩下x属于1类的概率,当y=0的时候,第一项没有了(为1),那就只剩下后面那个x属于0的概率(1减去x属于1的概率)

求θ最优值相当于求,θ使得已知样本出现的最大概率。

因为每个样本都是独立的,所以n个样本出现的概率就是他们各自出现的概率相乘,假设生成m个训练样本相互独立,我们可以写出关于参数θ的似然函数:

(为了方便计算)将它转换为log似然函数:

如何最大化似然函数呢?我们可以使用梯度下降即:

类似于其他算法,例如神经网络BP,根据输入样本,已知的x,每次更新θ),其中α为学习速率。

接下来的问题就是对于L(θ)对θ求导了。

首先,设g(z)为 sigmoid函数,有如下公式g’(z)=g(z)(1-g(z)):

上式中,我们使用了g’(z)=g(z)(1-g(z))。最终得出随机梯度下降法则:


代码实现

  1. 数据集见github,方便起见,数据集的读取使用pandas。
代码语言:javascript
复制
import pandas as pd
def get_data():
    path = '../dataset/logistic_regression/lr_ml_action.txt'

    data = pd.read_csv(path, delim_whitespace=True,
                          names=['f1', 'f2', 'label'],
                          dtype={'A': np.float64, 'B': np.float64, 'C': np.int64})

    # add bias w0 (添加逻辑回归的第一项即偏置W0)
    data['f0'] = 1
    print data.head()
    features = ['f0', 'f1', 'f2']
    # 输出转化为 numpy array
    return data[features].values, data.label.values

输出的前五行如下:

代码语言:javascript
复制
         f1         f2  label  f0
0 -0.017612  14.053064      0   1
1 -1.395634   4.662541      1   1
2 -0.752157   6.538620      0   1
3 -1.322371   7.152853      0   1
4  0.423363  11.054677      0   1

类如下:

代码语言:javascript
复制
import numpy as np

class LogisticRegression(object):
    def __init__(self):
        self._map_method()
        pass

    def _map_method(self):
        self._do_train = {"gd": self._gd, "sgd": self._sgd}

    def _sigmoid(self, x):
        return 1.0 / (1 + np.exp(-x))

    def fit(self, X, Y, **opt):
        m, n = X.shape
        self._weight = np.ones((n, 1))
        max_iter = opt.get("max_iter", 100)
        alpha = opt.get("alpha", 0.01)
        method = opt.get("method", "sgd")

        for k in xrange(max_iter):
            try:
                # 训练
                self._do_train[method](X, Y, alpha)
                # 输出当前迭代次数的错误率
                print "iter %s error rate %s" % (k, self._get_error_rate(X, Y))
            except KeyError:
                raise ValueError('method error')

    def _sgd(self, X, Y, alpha):
        """
        stochastic gradient descent随机梯度下降法
        """
        m, n = X.shape
        for i in xrange(m):
            # pred = self._sigmoid(X[i, :] * self._weight)
            pred = self._sigmoid(np.dot(X[i, :], self._weight))
            error = Y[i] - pred
            self._weight = self._weight + alpha * np.matrix(X[i, :]).T * error

    def _gd(self, X, Y, alpha):
        """
        gradient descent梯度下降法
        """
        pred = self._sigmoid(X * self._weight)
        error = Y - pred
        self._weight = self._weight + alpha * X.T * error

    def _get_error_rate(self, X, Y):
        all_num = len(Y)
        error_num = 0
        for i in xrange(all_num):
            pred = self._sigmoid(np.dot(X[i, :], self._weight)) > 0.5
            if pred != bool(Y[i]):
                error_num += 1

        return error_num * 1.0 / all_num

训练代码如下:

代码语言:javascript
复制
def test_lr():
    X, Y = get_data()

    lr = LogisticRegression()
    lr.fit(X, Y)

程序运行的结果如下(可见错误率一直在下降):

具体代码见github


参考

李航《统计学习方法》

《机器学习实战》

http://blog.csdn.net/zouxy09/article/details/20319673

http://blog.yhat.com/posts/logistic-regression-and-python.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年12月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 代码实现
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档