zoukankan      html  css  js  c++  java
  • A--python梯度下降算法实践

    In [1]:
    import numpy as np
    import pandas as pd
    import matplotlib
    import matplotlib.pyplot as plt
    %matplotlib inline
     
    In [2]:
    #自定义一个归一化函数(此函数的前提是我的数据是一个矩阵)
    def regularize(xMat):
        inMat = xMat.copy()#创建一个副本,这样对inmat进行操作不会影响到xmat
        inMeans = np.mean(inMat,axis = 0) #求均值
        inVar = np.std(inMat,axis = 0) #求标准差
        inMat = (inMat - inMeans)/inVar #归一化
        return inMat

    BGD批量梯度下降法

    In [ ]:
    w=w-a*x.T(X*W-Y)/M
    In [4]:
    #参数分别为 数据集 学习率(步长) 简单粗暴的设置最高迭代次数
    def gradDescent_0(dataSet,eps=0.01,numIt=50000):
        xMat = np.mat(dataSet.iloc[:, :-1].values)#分别为截取 x与y 放到矩阵(matrix)中
        yMat = np.mat(dataSet.iloc[:, -1].values).T
        xMat = regularize(xMat) #分别对X 与Y 进行归一化
        yMat = regularize(yMat) 
        m,n = xMat.shape
        weights = np.zeros((n,1)) #设我们的初始系数(权重)
        B=0
        for k in range(numIt): #迭代次数
            grad = xMat.T * (xMat * weights - yMat) / m #计算梯度
            B=
            weights = weights - eps * grad#更新权重
        return weights
     
    In [7]:
    aba = pd.read_table('abalone.txt', header = None)#该数据集源于UCI,记录了鲍⻥的⽣物属性,⽬标字段是该⽣物的年龄
    aba.head()
    Out[7]:
     012345678
    0 1 0.455 0.365 0.095 0.5140 0.2245 0.1010 0.150 15
    1 1 0.350 0.265 0.090 0.2255 0.0995 0.0485 0.070 7
    2 -1 0.530 0.420 0.135 0.6770 0.2565 0.1415 0.210 9
    3 1 0.440 0.365 0.125 0.5160 0.2155 0.1140 0.155 10
    4 0 0.330 0.255 0.080 0.2050 0.0895 0.0395 0.055 7
    In [8]:
    aba.shape
    Out[8]:
    (4177, 9)
    In [12]:
    aba.tail()
     
    Out[12]:
     012345678
    4172 -1 0.565 0.450 0.165 0.8870 0.3700 0.2390 0.2490 11
    4173 1 0.590 0.440 0.135 0.9660 0.4390 0.2145 0.2605 10
    4174 1 0.600 0.475 0.205 1.1760 0.5255 0.2875 0.3080 9
    4175 -1 0.625 0.485 0.150 1.0945 0.5310 0.2610 0.2960 10
    4176 1 0.710 0.555 0.195 1.9485 0.9455 0.3765 0.4950 12
    In [13]:
    aba.info()
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 4177 entries, 0 to 4176
    Data columns (total 9 columns):
    0    4177 non-null int64
    1    4177 non-null float64
    2    4177 non-null float64
    3    4177 non-null float64
    4    4177 non-null float64
    5    4177 non-null float64
    6    4177 non-null float64
    7    4177 non-null float64
    8    4177 non-null int64
    dtypes: float64(7), int64(2)
    memory usage: 293.8 KB
    
    In [29]:
    aba[1].isnull().value_counts()

    Out[29]:

    False    4177
    Name: 1, dtype: int64
    In [30]:
    #计算
    2
    gradDescent_0(aba,eps=0.01,numIt=5000)
    Out[30]:
    matrix([[ 0.01501141],
            [ 0.0304397 ],
            [ 0.31206232],
            [ 0.15730289],
            [ 0.38951011],
            [-0.94609003],
            [-0.10003637],
            [ 0.74573878]])
    In [31]:
    #用最小二乘得出结论以对比结果
    xMat = np.mat(aba.iloc[:, :-1].values)
    yMat = np.mat(aba.iloc[:, -1].values).T
    xMat = regularize(xMat)
    yMat = regularize(yMat)
    xTx = xMat.T*xMat
    ws = xTx.I * (xMat.T*yMat)
    ws
    Out[31]:
    matrix([[ 0.0162406 ],
            [-0.05874764],
            [ 0.41308287],
            [ 0.15391644],
            [ 1.4069792 ],
            [-1.39621019],
            [-0.3318546 ],
            [ 0.37046383]])
    In [32]:
    aba[0].mean()
    Out[32]:
    0.052908786210198705
    In [34]:
    weights = np.zeros((9,1))
    weights

    Out[34]:

    array([[0.],
           [0.],
           [0.],
           [0.],
           [0.],
           [0.],
           [0.],
           [0.],
           [0.]])
     

    SGD随机梯度下降法

     

    随机梯度下降法,其实和批量梯度下降法原理类似,区别在与求梯度时没有⽤所有的m个样本的数据,⽽是仅仅选取⼀个样本j来求梯度。

     

    另:由于是随机抽取一部分做梯度,随机性太强,所以最好加大迭代次数到6为数左右

     

    又:由于随机梯度下降输出系数随机性较大,所以不适合用来解线性回归

    In [39]:
    #可见基本操作都是一样的,区别在于我们对数据集进行了有放回抽样
    def gradDescent_1(dataSet,eps=0.01,numIt=500000):
        dataSet = dataSet.sample(numIt, replace=True)#sample函数进行随机抽样多少次,参数 replace=True 表示 是有放回的
        dataSet.index = range(dataSet.shape[0])#对index 进行规整化
        xMat = np.mat(dataSet.iloc[:, :-1].values)
        yMat = np.mat(dataSet.iloc[:, -1].values).T
        xMat = regularize(xMat)
        yMat = regularize(yMat) 
        m, n = xMat.shape
        weights = np.zeros((n,1))
        for i in range(m): #迭代次数
            grad = xMat[i].T * (xMat[i] * weights - yMat[i])#这里每次计算梯度时 只选取一条
            weights = weights - eps * grad
        return weights
    In [42]:
    import time
    %time gradDescent_1(aba)#几次计算的系数均不一致,是因为结果本身就是一个解空间,最终sse 可能差别不大
    Wall time: 46.6 s
    
    Out[42]:
    matrix([[ 0.05499166],
            [-0.11769103],
            [ 0.34716992],
            [ 0.40666376],
            [ 1.41184507],
            [-1.25264229],
            [-0.33662608],
            [ 0.28914221]])
    In [ ]:
    def sseCal(dataSet, regres):#设置参数为 数据集 与 回归方法
        n = dataSet.shape[0] 
        y = dataSet.iloc[:, -1].values
        ws = regres(dataSet)
        yhat = dataSet.iloc[:, :-1].values * ws
        yhat = yhat.reshape([n,])
        rss = np.power(yhat - y, 2).sum()
        return rss
    In [45]:
    %%time
    n=aba.shape[0]
    y=aba.iloc[:,-1].values
    ws=gradDescent_1(aba)
    yhat=aba.iloc[:,:-1].values * ws
    yhat=yhat.reshape([n,])
    rss = np.power(yhat - y, 2).sum()
    rss
    
     
    Wall time: 46.9 s
    In [46]:
    rss
    Out[46]:
    379691.65605548245
    In [48]:
    #封装R**2
    def rSquare(dataSet, regres):#设置参数为 数据集 与 回归方法
        sse = sseCal(dataSet, regres) 
        y = dataSet.iloc[:, -1].values
        sst = np.power(y - y.mean(), 2).sum()
        return 1 - sse / sst
    In [49]:
    rSquare(aba, gradDescent_1)
    Out[49]:
    -7.374175454585444
     
  • 相关阅读:
    【jquery的setTimeOut定时器使用】
    python windows安装 SQLServer pymssql,
    python csv文件转换成xml, 构建新xml文件
    python 修改xml文档 ing
    python XML文件解析:用ElementTree解析XML
    python XML文件解析:用xml.dom.minidom来解析xml文件
    python range函数
    python 数据序列化(json、pickle、shelve)
    python 使用json.dumps() 的indent 参数,获得漂亮的格式化字符串后输出
    python 将一个JSON 字典转换为一个Python 对象
  • 原文地址:https://www.cnblogs.com/Koi504330/p/11909392.html
Copyright © 2011-2022 走看看