[机器学习算法] 梯度下降 python实现 (多变量线性回归)

目录

 

思路

代码

效果


思路

依然是按照吴恩达老师机器学习课程上的思路进行编写,重点截图如下。

代码

from sklearn import datasets
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D  # plot 3d

class Mul_V_Linear_Regression():
    def __init__(self, dataset, learning_rate):
        self.dataset = dataset
        self.learning_rate = learning_rate
        self.row = len(dataset.data)
        self.col = len(dataset.data[0])+1
        self.features = np.c_[np.ones(self.row), dataset.data]
        self.label = dataset.target
        self.theta = np.zeros(self.col)

    # hypothesis
    def h(self, x):       # x's size = col+1, the first one is 1.
        res = 0
        for i in range(len(self.theta)):
            res += x[i] * self.theta[i]
        return res

    # cost function
    def J(self):
        temp = 0
        for i in range(self.row):
            temp += pow(self.h(self.features[i]) - self.label[i], 2)
        #print(temp)
        return 1 / (2 * self.row) * temp

    # partial derivative
    def pd_theta_J(self, index):
        temp = 0
        for i in range(self.row):
            temp += (self.h(self.features[i]) - self.label[i]) * self.features[i][index]
        return 1 / self.row * temp

    # gradient descent
    def gd(self):
        min_cost = 0.01
        round = 1
        max_round = 100
        while (min_cost < abs(self.J()) and round <= max_round):
            temp = np.zeros(self.col)
            for i in range(self.col):
                temp[i] = self.theta[i] - self.learning_rate * self.pd_theta_J(i)
            self.theta = temp
            print('round', round, ':')
            for i in range(self.col):
                print(self.theta[i])
            round += 1
        print(self.J())
        return self.theta


if __name__ == '__main__':
    boston = datasets.load_boston()
    x = boston.data[:, 5]
    y = boston.data[:, 12]
    z = boston.target

    boston.data = np.c_[x, y]   # only 5th and 12th is linear
    mul = Mul_V_Linear_Regression(boston, 0.008)
    theta = mul.gd()

    # plot scatter
    fig = plt.figure()
    ax = Axes3D(fig)
    ax.scatter(x, y, z)

    # plot line
    x = [8, 9]
    y = [40, 5]
    z = [theta[0]+theta[1]*x[0]+theta[2]*y[0], theta[0]+theta[1]*x[1]+theta[2]*y[1]]
    print(z)
    figure = ax.plot(x, y, z, c='r')

    ax.set_zlabel('Z', fontdict={'size': 15, 'color': 'red'})
    ax.set_ylabel('Y', fontdict={'size': 15, 'color': 'red'})
    ax.set_xlabel('X', fontdict={'size': 15, 'color': 'red'})
    plt.show()

选用sklearn的boston房价的数据,其中只有第5列和第12列(从0开始)与最终的房价呈线性关系。在画直线的时候选取的[9.3, 28.6, z1], [3.25, 1.25, z2]是根据数据画出来的散点图选取的x,y的点,但是感觉这样并不准确,最终形成的应该是一个平面(z = theta0 + theta1*x + theta2*y), 所以选取的点不同,直线应该会有一定的偏移,这是需要后续再弄明白的地方。(另外main中的代码有点丑陋...)

效果

迭代100次最终的损失值为15+

这样看起来还可以,但是换个角度...T T

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值