题目背景
波士顿房价预测问题是机器学习中多元线性回归算法的经典问题,问题的具体描述如下:
- 波士顿房屋数据共 506 个数据点,涵盖了波士顿不同郊区房屋 14 种特征的信息,通过多元线性回归方法利用该数据集构建一个波士顿房价预测模型,并对模型的预测准确度进行评估。
- 部分样本数据如下:
0.00632 18.00 2.310 0 0.5380 6.5750 65.20 4.0900 1 296.0 15.30 396.90 4.98 24.00
0.02731 0.00 7.070 0 0.4690 6.4210 78.90 4.9671 2 242.0 17.80 396.90 9.14 21.60
0.02729 0.00 7.070 0 0.4690 7.1850 61.10 4.9671 2 242.0 17.80 392.83 4.03 34.70
0.03237 0.00 2.180 0 0.4580 6.9980 45.80 6.0622 3 222.0 18.70 394.63 2.94 33.40
0.06905 0.00 2.180 0 0.4580 7.1470 54.20 6.0622 3 222.0 18.70 396.90 5.33 36.20
0.02985 0.00 2.180 0 0.4580 6.4300 58.70 6.0622 3 222.0 18.70 394.12 5.21 28.70
0.08829 12.50 7.870 0 0.5240 6.0120 66.60 5.5605 5 311.0 15.20 395.60 12.43 22.90
问题特性与线性假设的契合度
我们考虑为什么波士顿房价预测问题可以使用多元线性回归算法
- 自变量与因变量满足线性关系
例如当住房的面积增大时,房价也会随之增大; 出行的便利指数降低时,房价也会随之降低 - 自变量对于因变量的影响满足独立可加性
例如住房是否属于学区房地段和住房的占地面积的大小对于房价的影响是相互独立且具有可加性的
多元线性回归算法的实现
首先考虑多元线性回归算法的原理
多元线性回归算法的核心表达式:
y
=
β
0
+
β
1
x
1
+
β
2
x
2
+
⋯
+
β
n
x
n
+
ϵ
y = \beta_0 + \beta_1 x_1 + \beta_2 x_2 + \cdots + \beta_n x_n + \epsilon
y=β0+β1x1+β2x2+⋯+βnxn+ϵ
其中的y就是实际的房价,每一个x都代表影响房价的一个维度,最后的
ϵ
\epsilon
ϵ表示预测值和实际值之间的偏差,我们构建的这样一个表达式的含义就是,找到一条轨迹,这个轨迹满足样本中的所有数据都有一个按照这个轨迹进行分布的趋势,我们要找到的就是用来构建这个表达式的系数θ
对于已有的所有样本,每一行房价数据点都包含13个
x
i
x_i
xi值的数据和一个
y
y
y值数据,这就构建了一个y关于多个x的表达式,当多个表达式组合到一起时,对于多个多元线性方程组,这时就构成了矩阵运算的形式,其中
y
i
预测
=
β
i
0
∗
1
+
β
i
1
∗
x
i
1
+
β
i
2
∗
x
i
2
+
⋯
+
β
i
n
∗
x
i
n
y_{i预测} = \beta_{i0} *1 + \beta_{i1} *x_{i1} + \beta_{i2}*x_{i2} + \cdots + \beta_{in}*x_{in}
yi预测=βi0∗1+βi1∗xi1+βi2∗xi2+⋯+βin∗xin
i用来表示第i个样本,当所有方程组合到一起时,
y
y
y,
β
\beta
β,
x
x
x分别构成了三个矩阵,但注意,每一项的
β
0
\beta_0
β0并没有对应的x与之相乘,所以我们主动的认为1与之相乘,并且把1也包含到X所在的矩阵中去,所以这时X的矩阵的第一列都是1,表示成矩阵乘法:
tips:单行向量默认都是列向量
Y
预测
n
×
1
=
X
n
×
(
m
+
1
)
×
β
(
m
+
1
)
×
1
Y_{预测n\times1}= X_{n \times (m+1)} \times \beta_{(m+1)\times 1}
Y预测n×1=Xn×(m+1)×β(m+1)×1
也就是当我们把
β
\beta
β的值确定下来之后,就可以根据多元线性回归的式子求出预测的y值,我们期望的是能够使得
y
真实
−
y
预测
y_{真实}-y_{预测}
y真实−y预测的差值最小,即找到
h
(
β
)
=
Y
真实
−
(
X
×
β
)
h(\beta)=Y_{真实}-(X \times \beta)
h(β)=Y真实−(X×β)得到最小值,
这里涉及到矩阵求导的问题,即当这个表达式的导函数等于零,也即函数取到极(小)值的时候,两者的差值最小(这里就省略证明部分了,因为主播的实力很菜推导不来\qwq),下面给出结论:
θ
=
(
X
T
×
X
)
−
1
×
X
T
×
Y
真实
\theta =(X^{T}\times X)^{-1}\times X^{T} \times Y_{真实}
θ=(XT×X)−1×XT×Y真实
我们只需要对已知的数据进行矩阵运算就可以求得这个结果了,在结合上面给出的
Y
预测
Y_{预测}
Y预测的计算方法,就可以求出预测的房价值了,那么接下来我们将尝试着模拟矩阵运算
观察我们需要的矩阵操作,包括矩阵的转置,矩阵乘法,矩阵求逆(只有方阵可以求逆),是的,死去的线性代数又将攻击你的大脑,这里我们假定大家都还记得矩阵的相关运算,是的,相信你们,米娜( × \times ×)
我们尝试着使用c++来解决这个问题
#include<iostream>
#include<vector>//用来存储矩阵,一般我们就用vector好了
using namespace std;
class Matrix{
private:
vector<vector<double>> data;//先开辟一个用来存数据的二维数组做矩阵
int rows;
int cols;//可以开辟两个变量存放当前矩阵的行和列的数量
public:
//先实现一个初始化矩阵类的构造函数吧
Matrix(int row,int col):rows(row),cols(col),data(vector<vector<double>>(row,vector<double>(col,0))){}
//上面这个实现了一个传递进行列就能生成一个矩阵的效果,其他的用到时可以再补充
//这里来补充对于[]的重载,注意这类取到某个数的重载要同时写上两种,因为有的时候会对样本数据进行更改,有的时候不会进行更改,
vector<double>& operator [](int x){
return data[x];
}
const vector<double>& operator [](int x) const{//对于不会改变参数的值的函数推荐加上const标识,
return data[x];
}
//接下来我们考虑实现一个矩阵转置的函数
void transpose{
//先考虑矩阵转置的原理,Xij=Xji,转置前后行列对换
Matrix result(cols,rows);//有了上面写的构造函数,相当于可以直接把Matrix当做二维数组用了,这样写感觉也很方便
for(int i=0;i<rows;i++){
for(int j=0;j<cols;j++){
result[j][i]=data[i][j];//这里为了方便使用[]这个符号,所以在上面对这个符号也进行了重载,当然也可以重载(i,j)这样的这种符号
}
}
}
};
int main(){
```这里省略数据的读入操作
Matrix data;
}
1万+

被折叠的 条评论
为什么被折叠?



