如何让我的代码更快地计算 q2-LOO?
How to make my code calculate q2-LOO faster?
我编写了一些代码来计算多元线性回归的 q2-Leave One Out,它在准确性方面效果很好。然而,由于我在遗传算法中使用 q2LOO 作为评估指标,这段代码太慢了——现在,使用我的 q2LOO 代码的体面的 GA 运行 将花费 HOURS。我还没有找到任何计算 q2LOO 的库,所以我使用的是 numpy 和 scikit-learn。
import numpy as np
from sklearn import cross_validation
def mlrr(x_of_trainingset,y_actual):
npones=np.ones(len(x_of_trainingset), float)
A_sl=x_of_trainingset
A=np.column_stack([A_sl,npones])
lstsq,residuals,rank,something=np.linalg.lstsq(A, y_actual)
return lstsq
def kfoldmlr(xi,yi,nfolds):
x=xi.values
y=yi.values
kf = cross_validation.KFold(len(y), n_folds=nfolds)#indices=None, shuffle=False, random_state=None)
y_hats=[]
for train_index, test_index in kf:
x_train, x_test = x[train_index], x[test_index]
y_train=y[train_index]
coefficients=mlrr(x_train,y_train)
yhat=coefficients[-1]
for index in range(x_test.size):
slopetimesx=x_test[0][index]*coefficients[index]
yhat=yhat+slopetimesx
y_hats.append(float(yhat))
stack=np.asarray(y_hats)
return stack
def q2loo_mlr(x,y):
'''calculates q2loo of a linear regression of x and y where both x and y are 1-d'''
yhats=kfoldmlr(x,y,len(x))
PRESS=sum((y-yhats)**2)
TSS=sum((y-np.mean(y))**2)
r2cv=(TSS-PRESS)*(TSS**(-1))#1-(PRESS/TSS)
return r2cv
经过测试,这是我得到的速度:
%timeit q2loo_mlr(x, y)
10 loops, best of 3: 21.7 ms per loop
%timeit kfoldmlr(x, y, len(x))
1000 loops, best of 3: 156 µs per loop
显然速度慢是因为它一遍又一遍地做 np.linalg.lstsq,但是有什么替代方法吗?或者还有其他方法可以加快速度吗?
由于 q2loo_mlr
到 kfoldmlr
的运行时间是 139:1 我不认为 kfoldmlr
中对 mlrr
的调用明显减慢了代码速度down - kfoldmlr
只被调用一次。
如果是,缓存固定索引 train_index
的系数将是一个想法,因为系数似乎是 train_index
单独的函数,因此可以重复使用。
在q2loo_mlr
中,如果重写
TSS=sum((y-np.mean(y))**2)
作为
y_mean = np.mean(y)
TSS=sum((y - y_mean)**2)
这会降低运行时间吗?据我了解 np.mean(y)
是一个标量。
我编写了一些代码来计算多元线性回归的 q2-Leave One Out,它在准确性方面效果很好。然而,由于我在遗传算法中使用 q2LOO 作为评估指标,这段代码太慢了——现在,使用我的 q2LOO 代码的体面的 GA 运行 将花费 HOURS。我还没有找到任何计算 q2LOO 的库,所以我使用的是 numpy 和 scikit-learn。
import numpy as np
from sklearn import cross_validation
def mlrr(x_of_trainingset,y_actual):
npones=np.ones(len(x_of_trainingset), float)
A_sl=x_of_trainingset
A=np.column_stack([A_sl,npones])
lstsq,residuals,rank,something=np.linalg.lstsq(A, y_actual)
return lstsq
def kfoldmlr(xi,yi,nfolds):
x=xi.values
y=yi.values
kf = cross_validation.KFold(len(y), n_folds=nfolds)#indices=None, shuffle=False, random_state=None)
y_hats=[]
for train_index, test_index in kf:
x_train, x_test = x[train_index], x[test_index]
y_train=y[train_index]
coefficients=mlrr(x_train,y_train)
yhat=coefficients[-1]
for index in range(x_test.size):
slopetimesx=x_test[0][index]*coefficients[index]
yhat=yhat+slopetimesx
y_hats.append(float(yhat))
stack=np.asarray(y_hats)
return stack
def q2loo_mlr(x,y):
'''calculates q2loo of a linear regression of x and y where both x and y are 1-d'''
yhats=kfoldmlr(x,y,len(x))
PRESS=sum((y-yhats)**2)
TSS=sum((y-np.mean(y))**2)
r2cv=(TSS-PRESS)*(TSS**(-1))#1-(PRESS/TSS)
return r2cv
经过测试,这是我得到的速度:
%timeit q2loo_mlr(x, y)
10 loops, best of 3: 21.7 ms per loop
%timeit kfoldmlr(x, y, len(x))
1000 loops, best of 3: 156 µs per loop
显然速度慢是因为它一遍又一遍地做 np.linalg.lstsq,但是有什么替代方法吗?或者还有其他方法可以加快速度吗?
由于 q2loo_mlr
到 kfoldmlr
的运行时间是 139:1 我不认为 kfoldmlr
中对 mlrr
的调用明显减慢了代码速度down - kfoldmlr
只被调用一次。
如果是,缓存固定索引 train_index
的系数将是一个想法,因为系数似乎是 train_index
单独的函数,因此可以重复使用。
在q2loo_mlr
中,如果重写
TSS=sum((y-np.mean(y))**2)
作为
y_mean = np.mean(y)
TSS=sum((y - y_mean)**2)
这会降低运行时间吗?据我了解 np.mean(y)
是一个标量。