zoukankan      html  css  js  c++  java
  • 对数几率回归法(梯度下降法,随机梯度下降与牛顿法)与线性判别法(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]

  • 相关阅读:
    吊打996,来了?!
    微软开源浏览器自动化工具Playwright for Python(附源码)
    从0到1开始建设安全测试体系
    网友爆料vivo将取消大小周,不降薪,官方证实消息属实
    认识了一个在华为任职的50岁程序员!
    漫画:什么是自动驾驶?
    中国十大杰出人物
    最难调试修复的 bug 是怎样的?
    “十年不升职多得是,四年算什么”
    appium+pytest实现APP并发测试
  • 原文地址:https://www.cnblogs.com/whb-20160329/p/6846657.html
Copyright © 2011-2022 走看看