使用重复条目绘制置信区间和预测区间
Plotting confidence and prediction intervals with repeated entries
我有两个变量的相关图,x 轴上的预测变量(温度)和 y 轴上的响应变量(密度)。我最适合的最小二乘回归线是二阶多项式。我还想绘制置信区间和预测区间。 this 答案中描述的方法似乎很完美。但是,我的数据集 (n=2340) 有许多 (x,y) 对的重复条目。我的结果图如下所示:
这是我的相关代码(根据上面的链接答案稍作修改):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.sandbox.regression.predstd import wls_prediction_std
import statsmodels.formula.api as smf
from statsmodels.stats.outliers_influence import summary_table
d = {'temp': x, 'dens': y}
df = pd.DataFrame(data=d)
x = df.temp
y = df.dens
plt.figure(figsize=(6 * 1.618, 6))
plt.scatter(x,y, s=10, alpha=0.3)
plt.xlabel('temp')
plt.ylabel('density')
# points linearly spaced for predictor variable
x1 = pd.DataFrame({'temp': np.linspace(df.temp.min(), df.temp.max(), 100)})
# 2nd order polynomial
poly_2 = smf.ols(formula='dens ~ 1 + temp + I(temp ** 2.0)', data=df).fit()
# this correctly plots my single 2nd-order poly best-fit line:
plt.plot(x1.temp, poly_2.predict(x1), 'g-', label='Poly n=2 $R^2$=%.2f' % poly_2.rsquared,
alpha=0.9)
prstd, iv_l, iv_u = wls_prediction_std(poly_2)
st, data, ss2 = summary_table(poly_2, 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(poly_2.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)
如预期的那样,打印语句的计算结果为 0.0。
但是,我需要 单 线来表示多项式最佳拟合线,以及置信区间和预测区间(而不是我目前在我的图中的多条线)。有什么想法吗?
更新:
根据 @kpie 的第一个回答,我根据温度对置信区间和预测区间数组进行了排序:
data_intervals = {'temp': x, 'predict_low': predict_ci_low, 'predict_upp': predict_ci_upp, 'conf_low': predict_mean_ci_low, 'conf_high': predict_mean_ci_upp}
df_intervals = pd.DataFrame(data=data_intervals)
df_intervals_sort = df_intervals.sort(columns='temp')
这达到了预期的效果:
您需要根据温度对预测值进行排序。我觉得*
因此,要获得漂亮的曲线,您将不得不使用 numpy.polynomial.polynomial.polyfit 这将 return 一个系数列表。您必须将 x 和 y 数据拆分为 2 个列表,以使其适合函数。
然后您可以绘制此函数:
def strPolynomialFromArray(coeffs):
return("".join([str(k)+"*x**"+str(n)+"+" for n,k in enumerate(coeffs)])[0:-1])
from numpy import *
from matplotlib.pyplot import *
x = linespace(-15,45,300) # your smooth line will be made of 300 smooth pieces
y = exec(strPolynomialFromArray(numpy.polynomial.polynomial.polyfit(xs,ys,degree)))
plt.plot(x , y)
你可以更多地研究绘制平滑线here只要记住所有的线都是线性样条,因为连续曲率是不合理的。
我相信多项式拟合是用最小二乘拟合完成的(过程described here)
祝你好运!
我有两个变量的相关图,x 轴上的预测变量(温度)和 y 轴上的响应变量(密度)。我最适合的最小二乘回归线是二阶多项式。我还想绘制置信区间和预测区间。 this 答案中描述的方法似乎很完美。但是,我的数据集 (n=2340) 有许多 (x,y) 对的重复条目。我的结果图如下所示:
这是我的相关代码(根据上面的链接答案稍作修改):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.sandbox.regression.predstd import wls_prediction_std
import statsmodels.formula.api as smf
from statsmodels.stats.outliers_influence import summary_table
d = {'temp': x, 'dens': y}
df = pd.DataFrame(data=d)
x = df.temp
y = df.dens
plt.figure(figsize=(6 * 1.618, 6))
plt.scatter(x,y, s=10, alpha=0.3)
plt.xlabel('temp')
plt.ylabel('density')
# points linearly spaced for predictor variable
x1 = pd.DataFrame({'temp': np.linspace(df.temp.min(), df.temp.max(), 100)})
# 2nd order polynomial
poly_2 = smf.ols(formula='dens ~ 1 + temp + I(temp ** 2.0)', data=df).fit()
# this correctly plots my single 2nd-order poly best-fit line:
plt.plot(x1.temp, poly_2.predict(x1), 'g-', label='Poly n=2 $R^2$=%.2f' % poly_2.rsquared,
alpha=0.9)
prstd, iv_l, iv_u = wls_prediction_std(poly_2)
st, data, ss2 = summary_table(poly_2, 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(poly_2.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)
如预期的那样,打印语句的计算结果为 0.0。 但是,我需要 单 线来表示多项式最佳拟合线,以及置信区间和预测区间(而不是我目前在我的图中的多条线)。有什么想法吗?
更新: 根据 @kpie 的第一个回答,我根据温度对置信区间和预测区间数组进行了排序:
data_intervals = {'temp': x, 'predict_low': predict_ci_low, 'predict_upp': predict_ci_upp, 'conf_low': predict_mean_ci_low, 'conf_high': predict_mean_ci_upp}
df_intervals = pd.DataFrame(data=data_intervals)
df_intervals_sort = df_intervals.sort(columns='temp')
这达到了预期的效果:
您需要根据温度对预测值进行排序。我觉得*
因此,要获得漂亮的曲线,您将不得不使用 numpy.polynomial.polynomial.polyfit 这将 return 一个系数列表。您必须将 x 和 y 数据拆分为 2 个列表,以使其适合函数。
然后您可以绘制此函数:
def strPolynomialFromArray(coeffs):
return("".join([str(k)+"*x**"+str(n)+"+" for n,k in enumerate(coeffs)])[0:-1])
from numpy import *
from matplotlib.pyplot import *
x = linespace(-15,45,300) # your smooth line will be made of 300 smooth pieces
y = exec(strPolynomialFromArray(numpy.polynomial.polynomial.polyfit(xs,ys,degree)))
plt.plot(x , y)
你可以更多地研究绘制平滑线here只要记住所有的线都是线性样条,因为连续曲率是不合理的。
我相信多项式拟合是用最小二乘拟合完成的(过程described here)
祝你好运!