【机器学习 - 4】:线性回归算法

本文介绍了线性回归的基本概念,包括简单线性回归和多元线性回归,以及线性回归中的损失函数——最小二乘法。通过实例展示了如何在Python中手动实现线性回归,并封装成简单的类。此外,文章讨论了在sklearn库中使用线性回归模型,并介绍了评估指标如均方误差MSE、均方根误差RMSE和平均绝对误差MAE,以及R-squared误差。
摘要由CSDN通过智能技术生成

线性回归


线性回归的理解

线性回归:判断数据的特征和目标值之间具有一定的线性关系。
简单线性回归:样本的特征只有一个,用线性回归法进行预测,叫做简单线性回归。
多元线性回归:样本的特征有两个或两个以上,叫做多元线性回归。

如下图所示,为线性回归模型
在这里插入图片描述

损失函数

损失函数:np.sum((y`-y)**2),即预测值和真实值的差值之和。因为有复数的存在所以求平方,不用绝对值的原因:用平方方便后续的求导和求极值。

最小二乘法
在这里插入图片描述
一些推导过程:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
重要结论
在这里插入图片描述

简单线性回归


  1. 先画出数据的散点图
import numpy as np
import matplotlib.pyplot as plt

x = np.array([1,2,3,4,5])
y = np.array([2,1,3,2,5])

plt.scatter(x,y)
plt.axis([0,6,0,6])
plt.show()

在这里插入图片描述

  1. 对数据进行处理,求出a和b
# y = a * x + b
# 先求出平均值
x_mean = np.mean(x)
y_mean = np.mean(y)

num = 0.0 # 分子
d = 0.0 # 分母

for x_i, y_i in zip(x, y):
    num += (x_i-x_mean)*(y_i-y_mean)
    d += (x_i-x_mean)**2
a = num/d
b = y_mean-a*x_mean

在这里插入图片描述

  1. 求出y`,并画出预测直线,求出这条线,使得真实值与预测值的差值达到最小。
y_hat = a * x + b

plt.plot(x, y_hat, color='r')
plt.scatter(x,y)
plt.axis([0, 6, 0, 6])
plt.show()

在这里插入图片描述

封装线性回归算法

import numpy as np


class SimpleLinearRegression:
    def __init__(self):
        self.a_ = None
        self.b_ = None
        self.x_mean = None
        self.y_mean = None

    def fit(self, x_train, y_train):
        self.x_mean = np.mean(x_train)
        self.y_mean = np.mean(y_train)

        num = 0.0   # 分子
        d = 0.0     # 分母
        for x_i, y_i in zip(x_train, y_train):
            num += (x_i-self.x_mean) * (y_i-self.y_mean)
            d += (x_i-self.x_mean)**2
        self.a = num/d
        self.b = self.y_mean - self.a * self.x_mean

        return self

    def predict(self, x_test):
        return self.a * x_test + self.b

    def __repr__(self):
        return 'SimpleLinearRegression()'

在jupter notebook中导入运行
在这里插入图片描述

线性回归算法


使用线性回归算法的前提:数据具有一定的线性关系。

我们希望找到一条最佳拟合的直线方程,y=ax+b,对于每一个样本点,在这个直线方程上都有一个预测值,预测值和真实值有一定的差距,我们希望这些样本到直线方程的差距之和最小。

计算差距:sqrt(|y-y`|**2),使用平方并开根号的方式更适合我们进行求导或求值。

在sklearn中调用线性回归算法

  1. 导入模块
from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt
  1. 准备数据,训练模型
# 准备数据
x = np.array([1,2,3,4,5])
y = np.array([3,1,4,3,6])

lin_reg = LinearRegression()
lin_reg.fit(x.reshape(-1,1), y)	# 拟合,训练模型

在这里插入图片描述

  1. 画出散点图和预测直线
plt.scatter(x, y)
plt.plot(x, lin_reg.predict(x.reshape(-1,1)), color='r')
plt.axis([0,6,0,7])
plt.show()

在这里插入图片描述

向量化运算

如下图所示,向量化运算更加方便,向量点乘是先乘后加,原理一样。
在这里插入图片描述

x = np.array([1,2,3,4,5])
y = np.array([3,1,4,3,6])
def lin_fit(x, y):
    x_mean = np.mean(x)
    y_mean = np.mean(y)
    num = 0.0
    d = 0.0
    num = (x-x_mean).dot(y-y_mean)
    d = (x-x_mean).dot(x-x_mean)
    a = num/d
    b = y_mean-a*x_mean
    return a, b

在这里插入图片描述

线性回归模型中的误差


在分类问题可以将score看成准确率,在回归问题将score看成模型的好坏程度。
在这里插入图片描述

均方误差 MSE

均方误差的公式如下图所示:
在这里插入图片描述
为什么要除以样本数量m?
举个例子,比如第一个团队有2个人,统计其工资的均方误差为800,第二个团队有100个人,工资的均方误差为1000,能说明第一个团队比较好吗?这是不行的,因为统计的个数不同,样本不同,导致量纲不一样,所以需要除以样本数量m,减少量纲的影响。

封装的函数

# 均方误差 MSE
def MSE(y_true, y_predict):
    return np.sum((y_true-y_predict)**2)/len(y_true)

在这里插入图片描述

均方根误差

在这里插入图片描述
在均方误差中进行开根号处理,可以消除量纲的影响。

封装的均方根误差

# 均方根误差
from math import sqrt
def RMSE(y_true, y_predict):
    return sqrt(np.sum((y_true-y_predict)**2)/len(y_true))

在这里插入图片描述

平均绝对误差

在这里插入图片描述
封装的平均绝对误差

# 平均绝对误差
def MAE(y_true, y_predict):
    return np.sum(np.absolute(y_true-y_predict))/len(y_true)

在这里插入图片描述

调用sklearn中的均方根误差和平均绝对误差函数

from sklearn.metrics import mean_squared_error, mean_absolute_error
mean_squared_error(x, y_hat)
mean_absolute_error(x, y_hat)

在这里插入图片描述

R squared error (常用)

R^2(以下用R2表示)分类的准确度在0和1之间,R2为1时,模型最优,即没有出现任何错误。

计算公式如下:
在这里插入图片描述
封装R squared error

import numpy as np
x = np.array([1,2,3,4,5])
y = np.array([3,1,4,3,6])
def r2_score(x_true, y_predict):
    return 1-((np.sum((x_true-y_predict)**2)/len(x_true))/np.var(x_true))

在这里插入图片描述

或调用均值方差 MSE
在这里插入图片描述
调用sklearn中的线性回归算法,计算预测值,最终的误差结果还是一样

from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(x.reshape(-1,1), y)
y_predict = lin_reg.predict(x.reshape(-1,1))

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

街 三 仔

你的鼓励是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值