【问题标题】:Classifying with sci-kit learn for multi-valued output使用 scikit learn 进行多值输出分类
【发布时间】:2013-01-02 15:25:52
【问题描述】:

假设我从训练集中选择了一个训练文档。我已将它放入我选择的特征的特征向量 X 中。

我正在努力:

self.clf = LogisticRegression()
self.clf.fit(X, Y)

我的 Y 是这样的: [0 0 0 1 1 0 1 0 0 1 0]

我想训练我的一个模型,使其同时最好地拟合 11 个输出值中的每一个。这似乎不适用于fit,因为我收到unhashable type 'list' 错误,因为它需要一个单一的值,它是以太二进制或多类但不允许多个值。

sci-kit learn 有没有办法做到这一点?

【问题讨论】:

  • 我想我可以将每个输出编码为 0 到 2^11 - 1 之间的值,但是有没有更好的方法来处理这个问题?

标签: python machine-learning scikit-learn


【解决方案1】:

多标签分类的 API 与普通分类有所不同。您的 Y 应该是一系列序列,例如列表列表,例如

Y = [["foo", "bar"],          # the first sample is a foo and a bar
     ["foo"],                 # the second is only a foo
     ["bar", "baz"]]          # the third is a bar and a baz

然后可以将这样的Y 馈送到处理多个分类的估计器。您可以使用 OneVsRestClassifier 包装器构造这样的估算器:

from sklearn.multiclass import OneVsRestClassifier
clf = OneVsRestClassifier(LogisticRegression())

然后用clf.fit(X, Y) 训练。 clf.predict 现在也将生成序列序列。

UPDATE 从 scikit-learn 0.15 开始,此 API 已被弃用,因为它的输入不明确。您应该将我上面给出的Y 转换为带有MultiLabelBinarizer 的矩阵:

>>> from sklearn.preprocessing import MultiLabelBinarizer
>>> mlb = MultiLabelBinarizer()
>>> mlb.fit_transform(Y)
array([[1, 0, 1],
       [0, 0, 1],
       [1, 1, 0]])

然后将其提供给估算器的fit 方法。在 same 二值化器上使用inverse_transform 完成转换:

>>> mlb.inverse_transform(mlb.transform(Y))
[('bar', 'foo'), ('foo',), ('bar', 'baz')]

【讨论】:

  • 抱歉,我的术语一定太松散了。应用 OneVsRestClassifier 后,我输入的依赖于整个 250,000 个文档训练集的测试文档返回 [(0,)] 作为 predict 的输出,而不是所有 11 个项目的预测器。我得到了一个UserWarning: Label 0 is present in all training examples.,尽管在fit 函数中输入的11 个项目肯定有许多独特的组合。所以进入fit 我有类似Y=[[0,0,0,0,1,1,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],...]
  • @demongolem: Y 必须是标签序列的序列,而不是指示矩阵。
  • 啊,所以如果我理解正确,我想说文档 X 是 4 和 5,使用我在另一个答案的 cmets 中使用的术语作为 [4,5] 而不是将其编码为 11 二进制价值观?如果是这种情况,我如何说 X 缺少所有 11 个标签?我可以使用一个空列表来执行此操作,还是必须创建第 12 个标签才能完成此操作?
  • @demongolem:是的,我就是这个意思。这些列表将在内部转换为指标矩阵,但由于含糊不清,支持 API 中的那些会很复杂(任何指标矩阵也可以视为标签列表的列表)。空列表表示没有标签。
  • @demongolem:顺便说一句,指标矩阵可以用np.where 转换成预期的格式,例如Y = [[0,0,1], [1,0,0]]; [np.where(y)[0] for y in Y] 产生 [array([2]), array([0])],这对于 OneVsRestClassifier 是可以接受的。
【解决方案2】:

您能否更具体地说明您的任务是什么? 标签是二进制变量的固定长度向量吗?然后这将被称为多标签分类(即多个标签打开或关闭)。 如果每个标签可以有两个以上的值,则在 scikit-learn 中称为“多输出”,并且只能由树和集成来完成。

PS:如果你使用线性分类器,如逻辑回归,输出变量将被独立处理。

【讨论】:

  • 为了回答你的问题,我有一堆人工注释的文档。文档 X 显示或显示不质量 1。文档 X 显示或显示不质量 2 ...文档 X 显示或显示不质量 11。因此,每个标签恰好是 11 个二进制值,根据您的描述将是多标签。也许所有 11 都可以被视为彼此独立,但是根据我对主题的理解,显示出一些依赖性。也就是说,如果文档 X 显示 4,它也很可能也显示 5。
猜你喜欢
  • 2017-07-03
  • 2016-05-16
  • 2017-03-14
  • 2016-03-17
  • 2015-11-11
  • 1970-01-01
  • 2016-05-08
  • 1970-01-01
  • 2015-02-04
相关资源
最近更新 更多