我已经建立了一个线性回归模型来检验这个dataset中两个变量(chemical_1
和chemical_2
)之间的关系。
根据结果,intercept = 16.83488364225717
。
我刚刚开始发现数据科学的数学基础知识,而我目前对截距的理解是它是回归线与y-axis
(和x = 0)相交的值。所以现在我对使用Seaborn构建的结果感到困惑。
为什么它显示10到12之间的回归线交叉y-axis
,而不是拦截的实际值(16.83488364225717)和x = 0?我该怎么做才能解决这个问题?
这是我的代码:
from scipy import stats
X = df['chemical_1']
Y = df['chemical_2']
slope, intercept, r_value, p_value, slope_std_error = stats.linregress(X,Y)
print ("slope = " + str(slope))
print ("intercept = " + str(intercept))
print ("r_squared = " + str(r_value**2))
print ("r_value = " + str(r_value))
print ("p_value = " +str(p_value))
slope = -0.9345759557752411
intercept = 16.83488364225717
r_squared = 0.04205938806347038
r_value = -0.20508385617466426
p_value = 0.00784469031490164
predict_y = slope * X + intercept
fig, ax = plt.subplots()
sns.set(color_codes=True)
sns.set(rc={'figure.figsize':(10, 10)})
ax = sns.regplot(x=X, y=Y, line_kws={'label':'$y=%3.7s*x+%3.7s$'%(slope, intercept)});
sns.regplot(x=X, y=Y, fit_reg=False, ax=ax);
sns.regplot(x=X, y=predict_y,scatter=False, ax=ax);
ax.set_ylabel('chemical_2')
ax.legend()
plt.show()
UPD:当我使用Simon提出的解决方案时 - 扩展轴的极限,拦截仍未显示,情节如下所示:
当我使用set_ylim(0,20)时,绘图上的数据看起来很紧张。实际上,我设置的任何轴参数(默认值除外)都会导致数据,并且图表上的置信区间会受到挤压。
答案 0 :(得分:2)
正如评论中所提到的,当Y
的值为0时,截距是X
的值。因此,X轴的范围不允许显示实际的截距
import numpy as np
from scipy import stats
import seaborn as sns
np.random.seed(1236)
X = np.arange(5,10) + np.random.normal(0,1,5)
Y = np.arange(5,10) + np.random.normal(0,1,5)
slope, intercept, r_value, p_value, slope_std_error = stats.linregress(X,Y)
predict_y = slope * X + intercept
print("slope = " + str(slope))
print("intercept = " + str(intercept))
sns.regplot(x=X, y=Y, fit_reg=False)
sns.regplot(x=X, y=predict_y,scatter=False)
在这里我们可以看到拦截是0.115:
slope = 0.9897768121234015
intercept = 0.11521162448067557
这给出了一个如下所示的seaborn图:
如果你想真正看到交叉点,你想要做的是扩展轴的极限:
p = sns.regplot(x=X, y=Y, fit_reg=False)
p.axes.set_xlim(0,)
p.axes.set_ylim(0,)
sns.regplot(x=X, y=predict_y,scatter=False)
编辑:
如果您想在扩大轴限制时解决挤压数据的问题,可以通过计算Z得分来标准化数据:
X = np.arange(5,10) + np.random.normal(0,1,5)
Y = np.arange(5,10) + np.random.normal(0,1,5)
X = stats.zscore(X)
Y = stats.zscore(Y)
slope, intercept, r_value, p_value, slope_std_error = stats.linregress(X,Y)
predict_y = slope * X + intercept
print("slope = " + str(slope))
print("intercept = " + str(intercept))
sns.regplot(x=X, y=Y, fit_reg=False)
sns.regplot(x=X, y=predict_y,scatter=False)
参数值:
slope = 0.667021422528575
intercept = -2.8128800822178726e-16
非常非常重要,请注意,在这种情况下,您的X
和Y
不再是原始指标。因此现在对斜率的解释是,对于X的1个标准差增加,Y的值将增加0.667个标准偏差"。但是你会发现截距现在基本上是0(即当X = 0时Y的值),并且朝向图的中心显示