周志华《机器学习》Ch3. 线性模型:对数几率回归的python实现

标签: 西瓜书  机器学习  python  Logistic回归

理论

        “对数几率模型”就是常说的Logistic回归,是一个经典的线性模型。考虑二分类任务,其输出标记y\in\{0,1\},而线性回归模型产生的预测值z = \mathbf{w}^T\mathbf{x}+b是连续分布的实数,需要一个阶跃函数y = step(z)将连续值映射为离散二值。用一个对数几率函数y = \frac{1}{1+e^{-z}}近似阶跃函数,得到ln\frac{y}{1-y}=\mathbf{w}^T\mathbf{x}+b。从而y和1-y可以分别视为类后验概率p(y=1|\mathbf{x})p(y=0|\mathbf{x}),简记为p_1(\mathbf{x})p_0(\mathbf{x})

     训练时,用极大似然法估计模型参数\mathbf{w}b. 对给定的数据集\{\{\mathbf{x}_i, y_i\}\}_{i=1}^m,对数几率模型最大化对数似然函数l(\mathbf{w},b)=$\sum\limits_{i=1}^{m}$lnp(y_i|\mathbf{x}_i;\mathbf{w},b). 令\mathbf{\beta} = (\mathbf{w};b)\mathbf{\hat{x}} = (\mathbf{x};1), 似然函数可重写为l(\mathbf{\beta}) = $\sum\limits_{i=1}^m$(-y_i\mathbf{\beta}^T\mathbf{\hat{x}}_i + ln(1+e^{\mathbf{\beta}^T\mathbf{\hat{x}}_i })).

        上述似然函数可以用经典的优化算法如梯度下降法、牛顿法求解。以牛顿法为例,其第t+1轮迭代解的更新公式为\beta^{t+1} = \beta^t - (\frac{\partial^2l(\beta)}{\partial\beta\partial\beta^T})^{-1}\frac{\partial{l(\beta)}}{\partial\beta}, 其中\frac{\partial{l(\beta)}}{\partial\beta} = - \sum\limits_{i=1}^m\mathbf{\hat{x}}_i(y_i-p_1(\mathbf{\hat{x}}_i;\beta)), \frac{\partial^2l(\beta)}{\partial\beta\partial\beta^T} = \sum\limits_{i=1}^m \mathbf{\hat{x}}_i \mathbf{\hat{x}}_i^T p_1(\mathbf{\hat{x}};\beta) (1-p_1(\mathbf{\hat{x}};\beta)).

代码

# -*- coding: utf-8 -*-
"""
Logistic Regression
From 'Machine Learning, Zhihua Zhou'
Model: P69 problem 3.3
        linear model
        Newton Method
Dataset: P89 watermelon_3.0a (watermelon_3.0a.npy)

@author: weiyx15
"""

import numpy as np
import matplotlib.pyplot as plt

class Logistic:
    def load_data(self, filename):
        dic = np.load(filename)
        self.x = dic['arr_0']
        self.y = dic['arr_1']
        self.m = self.x.shape[0]
        self.d = self.x.shape[1]
        
    def plot_data(self):
        x1 = self.x[np.where(self.y==1),:]
        x1 = x1.reshape((x1.shape[1], x1.shape[2]))
        x0 = self.x[np.where(self.y==0),:]
        x0 = x0.reshape((x0.shape[1], x0.shape[2]))
        plt.plot(x1[:,0], x1[:,1], 'b.')
        plt.plot(x0[:,0], x0[:,1], 'r.')
        x0min = x0.min()
        x1min = x1.min()
        xmin = min(x0min, x1min)
        x0max = x0.max()
        x1max = x1.max()
        xmax = max(x0max, x1max)
        xs = np.linspace(xmin, xmax, 100)
        beta = self.beta.reshape((self.beta.shape[1],))
        ys = -beta[0]/beta[1]*xs - beta[2]/beta[1]
        plt.plot(xs, ys, 'g')
        plt.legend(['positive', 'negative', 'classifier'])
        
    def __init__(self):
        self.load_data('watermelon_3.0a.npz')
    
    def calculate_derivative(self, beta):
        pLpB = np.zeros((self.d+1,))
        pLpB2 = np.zeros((self.d+1, self.d+1))
        pLpB2 = np.mat(pLpB2)
        ones = np.ones((self.m,1))
        x1 = np.concatenate((self.x, ones), axis=1)
        for i in range(self.m):
            myexp = np.exp(np.dot(beta, x1[i]))
            p1 = myexp / (1+myexp)
            x1i = np.mat(x1[i])
            pLpB = pLpB - (self.y[i] - p1)*x1[i]
            addi = np.dot(x1i.T, x1i)
            addi = np.multiply(addi, p1*(1-p1))
            pLpB2 = pLpB2 + addi
        return pLpB, pLpB2
    
    def train(self):
        self.beta = np.ones((self.d+1,))
        p_beta = np.zeros((self.d+1,))
        while np.linalg.norm(self.beta-p_beta) > 1e-3:
            p_beta = self.beta
            pLpB, pLpB2 = self.calculate_derivative(p_beta)
            self.beta = p_beta - np.dot(pLpB2.I, pLpB).getA()
    
    def classify(self, xt):
        xt.append(1)
        xt = np.array(xt)
        myexp = np.exp(np.dot(self.beta.reshape((self.beta.size,)), xt))
        p1 = myexp / (1+myexp)
        if p1 > .5:
            return 1
        else:
            return 0

if __name__ == '__main__':
    lg = Logistic()
    lg.train()
    ans = lg.classify([.555, .354])
    lg.plot_data()

结果

版权声明:本文为da_kao_la原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/da_kao_la/article/details/81908154

智能推荐

机器学习(周志华)-python编程练习-习题3-5

系统3-5: 编辑实现线性判别分析,并给出西瓜数据集 3.0α 上的结果. 西瓜数据集3.0α: sn density suger_ratio good_melon 1 0.697 0.46 1 2 0.774 0.376 1 3 0.634 0.264 1 4 0.608 0.318 1 5 0.556 0.215 1 6 0.403 0.237 1 7 0.481 0....

周志华《机器学习》课后习题第三章解答:Ch3.3 - 编程实现对率回归

这里采用Python-sklearn的方式,环境搭建可参考 数据挖掘入门:Python开发环境搭建(eclipse-pydev模式). 相关答案和源代码托管在我的Github上:PY131/Machine-Learning_ZhouZhihua. 思路概要 编程实现对率回归: * 采用sklearn逻辑斯蒂回归库函数实现,通过查看混淆矩阵,绘制决策区域来查看模型分类效果; * 自己编程实现,从极大...

周志华机器学习3_5线性判例分析 编程实现(python&matlab)

作为小白一枚,在参考了大神们的代码(文末附链接)后首先利用python分别用两种方法进行了编程。编程结果与大神们的不一致,不知道是不是中间过程有问题。在阅读过程中如果看出问题,望能指出,谢谢大噶!(以下均将数据集中第15行数据去除后运行) 方法1:(利用sklearn库中的LDA函数) 其中有一个问题没有理解的是为什么LDA函数返回截距值,代码原理中只要过零点就可以了。后来仔细想想,截距不为零只是...

使用Python编程实现对数几率回归模型(不调用现成的对数几率回归函数),并对Iris数据集进行分类以验证模型的效能

使用Python编程实现对数几率回归模型(不调用现成的对数几率回归函数),并对Iris数据集进行分类以验证模型的效能 导入数据集 数据划分 训练模型 损失函数 结果展示 源码分享 导入数据集 数据划分 训练模型 教材指的是周志华的西瓜书。具体公式大家可以自行翻阅。 其中α是精度,指的是真实权重和计算得到的w的偏差,一般人为指定,在本次实现过程中,我将α指定为0.0001。 ...

基于sklearn的线性分类器logistics(对数几率回归)Python实现

基于sklearn的线性分类器logistics(对数几率回归)Python实现 声明:本人小白,文章作为自己的学习参考资料,供大家学习交流 本文章 refer to 作者:月见樽 链接:https://www.jianshu.com/p/f9cb59dc99ec 来源:简书 作者: 周志华 书名:《机器学习》 出版社:清华大学出版社 感谢此文章及书籍原创者 如有侵犯您的知识产权和版权问题,请通知...

猜你喜欢

Linux 给普通用户赋予sudo 权限

进入root 用户模式 输入密码进入root 先更改权限让sudoers文件可以写 然后修改sudoers文件 给hadoop 赋予sudo 权限 如图 保存退出 然后解除sudoers 可以被写的权限 从root 用户退出 OK啦...

每日一道算法题:20201014-环形链表

环形链表 前言 一、解决思路 1.快慢指针法 1,环很大 2,环很小 2.存放集合 二、实现代码 1.快慢指针法 2.存放集合 前言 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 说明:不允许修改给定的链表。 示例 1:...

【专题】Aho-Corasick automaton(AC自动机)精讲

Aho-Corasick automaton是什么? 要学会AC自动机,我们必须知道什么是Trie,也就是字典树。Trie树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。 首先我们要知道trie,而且要知道KMP,这样就可以学AC自动机了! 其实AC自动机就是trie和KMP的结合体。主...

C6748_UART_EDMA

通过EDMA来实现UART的收发,可以减轻CPU的负担。主函数如下: 函数中,注册了4号和5号CPU可屏蔽中断C674X_MASK_INT4和C674X_MASK_INT5的服务函数,分别为Edma3ComplHandlerIsr和Edma3CCErrHandlerIsr,然后将8号中断事件SYS_INT_EDMA3_0_CC0_INT1(EVT8)映射到C674X_MASK_INT4,将56号中...