Scikit-learn: 在拟合中改变样本大小的重采样器估计器

创建于 2014-11-15  ·  68评论  ·  资料来源: scikit-learn/scikit-learn

一些数据转换——包括过采样/欠采样 (#1454)、异常值去除、实例减少和其他形式的数据集压缩,就像在 BIRCH (#3802) 中使用的那样——需要在训练时改变数据集,但离开它在预测时没有改变。 (在某些情况下,例如异常值去除,将拟合模型重新应用于新数据是有意义的,而在其他情况下,拟合后模型重用似乎不太适用。)

其他地方所述,当前不支持更改样本数量的转换器,当然在Pipeline的上下文中,其中在fitpredict时间应用转换(尽管黑客可能会滥用fit_transform使情况并非如此)。 PipelineTransformer s 也无法应对受监督问题在拟合时样本大小的变化,因为Transformer s 不会返回修改后的y ,只有X

为了处理这类问题,我建议引入一种新的估计器类别,称为Resampler 。 它必须至少定义一个fit_resample方法, Pipeline将在fit时间调用该方法,其他时间不变地传递数据。 (出于这个原因, Resampler不能同时是Transformer ,否则我们需要定义它们的优先级。)

对于许多模型, fit_resample只需要返回sample_weight 。 对于样本压缩方法(例如 BIRCH 中的压缩方法),这还不够,因为代表性质心是从输入样本中修改的。 因此,我认为fit_resample应该以字典的形式直接返回更改后的数据,键Xysample_weight 。 (许多Resampler只修改sample_weight仍然可能是合适的;如有必要,可以链接另一个Resampler以将权重实现为X复制或删除的条目y 。)

API Moderate New Feature help wanted

所有68条评论

在与@MechCoder 讨论了这个完全相同的 pb 后,我积极地听到了这一点

你能用你想要的方式写几行代码吗
像 Birch 和支持 sample_weights 的估计器一样吗?

我不确定带有样本权重的管道桦木,但 BIRCH 可以实现为

make_pipeline(BirchResampler, PredictorToResampler(SomeClusterer), KNeighborsClassifier)

并不是说它那么简洁,但它提供了该方法强大功能的示例。 ( PredictorToResampler只是采用的方法的预测,并返回它作为y用于输入X 。)

我认为我们应该列出一些用例来提出一个 API
工作。 对于单个用例,代码似乎有点过于通用,我再次
承认我们在桦木方面的工作的相关性。

我认为这个问题是核心API问题,是1.0的阻碍。
感谢您带来辩论。

为了处理这类问题,我建议引入一个新类别
估计器,称为重采样器。 它必须至少定义一个 fit_resample 方法,
哪个流水线会在合适的时候调用,在其他时候不变地传递数据
次。 (因此,Resampler 不能同时是 Transformer,否则我们
需要定义它们的优先级。)

为什么将拟合和重采样混为一谈? 我可以看到单独适合的用例
并重新采样。

此外,恕我直言,变换不修改 y 的事实是设计失败
(矿)。 我会更高兴定义一个新的方法,类似于转换,
修改 y (我正在寻找一个好名字),并逐步退出
“转变”阶段。

这样我们就可以避免引入新的对象类和新概念。
库中对象的概念和类越多,
更难理解。

最后,我真的不喜欢“重新采样”这个名字。 我发现它太
特定的,并且它们是该方法的其他用例,而不是重新采样
(将标签传播到未标记数据的半监督学习,对于
实例)。

以下是名称建议:

  • 申请
  • 改变
  • 调整
  • 变异
  • 兑换

名称转换太好了,恕我直言。 从长远来看,我们可以来
回到它,经过几年对旧行为的弃用。
新的行为是它总是返回相同数量的数组
比它给出的(如果只给出 X 给一个有监督的
需要y)的方法。

修改y不是这里的基本问题。 是的,这是需要处理的其他事情。 这里的问题是从 resample 传出的样本集不一定是传入的样本集。 这种操作(重采样是象征性的,但我很高兴找到一个更好的名字)经常需要训练,并且当您希望预测与输入相对应时,这在测试时很少是正确的做法。

不仅仅是“在拟合时[在管道上下文中]大部分发生”(是的,如上所述,在某些情况下会重新应用拟合模型,尤其是异常值检测)将其与必须在拟合时同样适用的转换器区别开来运行时,但样本大小可以改变的想法。

所以不要介意修改y 。 不能在FeatureUnion使用允许样本大小改变的转换器。 允许样本大小改变的转换器不能在Pipeline除非它修改y也是因为score会损坏,但即便如此,它似乎是一个奇怪的评分定义一个数据集,如果它被这样修改。

因此,尽管重新设计转换器 API 可能是可取的,但在不同类型的估计器中存在 IMO 的价值:(a) 在训练期间对Pipeline有影响,否则没有影响; (b) 允许改变样本大小,其中Transformer s 或其继任者应该继续不这样做。

“重采样”这个名字的想法是,这类估计器最重要的工作是以某种方式改变样本大小,通过过采样、重新加权、压缩或合并来自其他地方的未标记实例。

允许样本大小改变的变压器不能用于
功能联盟。

这就是我所缺少的论点。 谢谢! 还有其他情况吗?

“重新采样”这个名字的想法是这个最重要的工作
类估计量以某种方式改变样本大小,通过
过采样,否则重新加权、压缩或合并
来自其他地方的未标记实例。

根据你证明需要新班级的论点,我一直
想着这个名字。 事实上,它应该围绕着这个概念
样本,甚至可能是“样本”一词,因为这是我们在
scikit-学习。 最明确的术语是“transform_samples”,但我
认为这太长了(我们可能需要像
“fit_transform_samples”)。

然而,我担心的一件事是,如果我们引入一个
“重新采样”并保持旧的“变换”方法,它会模棱两可
管道手段。 当然,我们可以引入一个论点
管道,或创建新的管道变体。 不过,我很担心
用户和开发人员增加的复杂性并不能证明创建
与变形金刚相比的额外对象。 在其他时间,我认为
我们最好说一些变压器改变了
样本数量(我们可以为此创建一个额外的子类)。

这个子类的变压器是否也只能在合适的时候运行? 我认为这足以激励不同的估计者家族,但我可能是错的。

这种类型的估算器流水线也可以很容易地建模为元估算器。 唯一真正的问题是参数名称的嵌套令人不舒服(尽管我曾经玩过一些魔术,允许包装嵌套结构,以便可以重命名参数或绑定它们的值),并且平面比嵌套更好。

这个子类的变压器是否也只能在合适的时候运行?

fit_transform 不能解决这个问题有什么原因吗?

如果允许fit_transformfit().transform具有不同的结果,则fit_transform求解该组件。 我认为转换器对许多用户来说已经足够令人困惑,尽管或多或少地承诺fit_transformfit().transform的功能等效。

如果 fit_transform 和 fit_transform 求解该组件
fit().transform 允许有不同的结果。 我认为
即使或多或少,变压器也足以让许多用户感到困惑
承诺 fit_transform 和
适合()。变换。

很明显,我同意你的看法,打破这种等价性将是一个
很糟糕的主意。

但我不确定为什么有必要(尽管我开始
明白你的意思,我还不相信这是不可能的
实现一个具有必要逻辑的转换方法
fit().transform 和 fit_transform 之间的匹配。

我正在准备一些例子,以便我们可以指出一些东西
讨论,但比写快速回复需要更长的时间!

自2014年11月17日20:45,盖尔Varoquaux [email protected]写道:

如果 fit_transform 和 fit_transform 求解该组件
fit().transform 允许有不同的结果。 我认为
即使或多或少,变压器也足以让许多用户感到困惑
承诺 fit_transform 和
适合()。变换。

很明显,我同意你的看法,打破这种等价性将是一个
很糟糕的主意。

但我不确定为什么有必要(尽管我开始
明白你的意思,我还不相信这是不可能的
实现一个具有必要逻辑的转换方法
fit().transform 和 fit_transform 之间的匹配。


直接回复此邮件或在 GitHub 上查看
https://github.com/scikit-learn/scikit-learn/issues/3855#issuecomment -63280553
.

我正在准备一些例子,以便我们可以指出一些东西
讨论,但比写快速回复需要更长的时间!

谢谢你。 这是非常有用的!

感谢您重新开始对此的讨论。
因此,通过实现一些东西,比如在训练期间将类重新采样到相同的大小,存在三个不同的问题:

1)它改变了y。
2)它在训练期间重新采样,但我们希望在测试期间对所有样本进行预测。
3) 此估算器不能与其他任何东西一起使用FeatureUnion

第一个可以通过改变变压器的行为来解决,对于其他两个,它并不像做什么那么明显。
不过,我认为我们仍然可以摆脱变压器接口。
我不会太担心 3)。 我认为当有人尝试时提出一个合理的错误会很好。 这应该很容易检测。

3) 可能是最棘手的,因为它肯定需要一些新机制,如果值得增加这种复杂性,我们应该小心。
添加transform(X, y, fit=False)transform(X, y, filter=False)或其他关键字如何,控制是否允许丢弃样本。
在管道中,该选项可能取决于是否有人称其为“适合”。

这让我想到:在拟合和预测过程中我们想要不同的行为时会出现什么情况? 我们是否总是想在学习期间重新采样,而不是在预测期间? 如果我们想做一些可视化并想过滤掉两者的异常值怎么办?

@jnothman

据我了解这个讨论,(对不起,如果我错过了什么,我只是快速浏览,尤其是说 Birch :P 的部分),你的意思是从一类新的估计器中继承 Birch(和其他实例减少方法) ,称为 Resamples,我们在管道的fit期间调用了其fit_resample方法,对吗? 初学者的一些幼稚问题。

  1. 以某种方式(如在 Birch 中),可以查看从 MBKMeans(和其他一些聚类器)获得的质心,作为实例减少,特别是当n_clusters足够大时,我们如何在fit_resample应该调用fit_transform
  2. 管道中通常使用的变压器的变换方法是什么? 在我看来,使用brc.subcluster_centers_可能比转换subcluster_centers_空间中的输入数据有用得多,尤其是在使用AgglomerativeClustering等管道传输时。 这是内部正在做的事情。

@MechCoder

首先,我不确定重新实现 BIRCH 是我在这里的意图。 更重要的是,这种类型的算法可以被构建为减少、聚类等的管道。 应该有一种_正确的方式_将估计器拼凑成 scikit-learn 中的这些类型的东西,无论 API 在多大程度上促进了它。 至于重新实现 BIRCH 本身,可以将重采样器作为单独的组件取出,也可以提供完整的聚类器。

是的,使用 MBKmeans 进行实例缩减同样适用; 事实上,它碰巧用一些不同的语义定义了transform ,这意味着它被包装为重采样器需要作为一个单独的类出现(有点像WardAgglommerationWard是不同的类)。

碰巧实现transform分类器或聚类器或回归器通常有点问题,因为正如您所建议的,关联变换的语义不一定是预测器固有的,不一定在相同的参考文本中描述作为预测器等。例如,尽管在 #2160 中建议为了一致性,所有带有coef_feature_importances_估计器也应该有_LearntSelectorMixin作为特征选择器,我后来认为现在过时的#3011 的方法会更合适,我们用一种包装分类器/回归器的方式替换这个 mixin,使其充当特征选择器; 或者,像.as_feature_selector()这样的分类器/回归器的方法可以执行相同的魔术。 这个想法是为了更清楚地分离模型和功能。

@amueller

3) 可能是最棘手的一个

你的意思是(2)?

当我们在拟合和预测过程中想要不同的行为时,有哪些情况? 我们是否总是想在学习期间重新采样,而不是在预测期间? 如果我们想做一些可视化并想过滤掉两者的异常值怎么办?

我认为这是一个关键问题。 当然,必须有一种方法可以在适当的情况下重新应用拟合的重采样; 可视化就是一个很好的例子。 然而,如果没有管道魔法,期望用户做这件事也许没什么大不了的。

@jnothman是的,我的意思是(2)。
抱歉,我不确定我是否理解您的回复。
“没有管道魔法”是什么意思? 在这种情况下,用户不应该使用 pipline 吗? 或者不为predictscoretransform应用重采样的启发式应该是默认值,但应该有一个不使用此启发式的选项?

顺便说一句,这种启发式方法让我无法计算所使用的训练集的分数,这有点奇怪。

我对它并不完全满意,但我在https://gist.github.com/jnothman/274710f945e311697466模拟了一些示例(不是绘图,只是使用代码)

“没有管道魔法”是什么意思? 在这种情况下,用户不应该使用 pipline 吗?

我的意思是,目前存在无法合理使用 Pipeline 的情况。 它对于涉及克隆和参数设置的网格搜索等特别有用,同时要求内点的可视化以不使用 Pipeline 对象可能不会对用户造成太大伤害。

我同意这个模型不提供计算训练分数的方法有点令人不安。

总结与@GaelVaroquaux的讨论,我们都认为打破fit().transform()fit_transform的等价性可能是一种可行的前进方式。 fit_transform会进行子采样,但fit().transform()不会。

我认为是时候解决这个问题了。 我们已经在其他地方打破了 fit_transform 和 transform 等价性。

但是你确定我们想让 fit_transform 有时返回 (X, y, props) 而其他时候只返回 X 吗? 那么我们是否要求转换只返回 X 或者它也允许改变 y(我认为我们不应该允许它改变 y;这对于评估来说是一个坏主意)。

我们在管道处理 fit_params 时也有一个小问题:重采样器下游的任何 fit_params 都不能使用,应该会引发错误。 (任何由重采样器返回的道具都需要用管道的路由策略来解释。)确实可能这是管道中的设计错误,但对样本道具和 y 的处理假设 fit_transform 的输出与输入对齐,样本为样本.

我发现这些论点一起令人信服地表明这值得一个单独的方法,例如 fit_resample,而不仅仅是转换器返回导致非常不同处理的元组的选项。 但是,我不认为我们应该有相应的示例方法(并且发现 imblearn 的 Pipeline.sample 方法很有问题)。 在测试时,应调用转换,否则我们可以考虑所有重采样器在测试时执行身份转换。 (在支持 fit_resample 的对象上,应禁止 fit_transform。)

让我们做到这一点。

我认为现在我们应该禁止重采样器实现变换,因为常见的用例是身份变换,并且在不破坏向后兼容性的情况下在将来允许变换是可能的。

这方面的工作建议和#9630:

执行

  1. 使用fit_resample创建一个OutlierDetectorMixin作为估计器的具体示例。 fit_resample被定义为只返回对应于内点的(X, y, props) 。 这样,一旦其余工作完成,异常值检测器将充当管道中的异常值移除器(请参阅 #9630)。 它们在这里只是作为重采样器的一个有形例子。 props只是将传递给 fit 的参数字典。 {'sample_weight': [...]}{}最常见。
  2. 在适当的地方从OutlierDetectorMixin继承。 测试一下。
  3. 扩展常见测试以涵盖重采样器。 这应该:

    • 检查fit_resample的输出结构是否正确

    • 检查fit_resample的输出长度是否一致

    • 检查fit_resample的输出对于重复调用是否一致

    • 断言fit_resample意味着没有fit_transformtransform

  4. 处理fit_resample中的Pipeline.fit ,确保正确处理道具(不应为下游管道步骤设置道具;返回的道具应解释为Pipeline.fitfit_params是)
  5. 为 Pipeline.{transform,predict,...} 中的重采样器执行身份变换
  6. ? 将fit_resample方法添加到最后一步为fit_resample流水线
  7. 可能实现其他重采样器(例如过采样),可能基于 #1454

文档

  1. 添加/修改异常值去除示例
  2. 讨论异常值检测文档中的异常值去除
  3. 在 Pipeline 文档中讨论重采样器
  4. 将 OutlierDetectorMixin 添加到 classes.rst
  5. 在异常值检测器下的词汇表中提及 OutlierDetectorMixin
  6. 词汇表中重采样器的条目
  7. 在开发人员文档中描述重采样器

如果其他人认为这是正确的方法,我很高兴向贡献者(或 GSoC)开放。

Ping @glemaitre

  1. 可能实现其他重采样器(例如过采样),可能基于 #1454

你认为OutlierDetectorMIxin会是重采样器的一个很好的命名吗?

异常值检测器是一种去除异常值的重采样器。 并非所有重采样器都是异常值检测器。

这个想法是从实现一些有形的东西开始,而不是一个无法测试的抽象 API 或管道。

我上面已经说明了。

好的。 你能链接到道具公关或问题。 否则计划似乎不错。
也许我们应该补充一点,不同的方法需要通过 estimators_checks 的共同测试。

道具我只是指将传递给适合的参数字典。 {'sample_weight': [...]}{}最常见。

这看起来是一个非常有趣的项目。 如果有疑问,我想探索更多并寻求帮助。

我已经标记了这个需要的帮助,并且真的很想看到有人追求https://github.com/scikit-learn/scikit-learn/issues/3855#issuecomment -357949997,如果只是为了我们有一个具体的实现可以达到达成共识。

我将 Mixin 命名为ResamplerMixinSamplerMixin 。 此外,我会将方法fit_sample命名为与不平衡学习内联。

我认为这样做符合不平衡学习会很好,我们应该采用他们的东西。 cc @NicolasHug也;)

我可以解决这个问题

去吧,我会说!

我很高兴看到这一进展。 如果我能帮上忙,请联系我 :)

我记得 imblearn 中一些我不想复制的奇怪行为
这里。 生成估计器支持样本方法,因此 fit_sample 听起来
像别的东西。 这听起来也像天真的用户期望的那样
它的意思是“适合样本”,即部分适合。 所以我反对 fit_sample

如果我没记错的话,我从你手里召回了fit_resample

我不介意别的,我只是不喜欢 fit_sample

对我来说,这听起来也像天真的用户期望它意味着“适合
在样本上”,即部分拟合。所以我反对 fit_sample

+1

这有点麻烦,但这是我对可以重新采样的 sklearn 管道的实现:

https://github.com/dmbee/seglearn/blob/master/seglearn/pipe.py

我认为我们不能重复使用变换动词。 我不认为我们可以
在测试时变换 y。 为什么你认为这样做是合适的
分段学习?

我同意乔尔的观点,大多数用例在测试期间不需要甚至禁止重采样。

seglearn 处理时间序列/序列,并且在测试分割数据时仍然需要重新采样。 我不确定是否有任何其他应用程序也需要在测试时重新采样。 暂时没有想到。

在任何情况下,您都可以将变换动词用于重采样器(就像我一样),并且仅在拟合/变换期间调用它。 但是,您提出的实现也是有道理的。 我刚刚发布了我的实现作为一个工作示例。

如果需要,很乐意提供帮助。

  • 大卫

@dmbee ,欢迎您在这里提供帮助。 我们需要有能力并致力于在核心开发团队的指导下推动这一进程的人。

@jnothman - 好的,我将开始并计划在寒假期间完成它。

@jnothman - 我有一个关于你提议的实施的问题:

sample_weight 在 fit / fit_transform / fit_predict 期间作为 **fit_params 的一部分传递给管道,并且必须以最终估计器的标签为前缀(例如'logreg__sample_weight')

我认为最干净的解决方案是让管道检查 *__sample_weight 是否在 fit_params 中,并将其作为 sample_weight 传递给重采样器。 然后重采样器将返回 (X, y, sample_weight),它可用于覆盖最终估计器的 sample_weight。

我不知道为什么你希望 fit_resample 返回字典道具? 由于管道中的每个步骤只接收使用前缀 api 分配给它的 fit_params。

干杯,
大卫

粗略地说,这里是我认为可以很好地用于重采样器的模板:

class ResamplerMixin(object):

    def fit_resample(self, X, y, **fit_params):
        sample_weight = None
        if 'sample_weight' in fit_params:
            sample_weight = fit_params.pop('sample_weight')

        return self.fit(X, y, **fit_params).resample(X, y, sample_weight)

    def fit(self, X, y):
        return self

    def resample(self, X, y, sample_weight):
        return X, y, sample_weight

您提出了正确的问题,所以这非常令人鼓舞:)

我不知道为什么你希望 fit_resample 返回字典道具? 由于管道中的每个步骤只接收使用前缀 api 分配给它的 fit_params。

好吧,我们确实有一个问题,我们还没有真正就示例属性路由机制的设计达成一致,而目前 Pipeline 的机制根本没有设计用于在调用 fit 时无法为每个步骤指定属性的情况。

但是如果我们希望fit_resample能够修改或生成sample_weight那么它需要能够修改或生成与每个样本对齐的其他东西(未指定); 与原始样本对齐没有意义。 因此有一个字典。

然而,在流水线中处理这个是有争议的

不应为下游管道步骤设置任何道具

我想应该是这样。

返回的道具应该被解释为 Pipeline.fit 的 fit_params 是

现在,如果在管道中并且 dict 不为空,我会考虑引发 NotImplementedError ,一旦我们制定了示例道具路由,我们就可以确定应该采取什么适当的行为(我是否有时间考虑一下!)。 ..

谢谢乔尔。 我很确定我明白你在追求什么。 本质上:

一些 fit_params(例如 sample_weight 和可能其他)与样本相关联,并且必须由重采样器针对任何下游估计器进行相应修改。 让我们称这些为 sample_props。

对 API(现有转换器、估计器等)进行最少更改的向后兼容实现可能如下所示。

向名为 sample_props 的管道拟合例程添加一个可选参数。 这是一个字符串列表,它对应于 fit_params 的键是 sample_props 并且需要由重采样器修改。 然后相关参数可以由重采样器传递和更新。 修改pipeline _fit 例程以获取每一步的相关fit_params 如下:

for step_idx, (name, transformer) in enumerate(self.steps[:-1]):

    fit_params_step = {key.split('__', 1)[1]: fit_params.pop(key) for key in fit_params if name + "__" in key};

    if isinstance(transformer, ResamplerMixin):
        props = {key : fit_params[key] for key in sample_props}
        X, y, props = transformer.fit_resample(X, y, **fit_params_step, props)
        fit_params.update(props)


    else: ... # is a regular transfomer

不急于做出这个架构决定,但我想在继续编写代码之前制定一个计划。

编辑为使用 pop 以避免重新计算上游变压器的 sample_props

不要特别担心流水线拟合例程。 担心
fit_resample API。 一般来说,拟合方法可以带附加参数
超出与 X 对齐的 (X, y),即示例道具。 我相信
fit_resample 需要能够返回这些东西并将它们作为
输入。 然后如何在管道中处理它们是一个悬而未决的问题,IMO
我们不需要为此做出承诺来创建重采样 API。

很公平。 我想修改管道是我发现最有趣的部分。 无论如何,您认为这是 API 的粗略轮廓吗?

class ResamplerMixin(object):

    def fit_resample(self, X, y, **fit_params, props=None ):
        return self.fit(X, y, **fit_params).resample(X, y, props)

class TakeOneSample(BaseEstimator, ResamplerMixin):

    def __init__(self):
        pass        

    def fit(self, X, y=None):
        return self

    def resample(self, X, y, props):
        return X[0], y[0], {k : v[k][0] for k in props}

我不知道任何需要重新采样方法的用例,真的,而且它
肯定会使 Pipeline 中的事情复杂化:我们为什么要更改
测试时的样本,以及这将如何影响对管道的评分
预测?

也就是说,我建议支持 fit_resample,但不支持 resample。

为什么我们要在测试时更改样本集,这将如何影响管道预测的评分?

是的,在测试时更改样本数量是一种语义
我不清楚。 我宁愿皱眉远离它。

+1 仅在 Mixin 中定义了fit_resample 。 我不记得任何用例只有resample

关于Pipeline实现,我认为imblearn 实现中所做的更改应该会成功,或者至少是一个好的开始。 关于props处理的问题仍然存在。

关于重采样器本身中sample_props的处理,看起来@dmbee的方向与我们认为处理sample_weight方向相同:
https://github.com/scikit-learn-contrib/imbalanced-learn/pull/463/files

@dmbee不要犹豫,重新进行imblearn一些代码/测试。 您也可以 ping 我查看 PR。 从下周开始,我将在scikit-learn再次活跃起来。

我不知道任何需要重新采样方法的用例,真的,它肯定会使管道中的事情复杂化:为什么我们要在测试时更改样本集,这将如何影响管道预测的评分?

以上,我无意在测试时支持重采样。 我知道这超出了这里/利基的范围。

允许单独的拟合/重采样方法(而不仅仅是 fit_resample)不会影响重采样器在管道中的使用方式或我认为管道的复杂性(请参阅上面的管道代码)。 我想到,对于某些潜在用例(例如生成重采样),将拟合和重采样方法分开可能会很有用。

但是,如果不需要此功能,我们可以使用非常相似的 API 来 imblearn 添加对 sample_props 的处理,如果重采样器只是索引数据,这很简单。 请参阅下面的粗略示例。

让我知道你的想法?

import numpy as np
from sklearn.base import BaseEstimator
from abc import abstractmethod

class ResamplerMixin(object):

    def fit_resample(self, X, y, props=None, **fit_params): # gets called by pipeline._fit()
        self._check_data(X, y, props)
        return self._fit_resample(X, y, props, **fit_params)

    <strong i="11">@abstractmethod</strong> # must be implemented in derived classes
    def _fit_resample(self, X, y, props=None, **fit_params):
        return X, y, props

    def _check_data(self, X, y, props): # to be expanded upon
        if props is not None:
            if not np.all((np.array([len(props[k]) for k in props]) == len(y))):
                raise ValueError

    def _resample_from_indices(self, X, y, props, indices):
        if props is not None:
            return X[indices], y[indices], {k : props[k][indices] for k in props}
        else:
            return X[indices], y[indices], None


class TakeOneSample(BaseEstimator, ResamplerMixin):

    def __init__(self, index = 0):
        self.index = index

    def _fit_resample(self, X, y, props=None):
        return self._resample_from_indices(X, y, props, self.index)

@glemaitre - 谢谢。 我当然不想复制imblearn所做的事情(顺便说一下,我喜欢并使用那个包!)。 似乎imblearn缺少 atm 的主要内容是支持 sample_props 所需的管道/重采样器更改。 否则,它似乎与sklearn非常兼容。

  • 大卫

从某种意义上说,我真的不喜欢我们在这里为示例道具提供一种格式,但我想这与现在交叉验证代码中fit_params的处理没有什么不同。 所以我认为它应该是好的。

我当然不想复制 imblearn 中所做的事情

实际上,您应该从 imblearn 中获取适用于 scikit-learn 的任何内容。 我们的想法是贡献任何好的上游并从我们的代码库中删除。 我们正处于 API 开始变得更加稳定的阶段,我们最近进行了一些更改以反映与 @jnothman 的一些讨论。

最重要的是,采取对 scikit-learn 有益的任何东西;)

所以我认为它应该是好的。

好吧,理论上,我们需要研究 SLEP。

然而,推进这个问题可能是一个很好的练习,以便
能够写出简洁的 SLEP。

实际上,您应该从 imblearn 中获取适用于 scikit-learn 的任何内容。 我们的想法是贡献任何好的上游并从我们的代码库中删除。

好的,很高兴知道 - 谢谢。 我应该使用重新实现而不是复制。 似乎imblearn大部分内容都可以轻松移植。

好吧,理论上,我们需要研究 SLEP。

不知道 SLEP 是什么....

SLEP 是(未充分利用的)Scikit-learn 增强建议。 https://github.com/scikit-learn/enhancement_proposals/

关于https://github.com/scikit-learn/scikit-learn/issues/3855#issuecomment -446690557 中的 API 提案,是的,这种重采样方法看起来不错……并非所有估算器都支持fit_resample可以从索引中做到这一点,但我认为您已经意识到这一点; 例如,样本减少技术不会。

关于#3855(评论)中的 API 提案,是的,这种重采样方法看起来不错……并非所有支持fit_resample估算器都可以从索引中做到这一点,但我认为您知道这一点; 例如,样本减少技术不会。

好东西。 是的 - 我知道并非所有重采样器都会从索引中采样。 那些不需要实现自己的处理 props 的方法(如果有一个明智的选择 - 如果不知道 props 中会有什么就很难确定),或者如果 props 不是 none 则引发未实现的错误。

巴黎有人在做这个吗? 我很乐意提供帮助(并且 api 对拟合半监督分类器很有用,如本评论中所述。)

是的,我开始移植 imblearn 实现。 你想拿其他的,我可以帮忙审查吗?

当然,我在哪里可以找到你?

我开始研究这个(我不在巴黎),但在过去的几个月里太忙了。 我很高兴分享我已经完成的工作,并继续努力。

我开始研究这个(我不在巴黎),但在过去的几个月里太忙了。 我很高兴分享我已经完成的工作,并继续努力。

我现在开始为 sprint 做这方面的工作。 如果您有您认为可能有用的现有工作,我非常乐意在您所做的工作的基础上再接再厉。

在这里 - 查看 sklearn 中的 resample 文件夹
https://github.com/dmbee/scikit-learn/tree/dmbee-resampling

此页面是否有帮助?
0 / 5 - 0 等级