目录
[四、scikit-learn线性回归实践 - 波斯顿房价预测](#四、scikit-learn线性回归实践 - 波斯顿房价预测)
摘要:
文章主要介绍了线性回归相关内容,包括简单线性回归与多元线性回归的概念及示例,阐述了残差的定义、在理想与非理想模型中的情况及意义,还讲解了线性回归的正规方程解,涵盖其适用场景、公式推导与代码实现,提及衡量线性回归性能指标可参考其他文章,最后以 scikit-learn 中的 LinearRegression 类为例,介绍了其在波士顿房价预测实践中的应用,包括数据集情况、类的常用参数及训练、预测函数的使用等。
一、简单线性回归与多元线性回归
1、简单线性回归
在生活中,我们常常能碰到这么一种情况,一个变量会跟着另一个变量的变化而变化,如圆的周长与半径的关系,当圆的半径确定了,那么周长也就确定了。还有一种情况就是,两个变量之间看似存在某种关系,但又没那么确定,如青少年的身高与体重,他们存在一种近似的线性关系:
身高/cm = 体重/kg +105。
但是,并不是每个青少年都符合这个公式,只能说每个青少年的身高体重都存在这么一种近似的线性关系。这就是其实就是简单的线性回归,那么,到底什么是线性回归呢?假如我们将青少年的身高和体重值作为坐标,不同人的身高体重就会在平面上构成不同的坐标点,然后用一条直线,尽可能的去拟合这些点,这就是简单的线性回归,如下图:
简单的线性回归模型:
其中x表示特征值(如:体重值),w表示权重,b表示偏置,y表示标签(如:身高值)。
2、多元线性回归
简单线性回归中,一个变量跟另一个变量的变化而变化,但是生活中,还有很多变量,可能由多个变量的变化决定着它的变化,比如房价,影响它的因素可能有:房屋面积、地理位置等等。如果我们要给它们建立出近似的线性关系,这就是多元线性回归,多元线性回归模型如下:
其中,表示第n个特征值,表示第n个特征对应的权重,b表示偏置,y表示标签。
3、残差
- 定义
- 残差是指在回归分析中,观测值与预测值之间的差异,即,其中是第个观测值,是对应的预测值。残差均值就是所有残差的平均值,即,其中n是样本数量。
- 在理想线性回归模型中的情况
- 在理想的线性回归模型(基于普通最小二乘法估计参数)中,残差均值为零。这是因为普通最小二乘法的目标是最小化残差平方和。
- 从几何角度看,线性回归是在寻找一条直线(在简单线性回归中)或一个超平面(在多元线性回归中),使得数据点到该直线或超平面的垂直距离(即残差)的平方和最小。在这个最优拟合的情况下,残差会在零附近分布,正残差和负残差相互抵消,导致残差均值为零。
- 残差均值不为零的情况及意义
- 如果残差均值不为零,这可能意味着模型存在偏差。例如,如果残差均值大于零,说明模型整体上低估了观测值;如果残差均值小于零,则说明模型整体上高估了观测值。
- 这可能是由于模型设定不正确(如遗漏了重要的变量、函数形式错误等)或者数据存在异常情况(如存在离群点等)导致的。在实际应用中,残差均值是评估模型拟合质量的一个简单指标,发现残差均值不为零后,需要进一步分析模型和数据,以改进模型的拟合效果。
如果线性回归方程有多个解,可以如何解决?
解决方法包括但不限于:
- 获取更多的训练样本
- 选取样本有效的特征,使样本数量大于特征数
- 加入正则化项
二、线性回归的正规方程解
1、线性回归训练流程
以波士顿房价数据集为例,该数据集每条数据包括对指定房屋的13项数值型特征和目标房价组成:
由数据集可以知道,每一个样本有13个特征与目标房价,而我们要做的事就是通过这13个特征来预测房价,我们可以构建一个多元线性回归模型,来对房价进行预测。模型如下:
其中,表示第n个特征值,表示第n个特征对应的权重,b表示偏置,y表示目标房价。
为了方便,我们稍微将模型进行变换(下面求解会用到):
其中。令,其中,。
而我们的目的就是找出能够正确预测的多元线性回归模型,即找出正确的参数。那么如何寻找呢?通常在监督学习里面都会使用这么一个套路,构造一个损失函数,用来衡量真实值与预测值之间的差异,然后将问题转化为最优化损失函数。既然损失函数是用来衡量真实值与预测值之间的差异,那么很多人自然而然的想到了用所有真实值与预测值的差的绝对值来表示损失函数。不过带绝对值的函数不容易求导,所以我们可以采用采用MSE(均方误差)作为损失函数(相关内容可以查看另一篇文章:机器学习 ---模型评估、选择与验证(1)),公式如下:
其中 表示第 i 个样本的真实标签, 表示模型对第 i 个样本的预测标签,m为样本总个数。最后,我们再使用正规方程解来求得我们所需要的参数。线性回归模型训练流程如下:
2、线性回归的正规方程解
(1)适用场景
- 在数据集规模较小且特征数量不是很多的情况下,正规方程解是比较常用的(对于其他方法,比如梯度下降法等将在之后的文章中提到)。例如,当我们处理一些简单的实验数据或者小型的商业分析数据集时,假设特征数量m较小(比如m<1000),数据样本数量n也不大(比如n<10000)。
- 因为正规方程解的公式在这种情况下计算起来相对简单直接 。它不需要像梯度下降法那样进行多次迭代来收敛到最优解 ,只要能够计算矩阵的逆,就可以一次性得到参数θ的最优解。
- 例如,在一个简单的房价预测模型中,我们仅考虑房屋面积、房间数量这两个特征来预测房价。数据集包含 100 套房子的数据,通过正规方程解可以快速得到线性回归模型的参数,从而构建预测模型。
(2)正规方程解的公式
对线性回归模型,假设训练集中m个训练样本,每个训练样本中有n个特征,可以使用矩阵的表示方法,预测函数可以写为:,其损失函数可以表示为:
其中,标签Y为的矩阵,训练特征X为的矩阵,回归系数θ为的矩阵,对θ求导,并令其导数等于0,可以得到:。所以,最优解为:
这个就是正规方程解,我们可以通过最优方程解直接求得我们所需要的参数。
代码实现:
python
import numpy as np
def mse_score(y_predict,y_test):
'''
input:y_predict(ndarray):预测值
y_test(ndarray):真实值
ouput:mse(float):mse损失函数值
'''
mse = np.mean((y_predict-y_test)**2)
return mse
class LinearRegression :
def __init__(self):
'''初始化线性回归模型'''
self.theta = None
def fit_normal(self,train_data,train_label):
'''
input:train_data(ndarray):训练样本
train_label(ndarray):训练标签
'''
# 在训练数据的特征矩阵前面添加一列全为1的列,用于表示截距项
X = np.hstack((np.ones((train_data.shape[0], 1)), train_data))
# 根据正规方程公式计算模型参数theta
# 先计算X的转置与X的乘积的逆矩阵
inverse_term = np.linalg.inv(X.T.dot(X))
# 再计算X的转置与训练标签的乘积
product_term = X.T.dot(train_label)
# 最后将逆矩阵与上述乘积相乘,得到模型参数theta
self.theta = inverse_term.dot(product_term)
return self.theta
三、衡量线性回归的性能指标
这部分在上面提到的另外一篇文章中有提到过,感兴趣的话可以去看一看,这里就不再过多赘述。
四、scikit-learn线性回归实践 - 波斯顿房价预测
1、数据集介绍
波斯顿房价数据集共有506条波斯顿房价的数据,每条数据包括对指定房屋的13项数值型特征和目标房价组成。用数据集的80%作为训练集,数据集的20%作为测试集,训练集和测试集中都包括特征和目标房价。
数据集中部分数据与标签如下图所示:
2、LinearRegression
LinearRegression 是 scikit-learn 库(通常简称为sklearn)中用于实现线性回归算法的一个类。
LinearRegression的构造函数中有两个常用的参数可以设置:
- fit_intercept:是否有截距,如果没有则直线过原点,默认为Ture。
- normalize:是否将数据归一化,默认为False。
LinearRegression类中的fit函数用于训练模型,fit函数有两个向量输入:
- X:大小为[样本数量,特征数量]的ndarray,存放训练样本。
- Y:值为整型,大小为[样本数量]的ndarray,存放训练样本的标签值。
LinearRegression类中的predict函数用于预测,返回预测值,predict函数有一个向量输入:
- X:大小为[样本数量,特征数量]的ndarray,存放预测样本。
利用LinearRegression进行线性回归,代码及相应的注释如下:(此处仅为一个简单的线性回归的示例)
python
from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
import pandas as pd
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
# 加载波士顿房价数据集
boston = load_boston()
# 将数据转换为DataFrame格式,这里的特征数据
train_data = pd.DataFrame(boston.data, columns=boston.feature_names)
# 目标数据(房价)作为训练标签
train_label = pd.Series(boston.target)
# 划分训练集和测试集,测试集占比可自行设置,这里设为0.2(即20%)
X_train, X_test, y_train, y_test = train_test_split(train_data, train_label, test_size=0.2, random_state=42)
# 创建线性回归模型对象
lr = LinearRegression()
# 模型训练
lr.fit(X_train, y_train)
# 模型预测
pred = lr.predict(X_test)
# 将预测结果转换为DataFrame
pred_df = pd.DataFrame({'result': pred})
# 模型评估
mse = mean_squared_error(y_test, pred)
mae = mean_absolute_error(y_test, pred)
r2 = r2_score(y_test, pred)
print("\n模型评估指标:")
print(f"均方误差(MSE): {mse}")
print(f"平均绝对误差(MAE): {mae}")
print(f"决定系数(R²): {r2}")