Python 的 Xgoost: ValueError('feature_names 可能不包含 [, ] 或 <')

问题描述 投票:0回答:5

XGBClassifier 的 Python 实现不接受字符

[, ] or <'
作为特征名称。

如果发生这种情况,则会引发以下问题:

ValueError('feature_names 可能不包含 [, ] 或 <')

看起来显而易见的解决方案是传递等效的 numpy 数组,并完全删除列名,但如果他们没有这样做,那一定是有原因的。

XGBoost 对特征名称有什么用处?简单地传递 Numpy 数组而不是 Pandas DataFrame 的缺点是什么?

python pandas numpy scikit-learn xgboost
5个回答
27
投票

我知道现在已经晚了,但在这里为其他可能面临这个问题的人写下这个答案。这是我遇到这个问题后发现的: 如果您的列名称包含符号

[ or ] or <
,通常会发生此错误。 这是一个例子:

import pandas as pd
import numpy as np
from xgboost.sklearn import XGBRegressor

# test input data with string, int, and symbol-included columns 
df = pd.DataFrame({'0': np.random.randint(0, 2, size=100),
                   '[test1]': np.random.uniform(0, 1, size=100),
                   'test2': np.random.uniform(0, 1, size=100),
                  3: np.random.uniform(0, 1, size=100)})

target = df.iloc[:, 0]
predictors = df.iloc[:, 1:]

# basic xgb model
xgb0 = XGBRegressor(objective= 'reg:linear')
xgb0.fit(predictors, target)

上面的代码会抛出错误:

ValueError: feature_names may not contain [, ] or <

但是,如果您从

'[test1]'
中删除那些方括号,那么它就可以正常工作。以下是从列名称中删除
[, ] or <
的通用方法:

import re
import pandas as pd
import numpy as np
from xgboost.sklearn import XGBRegressor
regex = re.compile(r"\[|\]|<", re.IGNORECASE)

# test input data with string, int, and symbol-included columns 
df = pd.DataFrame({'0': np.random.randint(0, 2, size=100),
                   '[test1]': np.random.uniform(0, 1, size=100),
                   'test2': np.random.uniform(0, 1, size=100),
                  3: np.random.uniform(0, 1, size=100)})

df.columns = [regex.sub("_", col) if any(x in str(col) for x in set(('[', ']', '<'))) else col for col in df.columns.values]

target = df.iloc[:, 0]
predictors = df.iloc[:, 1:]

# basic xgb model
xgb0 = XGBRegressor(objective= 'reg:linear')
xgb0.fit(predictors, target)

有关更多信息,请阅读 xgboost core.py 中的此代码行: xgboost/core.py。这就是检查失败并引发错误的原因。


3
投票

这是另一个正则表达式解决方案。

import re

regex = re.compile(r"\[|\]|<", re.IGNORECASE)

X_train.columns = [regex.sub("_", col) if any(x in str(col) for x in set(('[', ']', '<'))) else col for col in X_train.columns.values]

1
投票

另一个解决方案:

X.columns = X.columns.str.translate("".maketrans({"[":"{", "]":"}","<":"^"}))

如果您有兴趣看看哪些是罪魁祸首:

X.columns[X.columns.str.contains("[\[\]<]")]


0
投票

只需使用

to_numpy()
来生成numpy数组:

from sklearn.model_selection import train_test_split
from xgboost import XGBClassifier

X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.25, random_state=42)
clf = XGBClassifier(random_state=42)

###### Here
clf.fit(X_train.to_numpy(), y_train.to_numpy())

0
投票

这是最简单的解决方案......

只需在数据列中使用 str.replace('arg1','arg2') 即可。 arg1-> 定义你想要改变的符号。 [^a-zA-Z0-9] 该列表描述了所有符号 arg2 -> 定义你想要替换它的符号

示例:

X_train.columns = X_train.columns.str.replace('[^a-zA-Z0-9]', '_')

**在拟合 XGBRegressor 模型时效果很好 **

© www.soinside.com 2019 - 2024. All rights reserved.