2017-05-11 97 views
0

目的:我想計算擬合多元線性迴歸模型預測的測試誤差。將statsmodel預測與實際y值進行比較(索引問題)

問題:這是我的代碼。它旨在基於X_test變量擬合線性迴歸模型來訓練數據,然後預測y值(價格):

X.insert(0, 'constant', 1) # insert constant column 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2) 
lm_sm = sm.OLS(y_train, X_train).fit() 

y_pred = pd.DataFrame() # dataframe for predictions vs actual y-values 
y_pred['predictions'] = lm_sm.predict(X_test) 

print y_test.sort_index().head() 
print y_pred.sort_index().head() 

代碼輸出如下:

 price 
6 257500.0 
17 485000.0 
23 252700.0 
25 233000.0 
26 937000.0 
    predictions 
0 509428.615367 
1 324403.584917 
2 477385.431339 
3 484962.235105 
4 827039.820936 

比較預測的和實際的價格,這顯然是不對的。 predict()方法不保留我的火車/測試拆分中的索引。所以當我將預測價格與實際價格進行比較時,我無法確定我是在比較正確的價值。

我想過的唯一解決方案(我不知道這是否正確)我們在做預測時排序X_test,即y_pred['predictions'] = lm_sm.predict(X_test.sort_index())。這些預測看起來與我的預期(注意,這是第一線性迴歸/基準所以沒有功能工程是否已經被應用)多一點對齊:

 price 
6 257500.0 
12 310000.0 
18 189000.0 
25 233000.0 
29 719000.0 
    predictions 
0 259985.788272 
1 590648.478023 
2 339621.126287 
3 316402.199424 
4 635513.611634 

我會再執行基於這些分類dataframes測試誤差計算。這是正確的嗎?有沒有更乾淨的方法來做到這一點?我不知道的一種方法?任何幫助/想法將不勝感激,謝謝!

回答

2

我其實並不認爲排序有任何問題。混合指數y_test,與清潔指數y_pred相比,是造成混亂的根源。

當你在你的數據集(X, y)上使用train_test_split時,顯然會混洗東西,這就是爲什麼y_test有一個洗牌子集的索引。

當你做lm_sm.predict(X_test),輸出是一個普通的numpy數組。它不是帶有索引的熊貓物件,因此索引信息已經丟失。另外,在您的代碼中,您將結果存儲在新的y_pred數據框中。而在這新鮮y_pred,指數將是一個新的自動遞增:0,1,2 ...

所以根本就沒有使用sort_index(),你可以肯定的是y_pred因爲你擁有它會排隊與X_testy_test

編輯。希望這可以更好地說明問題。

import numpy as np 
import pandas as pd 
from sklearn.model_selection import train_test_split 
from statsmodels.regression.linear_model import OLS 

X = pd.DataFrame(np.random.random((60, 3))) 
y = pd.DataFrame(np.random.random((60, 1))) 

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2) 

print(X_test) 

測試儀的特點:

  0   1   2 
2 0.547993 0.479149 0.495539 
48 0.332964 0.857635 0.501391 
23 0.380500 0.377257 0.088766 
35 0.045725 0.432096 0.239523 
52 0.254861 0.207215 0.985722 
37 0.099525 0.205250 0.054000 
22 0.426227 0.253524 0.336110 
43 0.716443 0.006443 0.423447 
49 0.146820 0.803366 0.390921 
6 0.127666 0.848561 0.936604 
46 0.303034 0.548064 0.852688 
33 0.516726 0.977396 0.829725 

而且測試儀的目標與print(y_test)

  0 
2 0.123253 
48 0.494307 
23 0.312021 
35 0.939558 
52 0.958955 
37 0.681215 
22 0.181427 
43 0.907552 
49 0.589316 
6 0.613305 
46 0.947220 
33 0.696609 

指數洗牌,但他們同意。現在做:

lm_sm = OLS(y_train, X_train).fit() 
y_pred = pd.DataFrame() # dataframe for predictions vs actual y-values 
y_pred['predictions'] = lm_sm.predict(X_test) 

# Print this directly 
print(lm_sm.predict(X_test)) 

最後一行是隻是一個普通numpy的數組:

[ 0.44549342 0.44973765 0.24465328 0.17840542 0.42329909 0.09567253 
    0.30675321 0.38496281 0.33836597 0.49959203 0.47488055 0.63751567] 

當你看看新的數據框y_pred,該指數是一個新鮮的0,1,2 ... print(y_pred)

predictions 
0  0.445493 
1  0.449738 
2  0.244653 
3  0.178405 
4  0.423299 
5  0.095673 
6  0.306753 
7  0.384963 
8  0.338366 
9  0.499592 
10  0.474881 
11  0.637516 

你可能會感到意外的是,這些指標不匹配的y_test,但我發現,在predict()函數返回一個普通的numpy數組,並且沒有任何東西將結果y_pred連接到原始索引了。儘管如此,你可以確定一切都是一致的。