@w4nderlust@tgaddair 我注意到ludwig主要关注文本预处理,但在数值和类别编码方面存在一些弱点。
例如,我看不到用户可以声明以下功能:
- 对于低基数数据集(特征数量较少)的分类数据进行独热编码
- 稀有标签编码器,用于减少高基数数据集的类别数量
- 分位数编码,用于减少数值数据集中的离群值
- 顺序编码,用于对有序分类特征进行编码,例如特征 [非常小,小,正常,大,非常大] =>[0,1,2,3,4]
在我的工作中,我经常使用页面上的优秀编码器或自己编写的编码器:
https://feature-engine.readthedocs.io/en/latest/encoding/index.html
https://contrib.scikit-learn.org/category_encoders/
https://scikit-learn.org/stable/modules/classes.html#module-sklearn.preprocessing
是否有办法以典型的sklearn格式轻松地将其添加到项目的transformers中,因为这将扩展ludwig的功能:
# These allow us the class to inherit Scikit-learn methods
# such as fit and transform
from sklearn.base import BaseEstimator, TransformerMixin# This function just makes sure that the object is fitted
from sklearn.utils.validation import check_is_fitted
class SubtractMin(BaseEstimator, TransformerMixin):
def __init__(self, cols_to_operate):
self.columns = cols_to_operate
def fit(self, X, y = None):
self.min_val_ = X[self.columns].min()
return self
def transform(self, X):
# make sure that it was fitted
check_is_fitted(self, ‘min_val_’)
X = X.copy() # This is so we do not make changes to the
original dataframe
X[self.columns] = X[self.columns] — self.min_val_
return X
通过使用多元插补(使用所有特征而不是仅使用单个特征预测数据集中的缺失值)可以实现一些改进。
import numpy as np
from sklearn.experimental import enable_iterative_imputer
from sklearn.impute import IterativeImputer
imp_mean = IterativeImputer(random_state=0)
imp_mean.fit([[7, 2, 3], [4, np.nan, 6], [10, 5, 9]])
X = [[np.nan, 2, 3], [4, np.nan, 6], [10, np.nan, 9]]
imp_mean.transform(X)
现在我在ludwig之外进行预处理以准备csv文件,但也许可以将它放在ludwig的一个管道中。
4条答案
按热度按时间ykejflvf1#
你好,@PeterPirog,感谢你提供的详细问题!
你是对的,对于分类和数值特征,我们可以进行一些额外的预处理(欢迎提交PR!),但同时,你想要的一些特征已经在这里了。
sparse
来实现的。老实说,在深度学习模型中,这并不是很有用,因为一旦稀疏表示乘以一个全连接层的矩阵,就相当于从嵌入矩阵中选择一行,而这是默认的dense
编码器所做的。所以它在那里,但无论如何,它只是默认选项的一个不太高效的版本。most_common
参数。如果你的类别特征包含10个不同的值,并且将其设置为5,那么5个最不常见的类都将使用特殊标记进行编码。对于数值特征的分位数编码将是一个很好的补充,我们已经在待办事项列表中放了一段时间了。另一方面,序数编码可能有用,但作用较小,因为它仍然需要用户手动指定Map(然后在训练Ludwig之前使用pandas进行操作),但仍然是一个不错的选择。
关于转换的常见格式,我们已经在数值转换器方面朝着这个方向前进了,但你的建议很好。与你展示的主要区别在于假设数据框操作应该同时适用于pandas和dask。
关于插补,这也是一个很好的建议,尽管sklearn插补假设数据是平稳的,而Ludwig没有这样的假设,因为数据类型不同。与此同时,我们可以使用pandas/dask做类似的事情。
总的来说,预处理将是v0.6版本发布的主要关注点,这将在我们完成v0.5 PyTorch移植之后开始工作。非常高兴收到这些详细的建议!
siotufzp2#
你好,@w4nderlust
我不知道有些编码器已经实现了(稀疏=独热编码)。当然,对于具有高基数的数据,独热编码完全没有用处,所以我使用分位数编码器处理分类数据(分位数编码器用于数值数据和分类数据是完全不同的)
在具有非常高基数的监督学习中,分位数编码器对分类数据非常有用:
https://contrib.scikit-learn.org/category_encoders/quantile.html
我推荐这篇文章来解释它:https://maxhalford.github.io/blog/target-encoding/
出于个人目的,我自己为分位数编码器编写了一个转换器,但我还没有描述它(代码需要清理):
用法:
PercentileTargetEncoder(features=None, # 如果为None,则检测分类特征或['feature1','feature2']
ignored_features=None, # 不要转换这些分类特征,为None或列表
p=0.5, # 百分位数 - 如果为0.5,则为中位数或列表,例如[0.1,0.5,0.9]
m=1, # 在文章中描述的平滑参数,在文章中
remove_original=True, # 如果为True,则删除原始分类数据
return_df=True, # 如果为True,则返回数据框,否则返回numpy数组
use_internal_yeo_johnson=True, # 将内部的yeo-johnson变换集成到减少偏度中
verbose=True # 如果为True,则显示转换器内部的计算过程
):
rta7y2nd3#
关于@PeterPirog的更新。我们进行了一次内部会议,在完全完成PyTorch移植后,这些功能被优先作为主要功能之一。这需要更多的耐心,但它们将被添加到Ludwig中。非常感谢您的支持和帮助!
xxslljrj4#
感谢您提供的信息。现在我测试如何有效地对分类特征进行编码,使用两层
我测试了不同特征基数的不同的向量长度。