使用Python multiprocessing传递多参数报错,apply与starmap均异常
问题描述
使用multiprocessing模块加速实验时,调用自定义函数run_exp_anxia_sim出现两个问题:
- 使用
apply方法时提示缺少6个必要位置参数 - 使用
starmap方法时出现值解包错误
函数定义
def run_exp_anxia_sim(num_exp,num1,num2, eps, isfuzzy, remove, using_train, iscompress): if using_train == False: results,x , y,dic1,dic2 = classificator_pos_neg(all_pos, all_neg, test_anxia, num_feat1=num1,num_feat2=num2, tau=eps,fuzzy=isfuzzy,remove_stop=remove, train_data =using_train,compress = iscompress) result_name = 'result_anxia_key' + str(num_exp) + '.txt' path_name = '/content/sample_data'+ '/' + result_name with open(path_name, "w") as f: f.write("Experimento de anorexia número: " + str(num_exp) + '\n') f.write("Confusion matrix: \n") f.write(str(confusion_matrix(test_labels_anxia, results)) + '\n') f.write('Metrics classification \n') f.write(str(metrics.classification_report(test_labels_anxia, results)) + '\n') f.close() return f1_score(test_labels_anxia, results) if using_train == True: seed_val = 42 np.random.seed(seed_val) parameters = {'C': [.05, .12, .25, .5, 1, 2, 4]} results, x, y,z,dic1,dic2 = classificator_pos_neg(all_pos, all_neg, test_anxia,num1,num2, tau=eps,fuzzy = isfuzzy,remove_stop=remove, train_data =using_train,compress = iscompress) svr = svm.LinearSVC(class_weight='balanced', dual=False) grid_anorexia = GridSearchCV(estimator=svr, param_grid=parameters, n_jobs=8, scoring='f1_macro', cv=5) grid_anorexia.fit(z, tr_labels) y_pred = grid_anorexia.predict(results) a1 = grid_anorexia.best_params_ p, r, f, _ = precision_recall_fscore_support(test_labels_anxia, y_pred, average='macro', pos_label=1) result_name = 'result_anxia_key' + str(num_exp) + '.txt' path_name = '/content/sample_data' + '/' + result_name with open(path_name, "w") as f: f.write("Experimento de anorexia número: " + str(num_exp) + '\n') f.write("Confusion matrix: \n") f.write(str(confusion_matrix(test_labels_anxia, y_pred)) + '\n') f.write('Metrics classification \n') f.write(str(metrics.classification_report(test_labels_anxia, y_pred)) + '\n') f.write('Best parameter:\n') f.write(str(a1)) f.write('\n') f.close() return f1_score(test_labels_anxia, y_pred), a1
参数列表
arg1 = [1,2] arg6 = [1000,1500] arg7 = [1000,1500] arg8 = [0.99]*2 arg10 = [True]*2 arg11 = [False]*2 arg12 = [False]*2 arg13 = [False]*2
调用代码(apply方式)
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool: x,y,z,w,t = pool.apply(run_exp_anxia_sim, zip(arg1,arg6,arg7,arg8,arg10,arg11,arg12,arg13)) print(x,y,z,w,t)
错误信息(apply方式)
TypeError: run_exp_anxia_sim() missing 6 required positional arguments: 'num2', 'eps', 'isfuzzy', 'remove', 'using_train', and 'iscompress'
解决方法
1. 理清参数匹配关系
函数run_exp_anxia_sim需要8个参数,对应你的参数列表如下:
num_exp→ arg1num1→ arg6num2→ arg7eps→ arg8isfuzzy→ arg10remove→ arg11using_train→ arg12iscompress→ arg13
2. 修复apply方法的错误
pool.apply是单次调用函数,第二个参数必须是一个元组,代表传给函数的单个参数组。你当前传入的zip(...)是迭代器,不是单个参数元组,导致函数只拿到第一个元素作为唯一参数,后续参数全部缺失。
如果要跑单次实验,正确写法如下:
with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool: # 传入第一组参数 result = pool.apply(run_exp_anxia_sim, args=(arg1[0], arg6[0], arg7[0], arg8[0], arg10[0], arg11[0], arg12[0], arg13[0])) print(result)
3. 修复starmap的值解包错误
pool.starmap会把迭代器中的每个元组解包成函数参数,正好适配多组实验的需求。出现解包错误通常有两个原因:参数组长度不匹配,或函数返回值格式不一致。
步骤1:生成正确的参数迭代器
确保每个元组包含8个元素,对应函数的8个参数:
params = zip(arg1, arg6, arg7, arg8, arg10, arg11, arg12, arg13)
步骤2:统一函数返回值格式
函数在using_train=False时返回单个值,using_train=True时返回两个值,混合的返回格式会导致解包错误。统一返回元组格式:
def run_exp_anxia_sim(num_exp,num1,num2, eps, isfuzzy, remove, using_train, iscompress): if using_train == False: # ... 原有代码 ... # 改为返回元组,和True分支格式统一 return f1_score(test_labels_anxia, results), None if using_train == True: # ... 原有代码 ... return f1_score(test_labels_anxia, y_pred), a1
步骤3:正确调用starmap并处理结果
import multiprocessing params = zip(arg1, arg6, arg7, arg8, arg10, arg11, arg12, arg13) with multiprocessing.Pool(processes=multiprocessing.cpu_count()) as pool: results = pool.starmap(run_exp_anxia_sim, params) # 遍历结果,避免一次性解包出错 for idx, (f1_score, best_params) in enumerate(results): print(f"实验{idx+1}: F1分数={f1_score}, 最优参数={best_params}")
4. 额外注意事项
- 确保
all_pos、test_labels_anxia等全局变量能被子进程正常访问,Jupyter环境中建议将这些变量作为参数传入函数,或使用multiprocessing.Manager共享 - 外层
multiprocessing.Pool和内层GridSearchCV(n_jobs=8)同时使用会占用大量CPU资源,建议将GridSearchCV的n_jobs设为1,或减少外层Pool的进程数
内容的提问来源于stack exchange,提问作者Mari
相关产品推荐
相关产品推荐

