在对数据集进行拟合的时候常常会用到线性拟合,以前我都是在MATLAB的拟合工具箱中对数据进行拟合,现在我学习了通过python来实现线性回归。

points = np.genfromtxt("data.csv", delimiter=",")  # 读取数据时以逗号分割数据
learning_rate = 0.0001  # 学习率
initial_b = 0  # 初始化截距
initial_m = 0  # 初始化斜率
num_iterations = 1000  # 迭代次数
print("第一次迭代: b = {0}, m = {1}, error = {2}"
          .format(initial_b, initial_m,
                  compute_error_for_line_given_points(initial_b, initial_m, points))
          )  # 调用函数 第一次迭代时的截距、斜率、误差(损失函数计算所得)
    print("正在运行")

首先读取所要处理的数据,读取时以逗号为分隔符来读取,初始化学习率和迭代次数,这里先打印一次截距、斜率以及误差,这里调用了计算误差的自定义函数:

def compute_error_for_line_given_points(b, w, points):
    total_error = 0
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1]
        total_error += (y - (w * x + b)) ** 2  # 误差求和
    return total_error / float(len(points))  # 计算平均误差

用真实值减去预测值并平方来作为误差并求平均,这时的误差会非常大因为是一次迭代,但随着迭代次数的增加误差会逐渐减小。

[b, m] = gradient_descent_runner(points, initial_b, initial_m, learning_rate, num_iterations)

这是这个程序中最重要的一行命令,这里调用了自定义的函数,返回值为斜率与截距,他们都是迭代1000次后的结果。

def gradient_descent_runner(points, starting_b, starting_m, learning_rate, num_iterations):
    b = starting_b
    m = starting_m
    for i in range(num_iterations):
        b, m = step_gradient(b, m, np.array(points), learning_rate)
    return [b, m]

这个函数接收csv中的数据、初始化的截距、初始化的斜率、学习率以及迭代次数。函数接收后会调用step_gradient函数,这个函数是不断学习并用来修改斜率以及截距的,这个函数会被调用1000次。

def step_gradient(b_current, w_current, points, learningRate):
    b_gradient = 0
    w_gradient = 0
    N = float(len(points))
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1]
        b_gradient += -(2/N) * (y - ((w_current * x) + b_current))
        w_gradient += -(2/N) * x * (y - ((w_current * x) + b_current))
    new_b = b_current - (learningRate * b_gradient)
    new_m = w_current - (learningRate * w_gradient)
    return [new_b, new_m]

这个函数利用了梯度下降法来修改截距以及斜率,这里需要计算梯度。

在这里插入图片描述
程序中有一个N是因为这是一个循环要进行累加,利用这里计算的梯度可以对斜率以及截距进行改进。
在这里插入图片描述
最后将回归结果可视化:

    x = np.linspace(20, 80, 5)
    y = m * x + b
    pyplot.plot(x, y)
    pyplot.scatter(points[:, 0], points[:, 1])
    pyplot.show()

在这里插入图片描述

以下是完整程序

import numpy as np
from matplotlib import pyplot


def compute_error_for_line_given_points(b, w, points):
    total_error = 0
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1]
        total_error += (y - (w * x + b)) ** 2  # 误差求和
    return total_error / float(len(points))  # 计算平均误差


def step_gradient(b_current, w_current, points, learningRate):
    b_gradient = 0
    w_gradient = 0
    N = float(len(points))
    for i in range(0, len(points)):
        x = points[i, 0]
        y = points[i, 1]
        b_gradient += -(2/N) * (y - ((w_current * x) + b_current))
        w_gradient += -(2/N) * x * (y - ((w_current * x) + b_current))
    new_b = b_current - (learningRate * b_gradient)
    new_m = w_current - (learningRate * w_gradient)
    return [new_b, new_m]


def gradient_descent_runner(points, starting_b, starting_m, learning_rate, num_iterations):
    b = starting_b
    m = starting_m
    for i in range(num_iterations):
        b, m = step_gradient(b, m, np.array(points), learning_rate)
    return [b, m]


def run():
    points = np.genfromtxt("data.csv", delimiter=",")  # 读取数据时以逗号分割数据
    learning_rate = 0.0001  # 学习率
    initial_b = 0  # 初始化截距
    initial_m = 0  # 初始化斜率
    num_iterations = 1000  # 迭代次数
    print("第一次迭代: b = {0}, m = {1}, error = {2}"
          .format(initial_b, initial_m,
                  compute_error_for_line_given_points(initial_b, initial_m, points))
          )  # 调用函数 第一次迭代时的截距、斜率、误差(损失函数计算所得)
    print("正在运行")
    [b, m] = gradient_descent_runner(points, initial_b, initial_m, learning_rate, num_iterations)  # 调用函数
    print("迭代 {0} 次后 b = {1}, m = {2}, error = {3}".
          format(num_iterations, b, m,
                 compute_error_for_line_given_points(b, m, points))
          )
    x = np.linspace(20, 80, 5)
    y = m * x + b
    pyplot.plot(x, y)
    pyplot.scatter(points[:, 0], points[:, 1])
    pyplot.show()


if __name__ == '__main__':
    run()

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐