正文
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:导入相关库和类