1 多变量线性回归
1.1 概念
在上一篇文章中笔者详细的介绍了什么是线性回归以及一个典型的应用场景,同时还介绍了如何通过开源的sklearn来搭建一个简单的线性回归模型,使得对于线性回归的核心思想有了一定的掌握。接下来,笔记继续带领读者来进行下一步的学习。
在这里还是以房价预测为例。尽管影响房价的主要因素的面积,但是其它因素同样也可能影响到房屋的价格。例如房屋到学校的距离、到医院的距离和到大型商场的距离等等(总不能卖你一套深山老林的房子你也要吧)。虽然显示生活中没有这么量化,但是开发商也总是拿什么学区房做卖点对吧。因此,此时我们便有了影响房价的四个因素,并且在机器学习中我们将其称之为特征(feature)。因而包含有多个特征的线性回归就叫做多变量线性回归(Linear Regression Multiple Variables)。
1.2 建模
以波士顿房价数据集为例,其一共包含了13个特征属性。因此,我们便可以得到如下线性模型:
且同时,其目标函数为:
其中表示第
个样本的第
个特征属性,
为一个向量表示所有的权重,
为标量表示偏置。
由上一篇内容可知,只要通过某种方法最小化目标函数后,便可以求解出模型的参数。下面我们依旧以sklearn来进行建模求解。
1.3 求解
- 导入包与数据集
from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression
def load_data():
data = load_boston()
x = data.data
y = data.target
return x, y
- 求解与结果
def train(x, y):
print('X的形状:',x.shape)
model = LinearRegression()
model.fit(x,y)
print("权重为:",model.coef_)
print("偏置为:",model.intercept_)
print("第12个房屋的预测价格:",model.predict(x[12,:].reshape(1,-1)))
print("第12个房屋的真实价格:",y[12])
if __name__ == '__main__':
x,y = load_data()
train(x,y)
#输出结果:
#X的形状: (506, 13)
#权重为: [-1.08011358e-01 4.64204584e-02 2.05586264e-02 2.68673382e+00
# -1.77666112e+01 3.80986521e+00 6.92224640e-04 -1.47556685e+00
# 3.06049479e-01 -1.23345939e-02 -9.52747232e-01 9.31168327e-03
# -5.24758378e-01]
#偏置为: 36.45948838509001
#第10个房屋的预测价格: [20.90652153]
#第10个房屋的真实价格: 21.7
由于不能可视化高维数据,所以只能从预测结果来看模型的好坏,具体的模型评估见后文。
2 多项式回归
2.1 引例
假定现在你知道矩形的面积公式,而不知道求解梯形的面积公式,且同时你手上有若干个类似下图的梯形块儿。已知上底和下底,并且上底均等于高。现在让你建立一个模型,当给定一个上述梯形时你能近似的给出其面积。该如何建模呢?
2.2 建模
首先需要明确的是,即使直接建模成,那也是可以的,只是效果应该不会太好。对于这个梯形:左边可以看成是正方形,所以可以人为的构造第三个特征
;而整体可以看成是长方形的一部分,又可以认为的构造出
;最后,整体还可以看成是大正方形的一部分,因此可以构造出
。故,我们便可以得到如下模型:
有人可能会问,有的部分重复加了,计算出来的面积岂不大于实际面积?但这当然不会,因为每一项都有一个权重参数做系数。同时,可以看出
中包含了
这些项(其次数高于1),因此我们将其称之为多项式回归(Poloniumial Regression)。
但是,只要我们做如下替换,便又回到了普通的线性回归:
其中,只是在实际建模时我们先要将原始两个特征的数据转化为五个特征的数据;同时在做正式预测时,输入给模型
也将是包含五个特征的数据。
2.3 求解
- 特征转化
在正式建模前先介绍一个特征构造函数PolynomialFeatures,它的作用就是完成上述示例中的特征转化。
from sklearn.preprocessing import PolynomialFeatures
a = [[3, 4], [2, 3]] # 2 3 4 9 6
model = PolynomialFeatures(include_bias=False)
b = model.fit_transform(a)
print(b)
#输出结果:
#[[ 3. 4. 9. 12. 16.]
# [ 2. 3. 4. 6. 9.]]
- 导入包并构造数据集
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
import numpy as np
def make_data():
np.random.seed(10)
x1 = np.random.randint(5, 10, 50).reshape(50, 1)
x2 = np.random.randint(10, 16, 50).reshape(50, 1)
x = np.hstack((x1, x2))
# 在这里我们便得到了一个50行2列的样本数据,
#其中第一列为上底,第二列为下底
y = 0.5 * (x1 + x2) * x1
return x, y
- 求解与结果
def train(x, y):
poly = PolynomialFeatures(include_bias=False)
x_mul = poly.fit_transform(x)
model = LinearRegression()
model.fit(x_mul, y)
print("权重为:", model.coef_)
print("偏置为:", model.intercept_)
print("上底 {},下底 {}梯形真实面积:{}".
format(5, 8, 0.5 * (5 + 8) * 5))
x_mul = poly.transform([[5, 8]])
print(x_mul)
print("上底 {},下底为 {}梯形预测面积:{}".
format(5, 8, model.predict(x_mul)))
if __name__ == '__main__':
x, y = make_data()
train(x, y)
#输出结果:
#权重为: [[-6.176e-15 -5.552e-16 5.00e-01
#5.00e-01 -9.47e-17]]
#偏置为: [0.]
#上底为 5,下底为 8的梯形真实面积为:32.5
#[[ 5. 8. 25. 40. 64.]]
#上底为 5,下底为 8的梯形预测面积为:[[32.5]]
在上面,我们举了一个实际的例子作为预测,发现模型预测的结果居然和真实计算结果相等。并且,根据求解得到的权重和偏置,我们可以得到:
可以发现,模型居然自己已经总结(学习)出了计算公式,amazing!
3 总结
在这篇文章中,笔者以示例的形式详细讲解了多变量线性回归和多项式回归,同时还领略到了算法的魅力所在。由于篇幅所限,模型的评估与改善将在下一篇文章中介绍。本次内容就到此结束,感谢阅读!
若有任何疑问,请发邮件至moon-hotel@hotmail.com并附上文章链接,青山不改,绿水长流,月来客栈见!
引用
- 示例代码与练习: github.com/moon-hotel/…
- 吴恩达机器学习