0
点赞
收藏
分享

微信扫一扫

梯度上升算法实现


 

机器学习实战中也详细描述了梯度上升算法,附件里是一些笔记,再贴一个还不错的帖子

 

 

这个算法搞得我晚上十点打电话给弟弟,问Ln(x),1/x的导数公式。很惭愧,大学时被我用的出神入化、化成灰我都能认出的求导公式,我今天居然忘了;这时也要说说西市佳园的移动网络信号,真不怎么好。这次我重点学习Logistic回归,涉及到了最大似然函数最大化的优化解法。

优点:计算代价不高,易于理解和实现;

缺点:容易欠拟合,分类精度可能不高;

适用数据类型:数值型和标称型数据。

Logistic回归使用Sigmoid函数分类。

梯度上升算法实现_取值范围

当x为0时,Sigmoid函数值为0.5,随着x的增大,Sigmiod函数将逼近于1;随着x的减小,Sigmoid函数将逼近于0。详情请移步http://en.wikipedia.org/wiki/Sigmoid_function。

如果用Logistic来预测呢?假设房价x和大小x1,户型x2,朝向x3这三个因素相关,x = w0 + w1*x1 + w2 * x2 + w3*x3,这里w0,w1, w2,w3是各个因素对最终房价的影响力的衡量,照常来说,房间大小x1对房价的决定性更大,那么w1会更大一些,朝向相对其他两个的影响因素更小一些,那么w3会小一些,这里假设朝向,户型和大小一样有相同的取值范围,当然,现实中朝向的取值不会多到和房子大小那么多。我们对每一个影响因素x都乘以一个系数w,然后这些计算出一个房价x,将x代入Sigmiod函数,进而得到一个取值范围在0---1之间的数,任何大于0.5的数据就被划分为一类,小于0.5的被划分为另一类。

下来看看这个函数:

梯度上升算法实现_梯度上升_02

。这个函数很有意思,当真实值y为1时,这个函数预测值为1的概率就是Sigmoid概率,当真实值y为0时,这个函数预测值为0的概率为1-Sigmoid概率。于是这个函数代表了Sigmoid函数预测的准确程度。当我们有N个样本点时,似然函数就是这N个概率的乘积

梯度上升算法实现_数据_03

。我们要做的呢,就是找出合适的w(w0,w1,w2...)让这个似然函数最大化,也就是尽量让N个样本预测的准确率达到最高。ln(f(x))函数不会改变f(x)的方向,f(x)的最大值和ln(f(x))的的最大值应该在一个点,为了求

梯度上升算法实现_数据_03

的最大值,我们可以求

梯度上升算法实现_机器学习_05

的最大值。

 


 

好了,就是求最大值的问题,这次使用梯度上升法(梯度上升法是用来求函数的最大值,梯度下降法是用来求函数的最小值)。梯度上升法的的思想是:要找到某函数的最大值,最好的方法是沿着该函数的梯度方向探寻,这样梯度算子总是指向函数增长最快的方向:

梯度上升算法实现_取值范围_06

,a为每次上升移动的步长,

梯度上升算法实现_取值范围_07

是f(w)的导数。下来呢,为了求

梯度上升算法实现_机器学习_05

的最大值,需要求这个函数的导数?然后让我们让预估的参数每次沿着导数的方向增加一定的步长a。

梯度上升算法实现_似然函数_09

错误注解:上边求导错误,应该再乘以xi

于是w:=w+a(y-h(x)),y是真实分类值,x是真实属性值,h(x)是预测值,也即是h(x)= w0 + w1*x1 + w2 * x2 + w3*x3...

 

说了这多,下面来实现这个算法实现


 


  1. def grad_ascent(dataset, datalabel):  
  2. 1 for i in range(len(dataset[0]))]  
  3. 0.01  
  4. for k in range(500):  
  5.         errset = []  
  6. for i in range(len(dataset)):  
  7.             sig = sigmoid(dataset[i], weight)  
  8.             errset.append(datalabel[i]-sig)  
  9.               
  10. for i in range(len(dataset[0])):  
  11. for j in range(len(dataset)):  
  12.                 weight[i] += alpha*dataset[j][i]*errset[j]   
  13. return weight  
  14.       
  15. def rand_grad_ascent(dataset, datalabel):  
  16. 1 for i in range(len(dataset[0]))]  
  17. 0.01  
  18. for i in range(len(dataset)):  
  19.         sig = sigmoid(dataset[i], weight)  
  20.         err = datalabel[i] - sig  
  21. for j in range(len(weight)):  
  22.             weight[j] += alpha*err*dataset[i][j]  
  23.               
  24. return weight  


整体测试文件如下:

 

 


[python]  view plain copy print ?

 


  1. import math  
  2. def sigmoid(data, weight):  
  3. for i in range(len(data))])  
  4. try:  
  5. return 1.0/(1+math.exp(-z))  
  6. except:  
  7. if z > 0: return 1.0  
  8. else: return 0.0  
  9.       
  10. def logistic_classify(data, weight):  
  11.     prob = sigmoid(data, weight)  
  12. if prob > 0.5: return 1.0  
  13. else: return 0.0  
  14.       
  15. def grad_ascent(dataset, datalabel):  
  16. 1 for i in range(len(dataset[0]))]  
  17. 0.01  
  18. for k in range(500):  
  19.         errset = []  
  20. for i in range(len(dataset)):  
  21.             sig = sigmoid(dataset[i], weight)  
  22.             errset.append(datalabel[i]-sig)  
  23.               
  24. for i in range(len(dataset[0])):  
  25. for j in range(len(dataset)):  
  26.                 weight[i] += alpha*dataset[j][i]*errset[j]   
  27. return weight  
  28.       
  29. def rand_grad_ascent(dataset, datalabel):  
  30. 1 for i in range(len(dataset[0]))]  
  31. 0.01  
  32. for i in range(len(dataset)):  
  33.         sig = sigmoid(dataset[i], weight)  
  34.         err = datalabel[i] - sig  
  35. for j in range(len(weight)):  
  36.             weight[j] += alpha*err*dataset[i][j]  
  37.               
  38. return weight  
  39.       
  40. def test(class_func):  
  41. 'horseColicTraining.txt')  
  42. 'horseColicTest.txt')  
  43.       
  44.     trainset, trainlabel = [], []  
  45. for line in f_train.readlines():  
  46. '\t')  
  47. 1]+[float(line_cur[i]) for i in range(21)])  
  48. 21]))  
  49.           
  50.     trainweight = class_func(trainset, trainlabel)  
  51.       
  52. 0, 0  
  53. for line in f_test.readlines():  
  54. '\t')  
  55. 1]+[float(line_cur[i]) for i in range(21)], trainweight)  
  56. 21])  
  57. if pred_class == read_class:  
  58. #print "class succ"  
  59. pass  
  60. else:  
  61. 1  
  62. #print "class fail, read_class=%d, pred_class=%d" %(read_class, pred_class)  
  63. 1  
  64.           
  65. print "totol num=%d, fail num = %d, rate = %f" % (tolnum, errnu, float(errnu)/tolnum)  
  66.       
  67. if __name__ == '__main__':  
  68.     test(grad_ascent)  
  69.     test(rand_grad_ascent)  


 

 

 

 

 

 

 

举报

相关推荐

0 条评论