对数几率回归法(梯度下降法,随机梯度下降与牛顿法)与线性判别法(LDA)

Posted 视野

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对数几率回归法(梯度下降法,随机梯度下降与牛顿法)与线性判别法(LDA)相关的知识,希望对你有一定的参考价值。

  本文主要使用了对数几率回归法与线性判别法(LDA)对数据集(西瓜3.0)进行分类。其中在对数几率回归法中,求解最优权重W时,分别使用梯度下降法,随机梯度下降与牛顿法。

代码如下:

  1 #!/usr/bin/env python
  2 # -*- coding: utf-8 -*-
  3 # @Date    : 2017-05-09 15:03:50
  4 # @Author  : whb (whb@bupt.edu.cn)
  5 # @Link    : ${link}
  6 # @Version : $Id$
  7 
  8 import numpy as p
  9 import matplotlib.pyplot as plt
 10 import pandas as pd
 11 import random
 12 from scipy.linalg import solve,inv
 13 
 14 def read_data(file_name):
 15     train_data = pd.read_excel(file_name)  # 得到一个数据框(每一列代表一个实例)
 16     return[list(train_data.ix[0]), list(train_data.ix[1]), list(train_data.ix[2]), list(train_data.ix[3])]
 17 ###算法##
 18 # 1 对数几率回归
 19 def func(x, y, w):
 20     #\'x为样本,y为样本类别,w为权重+偏向\'
 21     n = len(x[0])  # 训练集个数
 22     m = len(x)  # 每个实例的属性个数 m-1
 23     result = 0
 24     for i in xrange(n):
 25         s = 0
 26         for j in xrange(m):
 27             s += x[j][i] * w[j]
 28         result += -y[i] * (s) + p.log(1 + p.exp(s))
 29     return result
 30 
 31 
 32 def p1(x, w):
 33     # 后验概率估计
 34     wx = 0
 35     for i in xrange(len(x)):
 36         wx += w[i] * x[i]
 37     return p.exp(wx) / (1 + p.exp(wx))
 38 
 39 
 40 def dfunc(x, y, w):
 41     # 一阶导数
 42     df = p.zeros(len(x))
 43     for i in xrange(len(x[0])):
 44         df += x[:, i] * (y[i] - p1(x[:, i], w))
 45     return -df
 46 
 47 
 48 def d2func(x, y, w):
 49     # 二阶导数
 50     n = len(x[0])
 51     d2f = p.zeros((n, n))
 52     for i in xrange(len(x[0])):
 53         d2f[i][i] = (1 - p1(x[:, i], w)) * p1(x[:, i], w)
 54     return p.mat(x) * p.mat(d2f) * p.mat(x.transpose())
 55 
 56 
 57 # 牛顿法
 58 def newtown(x, y, w, error, n):
 59     i = 1
 60     while i < n:
 61         d1 = dfunc(x, y, w)
 62         if p.dot(d1, d1) < error:
 63             print \'牛顿法: 迭代 \' + str(i) + \'步:w=\', w
 64             return w
 65             break
 66         w = w - solve(d2func(x, y, w), dfunc(x, y, w))
 67         i += 1
 68     
 69 
 70 # 梯度下降法
 71 def gradienet_down(x, y, w, error, n):
 72     i = 1
 73     h = 0.1
 74     while i < n:
 75         start1 = func(x, y, w)
 76         df = dfunc(x, y, w)
 77         w = w - h * df
 78         start2 = func(x, y, w)
 79         if abs(start1 - start2) < error:
 80             print \'梯度下降法:迭代 \' + str(i) + \'步:w=\', w
 81             return w
 82             break
 83         i += 1
 84     
 85 
 86 #随机梯度下降算法
 87 def SGD(x, y, w, error, n):
 88     i = 1
 89     h = 0.1
 90     while i < n:
 91 
 92         start1 = func(x, y, w)
 93         
 94         x_set=range(17)
 95         random.shuffle(x_set) #随机洗牌
 96         for k in  x_set: #只使用一个样本更新权重
 97             df = -x[:, k] * (y[k] - p1(x[:, k], w))
 98             w = w - h * df
 99         start2 = func(x, y, w)
100         if abs(start1 - start2) < error:
101             print \'随机梯度法: 迭代\' + str(i) + \'步:w=\', w
102             return w
103             break
104         i += 1
105     
106 
107 
108 
109 #LDA线性判别法
110 def LDA(x,y):
111     x=p.mat(x[:2])
112     u0=p.zeros((2,1))
113     m0=0
114     u1=p.zeros((2,1))
115     m1=0
116     for  j in xrange(len(y)):
117         if y[j]==1:
118             u1 += x[:,j]
119             m1 +=1
120         else:
121             u0 += x[:,j]
122             m0 +=1
123     u0=u0/m0 #均值
124     u1=u1/m1      
125     sum_=p.zeros((2,2)) #类内方差矩阵。
126     for i in xrange(17):
127         if y[i]==1:
128             sum_ += (x[:,i]-u1)*(p.mat(x[:,i]-u1).T)
129         else:
130             sum_ += (x[:,i]-u0)*(p.mat(x[:,i]-u0).T)
131     return inv(sum_)*p.mat(u0-u1)
132 
133 #可视化
134 def result_plot(x,y,w_min):
135     x1 = p.arange(0, 0.8, 0.01)
136     y1 = [-(w_min[2] + w_min[0] * x1[k]) / w_min[1] for k in xrange(len(x1))]
137     color = [\'r\'] * y.count(1.) + [\'b\'] * y.count(0.)
138     plt.scatter(x[0], x[1], c=color)
139     plt.plot(x1, y1)
140 
141 
142 if __name__ == \'__main__\':
143     file_name = \'xigua.xls\'
144     data = read_data(file_name)
145     x = data[:3]  # 各实例的属性值
146     x = p.array(x)
147     y = data[-1] # 类别标记
148     w = [1, 1, 1]  # 初始值
149     error = 0.0001  # 误差
150     n = 1000  # 迭代步数
151 
152     w_min=newtown(x,y,w,error,n)
153 
154     w_min1= gradienet_down(x, y, w, error, n)
155 
156     w_min11=SGD(x, y, w, error, n)
157   
158     w_min2=LDA(x, y)
159     
160     w_min2=[w_min2[0,0],w_min2[1,0],0]
161     # 可视化
162     plt.figure(1)
163     plt.subplot(221)
164     result_plot(x,y,w_min)
165     plt.title(u\'牛顿法\')
166     plt.subplot(222)
167     result_plot(x,y,w_min1)
168     plt.title(u\'梯度下降法\')
169     plt.subplot(223)
170     result_plot(x,y,w_min11)
171     plt.title(u\'随机梯度下降法\')
172     plt.subplot(224)
173     result_plot(x,y,w_min2)
174     plt.title(u\'LDA\')
175     plt.show()
176     
View Code

结果:

牛顿法: 迭代 5步:w= [ 3.14453235 12.52792035 -4.42024654]
梯度下降法:迭代 838步:w= [ 2.80637226 11.14036869 -3.95330427]
随机梯度法: 迭代182步:w= [ 1.84669379 6.02658819 -2.31718771]

以上是关于对数几率回归法(梯度下降法,随机梯度下降与牛顿法)与线性判别法(LDA)的主要内容,如果未能解决你的问题,请参考以下文章

python与R语言手推logistic回归(梯度下降法/牛顿法)

最小二乘法+牛顿法+拟牛顿法+梯度下降法+梯度上升法+共轭梯度法

梯度下降法与牛顿下降法速度的比较

牛顿法梯度下降法与拟牛顿法

梯度下降法实现对数几率回归

梯度下降之模拟退火梯度下降之学习计划牛顿法拟牛顿法共轭梯度法