西瓜书3.3 尝试解题(python)对率回归 极大似然估计
数据如下:
x01=[0.697,0.774,0.634,0.608,0.556,0.403,0.481,0.437,0.666,\
0.243,0.245,0.343,0.639,0.657,0.360,0.593,0.719]
x02=[0.460,0.376,0.264,0.318,0.215,0.237,0.149,0.211,0.091,\
0.267,0.057,0.099,0.161,0.198,0.370,0.042,0.103]
y=[1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0]
x01表示密度,x02表示含糖率,y标志瓜的好坏(1为好,0为坏)
这道题的目的是实现对率回归,那么从3.3节看起。
可以看到我们要求的其实是一个系数序列ω和一个偏差b。简单看过对率回归的介绍后,直接来看推导过程。
将前面的3.19稍微改写一下就可以得到3.22,而由于又有p(y=1|x)+p(y=0|x)=1,所以可以得到3.23和3.24这样的式子。
3.19:ln(y/(1-y))=ωΤx+b
3.22:ln p(y=1|x)/p(y=0|x) =ωΤx+b
按照提示,跳到7.2查看极大似然估计。第一句话指出在估计参数前要假定其具有某种确定的概率分布形式,而在这一题中
我们的概率分布形式就是对率函数,使用极大似然估计就是根据已知的样本来估计参数,解释一下类条件概率指的是在
某种前提下发生某一事件的概率,则P(x|θc)的具体含义就是参数向量为θc时事件x的发生概率。需要厘清一下“概率”和“似然”的区别,
简单来讲概率就是在给定参数时事件发生的可能性,而似然就是在已知随机事件后、概率分布的参数为某一值的可能性(相对于其他
参数取值而言)。具体的解释指路大佬的博客:https://blog.csdn.net/songyu0120/article/details/85059149 讲得非常详尽易懂
而7.9告诉我们的就应当是,已知发生c类事件时,参数θ的值为θc的概率等于参数值为θc时每一个c类事件发生的概率的乘积,
理所当然的,对问题而言最合适的θc就是使7.9式等号右侧的值最大的那个。而7.10中的对数转换操作原理就是将乘法转化为加法,
从而有效防止下溢(超出数据类型所能表示的最小数字),而对数的转换也不会带来信息的损失。
再回到3.25就能看明白它的含义了:对于给定的数据集{(xi,yi)} i∈(1,m) 和一组参数集(ω,b),每个样本属于其真实标记的概率p
的累乘就是这组参数集的似然。而在式中使用了对数似然来防止下溢。
3.25到3.26的操作只是进行了符号的合并简化以及将两种情况的概率巧妙地分离开。
而将3.23与3.34的p1、p0式子代入3.26后,分类讨论y=0、y=1的情况而后观察,就可以把结果合并为3.27的形式,再取负就得到3.27。
因为取负了,所以本来我们要求的是式子的最大值现在变成求式子的最小值。书上应用的是牛顿法。
牛顿法,其核心思想就是泰勒展开。首先讲讲其在方程求解中的应用,然后理解其在最优化的应用会方便很多。
在求解方程的求根公式很复杂甚至没有求根公式时,可以利用牛顿法进行迭代求解,过程就是利用泰勒公式在x0处展开到
一阶,使f(x)=f(x0)+(x-x0)f'(x0)=0,求得一个x1使f(x)比较接近于0,显然,要是我们重复使用这个方法也就是迭代,我们就可以
得到更加准确的答案直到最后在f(x*)=0收敛。
在最优化问题中,如果我们要求一个函数的极大极小问题,显然可以转化为求解函数导数=0的问题,那么就可以使用牛顿法
在方程求解中的方法。因为要求一阶导数的结果等于0,所以对原函数进行两阶泰勒展开,得到
f(x+△x)=f(x+△x)+f'(x+△x)△x+f''(x+△x)△x²/2,两侧对△x求导,在△x无限趋近于0的时候,就可以忽略函数中的△x,从而得到
f'(x)+f''(x)△x=0。则△x=-f'(x)/f''(x)。把△x视作Xn+1(第n+1个迭代解)与Xn(第n个迭代解)的差值,我们就可以得到
迭代解的更新公式,Xn+1=Xn-f'(x)/f''(x)。用矩阵计算代换就可以得到3.29。其中一阶项和二阶项的计算方法都在后面给出,
那么我们只要使用编程实现就行了。
首先,为了方便起见我们要引入numpy这个库来进行矩阵计算,所以对于数据集我们要做一些改动:
x=np.array([[0.697,0.774,0.634,0.608,0.556,0.403,0.481,0.437,0.666,\
0.243,0.245,0.343,0.639,0.657,0.360,0.593,0.719],
[0.460,0.376,0.264,0.318,0.215,0.237,0.149,0.211,0.091,\
0.267,0.057,0.099,0.161,0.198,0.370,0.042,0.103],\
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]])
y=np.array([1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0])
before=np.array([[0],[0],[1]])
将x的数据合并并加入一行1,这个操作对应于3.25和3.26之间那段中的操作,before矩阵就是参数的数据集合,我们不妨设起始参数为0,0,1。
编写程序时要时刻记住x、y、before在书上推导过程中都是单列矩阵,但操作中我们的一些操作会使之变成行矩阵,在后续计算中要及时转置
回来。比如:
np.array([x[:,i]])
这样的操作,目的是从x中取出第i列作为一个单独矩阵,取出后默认是行矩阵,要及时转置。
清楚这点后着手编写各部分的代码。
首先是一阶导的计算:
def fd():
b1 = 0
for i in range(17):
k=np.exp(np.dot(before.T,np.array([x[:,i]]).T))
b1=b1-np.array([x[:,i]])*( y[i]-(k/(1+k)))
return b1
而后是二阶导的计算:
def sd():
b2 = 0
for i in range(17):
k = np.exp(np.dot(before.T,np.array([x[:,i]]).T))
b2=b2+np.dot(np.array([x[:,i]]).T,np.array([x[:,i]])) * (k/(1+k)) * (1-(k/(1+k)))
return b2
最后是主函数,偷个懒不追求最终结果是否收敛的话,限定一个迭代次数上限就完事:
k=1000
while(k):
k-=1
b1=fd()
b2=sd()
before=before-np.dot(linalg.inv(b2),b1.T) print(before)
如果要寻求更精确的结果,可以稍微修改主函数的内容:
mae=0
ima=0
n=0
while(1):
ima=0
for i in range(17):
k=np.dot(before.T,np.array([x[:,i]]).T)
ima=ima+(-y[i]*k+np.log(1+np.exp(k)))
if(np.abs(ima-mae)<=0.001):
break
mae=ima
n=n+1
b1=fd()
b2=sd()
before=before-np.dot(linalg.inv(b2),b1.T)
print('迭代次数:',n)
print('最终参数:',before)
其实就是每次计算出3.27式的值并且在和前次差值小于等于0.00001时退出并输出结果。
结果:
迭代次数: 4
最终参数: [[ 3.15832738]
[12.52119012]
[-4.42886222]]
完整代码:
import math
import numpy as np
from numpy import linalg x=np.array([[0.697,0.774,0.634,0.608,0.556,0.403,0.481,0.437,0.666,\
0.243,0.245,0.343,0.639,0.657,0.360,0.593,0.719],
[0.460,0.376,0.264,0.318,0.215,0.237,0.149,0.211,0.091,\
0.267,0.057,0.099,0.161,0.198,0.370,0.042,0.103],\
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]])
y=np.array([1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0])
before=np.array([[0],[0],[1]]) def fd():
b1 = 0
for i in range(17):
k=np.exp(np.dot(before.T,np.array([x[:,i]]).T))
b1=b1-np.array([x[:,i]])*( y[i]-(k/(1+k)))
return b1 def sd():
b2 = 0
for i in range(17):
k = np.exp(np.dot(before.T,np.array([x[:,i]]).T))
b2=b2+np.dot(np.array([x[:,i]]).T,np.array([x[:,i]])) * (k/(1+k)) * (1-(k/(1+k)))
return b2 mae=0
ima=0
n=0
while(1):
ima=0
for i in range(17):
k=np.dot(before.T,np.array([x[:,i]]).T)
ima=ima+(-y[i]*k+np.log(1+np.exp(k)))
if(np.abs(ima-mae)<=0.000001):
break
mae=ima
n=n+1
b1=fd() b2=sd()
before=before-np.dot(linalg.inv(b2),b1.T) print('迭代次数:',n)
print('最终参数:',before)
西瓜书3.3 尝试解题(python)对率回归 极大似然估计的更多相关文章
- python实现简单决策树(信息增益)——基于周志华的西瓜书数据
数据集如下: 色泽 根蒂 敲声 纹理 脐部 触感 好瓜 青绿 蜷缩 浊响 清晰 凹陷 硬滑 是 乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 是 乌黑 蜷缩 浊响 清晰 凹陷 硬滑 是 青绿 蜷缩 沉闷 清晰 ...
- 决策树ID3原理及R语言python代码实现(西瓜书)
决策树ID3原理及R语言python代码实现(西瓜书) 摘要: 决策树是机器学习中一种非常常见的分类与回归方法,可以认为是if-else结构的规则.分类决策树是由节点和有向边组成的树形结构,节点表示特 ...
- 朴素贝叶斯python代码实现(西瓜书)
朴素贝叶斯python代码实现(西瓜书) 摘要: 朴素贝叶斯也是机器学习中一种非常常见的分类方法,对于二分类问题,并且数据集特征为离散型属性的时候, 使用起来非常的方便.原理简单,训练效率高,拟合效果 ...
- 孤荷凌寒自学python第五十九天尝试使用python来读访问远端MongoDb数据服务
孤荷凌寒自学python第五十九天尝试使用python来读访问远端MongoDb数据服务 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第五天.今天的感觉是,mongoDB数 ...
- 孤荷凌寒自学python第五十七天初次尝试使用python来连接远端MongoDb数据库
孤荷凌寒自学python第五十七天初次尝试使用python来连接远端MongoDb数据库 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第三天.感觉这个东西学习起来还是那么困 ...
- 孤荷凌寒自学python第五十二天初次尝试使用python读取Firebase数据库中记录
孤荷凌寒自学python第五十二天初次尝试使用python读取Firebase数据库中记录 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数 ...
- 孤荷凌寒自学python第五十一天初次尝试使用python连接Firebase数据库
孤荷凌寒自学python第五十一天初次尝试使用python连接Firebase数据库 (完整学习过程屏幕记录视频地址在文末) 今天继续研究Firebase数据库,利用google免费提供的这个数据库服 ...
- 周志华-机器学习西瓜书-第三章习题3.5 LDA
本文为周志华机器学习西瓜书第三章课后习题3.5答案,编程实现线性判别分析LDA,数据集为书本第89页的数据 首先介绍LDA算法流程: LDA的一个手工计算数学实例: 课后习题的代码: # coding ...
- LASSO回归与L1正则化 西瓜书
LASSO回归与L1正则化 西瓜书 2018年04月23日 19:29:57 BIT_666 阅读数 2968更多 分类专栏: 机器学习 机器学习数学原理 西瓜书 版权声明:本文为博主原创文章,遵 ...
- 决策树 机器学习,西瓜书p80 表4.2 使用信息增益生成决策树及后剪枝
使用信息增益构造决策树,完成后剪枝 目录 使用信息增益构造决策树,完成后剪枝 1 构造决策树 1 根结点的选择 色泽 信息增益 根蒂 信息增益 敲声 信息增益 纹理 信息增益 脐部 信息增益 触感 信 ...
随机推荐
- SQL server数据库中nvarchar和varchar的区别
先说结论: 存储内容含有汉字的使用nvarchar 存储内容全是英文没有汉字的使用varchar 1.varchar是非Unicode可变长度类型,nvarchar是Unicode可变长度类型. 2. ...
- 使用 EMQX Cloud 桥接数据到 GCP Pub/Sub
前不久,Google 宣布其旗下的 GCP IoT Core 即将在 2023 年 8 月 16 日停止提供服务.这意味着大量使用 GCP IoT Core 的用户可能需要将他们的 IoT 应用迁移到 ...
- NTP Mode 6 检测漏洞【原理扫描】
系统: AIX7 cd /etc cp ntp.conf ntp.conf.bak vi net.conf ## 在最后加上一行 restrict default notrust nomodify n ...
- noi 2.1 1978 生理周期
noi 1978 生理周期 1.描述 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为23天.28天和33天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如, ...
- 所谓的安装phpmyadmin
所谓的安装phpmyadmin, 或者 安装drush, 都是下载一个文件, 然后URL访问或者命令行访问这个文件, 进入到某个页面或者获得某个结果.刚开始觉得很神秘哦, 为什么?--安装软件分两种1 ...
- 华为交换机,改vlan的方法
telnet 登录1.1.1.111, 如果登录再到其他交换机,需要在用户状态,telnet其他的ip.不能在系统用户状态下跳转登录. sys改为系统用户 状态符由尖括号,改为方括号 display ...
- sudo apt update 没有 Release 文件
注: 不同环境出错原因可能不同,本文仅供参考. 今天在Ubuntu 19.04 系统运行指令 sudo apt update 时,忽然提示错误,报错如下: 404 Not Found [IP: 101 ...
- k8s入门_RC、RS、Deployment
RC 什么是RC: Replication Controller(副本控制器),RC能够保证pod在任意时间运行的副本数量,能够保证pod总是可用的. RC控制的pod的多个副本,每个副本都有独立的i ...
- android studio 导出 release aar
- 2020ICPC上海I - Sky Garden
思维 [I-Sky Garden_第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海)(重现赛)@hzy0227 (nowcoder.com)](https://codeforces.co ...