在《机器学习》第53页,书中应该是存在对行向量(1×N矩阵)、列向量(N×1矩阵)的描述错误问题。如下图:
我在划线位置分别加上了两个转置符号"T"。按照原来书上的写法w和x都是一个行向量,wT则是列向量。因此wT与x的结果应该是一个N×N的矩阵,而并非式(3.1)所写的具体的值。
我们希望找到一个函数满足下面的条件:
正例 | 反例 |
---|---|
y=1 | y=0 |
单位阶跃函数可以满足上述要求,但是单位阶跃函数并不“线性”,因此只能寻找一个替代函数。对数几率函数恰好可以近似地满足上述要求。
因此,采用对数几率函数分类的基本思想就是——大于0的为正例,小于0的为反例。
最初的权重是我们“蒙”的,我们希望计算机能够根据数据集总结出一个靠谱的规律。在每次学习的过程中,计算机都会对这个权重进行一些改变。如果这个数据集中存在一定规律,那么最终的权重就会逐渐“收敛”到一个值,也就是“回归”。
from numpy import *
data_count = 17
density_list = [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]
sugar_list = [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]
# 二者均为列向量
beta = mat((3.159, 12.521, -4.43)).T
beta1 = mat((0, 0, 0)).T
beta2 = mat(zeros((3, 3)))
# 分别记录当前和之后的似然估计值
l_before = 0
l_now = 0
while True:
l_before = l_now
l_now = 0
for i in range(0, data_count):
# x为列向量
x = mat((density_list[i], sugar_list[i], 1)).T
z = (beta.T * x)[0, 0]
p1 = 1 / (1 + e ** (-z))
beta1 = beta1 - x * (y[i] - p1)
beta2 = beta2 + (x * x.T) * p1 * (1 - p1)
l_now = l_now + log(1 + e ** z) - y[i] * z
beta = beta - beta2.I * beta1
if abs(l_now - l_before) < 10 ** -8:
break
print('min-log-likelihood:', l_now)
print('-' * 50)
print('density_weight:', beta[0, 0])
print('sugar_weight:', beta[1, 0])
print('b:', beta[2, 0])
print('-' * 50)
for i in range(0, data_count):
result = beta[0, 0] * density_list[i] + beta[1, 0] * sugar_list[i] + beta[2, 0]
print(i ,'--->估计结果:', result)
上述代码中,beta1表示对beta求一阶偏导(书中式3.30),beta2表示对beta求二阶偏导(书中式3.31),l_now是对书中式3.27的应用。
代码很简单,更重要的是对结果进行分析,从发现一些问题。
if abs(l_now - l_before) < 10 ** -8:
break
上述为本人自己在学习、编程过程中的一点体会,如果有错误,希望各位指正。顺便希望各位支持一下。