繼續上一篇,接下來是股票分析中使用線性回歸
在現實世界中,存在着大量這樣的情況:兩個變量例如X和Y有一些依賴關系。由X可以部分地決定Y的值,但這種決定往往不很確切。常常用來說明這種依賴關系的最簡單、直觀的例子是體重與身高,用Y表示他的體重。眾所周知,一般說來,當X大時,Y也傾向於大,但由X不能嚴格地決定Y。又如,城市生活用電量Y與氣溫X有很大的關系。在夏天氣溫很高或冬天氣溫很低時,由於室內空調、冰箱等家用電器的使用,可能用電就高,相反,在春秋季節氣溫不高也不低,用電量就可能少。但我們不能由氣溫X准確地決定用電量Y。類似的例子還很多,變量之間的這種關系稱為“相關關系”,回歸模型就是研究相關關系的一個有力工具。
線性回歸模型生成一個確定自變量和因變量之間關系的方程。
線性回歸方程可以寫成:
x1, x2, ....xn代表自變量,系數θ1,θ2,....θn代表權重。
使用時間(date)列提取特征,如- day, month, year, mon/fri等,然后擬合線性回歸模型。
首先按升序對數據集進行排序,然后創建一個單獨的數據集,這樣創建的任何新特性都不會影響原始數據。
#setting index as date values 以date作為索引
df['Date'] = pd.to_datetime(df.Date,format='%Y-%m-%d')
df.index = df['Date']
#sorting 升序排列
data = df.sort_index(ascending=True, axis=0)
#creating a separate dataset 創建一個單獨的數據集
new_data = pd.DataFrame(index=range(0,len(df)),columns=['Date', 'Close'])
#將數據中的date和close都放到一個list中
for i in range(0,len(data)):
new_data['Date'][i] = data['Date'][i]
new_data['Close'][i] = data['Close'][i]
#create features 自己添加一些特征,同時第三行刪除了一些數據
from fastai.structured import add_datepart
add_datepart(new_data, 'Date')
new_data.drop('Elapsed', axis=1, inplace=True) #elapsed will be the time stamp
這將創建以下特征:
‘Year’, ‘Month’, ‘Week’, ‘Day’, ‘Dayofweek’, ‘Dayofyear’, ‘Is_month_end’, ‘Is_month_start’, ‘Is_quarter_end’, ‘Is_quarter_start’, ‘Is_year_end’, and ‘Is_year_start’.
注意:我使用了來自fastai庫的add_datepart。如果您沒有安裝它,您可以簡單地使用命令pip install fastai。您也可以使用python中的簡單for循環來創建這些特性。我在下面展示了一個例子。
除此之外,我們還可以添加自己的一組特性,我們認為這些特性與預測相關。例如,我的假設是,本周的頭幾天和最后幾天對股票收盤價的影響可能遠遠超過其他日子。因此,我創建了一個特性來識別給定的一天是星期一/星期五還是星期二/星期三/星期四。這可以用以下幾行代碼來完成:
new_data['Dayofweek'][i] == 0 代表 周日 (因為數組下標標注都是從0開始的)
new_data['Dayofweek'][i] == 4 代表 周一
mon_fri其實就是一個flag,如果是星期日或星期五,列值將為1,否則為0。
new_data['mon_fri'] = 0
for i in range(0,len(new_data)):
if (new_data['Dayofweek'][i] == 0 or new_data['Dayofweek'][i] == 4):
new_data['mon_fri'][i] = 1
else:
new_data['mon_fri'][i] = 0
類似地,您可以創建多個有助於預測股價的特征
現在我們將把數據分成訓練集和驗證集來檢查模型的性能。
#split into train and validation 分成訓練集和驗證
train = new_data[:987]
valid = new_data[987:]
#這里把訓練集和驗證集中的close的列剔除
x_train = train.drop('Close', axis=1)
y_train = train['Close']
x_valid = valid.drop('Close', axis=1)
y_valid = valid['Close']
#implement linear regression 使用sklearn的庫函數構建模型
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(x_train,y_train)
結果
#make predictions and find the rmse模型預測,計算rmse
preds = model.predict(x_valid)
rms=np.sqrt(np.mean(np.power((np.array(y_valid)-np.array(preds)),2)))
#這下面兩行是計算結果,可不執行
rms
121.16291596523156
RMSE值高於之前的方法,這清楚地表明線性回歸的表現很差。讓我們看看這個圖,並理解為什么線性回歸預測效果不是很好:
#plot 打印繪圖
valid['Predictions'] = 0
valid['Predictions'] = preds
#下面這兩行顛倒一下會好理解一些,分別取兩個數據集的索引
valid.index = new_data[987:].index
train.index = new_data[:987].index
#打印訓練集中close的部分(之前訓練的時候刪除了),打印測試集中close和預測值
plt.plot(train['Close'])
plt.plot(valid[['Close', 'Predictions']])
推論
線性回歸是一種簡單的技術,很容易解釋,但也有一些明顯的缺點。
使用回歸算法的一個問題是,模型過度擬合了日期和月份。模型將考慮一個月前相同日期或一年前相同日期/月的值,而不是從預測的角度考慮以前的值。
從上圖可以看出,2016年1月和2017年1月,股價出現下跌。該模型預測2018年1月也將如此。
線性回歸技術可以很好地解決像大賣場銷售這樣的問題,在這些問題中,獨立的特征對於確定目標值是有用的。