完全忘记之前是怎么写的了,而且这章对数学的要求比较高,看了半天才有所了解,还不一定能自己推导出来公式
Logistic回归算法优点:对计算代价不高(没有太多的运算)易于理解和实现(对于代码的确好敲,但是要实现公式推导不好实现)。缺点:容易欠拟合(因为weight是根据X向量的值所产生的,X向量万一变化很大,weight有可能变化的比X慢的多,所以点与模拟曲线差距会变大)分类京都可能不高(由这题结果可以看出来)
Sigmoid函数不用多说,书上都有。但是看到《机器学习实战》第79页最上面的一段话
最后还需说明一点,你可能对2中公式的前两行觉得陌生。此处略去了一个简单的数学推导,我把它留给有兴趣的读者。
也就是下面两句
error = (lable - h)
weights = weights + alpha * dataMatrix.transpose() * error
这个error就是要推导的公式。
Logistic回归要用到梯度上升算法和极大似然估计方法。梯度上升算法这个书上讲了,相当于爬破,一点一点的接近最高点
,这样一点一点接近最高点,这就是梯度上升算法
接下来会用到极大似然估计方法,请原谅字丑,已经尽量写好了
然后回到代码部分。这次要跟书上不同的地方有两个,不知道怎么搞的,我用书上的代码会报错,所以修改了一下。
第一个:Sigmoid()函数,传进来的参数可能为负数,所以要分开处理
def Sigmoid(inX):
if inX>=0:
return 1.0/(1+exp(-inX))
else:
return exp(inX)/(1+exp(inX))
第二个:dataIndex = list(range(m)),因为不加list():dataIndex是range(m),在后面的del()会报错,因为del()不能对rande()执行,所以要写成list(range(m)),这样dataIndex就是个list了
然后完整代码:
from numpy import array,shape,random,ones
from math import exp
def GetDataSet(filename):
fl = open(filename,'r')
DataSet = []
LabelSet = []
lines = fl.readlines()
for line in lines:
line = line.split('\n')[0] #去掉最后一个换行符号,不可以用line = line[:-1]因为最后一行没有'\t',这样做会删掉最后一个数字。
list_line = [float(x) for x in line.split('\t')]
label = list_line.pop(-1)
DataSet.append(list_line)
LabelSet.append(label)
return DataSet,LabelSet
def Sigmoid(inX):
if inX>=0:
return 1.0/(1+exp(-inX))
else:
return exp(inX)/(1+exp(inX))
def Logistic():
filename = 'PythonTest/机器学习/machinelearninginaction-master/Ch05/horseColicTraining.txt'
DataSet,LabelSet = GetDataSet(filename)
m,n=shape(DataSet)
weight = ones(n)
for j in range(200): #循环200遍
dataIndex = list(range(m))
#这里不加list()会报错,原因上面说了
for i in range(m):
a = 1/(i+j+1) + 0.001 #我觉得书上说错了,应该是每次缩小1/(i+j+1)*(i+j+2),不过无所谓啦。
rand_x = int(random.uniform(0,len(dataIndex)))
h = Sigmoid(sum(DataSet[rand_x]*weight))
error = LabelSet[rand_x] - h
weight = weight + a*error*array(DataSet[rand_x])
del(dataIndex[rand_x])
return weight
def Classify(x):
if x > 0.5:
return 1
else:
return 0
def LogisticTest():
filename = 'PythonTest/机器学习/machinelearninginaction-master/Ch05/horseColicTest.txt'
DataSet,LabelSet = GetDataSet(filename)
weight = Logistic()
i = 0
right = 0.0
count = 0.0
for testdata in DataSet:
Label = Sigmoid(sum(weight*testdata))
if Classify(Label) == LabelSet[i]:
right += 1
count += 1
right_rate = right/count
print(right_rate)
LogisticTest()