T
U
SHARE
金融与技术学习兴趣小组
翻译整理 | One
本期编辑 | 一只小绿怪兽
译者简介:
西南财经大学应用数学本科,英国曼彻斯特大学金融数学硕士,金融分析师,专注于利用数据建立金融模型,发掘潜在投资价值。
作者:Mirko Stojiljkovic
线性回归是统计学和机器学习的基础之一。无论是做统计,机器学习还是科学计算,都可能用上线性回归。因此,建议先掌握线性回归,然后再学习更复杂的方法。
通过阅读本文,你将了解到:
· 什么是线性回归
· 线性回归的用途
· 线性回归的原理
· 在Python中实现线性回归
01
什么是回归
回归主要用于研究变量之间的关系。例如,可以通过观察一些公司的职员,并试着了解他们的特征如何影响他们的薪水,比如经验,教育水平,职位,工作地点等等。
这就个回归问题,与每个职员相关的数据都是代表一次观察。其中职员的经验,教育水平,职位,工作地点都是独立的特征,这些特征决定了职员的薪水水平。
类似的,也可以试着建立房屋价格与地域,卧室数量,到市中心距离的数学依赖关系。
在回归分析中,经常会发现一些有趣的现象和一些观察,每次观察都会有两个或者更多的特征。假设其中一个特征依赖其他几个特征,可以试着去建立回归发现特征之间的关系。
换种说法,
就是需要找到一个能够很好地将某些特征映射到其他特征的函数。
依赖特征称为
因变量
,独立特征称为
自变量
。
回归模型中通常有一个连续且无界的因变量。但是,自变量可以是连续的,离散的,甚至是像性别,国籍,品牌等分类数据。
通常用y表示因变量,x表示自变量。如果有两个或者多个自变量,可以用向量
x=(x
1
, …, x
r
)
表示。
02
回归的用途
通常,回归被用来回答某些现象是否会对其他现象产生影响,或者说,
几个变量之间是否存在关联
。例如,可以用回归的方法确定工作经验或者性别是否在某种程度上影响到工资水平。
用新的自变量数据集去
预测因变量
时,回归也是非常有用的。举个例子,已知室外气温,一天的某个时间,以及家里居住的人数,可以试着预测下一个小时的家庭用电量。
回归可用于许多领域:经济,IT,社会科学等等。随着大量数据的可获取性提升以及人们对于数据的实用价值认知的提高,回归变得越来越重要了。
03
线性回归的原理
线性回归是被广泛使用的回归方法中比较重要的一种。它是最基础也是最简单的回归方法。它的主要优点是易懂。
在对一组自变量
x=(x
1
,…,xr)
和因变量y进行回归时,我们假设y与x的关系:
y=β
0
+β
1
x
1
+···+β
r
x
r
+ε
。这个方程叫做
回归方程
。
β
0
,
β
1
,... ,β
r
是
回归系数
, ε是
随机误差
。
线性回归计算回归系数的估计值,或者说计算以
b
1
,b
2
,…,b
r
表示并
用于预测的权重
。其中
回归函数
被定义为
f(x)=b
0
+b
1
x
1
+b
2
x
2
+···+b
r
x
r
。回归函数可以很好地捕获自变量与因变量的依赖关系。
对于每一次观测
i=1,…,n
,
回归函数
f(xi)应该要足够接近
实际观测
的因变量
y
i
值,其中
y
i
与f(xi)的差值称为
残差
。回归是为了找到最优权重并用于预测,而
残差最小
的时候说明回归函数f(xi)与实际观测的yi是
最接近
的,此时对应的权重便是
最优权重
b=(b
1
,b
2
,…,b
r
)
。
通常使用
最小化残差平方和
的方法来计算最优权重,即最小化
SSR=∑
i
(y
i
-f(x
i
))
2
。这种方法叫做
最小二乘法OLS
。
实际观测值
y
i
的变化一部分由于自变量
x
i
的变化导致的。但是实际观测值
y
i
仍然会有无法用回归函数f(xi)解释的部分。
而
决定系数
R
2
,用来说明实际观测值
y
i
中有多大程度可以由回归函数
f(x)
解释。
R
2
越大,两者拟合程度越高,意味着观测值
y
i
-x
i
数据组可以很好的契合回归函数
f(x)
。
R
2
=1时,即SSR=0,称作
完全拟合
,这意味着所有
y
i
-x
i
可以完全匹配回归函数
f(x)
。
单变量线性回归是线性回归中最简单的一种情形,即回归模
型中只有一个自变量
x=x
1
。
这些数据集一般来自实际业务中的数据采集。上图中,最左边绿点
x=5,y=5
就是观测值。
回归函数以图中黑线表示,其表达式为
f(x)=b
0
+b
1
x
。我们需要用最小化残差平方和SSR的方法来计算回归函数中的权重
b
0
与b
1
。其中
b
0
为
截距
,即回归函数f(x)与y轴的交点。
b
1
为回归函数的
斜率
,也可以理解为黑线的倾斜程度。
图中红色方块表示的是
x
i
-f(x
i
)
的数据集,该数据集都落在直线上。例如
x=5,f(5)=8.33
。
有了以上两组数据后,便可以计算残差,即
y
i
-f(x
i
)=y
i
-b
0
-b
1
x
i
,i=1,…,n。
在图中残差可表示为绿点到红方块的距离,用虚线表示。在执行线性回归时,事实上是在试着使图中绿点到红方块的虚线总长度最小,即残差最小。
假如仅有两个自变量,回归函数可以写成
f(x
1
,x
2
)=b
0
+b
1
x
1
+b
2
x
2
。这个函数在三维空间中是一个平面。
这种回归的目标也是确定权重
b
0
,b
1
,b
2
,即使得这个平面
f(x
1
,x
2
)
与实际观测的数值间的距离最小,即最小化SSR。
两个自变量以上的多变量回归也与上述的方法类似。例如
f(x
1
,…,x
r
)=b
0
+b
1
x
1
+···+b
r
x
r
,这个方程中有r+1个权重
b
i
需要估计。
可以将多项式回归视为线性回归的一般情形。自变量与因变量的多项式依赖关系可以通过回归得到多项式回归函数。
换句话说,回归函数f中,除了包含线性部分如
b
1
x
1
,还可以加入非线性部分如
b
2
x
1
2
,b
3
x
1
3
,
甚至
b
4
x
1
x
2
,b
5
x
1
2
x
2
等等。
单变量多项式回归是其中最简单的一种形式,例如2阶单变量多项式回归函数:
f(x)=b
0
+b
1
x+b
2
x
2
。
。
现在只需要通过最小二乘法计算
b
0
,b
1
,b
2
即可。与上一节的线性回归函数
f(x
1
,x
2
)=b
0
+b
1
x
1
+b
2
x
2
相比较,两种回归非常相似,并且都需要估计系数
b
0
,b
1
,b
2
。因此,只需要将高阶项如x2视为因变量,多项式回归与普通的线性回归是一样的。
在2阶多变量的情形中,回归函数可以像这样:
f(x
1
,x
2
)=b
0
+b
1
x
1
+b
2
x
2
+b
3
x
1
2
+b
4
x
1
x
2
+b
5
x
2
2
,回归的方法和前面叙述的一样。对五个自变量应用线性回归:
x
1
,x
2
,x
1
2
,
x
1
x
2
,x
2
2
。回归的结果得到6个在SSR最小化时的权重:
b
0
,b
1
,b
2
,b
3
,b
4
,b
5
。
在执行多项式回归中,一个需要引起高度重视的问题是:
关于多项式回归函数最优阶数的选择
。
阶数的选择并没有明确的规则。它需要视情况而定。但是,在选择阶数的时候,需要关注两个问题:
欠拟合与过拟合。
当模型无法准确的捕获数据之间的依赖关系时导致
欠拟合
,这通常是由于模型过于简单导致的。欠拟合的模型在用现有数据进行回归时会有较低的决定系数
R
2
,同时它的
预测能力也不足
。
当数据和随机波动性都拟合到模型中时会导致
过拟合
。换种说法,就是模型和现有数据契合程度过高了。高度复杂的模型一般都有很多自变量,这通常容易导致模型过拟合。将现有数据拟合这种模型的时候一般会有很高的决定系数
R
2
。但是在使用新数据时,模型可能会表现出
很弱的预测能力
和低决定系数
R
2
。
下图分别展示了欠拟合,好的拟合,和过拟合的模型:
左上图是个低决定系数
R
2
的线性回归。这条直线没有考虑当x变化时观测值
y
i
的剧烈变动。这也许是一个欠拟合的例子。
右上图是个2阶多项式回归。在这个回归模型中,2阶也许是拟合该组数据的最优阶数。这个回归模型的
R
2
还不错,并且可以很好地勾勒出了数据的趋势。
左下图是个3阶的多项式回归。回归模型的
R
2
比右上图的要高。对于现有的数据,这个模型比右上图的模型要好。但是,它可能有一些过拟合的迹象,尤其是在x接近60的时候,现有的观测数据并没有显示出回归模型中给出的下降趋势。
最后,在右下图中,这是一个完全拟合,6个观测值都落在回归模型的曲线上。这可能是我们想要的回归模型,但是在多数情况下,这是一种过拟合的模型。它可能会有糟糕的预测能力。在这例中,可以看到曲线在x大于50时候毫无征兆的急速下降,并且在x=60附近归零。这种曲线可能是过度学习或者过度拟合现有数据导致的。
numpy
是一款基础Python包,它可以在单维和多维数组上进行高效的操作。它还提供很多数值计算方法,同时也是开源库。
如果不熟悉numpy,可以阅读官方的numpy使用指南,此外还有numpy相关的文章会在附录中提供。网络上还有大量的numpy资料可供搜索。
scikit-learn
是一个被大量用户用于机器学习的Python库,该库是基于numpy和其他库建立的。它可以执行数据预处理,降维,回归,分类和聚类等功能。和numpy一样,scikit-learn也是开源的。
可以在scikit-learn官网上查看Generalized Linear Models页面了解更多关于线性模型的内容以进一步了解该库的原理。
statsmodels
库可以实现一些在做线性回归时scikit-learn中没有的功能。它也是一个不错的Python库,主要用于统计模型的估计,模型的测试等等。同时它也是开源的。
这里从最简单的单变量线性回归开始,手把手教你在Python中做线性回归模型,整个过程大致分五个基本步骤:
① 导入相关库和类
② 读取相关数据,对数据进行适当处理
③ 创建回归模型并对现有数据样本进行拟合
④ 查看模型的拟合结果,判断模型是否合理
⑤ 用模型进行预测
这几个步骤在大多数回归方法中基本是通用的。
Step 1:导入相关库和类
首先导入
pandas
,
tushare
库和
sklearn.linear_model
中的
LinearRegression
类:
import pandas as pd
import numpy as np
import tushare as ts
from sklearn.linear_model import LinearRegression
当然,也可以用
numpy
库。
pandas
和numpy的数据类型可以与
sklearn
无缝对接,并且高效,可读性强
。
而类
sklearn.linear_model.LinearRegression
提供了执行线性回归的相关功能。
Step 2:读取数据
这一步主要是读取数据,并进行必要的预处理。这里采用了
tushare.pro
的个股和指数日收益率数据,并对数据进行了适当的处理。
ts.set_token('your token')
pro = ts.pro_api()
index_hs300 = pro.index_daily(ts_code='399300.SZ', start_date='20180101', end_date='20190110')
stock_000001 = pro.query('daily', ts_code='000001.SZ', start_date='20180101', end_date='20190110', fields='ts_code, trade_date ,pct_chg')
index_pct_chg = index_hs300.set_index('trade_date')['pct_chg']
stock_pct_chg = stock_000001.set_index('trade_date')['pct_chg']
df = pd.concat([stock_pct_chg, index_pct_chg], keys=['y_stock', 'x_index'], join='inner', axis=1, sort=True)
df_existing_data = df[df.index '20190101']
x = df_existing_data[['x_index']]
y = df_existing_data['y_stock']
经过简单处理,现在有了自变量x和因变量y。需要注意的是,
sklearn.linear_model.LinearRegression
类需要传入的自变量是一组二维数组结构,因此可以通过numpy的
.reshape()
方法将一维数组变更为二维数组,另一种方法就是使用pandas的DataFrame格式。
现在自变量和因变量看起来像这样:
print(x.head())
print(y.head())
x_index
trade_date
20180102 1.4028
20180103 0.5870
20180104 0.4237
20180105 0.2407
20180108 0.5173
trade_date
20180102 3.01
20180103 -2.70
20180104 -0.60
20180105 0.38
20180108 -2.56
Name: y_stock, dtype: float64
可以通过
.shape
参数看到x有两个维度(243, 1),而y是一维数组,(243, )。
Step 3:建立模型并拟合数据
第三步,建立线性回归模型,并用中国平安和沪深300的2018年全年日线收益率数据进行拟合。
先创建一个
LinearRegression
的实例用于建立回归模型:
model = LinearRegression()
这里创建了一个默认参数的
LinearRegression
类实例。可以为
LinearRegression
传入以下几个可选参数:
fit_intercept
:
布尔值,默认为True。True为需要计算截距b
0
,False为不需要截距,即b
0
=0。
normalize
:布尔值,默认为False。参数作用是将数据标准化,False表示不做标准化处理。
copy_x
:布尔值,默认为True。True为保留x数组,False为覆盖原有的x数组。
n_jobs
:整型或者None,默认为None。这个参数用于决定并行计算线程数。None表示单线程,-1表示使用所有线程。
模型建立以后,首先需要在模型上调用
.fit()
方法:
用现有的数据集x-y,通过.fit()方法,可以计算出线性回归方程的最优权重b
0
和b
1
。换句话说,数据集x-y通过.fit()方法拟合了回归模型。.fit()方法输出self,也就是输出model模型本身。可以将以上两个语句简化为:
model = LinearRegression().fit(x, y)
Step 4:输出结果
数据拟合模型后,可以输出结果看看模型是否满意,以及是否可以合理的解释数据的趋势或者依赖关系。
可以通过调用
.score()
方法来获取model的
R
2
:
model = LinearRegression().fit(x, y)
r_sq = model.score(x, y)
print('coefficient of determination: ', r_sq)
coefficient of determination: 0.5674052646582468
同时,也可以通过调取model的
.intercept_
和
.coef_
属性获取截距
b
0
和斜率b
1
:
print('intercept:', model.intercept_)
print('slope:', model.coef_)
intercept: 0.01762302497463801
slope: [1.18891167]
需要注意的是,
.intercept_
是一个numpy.float64数值,而
.coef_
是一个numpy.array数组。
b
0
=0.017,表示自变量沪深300的日收益率为0时,因变量中国平安股票的日收益率大约为 0.017%。而b1=1.189,表示沪深300的日收益率增加1%时,中国平安股票的日收益率增加1.189%。反之亦然。
在上面的数据载入中,因变量y也可以是二维数组,这种情形下的输出结果和以上类似:
y = pd.DataFrame(y)
new_model = LinearRegression().fit(x, y)
print('intercept:', new_model.intercept_)
print('slope:', new_model.coef_)
intercept: [0.01762302]
slope: [[1.18891167]]
可以看到此次输出结果中,b
0
变为一维numpy.array数组,而不是之前的float64数值。而b
1
输出一组二维numpy.array数组。
Step 5:模型预测
获得了比较合理的模型后,可以用现有数据或者新数据来进行预测。
本例中使用了沪深300指数2019年前7个交易日的收益率数据对中国平安股票进行预测,由于本文主旨是介绍线性回归的原理与相关使用方法,模型的预测效果本文中不做探讨。当然,也可以用2018年的现有的自变量数据获取回归模型的数据f(x)。
要获得预测结果,可以使用
.predict()
方法:
df_new_data = df[df.index > '20190101']
new_x = df_new_data[['x_index']]
y_pred = model.predict(new_x)
print('predicted response:', y_pred, sep='\n')
predicted response:
[-1.60619253 -0.17022502 2.86601759 0.73929241 -0.23930079 1.21806713
-0.20601126]
.predict()
方法需要将新的自变量传入该方法中以获得预测值。也可以用下面这种方法:
b0, b1 = model.intercept_, model.coef_
y_pred = b0 + b1 * new_x
y_pred.columns = ['y_pred'
]
print('predicted response:', y_pred, sep='\n')
predicted response:
y_pred
trade_date
20190102 -1.606193
20190103 -0.170225
20190104 2.866018
20190107 0.739292
20190108 -0.239301
20190109 1.218067
20190110 -0.206011
这种方式可以将模型通过函数形式直观的表达出来。与
.predict()
的方法相比,这种方式的输出结果是一个DataFrame类型,其为二维数组结构。而.predict()仅输出一组一维numpy.array数组。
如果将new_x改为一维数组,y_pred的输出结果将与.predict()一致。
实践中,回归模型通常可以用来做预测。这意味着可以将一些新的自变量数据x传入拟合好的模型中来计算结果。比如假设一组沪深300日收益率数据[0, 1, 2, 3, 4],通过model获得中国平安股票的日收益率预测结果:
x_new = np.arange(5).reshape((-1, 1))
y_new = model.predict(x_new)
print(y_new)
[0.01762302 1.20653469 2.39544636 3.58435802 4.77326969]
多元线性回归和基础线性回归实现步骤基本一致。
Step 1:导入相关库和类
Step 2:读取数据
本例使用了
tushare.pro
中的沪深300作为因变量,中金的细分金融指数和细分有色指数作为两个自变量。
import pandas as pd
import numpy as np
from sklearn.linear_model import LinearRegression
import tushare as ts
ts.set_token('your token')
pro = ts.pro_api()
index_hs300 = pro.index_daily(ts_code='399300.SZ', start_date='20180101', end_date='20190110')
index_metal = ts.pro_bar(ts_code='000811.CSI', freq='D', asset='I', start_date='20180101', end_date='20190110')
index_finance = ts.pro_bar(ts_code='000818.CSI', freq='D', asset='I', start_date='20180101', end_date='20190110')
index_hs300_pct_chg = index_hs300.set_index('trade_date')['pct_chg']
index_metal_pct_chg = index_metal.set_index('trade_date')['pct_chg']
index_finance_pct_chg = index_finance.set_index('trade_date')['pct_chg']
df = pd.concat([index_hs300_pct_chg, index_metal_pct_chg, index_finance_pct_chg], keys=['y_hs300', 'x1_metal', 'x2_finance'], join='inner', axis=1, sort=True)
df_existing_data = df[df.index '20190101']
x = df_existing_data[['x1_metal', 'x2_finance']]
y = df_existing_data['y_hs300']
因变量和自变量如下:
print
(x.head())
print(y.head())
x1_metal x2_finance
trade_date
20180102 0.8574 1.6890
20180103 1.0870 -0.0458
20180104 0.9429 -0.3276
20180105 -0.7645 0.1391
20180108 2.2010 0.0529
trade_date
20180102 1.4028
20180103 0.5870
20180104 0.4237
20180105 0.2407
20180108 0.5173
Name: y_hs300, dtype: float64
DataFrame类型可以非常直观的列出多个自变量,语法也相当简洁,最重要的是该数据类型可以直接应用于LinearRegression类。当然,这里也可以使用numpy.array的数据类型。
Step 3:建立模型并拟合数据
和前一个例子一样,建立模型并数据拟合:
model = LinearRegression().fit(x, y)
Step 4:输出结果
一样的方式,通过model的
.score()
,
.intercept_
,
.coef_
属性获取回归模型的决定系数,截距
b
0
,
以及权重
b
1
,b
2
:
model = LinearRegression().fit(x, y)
r_sq = model.score(x, y)
print('coefficient of determination:', r_sq)
print('intercept:', model.intercept_)
print('slope:', model.coef_)
coefficient of determination: 0.8923741832489497
intercept: 0.0005333314305123599
slope: [0.30529472 0.64221632]
输出结果可以看出,截距b
0
大致为0,即当x
1
=x
2
=0时,f(x
1
, x
2
)=0。更多地,当x
1
增加1时,相应的f(x
1
, x
2
)增加大约0.305,而当x
2
增加1时,相应的f(x
1
, x
2
)增加大约0.642。反之亦然。
Step 5:模型预测
预测方式与前面也是一致的:
df_new_data = df[df.index > '20190101']
new_x = df_new_data[['x1_metal', 'x2_finance']]
y_pred = model.predict(new_x)
print('predicted response:', y_pred, sep='\n')
predicted response:
[-1.4716842 1.17891556 2.55034238 0.17701977 -0.81283822 0.57159138
-0.19729323]
也可以用下面这种方式:
y_pred = model.intercept_ + (model.coef_ * new_x).sum(axis=1)
print('predicted response:', y_pred, sep='\n')
predicted response:
trade_date
20190102 -1.471684
20190103 1.178916
20190104 2.550342
20190107 0.177020
20190108 -0.812838
20190109 0.571591
20190110 -0.197293
dtype: float64
这种方式就是将每列自变量x
1
,x
2
乘上其对应的权重b
1
,b
2
,再加上一个固定的截距b
0
,得到预测的因变量。
执行多项式回归步骤与前面也相似,只是需要增加一组经过转换的自变量作为非线性项,如x
2
。
Step 1:导入相关库和类
除了需要导入pandas和tushare,sklearn.linear_model.LinearRegression外,还需要导入
sklearn.preprocessing
中的
PolynomialFeatures
类用来处理非线性项。
import pandas as pd
import tushare as ts
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import PolynomialFeatures
Step 2:读取数据
本例就采用
tushare.pro
上面的沪深300和中金细分金融指数数据。
index_hs300 = pro.index_daily(ts_code='399300.SZ', start_date='20180101', end_date='20190110')
index_finance = ts.pro_bar(ts_code='000818.CSI', freq='D', asset='I', start_date='20180101', end_date='20190110')
index_hs300_pct_chg = index_hs300.set_index('trade_date')['pct_chg']
index_finance_pct_chg = index_finance.set_index('trade_date')['pct_chg']
df = pd.concat([index_hs300_pct_chg, index_finance_pct_chg], keys=['y_hs300', 'x_finance'], join='inner', axis=1, sort=True)
df_existing_data = df[df.index '20190101']
x = df_existing_data[['x_finance'
]]
y = df_existing_data['y_hs300']
Step 3:自变量转换
这个步骤是多项式回归需要执行的步骤。由于多项式回归中有x
2
项,因此需要将x数组转换成x
2
并作为新的列。
有很多种转换方式,比如使用numpy中的insert()方法,或者pandas的DataFrame添加x
2
列。本例中使用的是
PolynomialFeatures
类:
transformer = PolynomialFeatures(degree=2, include_bias=False)
transformer
是PolynomialFeatures类的实例,用于对自变量x进行转换。
PolynomialFeatures
类中有以下几个可选参数:
degree
:整型,默认为2。用于决定线性回归模型的阶数。
interaction_only
:布尔值,默认为False。如果指定为True,那么就不会有
x
i
2
项,只有如
x
i
x
j
的交叉项。
include_bias
:布尔值,默认为True。此参数决定是否将截距项添加为回归模型中的一项,即增加一列值为1的列。False表示不添加。
先将自变量x数据传入转换器
transformer
中:
传入
transformer
之后,就可以使用
.transform()
方法获得转换后的数据x和x
2
:
x_ = transformer.transform(x)
当然也可以用
.fit_transform()
来替代以上三个语句:
x_ = PolynomialFeatures(degree=2, include_bias=False).fit_transform(x)
转换后的数组效果如下:
print(x_[:5])
[[ 1.6890000e+00 2.8527210e+00]
[-4.5800000e-02 2.0976400e-03]
[-3.2760000e-01 1.0732176e-01]
[ 1.3910000e-01 1.9348810e-02]
[ 5.2900000e-02 2.7984100e-03]]
可以看到新的数据中有两列:一列是原始的自变量x的数据,另一列是
x
2
项。
Step 4:建立模型并拟合数据
数据经过转换后,模型的建立和拟合的方式与前面一样:
model = LinearRegression().fit(x_, y)
【注】
模型中第一个参数变为经过处理后的数据
x_
,而不是原始的自变量x数组。
Step 5:输出结果
r_sq = model.score(x_, y)
print('coefficient of determination:', r_sq)
print('intercept:', model.intercept_)
print('coefficients:', model.coef_)
.score()返回R
2
=0.813,截距项b
0
大约为-0.014,x项的权重b
1
约为0.862,x
2
项的权重b
2
约为-0.014。
另外一种回归方法,也可以通过向转换器中传入不同的参数获得相同的回归结果:
x_ = PolynomialFeatures(degree=2, include_bias=True).fit_transform(x)
这里将include_bias参数设置为True,其他的依然是默认参数。这种方法和step3中的相比,x_中会多出值为1的列,这列对应的是回归模型中的截距项:
print(x_[:5])
[[ 1.0000000e+00 1.6890000e+00 2.8527210e+00]
[ 1.0000000e+00 -4.5800000e-02 2.0976400e-03]
[ 1.0000000e+00 -3.2760000e-01 1.0732176e-01]
[ 1.0000000e+00 1.3910000e-01 1.9348810e-02]
[ 1.0000000e+00 5.2900000e-02 2.7984100e-03]]
这组数据中,第一列全为1,第二列为x,第三列为x
2
。
由于截距项已经包含在新的数据x_中了,因此在创建LinearRegression类时应该忽略截距项,即传入参数fit_intercept=
False
:
model = LinearRegression(fit_intercept=False).fit(x_, y)
至此,模型和数据x_是匹配的。模型结果如下:
r_sq = model.score(x_, y)
print('coefficient of determination:', r_sq)
print('intercept:', model.intercept_)
print('coefficients:', model.coef_)
coefficient of determination: 0.8133705974408868
intercept: 0.0
coefficients: [-0.01395755 0.86215933 -0.01444605]
可以看到.intercept_为0,但实际上截距b
0
已经包含在.coef_中了。其他结果都是一样的。
Step 6:模型预测
同样的,模型预测只需要调用
.predict()
方法,但是需要注意的是,传入的新数据也需要做转换:
df_new_data = df[df.index>'20190101']
new_x = df_new_data[['x_finance']]
new_x_ = PolynomialFeatures(degree=2, include_bias=True).fit_transform(new_x)
y_pred = model.predict(new_x_)
print('predicted response:', y_pred, sep='\n')
predicted response:
[-1.32738808 0.98948547 2.38535216 -0.30448932 -0.40485458 0.78721444
-0.23448668]
已经了解到了,多项式回归模型的预测方式与前面两例基本一样,只需要将用于预测的数据做下转换就好了。
如果有
多个自变量
,执行的过程也是一样的。
这里使用了和前面提到的多变量回归中相同的三组指数日收益率数据:
x = df_existing_data[['x1_metal', 'x2_finance']]
y = df_existing_data['y_hs300']
x_ = PolynomialFeatures(degree=2, include_bias=False).fit_transform(x)
model = LinearRegression().fit(x_, y)
r_sq = model.score(x_, y)
intercept, coefficients = model.intercept_, model.coef_
df_new_data = df[df.index > '20190101']
new_x = df_new_data[['x1_metal', 'x2_finance']]
new_x_ = PolynomialFeatures(degree=2, include_bias=False).fit_transform(new_x)
y_pred = model.predict(new_x_)
模型结果和预测如下: