线性回归残差 - 我应该“标准化”结果以及如何执行此操作

时间:2016-03-23 11:42:47

标签: python scipy regression linear-regression statsmodels

我是一名生物学家。我想复制一份我在论文中读到的方法:“为了允许独立于体重调查与死亡率的关联,通过从观察值中减去预测来计算死亡率的残差”。

我有一套死亡率(范围从大约0.1到0.5),一组体重(范围从大约2到80),我想计算体重后的死亡率残差

我写了这段代码:

import scipy
from scipy import stats
import sys


# This reads in the weight and mortality data to two lists. 
Weight = []
Mortality = []
for line in open(sys.argv[1]):
        line = line.strip().split()
        Weight.append(float(line[-2]))
        Mortality.append(float(line[-1]))

# This calculates the regression equation.
slope, intercept, r_value, p_value, std_err = scipy.stats.linregress(Mortality,Weight)

# This calculates the predicted value for each observed value
obs_values = Mortality
pred_values = []
for i in obs_values:
    pred_i = float(i) * float(slope) + float(intercept)
    pred_values.append(pred_i)

# This prints the residual for each pair of observations
for obs_v,pred_v in zip(obs_values,pred_values):
    Residual = str(obs_v - pred_v)
    print Residual

我的问题是,当我运行此代码时,我的一些残差看起来很大:

> Sample1 839.710240214 
> Sample2 325.787250084 
> Sample3 -41.3006000084
> Sample4 -70.6676280159
> Sample5 267.05319407
> Sample6 399.204820103
> Sample7 560.723474144
> Sample8 766.292670196
> Sample9 267.05319407
> Sample10 2.7499420027

我想知道,这些结果看起来是“正常的”/它们是否应该以某种方式“标准化”/我是否做了一些错误来获得重量后的死亡率残差?

如果有可能,我会很感激简单的“普通英语”答案以及可能的代码片段,因为我不是统计专家!

非常感谢

2 个答案:

答案 0 :(得分:4)

查看scipy.stats.linregess()的文档:第一个参数是x,横坐标,第二个参数是y,即您的观察值。因此,如果obs_values = Mortality应该是观察值,则必须置换线性回归的两个参数,并且必须根据Weight计算预测值x(不是Mortality作为y):

# This calculates the regression equation.
slope, intercept, r_value, p_value, std_err = scipy.stats.linregress(x=Weight, y=Mortality)

# This calculates the predicted value for each observed value
obs_values = Mortality
pred_values = []
for i in Weight:
    pred_i = float(i) * float(slope) + float(intercept)
    pred_values.append(pred_i)

另外,你可以通过使用numpy(scipy无论如何使用它)来大幅减少(并加速)你的代码。

import numpy as np
from scipy import stats
import sys

# This reads in the weight and mortality data to two arrays.
arr = np.loadtxt(sys.argv[1])
Weight = arr[:,-2]
Mortality = arr[:,-1]

# This calculates the regression equation.
slope, intercept, r_value, p_value, std_err = stats.linregress(x=Weight,y=Mortality)

# This calculates the predicted value for each observed value
obs_values = Mortality
pred_values = slope * Weight + intercept

# This prints the residual for each pair of observations
Residual = obs_values - pred_values
print(Residuals)

答案 1 :(得分:0)

我知道我并不打算在这里提出跟进问题,如果有人能告诉我如何继续讨论我原来的问题(带代码而没有字符数)而不点击"回答问题",我很乐意将此文本移至该部分;我道歉。

我的最后一个问题是如何"允许对死亡率的关联进行独立于体重调查"。我的下一个问题只是出于好奇,如果要对此进行扩展,如果我想检查死亡率,独立于体重和身高?

我已经编写了这段代码,对于我的数据,这些残差确实加起来为0,但我只是想与专家核实这是我将要采用的方式以供将来参考:

import numpy as np
import statsmodels.formula.api as smf
import sys

dat = np.loadtxt(sys.argv[1],dtype={"names":("SpeciesName","Mortality","Height","Weight"),"formats":("S40","f4","f4","f4")})
mymodel = smf.ols("Mortality~Height+Weight",data=dat).fit()
Residues = list(mymodel.resid_pearson)
SpeciesList = list(dat["SpeciesName"])
for species,residue in zip(SpeciesList,Residues):
    print species + "\t" + str(residue)

再一次,如果我在错误的部分写了这个,我会道歉;我没有觉得这是一个新问题,作为评论,我无法添加代码;如果更合适,我很乐意将这个问题作为一个新问题。