《统计学习方法》-逻辑回归笔记和python源码

逻辑回归(Logistic regression)

逻辑回归是统计学习中的经典分类方法。其多用在二分类{0,1}问题上。

定义1:

设X是连续随机变量,X服从逻辑回归分布是指X具有下列分布函数与密度函数:

分布函数属于逻辑斯谛函数,其图形是一条S形曲线。

定义2:

二项逻辑斯谛回归模型是如下条件概率分布:

从上式可以看出,逻辑回归对线性回归经行了归一化操作,将输出范围规定在{0,1}。

现在来看,逻辑回归的的特点,几率,指一件事件发生的概率与不发生的概率的比值。对上式分别求对数,我们可得如下式子。

这就是说,在逻辑回归模型中,输出Y=1的对数几率是输入x的线性函数。

对输入x经行分类的线性函数w*x,其值域为实数域。通过逻辑回归模型可以将线性函数转化为概率,

这就意味着,线性函数值越接近正无穷,概率越接近1;线性函数值越接近负无穷,概率值越接近0。这样的模型称为逻辑回归模型。

损失函数:

如同,在感知机一节中一样,我们需要构造损失函数,更新权值参数。我们利用极大似然估计法估计模型参数,即w。极大似然估计法是已经知道结果,然后寻求使该结果成立的最大可能条件(条件即模型参数)。

似然函数:

对数似然函数:

这样子,我们有了损失函数,这里我们只要将该函数极大化即可,求其最大值时的w即可。

优化求解:

梯度下降法

总是朝着负方向改变,直到找到极小值。初中数学中,对一个函数求导可以得到函

数在某一点的斜率k(表示函数的增长速率,朝着正方向改变),如果我们将斜率取负号

-k,那么就得到了朝着负方向增长的速率。在这里,由于我们要极大化对数似然函数,所

以在这里不用加负号。

更新公式:

其中,alpha是学习率。

python源码:

#coding=utf-8
#author=altman
import numpy as np
import matplotlib.pyplot as plt
def loadData():
    train_x = []
    train_y = []
    fileIn = open('data.txt')
    for line in fileIn.readlines():
        lineArr = line.strip().split()
        train_x.append([1.0, float(lineArr[0]), float(lineArr[1])])
        train_y.append(float(lineArr[2]))
    train_x = np.array(train_x)
    train_y = np.array(train_y).T
    return train_x,train_y
def sigmod(x):
    return 1.0/(1.0+np.exp(-x))
def train(matrix,labels):
    size = matrix.shape[1]
    w = np.ones(size)
    while True:
        x = np.dot(matrix,w)
        y = sigmod(x)
        diff = labels - y
        tmpW = w + 0.01*np.dot(matrix.T,diff)
        diff2 = (tmpW-w)**2
        sum_diff2 = sum(diff2)
        sq = sum_diff2**0.5
        if sq < 0.001:
            break
        else:
            w = tmpW
    return w
def test(matrix,labels,w):
    x = np.dot(matrix,w)
    y = sigmod(x)
    error = 0.0
    for i,result in enumerate(y):
        if result > 0.5:
            predict = 1.0
            if predict != labels[i]:
                error +=1
        else:
            predict = 0.0
            if predict != labels[i]:
                error +=1
    print("错误率:%3.2f" %(error/100.0))
def show(data,labels,w):
    x1=[]
    y1=[]
    x2=[]
    y2=[]
    for i in range(len(labels)):
        if labels[i] == 0:
            x1.append(data[i,1])
            y1.append(data[i,2])
        else:
            x2.append(data[i,1])
            y2.append(data[i,2])
    plt.scatter(x1,y1,edgecolors='r')
    plt.scatter(x2,y2,edgecolors='k')
    max_x = (np.max(data[:,1]))
    min_x = (np.min(data[:,1]))
    y_min_x = float(-w[0] - w[1] * min_x) / w[2]
    y_max_x = float(-w[0] - w[1] * max_x) / w[2]
    plt.plot([min_x, max_x], [y_min_x, y_max_x], '-g')
    plt.show()
def main():
    matrix,labels = loadData()
    weights = train(matrix,labels)
    test(matrix,labels,weights)
    show(matrix,labels,weights)
if __name__ == '__main__':
    main()

实验结果图:

实验数据集:

-0.017612	14.053064	0
-1.395634	4.662541	1
-0.752157	6.538620	0
-1.322371	7.152853	0
0.423363	11.054677	0
0.406704	7.067335	1
0.667394	12.741452	0
-2.460150	6.866805	1
0.569411	9.548755	0
-0.026632	10.427743	0
0.850433	6.920334	1
1.347183	13.175500	0
1.176813	3.167020	1
-1.781871	9.097953	0
-0.566606	5.749003	1
0.931635	1.589505	1
-0.024205	6.151823	1
-0.036453	2.690988	1
-0.196949	0.444165	1
1.014459	5.754399	1
1.985298	3.230619	1
-1.693453	-0.557540	1
-0.576525	11.778922	0
-0.346811	-1.678730	1
-2.124484	2.672471	1
1.217916	9.597015	0
-0.733928	9.098687	0
-3.642001	-1.618087	1
0.315985	3.523953	1
1.416614	9.619232	0
-0.386323	3.989286	1
0.556921	8.294984	1
1.224863	11.587360	0
-1.347803	-2.406051	1
1.196604	4.951851	1
0.275221	9.543647	0
0.470575	9.332488	0
-1.889567	9.542662	0
-1.527893	12.150579	0
-1.185247	11.309318	0
-0.445678	3.297303	1
1.042222	6.105155	1
-0.618787	10.320986	0
1.152083	0.548467	1
0.828534	2.676045	1
-1.237728	10.549033	0
-0.683565	-2.166125	1
0.229456	5.921938	1
-0.959885	11.555336	0
0.492911	10.993324	0
0.184992	8.721488	0
-0.355715	10.325976	0
-0.397822	8.058397	0
0.824839	13.730343	0
1.507278	5.027866	1
0.099671	6.835839	1
-0.344008	10.717485	0
1.785928	7.718645	1
-0.918801	11.560217	0
-0.364009	4.747300	1
-0.841722	4.119083	1
0.490426	1.960539	1
-0.007194	9.075792	0
0.356107	12.447863	0
0.342578	12.281162	0
-0.810823	-1.466018	1
2.530777	6.476801	1
1.296683	11.607559	0
0.475487	12.040035	0
-0.783277	11.009725	0
0.074798	11.023650	0
-1.337472	0.468339	1
-0.102781	13.763651	0
-0.147324	2.874846	1
0.518389	9.887035	0
1.015399	7.571882	0
-1.658086	-0.027255	1
1.319944	2.171228	1
2.056216	5.019981	1
-0.851633	4.375691	1
-1.510047	6.061992	0
-1.076637	-3.181888	1
1.821096	10.283990	0
3.010150	8.401766	1
-1.099458	1.688274	1
-0.834872	-1.733869	1
-0.846637	3.849075	1
1.400102	12.628781	0
1.752842	5.468166	1
0.078557	0.059736	1
0.089392	-0.715300	1
1.825662	12.693808	0
0.197445	9.744638	0
0.126117	0.922311	1
-0.679797	1.220530	1
0.677983	2.556666	1
0.761349	10.693862	0
-2.168791	0.143632	1
1.388610	9.341997	0
0.317029	14.739025	0
时间: 2024-08-01 09:36:08

《统计学习方法》-逻辑回归笔记和python源码的相关文章

《python源码剖析》笔记 Python虚拟机框架

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1. Python虚拟机会从编译得到的PyCodeObject对象中依次读入每一条字节码指令, 并在当前的上下文环境中执行这条字节码指令. Python虚拟机实际上是在模拟操作中执行文件的过程 PyCodeObject对象中包含了字节码指令以及程序的所有静态信息,但没有包含 程序运行时的动态信息--执行环境(PyFrameObject) 2.Python源码中的PyFrameObject

Python源码剖析笔记3-Python执行原理初探

Python源码剖析笔记3-Python执行原理初探 本文简书地址:http://www.jianshu.com/p/03af86845c95 之前写了几篇源码剖析笔记,然而慢慢觉得没有从一个宏观的角度理解python执行原理的话,从底向上分析未免太容易让人疑惑,不如先从宏观上对python执行原理有了一个基本了解,再慢慢探究细节,这样也许会好很多.这也是最近这么久没有更新了笔记了,一直在看源码剖析书籍和源码,希望能够从一个宏观层面理清python执行原理.人说读书从薄读厚,再从厚读薄方是理解了

python源码剖析笔记1——Python对象初见

python源码剖析笔记1--Python对象初见 工作整两年了,用python最多,然而对于python内部机制不一定都清楚,每天沉醉于增删改查的简单逻辑编写,实在耗神.很多东西不用就忘记了,比如C语言,正好,python源码用C写的,分析python源码的同时又能温故C语言基础,实在是件很好的事情.另外,还有陈儒大神的<python源码剖析>做指引,分析也不至于没头没脑.期望在一个月的业余时间,能有所小成,以此为记. 1 python中的对象 python中,一切东西都是对象,在c语言实现

《python源码剖析》笔记 python虚拟机中的一般表达式

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.字节码指令 LOAD_CONST:从consts表中读取序号为i的元素并压入到运行时栈中 STORE_NAME:改变local名字空间.从符号表names取序号为i的元素作为变量名, 取运行时栈的栈顶元素作为变量值,完成从变量名到变量值的映射关系的创建. BUILD_MAP:创建一个空的PyDictObject对象,并压入运行时栈 DUP_TOP:将栈顶元素的引用计数增加1,并将它再次

Python源码剖析笔记0 ——C语言基础

python源码剖析笔记0--C语言基础回顾 要分析python源码,C语言的基础不能少,特别是指针和结构体等知识.这篇文章先回顾C语言基础,方便后续代码的阅读. 1 关于ELF文件 linux中的C编译得到的目标文件和可执行文件都是ELF格式的,可执行文件中以segment来划分,目标文件中,我们是以section划分.一个segment包含一个或多个section,通过readelf命令可以看到完整的section和segment信息.看一个栗子: char pear[40]; static

《python源码剖析》笔记 pythonm内存管理机制

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.内存管理架构 Python的内存管理机制都有两套实现:debug模式和release模式 Python内存管理机制的层次结构: 图16-1 第0层是操作系统提供的内存管理接口,如malloc.free 第1层是Python基于第0层操作系统的内存管理接口包装而成的,主要是为了处理与平台相关的内存分配行为. 实现是一组以PyMem_为前缀的函数族 两套接口:函数和宏. 宏,可以避免函数调

《python源码剖析》笔记 python虚拟机中的函数机制

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.Python虚拟机在执行函数调用时会动态地创建新的 PyFrameObject对象, 这些PyFrameObject对象之间会形成PyFrameObject对象链,模拟x86平台上运行时栈 2.PyFuctionObject对象 typedef struct { PyObject_HEAD PyObject *func_code: //对应函数编译后的PyCodeObject对象 Py

Python源码剖析笔记4-内建数据类型

Python源码剖析笔记4-内建数据类型 Python内建数据类型包括整数对象PyIntObject,字符串对象PyStringObject,列表对象PyListObject以及字典对象PyDictObject等.整数对象之前已经分析过了,这一篇文章准备分析下余下几个对象,这次在<python源码剖析>中已经写的很详细的部分就不赘述了,主要是总结一些之前看书时疑惑的地方. 1 整数对象-PyIntObject 参见 python整数对象. 2 字符串对象-PyStringObject 2.1

《python源码剖析》笔记 python中的List对象

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.PyListObject对象 --> 变长可变对象,可看作vector<PyObject *> typedef struct{ PyObject_VAR_HEAD //其中的ob_size表示实际被使用的内存的数量 PyObject **ob_item;//ob_item为指向元素列表的指针,实际上,Python中的list[0]就是ob_item[0] int allocat