繁体   English   中英

加速迭代或向量化

[英]Speed up iteration or vectorize

我有大约 50 个州的数据(很多属性)。 对于每个状态,我想从逻辑回归中找到给出最小 RMSE 的属性组合。 由于有许多属性和状态,我有大约 5100 万个状态和自变量组合要循环。 我曾尝试用 numpy 编写我的函数,但我需要帮助对其进行矢量化。 我有这样的事情:

import pandas as pd
import numpy as np
import random
import statsmodels.api as sm
import itertools

rows = 20000
total_rows = 13*rows

data = pd.DataFrame({
    'state': ['a', 'b', 'c','d','e','f','g','h','i','j','k','l','m']*rows,
    'y_var': [random.uniform(0,1) for i in range(total_rows)],
    'school': [random.uniform(0,10) for i in range(total_rows)],
    'church': [random.uniform(11,20) for i in range(total_rows)],
    'bar': [random.uniform(2,10) for i in range(total_rows)],
    'mosque': [random.uniform(10,50) for i in range(total_rows)],
    'office': [random.uniform(0,10) for i in range(total_rows)],
    'cafe': [random.uniform(11,20) for i in range(total_rows)],
    'mall': [random.uniform(2,10) for i in range(total_rows)],
    'washroom': [random.uniform(10,50) for i in range(total_rows)],
    'bedroom': [random.uniform(0,10) for i in range(total_rows)],
    'hotel': [random.uniform(11,20) for i in range(total_rows)],
    'car': [random.uniform(2,10) for i in range(total_rows)],
    'mailroom': [random.uniform(2,10) for i in range(total_rows)],
    'motel': [random.uniform(10,50) for i in range(total_rows)],
    'bank': [random.uniform(0,10) for i in range(total_rows)],
    'trailer': [random.uniform(11,20) for i in range(total_rows)],
    'camp': [random.uniform(2,10) for i in range(total_rows)],
    'sample': [1]*int(0.8*total_rows)+ [0]*int(0.2*total_rows)
}).to_numpy()

ind_variables = [i for i in range(2,18)]
combinations = np.array(
    [np.array(b) for b in [c for i in range(len(ind_variables)+1) for c in itertools.combinations(ind_variables,i)]]
)[1:]
states = np.unique(data[:,0])

def reg_frac(state, ind_vars):
    
    try:
        
        x_train, y_train = sm.add_constant(np.array(data[(data[:,18] == 1) & (data[:,0] == state)][:,ind_vars], dtype=float)), np.array(data[(data[:,18] == 1) & (data[:,0] == state), 1], dtype=float)
        x_test, y_test = sm.add_constant(np.array(data[(data[:,18] == 0) & (data[:,0] == state)][:,ind_vars], dtype=float)), data[(data[:,18] == 0) & (data[:,0] == state), 1]

        model = sm.Logit(y_train, x_train).fit(cov_type='HC0', disp=False)      

        rmse = np.sqrt(np.square(np.subtract(y_test, model.predict(x_test))).mean())
        
    except:
        rmse = np.nan
        
    return [state, ind_vars, rmse] 

我尝试过 itertools、itertuples、map 等,但它们都很慢。 有没有一种有效的方法可以循环遍历所有状态和自变量而不必将其放置数小时? 我也可以获得向量化函数的帮助吗? 我相信这可以加快速度。 谢谢

有很多方法可以优化这些类型的事物,这些方法取决于很多因素,因此会涉及一些反复试验。 一些快速的方法是尝试使用Numba和 JIT 编译它。 您还可以使用 Numba 进行矢量化,这将提供最大的速度,并允许 GPU 编译(如果有的话)。

此外,创建 numpy 数组很昂贵,因此在您的 add_constant 部分中这样做非常昂贵。 此外,由于您的数据已经是一个 numpy 数组,因此您无需将其子集转换为该行中的数组。

为了获得最大的加速,您可能不得不转向像 Cython 这样的编译方法,但这需要大量工作; 与 Numba 相比非常快速和容易。

除了@Dan 的评论外,LR 中还有一些已知的特征选择方法,它们比测试每种组合更有效。 查看 Sklearns Kbest

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM