簡體   English   中英

使用 StatsModels 的置信區間和預測區間

[英]confidence and prediction intervals with StatsModels

我用StatsModels做這個linear regression

import numpy as np
import statsmodels.api as sm
from statsmodels.sandbox.regression.predstd import wls_prediction_std

n = 100

x = np.linspace(0, 10, n)
e = np.random.normal(size=n)
y = 1 + 0.5*x + 2*e
X = sm.add_constant(x)

re = sm.OLS(y, X).fit()
print(re.summary())

prstd, iv_l, iv_u = wls_prediction_std(re)

我的問題是, iv_liv_u是上下置信區間預測區間

我怎么得到別人?

我需要所有點的置信區間和預測區間,才能得到 plot。

對於測試數據,您可以嘗試使用以下內容。

predictions = result.get_prediction(out_of_sample_df)
predictions.summary_frame(alpha=0.05)

我發現summary_frame()方法埋在這里,你可以找到get_prediction()方法在這里 您可以通過修改“alpha”參數來更改置信區間和預測區間的顯着性水平。

我在這里發布這個是因為這是在尋找置信和預測區間的解決方案時出現的第一篇文章——盡管這與測試數據有關。

這是一個使用這種方法獲取模型、新數據和任意分位數的函數:

def ols_quantile(m, X, q):
  # m: OLS model.
  # X: X matrix.
  # q: Quantile.
  #
  # Set alpha based on q.
  a = q * 2
  if q > 0.5:
    a = 2 * (1 - q)
  predictions = m.get_prediction(X)
  frame = predictions.summary_frame(alpha=a)
  if q > 0.5:
    return frame.obs_ci_upper
  return frame.obs_ci_lower

更新請參閱更新的第二個答案 一些模型和結果類現在有一個get_prediction方法,該方法提供附加信息,包括預測均值的預測區間和/或置信區間。

舊答案:

iv_liv_u為您提供每個點的預測區間的限制。

預測區間是觀測值的置信區間,包括誤差估計值。

我認為,平均預測的置信區間在statsmodels尚不可用。 (實際上,擬合值的置信區間隱藏在influence_outlier的summary_table中,但我需要驗證這一點。)

統計模型的正確預測方法在 TODO 列表中。

添加

OLS 有置信區間,但訪問有點笨拙。

在運行腳本后包含:

from statsmodels.stats.outliers_influence import summary_table

st, data, ss2 = summary_table(re, alpha=0.05)

fittedvalues = data[:, 2]
predict_mean_se  = data[:, 3]
predict_mean_ci_low, predict_mean_ci_upp = data[:, 4:6].T
predict_ci_low, predict_ci_upp = data[:, 6:8].T

# Check we got the right things
print np.max(np.abs(re.fittedvalues - fittedvalues))
print np.max(np.abs(iv_l - predict_ci_low))
print np.max(np.abs(iv_u - predict_ci_upp))

plt.plot(x, y, 'o')
plt.plot(x, fittedvalues, '-', lw=2)
plt.plot(x, predict_ci_low, 'r--', lw=2)
plt.plot(x, predict_ci_upp, 'r--', lw=2)
plt.plot(x, predict_mean_ci_low, 'r--', lw=2)
plt.plot(x, predict_mean_ci_upp, 'r--', lw=2)
plt.show()

在此處輸入圖片說明

這應該給出與 SAS 相同的結果, http://jpktd.blogspot.ca/2012/01/nice-thing-about-seeing-zeros.html

當您需要單個分位數的精確結果時, summary_framesummary_table可以很好地工作,但不能很好地矢量化。 這將提供預測區間(不是置信區間)的正常近似值,並適用於分位數向量:

def ols_quantile(m, X, q):
  # m: Statsmodels OLS model.
  # X: X matrix of data to predict.
  # q: Quantile.
  #
  from scipy.stats import norm
  mean_pred = m.predict(X)
  se = np.sqrt(m.scale)
  return mean_pred + norm.ppf(q) * se

對於時間序列結果,您可以使用get_forecast()方法獲得更平滑的圖。 下面是一個時間序列的例子:

# Seasonal Arima Modeling, no exogenous variable
model = SARIMAX(train['MI'], order=(1,1,1), seasonal_order=(1,1,0,12), enforce_invertibility=True)

results = model.fit()

results.summary()

在此處輸入圖片說明

下一步是進行預測,這會生成置信區間。

# make the predictions for 11 steps ahead
predictions_int = results.get_forecast(steps=11)
predictions_int.predicted_mean

在此處輸入圖片說明

這些可以放在數據框中,但需要一些清理:

# get a better view
predictions_int.conf_int()

在此處輸入圖片說明

連接數據框,但清理標題

conf_df = pd.concat([test['MI'],predictions_int.predicted_mean, predictions_int.conf_int()], axis = 1)

conf_df.head()

在此處輸入圖片說明

然后我們重命名列。

conf_df = conf_df.rename(columns={0: 'Predictions', 'lower MI': 'Lower CI', 'upper MI': 'Upper CI'})
conf_df.head()

在此處輸入圖片說明

制作情節。

# make a plot of model fit
# color = 'skyblue'

fig = plt.figure(figsize = (16,8))
ax1 = fig.add_subplot(111)


x = conf_df.index.values


upper = conf_df['Upper CI']
lower = conf_df['Lower CI']

conf_df['MI'].plot(color = 'blue', label = 'Actual')
conf_df['Predictions'].plot(color = 'orange',label = 'Predicted' )
upper.plot(color = 'grey', label = 'Upper CI')
lower.plot(color = 'grey', label = 'Lower CI')

# plot the legend for the first plot
plt.legend(loc = 'lower left', fontsize = 12)


# fill between the conf intervals
plt.fill_between(x, lower, upper, color='grey', alpha='0.2')

plt.ylim(1000,3500)

plt.show()

在此處輸入圖片說明

您可以在我的存儲庫 (https://github.com/shahejokarian/regression-prediction-interval ) 中使用 Ipython 筆記本中的 LRPI() 類來獲取預測間隔。

您需要設置 t 值以獲得預測值所需的置信區間,否則默認為 95% conf。 間隔。

LRPI 類使用 sklearn.linear_model 的 LinearRegression 、 numpy 和 pandas 庫。

筆記本中也顯示了一個示例。

要在此處添加 Max Ghenis 的響應 - 您可以使用 .get_prediction() 生成置信區間,而不僅僅是預測區間,方法是在之后使用 .conf_int() 。

predictions = result.get_prediction(out_of_sample_df)
predictions.conf_int(alpha = 0.05)

您可以根據 statsmodel 給出的結果和正態性假設來計算它們。

以下是平均值的 OLS 和 CI 示例:

import statsmodels.api as sm
import numpy as np
from scipy import stats

#Significance level:
sl = 0.05
#Evaluate mean value at a required point x0. Here, at the point (0.0,2.0) for N_model=2:
x0 = np.asarray([1.0, 0.0, 2.0])# If you have no constant in your model, remove the first 1.0. For more dimensions, add the desired values.

#Get an OLS model based on output y and the prepared vector X (as in your notation):
model = sm.OLS(endog = y, exog = X )
results = model.fit()
#Get two-tailed t-values:
(t_minus, t_plus) = stats.t.interval(alpha = (1.0 - sl), df =  len(results.resid) - len(x0) )
y_value_at_x0 = np.dot(results.params, x0)
lower_bound = y_value_at_x0 + t_minus*np.sqrt(results.mse_resid*( np.dot(np.dot(x0.T,results.normalized_cov_params),x0) ))
upper_bound = y_value_at_x0 +  t_plus*np.sqrt(results.mse_resid*( np.dot(np.dot(x0.T,results.normalized_cov_params),x0) ))

你可以用輸入結果、點 x0 和顯着性水平 sl 圍繞這個包裹一個很好的函數。

我現在不確定您是否可以將它用於 WLS(),因為那里發生了額外的事情。

參考:[DC Montgomery 和 EA Peck。 “線性回歸分析簡介。” 4. 編輯,威利,1992]。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM