来自维基百科https://en.wikipedia.org/wiki/Stepwise_regression
前进选择,包括从中没有变量开始 模型,使用所选模型测试每个变量的添加 比较标准,添加改进的变量(如果有的话) 模型最多,并重复这个过程,直到没有改善 模型。
我认为这个算法的实现非常有趣,因为它可以看作是爬山算法的组合版本,其中邻居函数相当于向当前模型添加变量。
我没有足够的经验以优化的方式编写此算法。这是我目前的实施:
class FSR():
def __init__(self, n_components):
self.n_components = n_components
def cost(self, index):
lr = LinearRegression().fit(self.x[:, index], self.y)
hat_y = lr.predict(self.x[:, index])
e = np.linalg.norm(hat_y - self.y)
return e
def next_step_fsr(self, comp, cand):
""" given the current components and candidates the function
return the new components, the new candidates and the new EV"""
if comp == []:
er = np.inf
else:
er = self.cost(comp)
for i in range(len(cand)):
e = cand.popleft()
comp.append(e)
new_er = self.cost(comp)
if new_er < er:
new_comp = comp.copy()
new_cand = deque(i for i in cand)
er = new_er
comp.pop()
cand.append(e)
return new_comp, new_cand, new_er
def fsr(self):
n, p = self.x.shape
er = []
comp = []
cand = deque(range(p))
for i in range(self.n_components):
comp, cand, new_er = self.next_step_fsr(comp, cand)
er.append(new_er)
return comp, er
def fit(self, x, y):
self.x = x
self.y = y
self.comp_, self.er_ = self.fsr()
我想知道如何提高此代码的速度。
x = np.random.normal(0,1, (100,20))
y = x[:,1] + x[:,2] + np.random.normal(0,.1, 100)
fsr = FSR(n_components=2)
fsr.fit(x,y)
print('selected component = ', fsr.comp_)
我希望最终的代码看起来与发布的代码没有太大区别。这是因为我想将问题扩展到具有不同成本函数的不同组合问题。
我认为应该更改的函数是next_step_fsr
,其中给定当前选定的变量,尝试哪一个是包含在模型中的最佳变量。特别是我对x有很多列(如10000)的情况感兴趣。我认为当前的瓶颈是复制候选人名单的行new_cand = deque(i for i in cand)
。