Matplotlibのみで線形回帰の信頼区間を描画する
最近はずっとPythonで、RもMatlabも使っていません。頑張れば使えないわけではないですが、できればPythonで完結させたいものです。というわけで今回は基本的な統計解析の描画をPythonでやってみます。
やりたいことは回帰における信頼帯 (confidence band) または信頼区間 (confidence interval) の描画です。線形回帰を例にしてみます。
seabornを使う場合
「Pythonで信頼区間を描画」と検索すればseabornのsns.regplotを用いた方法がすぐに出てきます。今回はこれを使わずに描画を目指しますが、とりあえずコードを紹介。
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style("whitegrid")
np.random.seed(0)
# Generate toy data
n_data = 100
x = np.random.randn(n_data)
y = x + np.random.randn(n_data) + 10
# Plot
plt.figure(figsize=(4, 4))
sns.regplot(x, y)
plt.xlabel("x"); plt.ylabel("y")
plt.tight_layout()
plt.show()
描画はできるものの、肝心の統計値が出てきません。
Statsmodels + matplotlibの場合
Statsmodelsとmatplotlibを用いてconfidence bandを描画します。要はfill_betweenで上部信頼限界と下部信頼限界の間を塗りつぶせばいいわけです。 (参考)Using python statsmodels for OLS linear regression
import statsmodels.api as sm
from scipy import stats
次に回帰を実行します。
# Regression
X = sm.add_constant(x) # constant intercept term
# Model: y ~ a*x + c
model = sm.OLS(y, X)
fitted = model.fit()
x_pred = np.linspace(x.min(), x.max(), 50)
X_pred = sm.add_constant(x_pred)
y_pred = fitted.predict(X_pred)
回帰の結果を見ておきましょう。
#print(fitted.params) # the estimated parameters for the regression line
print(fitted.summary()) # summary statistics for the regression
Congfidence bandの計算を行います。
# Congfidence band
y_hat = fitted.predict(X) # x is an array from line 12 above
y_err = y - y_hat
mean_x = np.mean(x)
dof = n_data - fitted.df_model - 1 # degree of freedom
alpha = 0.025
t = stats.t.ppf(1-alpha, df=dof) # t-value
s_err = np.sum(y_err**2)
std_err = np.sqrt(s_err/(n_data-2))
std_x = np.std(x)
conf = t*std_err/np.sqrt(n_data)*np.sqrt(1+((x_pred-mean_x)/std_x)**2)
upper = y_pred + abs(conf)
lower = y_pred - abs(conf)
# Plot
plt.figure(figsize=(4, 4))
plt.scatter(x, y)
plt.plot(x_pred, y_pred, '-', linewidth=2)
plt.fill_between(x_pred, lower, upper, color='#888888', alpha=0.4)
plt.xlabel("x"); plt.ylabel("y")
plt.tight_layout()
plt.show()