线性回归之简单线性回归算法

一、什么是线性回归

线性回归是指使用一个线性关系来表示数据

我们数学中学习的 y = a*x + b ,就是最典型的线性回归

二、线性回归的分类

根据未知数的数量,线性回归分为:

  • 一元线性回归

  • 多元线性回归

例如:

对于结果 y 而言,若只含有一个未知数 x,就是一元线性回归

若有未知数 x1,x2,x3,x4,就是多元线性回归

三、一元线性回归的数学知识

对于一元线性回归,表达式的行式为:

y = a*x + b

根据数学知识,可以得到:

mean(x) 表示 X的的平均数

四、封装一个自己的一元线性回归

import numpy as np

class SimpleLinearRegression3:
    def __init__(self):
        self.a = None
        self.b = None

    def fit(self, x_arr, y_arr):
        assert x_arr.ndim == y_arr.ndim and x_arr.ndim == 1, "the ndim of x_arr and y_arr must be 1"
        assert x_arr.shape[0] == y_arr.shape[0], 'the length of x_arr must be equal to y_arr'
        self.x_mean_ = np.mean(x_arr)
        self.y_mean_ = np.mean(y_arr)

        upper = (x_arr - self.x_mean_).dot(y_arr - self.y_mean_)
        down = (x_arr - self.x_mean_).dot(x_arr - self.x_mean_)

        self.a = upper / down
        self.b = self.y_mean_ - self.a * self.x_mean_

        return self

    def predict(self, x_preduct):
        return np.array([self._predict(x) for x in np.array(x_preduct)])

    def _predict(self, x):
        return self.a * x + self.b

    def score(self,X_test,y_test):
        """ R-Squared """
        return r2_score(y_test,self.predict(X_test))

    def __repr__(self):
        return "SimpleLinearRegression3()"

这里的 r2_score() 在下面的评判方法中有具体的介绍和实现代码

五、使用自己的一元线性回归预测波士顿房价

我们使用一元线性回归方法预测一下波士顿的房价

sklearn 中的波士顿房价有多个特征值,这里我们只取出其中的一个特征:房价数量RM

from playML.SimpleLinearRegression import SimpleLinearRegression3
from sklearn import datasets
from sklearn.model_selection import train_test_split
boston = datasets.load_boston()

# 查看数据集的关键字
print(boston.keys())
# dict_keys(['data', 'target', 'feature_names', 'DESCR', 'filename'])

# 查看一下数据集的特征值都有什么
print(boston.feature_names)
# 第六个特征 RM 便是房间数量
# ['CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO'
 'B' 'LSTAT']

X = boston.data
y = boston.target

X_data = X[y<50][:,5]
y_data = y[y<50]

X_train , X_test , y_train , y_test = train_test_split(X_data , y_data,test_size=0.2,random_state=666)

linear = SimpleLinearRegression3()

linear.fit(X_train , y_train)

y_predict = linear.predict(X_test)

print(y_predict[:10])

print(linear.score(X_test,y_test))
# 0.6129316803937324

六、使用sklearn的一元线性回归预测波士顿房价

这里我们仍然只取出其中的一个特征:房价数量RM

from sklearn.linear_model import LinearRegression
from sklearn import datasets
import numpy as np
from sklearn.model_selection import train_test_split

boston = datasets.load_boston()
    
X = boston.data
y = boston.target

用散点图的方式简单看一下 RM 一列与房价的大概关系

from matplotlib import pyplot as plt

plt.scatter(X[:,5],y)
plt.show()

可以看到有一小部分数据的房价达到了最大值,这些数据的房价极有可能并不是50,而是50+

所以,我们可以过滤掉这些极端值

# 过滤掉极大值
X_data = X[y<50]
y_data = y[y<50]

# 我们使用的是一元线性回归,所以需要把数据集由矩阵转换为向量
X_data = X_data[:,5].reshape(-1,1)

# 数据集划分为训练集与测试集
X_train , X_test , y_train , y_test = train_test_split(X_data,y_data,test_size=0.2,random_state=666)

# 生成线性回归对象
linear = LinearRegression()

# 训练模型
linear.fit(X_train,y_train)

# 预测数据
y_predict = linear.predict(X_test)
print(y_predict)

# 查看预测的准确率
linear.score(X_test,y_test)
# 0.6129316803937324

因为在数据集中,波士顿房价有13个特征值,而我们在这里进行回归时只取出了一个特征,所以模型预测出来的准确度比较低

七、回归算法的评判方法

1、MSE:均方误差

公式:

y(i) 表示实际值

y(j) 表示预测值

自己实现

def mean_squared_error(y_test, y_predict):
    """均方误差 MSE"""
    assert len(y_test) == len(y_predict), "the length of y_test must be equal to y_predict"
    assert y_test.ndim == 1 and y_predict.ndim == 1, "the ndim of y_test and y_predict must be 1"

    return np.sum((y_test - y_predict) ** 2) / len(y_test)

该方法对应于 sklearn 库中的 mean_squared_error( y_test , y_predict )

from sklearn.metrics import mean_squared_error

2、RMSE均方根误差

公式:

def mean_absolute_error(y_test, y_predict):
    """平均绝对误差"""
    assert len(y_test) == len(y_predict), "the length of y_test must be equal to y_predict"
    assert y_test.ndim == 1 and y_predict.ndim == 1, "the ndim of y_test and y_predict must be 1"

    return np.sum(np.abs(y_test - y_predict)) / len(y_test)

sklearn 中没有该评测方法

这种评测方法其实就是 MSE 评分的开方

3、平均绝对误差

公式:

def mean_absolute_error(y_test, y_predict):
    """平均绝对误差"""
    assert len(y_test) == len(y_predict), "the length of y_test must be equal to y_predict"
    assert y_test.ndim == 1 and y_predict.ndim == 1, "the ndim of y_test and y_predict must be 1"

    return np.sum(np.abs(y_test - y_predict)) / len(y_test)

该方法对应于 sklearn 库中的 mean_absolute_error( y_test , y_predict )

from sklearn.metrics import mean_absolute_error

4、R-squared

公式:

def r2_score(y_test, y_predict):
    """ R**2 """
    assert len(y_test) == len(y_predict), "the length of y_test must be equal to y_predict"
    assert y_test.ndim == 1 and y_predict.ndim == 1, "the ndim of y_test and y_predict must be 1"

    return 1 - (np.sum((y_test - y_predict) ** 2)) / (np.sum((y_test - np.mean(y_test)) ** 2))

该方法对应于 sklearn 库中的 r2_score( y_test , y_predict )

from sklearn.metrics import r2_score

前三种评测方法的结果绝大多数情况下都是一个大于 1 的数值

对于同一种算法而言,即使使用不同类型的数据训练,对不同类型的数据进行预测,根据前三种评测结果,无法得出谁好谁坏的结论

例如使用多元线性回归算法,分别预测下个月的销售额和下次考试的语文成绩,评测结果无法看出是预测的销售额准确,还是预测的语文成绩准确

R-Squared 评测方法 完美解决了这个问题

  • R-Squared 将评测结果转换到 0~1 之间(也有可能会小于0)

  • R-squared 的最大值为 1 ,最小值可能会小于0

  • ∑ ( y(i) - y(j) )² 表示我们的训练模型的预测值产生的错误大小

  • ∑ ( y(i) - mean(y) )² 表示直接使用BaseModel模型预测数据产生的错误

  • 当评测值小于 0 时,表示目前的训练模型效果还不如 BaseModel,此时数据之间很有可能不存在线性关系

BaseModel : 使用均值作为训练模型,即无论预测时传入的数据是什么,都预测为训练数据集的均值

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值