python - 如何加快python中的嵌套交叉验证?
问题描述
根据我的发现,还有 1 个类似这样的问题(加速嵌套交叉验证)但是在尝试了本网站和微软也建议的几个修复后,安装 MPI 对我不起作用,所以我希望有另一个包或回答这个问题。
我正在寻找比较多种算法和网格搜索各种参数(可能参数太多?),除了 mpi4py 之外还有哪些方法可以加快运行我的代码?据我了解,我不能使用 n_jobs=-1 因为那不是嵌套的?
还要注意的是,我无法在下面尝试查看的许多参数上运行它(运行时间比我有时间长)。如果我只给每个模型 2 个参数进行比较,则只有 2 小时后才有结果。此外,我在包含 252 行和 25 个特征列的数据集上运行此代码,其中包含 4 个分类变量来预测(“确定”、“可能”、“可能”或“未知”)基因(具有 252 个基因)是否会影响疾病. 使用 SMOTE 将样本大小增加到 420,然后就可以使用了。
dataset= pd.read_csv('data.csv')
data = dataset.drop(["gene"],1)
df = data.iloc[:,0:24]
df = df.fillna(0)
X = MinMaxScaler().fit_transform(df)
le = preprocessing.LabelEncoder()
encoded_value = le.fit_transform(["certain", "likely", "possible", "unlikely"])
Y = le.fit_transform(data["category"])
sm = SMOTE(random_state=100)
X_res, y_res = sm.fit_resample(X, Y)
seed = 7
logreg = LogisticRegression(penalty='l1', solver='liblinear',multi_class='auto')
LR_par= {'penalty':['l1'], 'C': [0.5, 1, 5, 10], 'max_iter':[500, 1000, 5000]}
rfc =RandomForestClassifier()
param_grid = {'bootstrap': [True, False],
'max_depth': [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, None],
'max_features': ['auto', 'sqrt'],
'min_samples_leaf': [1, 2, 4,25],
'min_samples_split': [2, 5, 10, 25],
'n_estimators': [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]}
mlp = MLPClassifier(random_state=seed)
parameter_space = {'hidden_layer_sizes': [(10,20), (10,20,10), (50,)],
'activation': ['tanh', 'relu'],
'solver': ['adam', 'sgd'],
'max_iter': [10000],
'alpha': [0.1, 0.01, 0.001],
'learning_rate': ['constant','adaptive']}
gbm = GradientBoostingClassifier(min_samples_split=25, min_samples_leaf=25)
param = {"loss":["deviance"],
"learning_rate": [0.15,0.1,0.05,0.01,0.005,0.001],
"min_samples_split": [2, 5, 10, 25],
"min_samples_leaf": [1, 2, 4,25],
"max_depth":[10, 20, 30, 40, 50, 60, 70, 80, 90, 100, None],
"max_features":['auto', 'sqrt'],
"criterion": ["friedman_mse"],
"n_estimators":[200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]
}
svm = SVC(gamma="scale", probability=True)
tuned_parameters = {'kernel':('linear', 'rbf'), 'C':(1,0.25,0.5,0.75)}
def baseline_model(optimizer='adam', learn_rate=0.01):
model = Sequential()
model.add(Dense(100, input_dim=X_res.shape[1], activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(50, activation='relu')) #8 is the dim/ the number of hidden units (units are the kernel)
model.add(Dense(4, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=['accuracy'])
return model
keras = KerasClassifier(build_fn=baseline_model, batch_size=32, epochs=100, verbose=0)
learn_rate = [0.001, 0.01, 0.1, 0.2, 0.3]
optimizer = ['SGD', 'RMSprop', 'Adagrad', 'Adadelta', 'Adam', 'Adamax', 'Nadam']
kerasparams = dict(optimizer=optimizer, learn_rate=learn_rate)
inner_cv = KFold(n_splits=10, shuffle=True, random_state=seed)
outer_cv = KFold(n_splits=10, shuffle=True, random_state=seed)
models = []
models.append(('GBM', GridSearchCV(gbm, param, cv=inner_cv,iid=False, n_jobs=1)))
models.append(('RFC', GridSearchCV(rfc, param_grid, cv=inner_cv,iid=False, n_jobs=1)))
models.append(('LR', GridSearchCV(logreg, LR_par, cv=inner_cv, iid=False, n_jobs=1)))
models.append(('SVM', GridSearchCV(svm, tuned_parameters, cv=inner_cv, iid=False, n_jobs=1)))
models.append(('MLP', GridSearchCV(mlp, parameter_space, cv=inner_cv,iid=False, n_jobs=1)))
models.append(('Keras', GridSearchCV(estimator=keras, param_grid=kerasparams, cv=inner_cv,iid=False, n_jobs=1)))
results = []
names = []
scoring = 'accuracy'
X_train, X_test, Y_train, Y_test = train_test_split(X_res, y_res, test_size=0.2, random_state=0)
for name, model in models:
nested_cv_results = model_selection.cross_val_score(model, X_res, y_res, cv=outer_cv, scoring=scoring)
results.append(nested_cv_results)
names.append(name)
msg = "Nested CV Accuracy %s: %f (+/- %f )" % (name, nested_cv_results.mean()*100, nested_cv_results.std()*100)
print(msg)
model.fit(X_train, Y_train)
print('Test set accuracy: {:.2f}'.format(model.score(X_test, Y_test)*100), '%')
print("Best Parameters: \n{}\n".format(model.best_params_))
print("Best CV Score: \n{}\n".format(model.best_score_))
例如,大多数数据集是二进制的,如下所示:
gene Tissue Druggable Eigenvalue CADDvalue Catalogpresence Category
ACE 1 1 1 0 1 Certain
ABO 1 0 0 0 0 Likely
TP53 1 1 0 0 0 Possible
任何有关我如何加快速度的指导将不胜感激。
编辑:我也尝试过将并行处理与 dask 一起使用,但我不确定我做得对,而且它似乎并没有运行得更快:
for name, model in models:
with joblib.parallel_backend('dask'):
nested_cv_results = model_selection.cross_val_score(model, X_res, y_res, cv=outer_cv, scoring=scoring)
results.append(nested_cv_results)
names.append(name)
msg = "Nested CV Accuracy %s: %f (+/- %f )" % (name, nested_cv_results.mean()*100, nested_cv_results.std()*100)
print(msg)
model.fit(X_train, Y_train)
print('Test set accuracy: {:.2f}'.format(model.score(X_test, Y_test)*100), '%')
#print("Best Estimator: \n{}\n".format(model.best_estimator_))
print("Best Parameters: \n{}\n".format(model.best_params_))
print("Best CV Score: \n{}\n".format(model.best_score_)) #average of all cv folds for a single combination of the parameters you specify
编辑:还要注意减少网格搜索,我已经尝试过每个模型使用例如 5 个参数,但这仍然需要几个小时才能完成,所以在减少数量的同时,如果有任何关于效率的建议,我会非常感激。
解决方案
Dask -ML具有可扩展的实现 GridSearchCV
,RandomSearchCV
我相信它可以替代 Scikit-Learn。它们是与 Scikit-Learn 开发人员一起开发的。
它们可以更快有两个原因:
- 他们避免在管道的不同阶段之间重复共享工作
- 它们可以扩展到任何可以部署 Dask 的集群(这在大多数集群基础架构上都很容易)
推荐阅读
- sql-server - SQL Server 你可以更新通过多个 UNION ALL 创建的表中的元素吗
- javascript - Vuetify从方法修改内联编辑数据表内容
- google-cloud-platform - 我可以在谷歌云功能中使用 pdfkit 吗?
- mediawiki - 来自 MediaWiki 模板的皮肤中的元标记
- tensorflow - Keras Inception V3 预测图像不起作用
- javascript - 使用实时 Firebase 数据库(Web)在无限滚动中获取空错误
- hibernate-search - hibernate search - 6.0 版本是否支持对嵌入式实体的投影?
- excel - 如何使用表中不同行的值运行 Excel 宏?
- javascript - 检测 HTML 自定义元素丢失
- python - 如何打开由于日期更改而每天具有不同名称的文件