Python训练新模型时遇IndexError: pop from empty list问题求解
解决RandomForestClassifier训练时的IndexError: pop from empty list问题
这个错误看起来有点棘手,但本质是旧版本scikit-learn和Python 3.5的兼容性bug,再加上你代码里有个容易忽略的小问题,咱们一步步来解决:
错误核心原因
你遇到的IndexError: pop from empty list来自scikit-learn内部的get_params方法,旧版本的sklearn在处理警告过滤器时,会尝试弹出列表的第一个元素,但如果警告过滤器列表是空的,就会触发这个错误。这个bug在后续的scikit-learn版本中已经被修复了。
解决方案
1. 优先升级scikit-learn版本
因为你用的是Python 3.5,需要安装支持这个版本的最后一个稳定scikit-learn版本:
pip install scikit-learn==0.20.4
这个版本已经修复了警告过滤器的bug,升级后大概率能直接解决问题。
2. 修正代码里的DataFrame赋值问题
你代码里的test.assign(**d)不会修改原test对象——assign是返回一个新的DataFrame,所以你需要把返回值重新赋值给test,否则训练集和测试集的列数不一致,后续训练也会出问题:
# 错误写法: # test.assign(**d) # 正确写法: test = test.assign(**d)
3. 临时 workaround(如果暂时没法升级)
如果因为环境限制没法升级sklearn,可以在代码开头手动添加一个默认的警告过滤器,避免过滤器列表为空:
import warnings warnings.filterwarnings("default")
修正后的完整代码示例
import pandas as pd from sklearn.ensemble import RandomForestClassifier import warnings # 可选:如果不升级sklearn,添加这一行避免过滤器为空 warnings.filterwarnings("default") train = pd.read_csv("%s/%s/LabelDataSet.csv" % (dirpath, dirname), encoding='utf-8') test = pd.read_csv("%s/%s/TestDataSet.csv" % (dirpath, dirname), encoding='utf-8') traincl = list(train.columns.values) testcl = list(test.columns.values) los = list(set(traincl) - set(testcl)) d = dict.fromkeys(los, 0) # 修正assign的赋值问题 test = test.assign(**d) test.columns = test.columns.astype(int) test.sort_index(axis=1, inplace=True) clf = RandomForestClassifier(n_estimators=100) clf.fit(train, trainLabel.iloc[:, 0])
内容的提问来源于stack exchange,提问作者user3806649
相关产品推荐
相关产品推荐

