将 pandas Interval 转换为字符串(然后再返回)

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

我对 Python 比较陌生,正在尝试准备一些数据来训练随机森林。 由于各种原因,我们希望数据是离散的,因此有一些连续变量需要离散化。 我在 pandas 中发现了

qcut
,它似乎可以实现我想要的功能 - 我可以设置多个 bin,它会将变量离散化到多个 bin 中,试图使每个 bin 中的计数保持均匀。

但是,

pandas.qcut
的输出是一个Intervals列表,而scikit-learn中的RandomForest分类器需要一个字符串。 我发现我可以使用
.astype(str)
将间隔转换为字符串。 这是我正在做的事情的一个简单示例:

import pandas as pd
from random import sample

vals = sample(range(0,100), 100)
cuts = pd.qcut(vals, q=5)
str_cuts = pd.qcut(vals, q=5).astype(str)

然后 str_cuts 是传递到随机森林的变量之一。

但是,该系统的目的是训练随机森林,将其保存到文件中,然后允许某人在以后加载它并获得新测试实例的分类,这在训练时不可用。 由于分类器是根据离散数据进行训练的,因此新的测试实例在使用之前需要进行离散化。 所以我想要做的是在一个新实例中读取,对其应用已经建立的离散化方案,将其转换为字符串,然后在随机森林中运行它。 然而,我对“应用离散化方案”的最佳方法感到困惑。

有没有简单的方法来处理这个问题? 我认为没有直接的方法可以将字符串转换回间隔。 我可以从离散化中获取所有间隔值的列表(例如:

cuts.unique()
)并在测试时应用它,但这需要在随机森林旁边保存/加载离散化字典,这看起来很笨重,我担心尝试重新创建分类变量时遇到问题(主要来自 R,它对分类变量的格式非常挑剔)。 或者还有另一种我没有看到的解决方法吗?

python pandas random-forest binning discretization
4个回答
4
投票

labels
 中使用 
qcut
参数并使用
pandas Categorical

其中任何一个都可以帮助您为变量创建类别而不是间隔。然后,您可以使用某种形式的编码,例如 Label EncodingOrdinal Encoding 将类别(如果您习惯使用 R,则为因子)转换为森林能够使用的数值。

然后流程进行:

cutting => categoricals => encoding

而且您不再需要手动完成。

最后,一些梯度增强树库支持分类变量,尽管这不是灵丹妙药,并且取决于您的目标。请参阅 catboostlightgbm


0
投票

对于未来的搜索者来说,使用 scikit-learn 中的转换器而不是 pandas 有好处。 在本例中,

KBinsDiscretizer
是 scikit 中的
qcut
。 它可以在管道中使用,管道将处理将先前学习的离散化应用到未见过的数据,而不需要单独存储离散化字典或往返字符串转换。 这是一个例子:

from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import KBinsDiscretizer


pipeline = make_pipeline(KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='quantile'), 
                         RandomForestClassifier())
X, y = make_classification()
X_train, X_test, y_train, y_test = train_test_split(X, y)
pipeline.fit(X_train, y_train)
predictions = pipeline.predict(X_test)

如果您真的需要在pandas

IntervalIndex
和字符串之间来回转换,您可能需要按照此答案中所述进行一些解析:https://stackoverflow.com/a/65296110/3945991并使用
FunctionTransformer
或编写您自己的
Transformer
进行管道集成。


0
投票

要将 pandas 间隔 转换为字符串,一个好方法是利用 pandas 间隔的 'left' 和 'right' 属性:

intervalString=f"{interval.left} - {interval.right}"

-2
投票

虽然这可能不是最干净的方法,但将字符串转换回间隔确实是可能的:

import pandas as pd
str_intervals = [i.replace("(","").replace("]", "").split(", ") for i in str_cuts]
original_cuts = [pd.Interval(float(i), float(j)) for i, j in str_intervals]
© www.soinside.com 2019 - 2024. All rights reserved.