LightGBM fit抛出“ValueError:检测到循环引用”的分类功能来自钯铜

2024-04-23 20:23:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在非常满意地使用lightGBM模型,因为我有具有数十个特性和数百万行的大数据集,其中有许多分类列。 我很喜欢lightGBM可以获得一个pandas数据帧的方式,该数据帧具有用astype('category')简单定义的分类特性,而不需要任何热编码。 我还有一些浮动列,我正试图将其转换为分类容器,以加快收敛速度并强制确定决策点的边界。 问题是,试图用pd.cut来存储浮点列会导致fit方法失败并抛出一个ValueError: Circular reference detected

有一个类似的问题here,实际上在回溯中提到了Json编码器,但是我没有得到答案所建议的DateTime列。 我想.cut类别可能不受lightGBM的支持,但是我在文档中找不到任何关于这个的信息。在

为了复制这个问题,不需要大数据集,这里有一个玩具exmaple,我在这里构建了一个100行,10列的数据集。 5列是int数,我用astype转换成category 5列为浮点数。 将浮点数保持为float一切正常,将一个或多个float列转换为category withpd.切割使fit函数抛出错误。在

import lightgbm as lgb
from sklearn.model_selection import train_test_split

rows = 100
fcols = 5
ccols = 5
# Let's define some ascii readable names for convenience
fnames = ['Float_'+str(chr(97+n)) for n in range(fcols)]
cnames = ['Cat_'+str(chr(97+n)) for n in range(fcols)]

# The dataset is built by concatenation of the float and the int blocks
dff = pd.DataFrame(np.random.rand(rows,fcols),columns=fnames)
dfc = pd.DataFrame(np.random.randint(0,20,(rows,ccols)),columns=cnames)
df = pd.concat([dfc,dff],axis=1)
# Target column with random output
df['Target'] = (np.random.rand(rows)>0.5).astype(int)

# Conversion into categorical
df[cnames] = df[cnames].astype('category')
df['Float_a'] = pd.cut(x=df['Float_a'],bins=10)

# Dataset split
X = df.drop('Target',axis=1)
y = df['Target'].astype(int)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)

# Model instantiation
lgbmc = lgb.LGBMClassifier(objective      = 'binary',
                           boosting_type  = 'gbdt' ,
                            is_unbalance   = True,
                           metric         = ['binary_logloss'])

lgbmc.fit(X_train,y_train)

这是错误,如果没有错误,则不会出现np.类别列。在

^{pr2}$

Tags: 数据testtargetdfnptrainrandomrows
1条回答
网友
1楼 · 发布于 2024-04-23 20:23:10

here一样,您的问题与JSON序列化有关。序列化程序“不喜欢”由创建的类别的标签pd.切割(类似于'(0.109,0.208]'的标签)。在

您可以重写使用剪切函数(https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.cut.html)的labels可选参数生成的标签。在

在您的示例中,可以替换以下行:

df['Float_a'] = pd.cut(x=df['Float_a'],bins=10)

有了台词:

^{pr2}$

相关问题 更多 >