我想创建我自己的SCRKIT-学习转换器,用于编码包含分类的数字特征,如邮政编码或行业代码(NAICS,MCC等).在这类代码中有一种 struct :例如,MCC 3000-3999是"旅行和娱乐",它被进一步细分为更细粒度的类别,如"航空公司"、"汽车租赁"等.我们不能将它们用作顺序特征,但如果我们将它们视为纯粹的分类特征(例如,通过一热编码),我们需要 Select 在代码 struct 的哪个级别应用特征编码.

为了解决这个问题,我创建了我自己的SCRICKIT-LEARN转换器,它是使用决策树的TargetEncoder的变体.代码如下所示.重要的是要认识到,在模型训练过程中,应该使用样本外的决策树回归分数,以避免过度拟合.出于这个原因,我实现了自己的fit_transform函数,该函数从样本分数中生成以下分数:

from sklearn.tree import DecisionTreeRegressor

from sklearn.base import TransformerMixin, BaseEstimator
from sklearn.model_selection import cross_val_predict

class TaxonomyEncoder(TransformerMixin, BaseEstimator):

def __init__(self, n_leafs=10, cv=3):
    self.n_leafs = n_leafs
    self.cv = cv

def fit(self, X, y=None):
    self.tree_ = DecisionTreeRegressor(max_leaf_nodes=self.n_leafs).fit(X,y)
    return self

def transform(self, X):
    return self.tree_.predict(X).reshape(-1,1)

def fit_transform(self, X, y=None):
    self.tree_ = DecisionTreeRegressor(max_leaf_nodes=self.n_leafs)
    return cross_val_predict(self.tree_, X, y, cv=self.cv).reshape(-1,1)

变压器工作正常,但在ColumnTransformer范围内使用时除外:

from sklearn.compose import ColumnTransformer

transformer = ColumnTransformer([('taxonomy', TaxonomyEncoder(), ['mcc'])])
transformer.fit(df[['mcc']], df['y'])
transformer.transform(df[['mcc']])

然后,我得到的错误是决策树还不适合:

NotFittedError: This DecisionTreeRegressor instance is not fitted yet. Call 'fit' with appropriate arguments before using this estimator.

显然,SCRICKIT-LEARN会在表面之下进行一些判断,从而导致这个错误.请注意,实际上没有理由具有适合的决策树,因为该树是在cross_val_predict函数中重新设置的.我怎么才能解决这个问题呢?

下面是一个完整的工作示例来重现错误:

import pandas as pd
df = pd.DataFrame({'mcc':[3000,3500,7339], 'y':[0,0,1]})

te = TaxonomyEncoder().fit(df[['mcc']], df['y'])
te.transform(df[['mcc']])

提供:

array([[0.],
       [0.],
       [1.]])

FIT_Transform也提供了预期的结果:

te.fit_transform(df[['mcc']], df['y'])

array([[0.],
       [0.],
       [0.]])

但当包装在ColumnTransformer中时,事情就出错了:

transformer = ColumnTransformer([('taxonomy', TaxonomyEncoder(), ['mcc'])])
transformer.fit(df[['mcc']], df['y'])
transformer.transform(df[['mcc']])

推荐答案

fit_transform人中,你需要将树与整个数据集相适应,以防你稍后调用transform.如上所述,您还会在try

te = TaxonomyEncoder()
te.fit_transform(df[['mcc']], df['y'])
te.transform(df[['mcc']])

解决办法可能很简单:

def fit_transform(self, X, y=None):
    self.fit(X, y)
    return cross_val_predict(self.tree_, X, y, cv=self.cv).reshape(-1,1)

ColumnTransformer有一个小问题,会导致在使用它时出错:它实际上总是fit_transform个它的所有转换器(即使只是安装列转换器本身),以便确定输出是否稀疏,从而确定h栈是否应该稀疏.

Python相关问答推荐

从收件箱中的列中删除html格式

为什么sys.exit()不能与subproccess.run()或subprocess.call()一起使用

如何使用根据其他值相似的列从列表中获取的中间值填充空NaN数据

无法定位元素错误404

如何更改分组条形图中条形图的 colored颜色 ?

Pandas—在数据透视表中占总数的百分比

移动条情节旁边的半小提琴情节在海运

当我try 在django中更新模型时,模型表单数据不可见

如何从列表框中 Select 而不出错?

手动设置seborn/matplotlib散点图连续变量图例中显示的值

Python pint将1/华氏度转换为1/摄氏度°°

Python日志(log)模块如何在将消息发送到父日志(log)记录器之前向消息添加类实例变量

pandas:在操作pandora之后将pandora列转换为int

GPT python SDK引入了大量开销/错误超时

裁剪数字.nd数组引发-ValueError:无法将空图像写入JPEG

使用np.fft.fft2和cv2.dft重现相位谱.为什么结果并不相似呢?

为罕见情况下的回退None值键入

Python日志(log)库如何有效地获取lineno和funcName?

在pandas中,如何在由两列加上一个值列组成的枢轴期间或之后可靠地设置多级列的索引顺序,

组颠倒大Pandas 数据帧