【问题标题】:Why is vectorizer.fit_transform(x).astype('bool') different from vectorizer.set_params(binary=True).fit_transform(x)?为什么vectorizer.fit_transform(x).astype('bool') 与vectorizer.set_params(binary=True).fit_transform(x) 不同?
【发布时间】:2019-04-08 06:45:22
【问题描述】:

这是我正在谈论的一个最小示例:

import numpy as np
from sklearn.datasets import fetch_20newsgroups
from sklearn.feature_extraction.text import TfidfVectorizer

data = fetch_20newsgroups()
x = data.data

vec = TfidfVectorizer(min_df=0.01, max_df=0.5)
mat = vec.fit_transform(x).astype('bool')

vec.set_params(binary=True)
print(np.array_equal(mat, vec.fit_transform(x)))

这会打印出False。设置 binary=True 和将所有非零值设置为 True 之间的根本区别是什么?

编辑:正如@juanpa.arrivillaga 回答的那样,TfidfVectorizer(binary=True) 仍然进行逆文档频率计算。但是,我也注意到CountVectorizer(binary=True) 也不会产生与.astype('bool') 相同的输出。下面是一个例子:

In [1]: import numpy as np
   ...: from sklearn.datasets import fetch_20newsgroups
   ...: from sklearn.feature_extraction.text import CountVectorizer
   ...:
   ...: data = fetch_20newsgroups()
   ...: x = data.data
   ...:
   ...: vec = CountVectorizer(min_df=0.01, max_df=0.5)
   ...: a = vec.fit_transform(x).astype('bool')
   ...:
   ...: vec.set_params(binary=True)
   ...: b = vec.fit_transform(x).astype('bool')
   ...: print(np.array_equal(a, b))
   ...:
False

In [2]: a
Out[2]:
<11314x2141 sparse matrix of type '<class 'numpy.bool_'>'
        with 950068 stored elements in Compressed Sparse Row format>

In [3]: b
Out[3]:
<11314x2141 sparse matrix of type '<class 'numpy.bool_'>'
        with 950068 stored elements in Compressed Sparse Row format>

维度和 dtype 是相同的,这让我相信这些矩阵的内容是不同的。仅仅通过观察print(a)print(b) 的输出,它们看起来是一样的。

【问题讨论】:

  • binary=TrueTfidfVectorizer 的文档中进行了解释。他们不做同样的事情。

标签: python scikit-learn


【解决方案1】:

您从根本上混淆了两件事。

一种是转换为布尔 numpy 数据类型,它等效于接受两个值 True 和 False 的 python 数据类型,不同之处在于它在底层原始数组中表示为单个字节。

binary 参数传递给TfidfVectorizer 会改变数据建模的方式。简而言之,如果您使用binary=True,总计数将是二进制的,即看到或未看到。 然后你进行通常的 tf-id 转换。 From the docs:

如果为 True,则所有非零项计数都设置为 1。这并不意味着 输出将只有 0/1 值,只有 tf-idf 中的 tf 项是 二进制。 (将 idf 和归一化设置为 False 以获得 0/1 输出。)

所以你甚至没有得到布尔输出。

所以考虑一下:

In [10]: import numpy as np
    ...: from sklearn.feature_extraction.text import TfidfVectorizer
    ...:

In [11]: data = [
    ...:     'The quick brown fox jumped over the lazy dog',
    ...:     'how much wood could a woodchuck chuck if a woodchuck could chuck wood'
    ...: ]

In [12]: TfidfVectorizer().fit_transform(data).todense()
Out[12]:
matrix([[ 0.30151134,  0.        ,  0.        ,  0.30151134,  0.30151134,
          0.        ,  0.        ,  0.30151134,  0.30151134,  0.        ,
          0.30151134,  0.30151134,  0.60302269,  0.        ,  0.        ],
        [ 0.        ,  0.45883147,  0.45883147,  0.        ,  0.        ,
          0.22941573,  0.22941573,  0.        ,  0.        ,  0.22941573,
          0.        ,  0.        ,  0.        ,  0.45883147,  0.45883147]])

In [13]: TfidfVectorizer().fit_transform(data).todense().astype('bool')
Out[13]:
matrix([[ True, False, False,  True,  True, False, False,  True,  True,
         False,  True,  True,  True, False, False],
        [False,  True,  True, False, False,  True,  True, False, False,
          True, False, False, False,  True,  True]], dtype=bool)

现在请注意,使用 binary 仍将返回浮点类型:

In [14]: TfidfVectorizer(binary=True).fit_transform(data).todense()
Out[14]:
matrix([[ 0.35355339,  0.        ,  0.        ,  0.35355339,  0.35355339,
          0.        ,  0.        ,  0.35355339,  0.35355339,  0.        ,
          0.35355339,  0.35355339,  0.35355339,  0.        ,  0.        ],
        [ 0.        ,  0.37796447,  0.37796447,  0.        ,  0.        ,
          0.37796447,  0.37796447,  0.        ,  0.        ,  0.37796447,
          0.        ,  0.        ,  0.        ,  0.37796447,  0.37796447]])

它只是改变了结果。

【讨论】:

  • 谢谢!所以据我了解,binary=True 仍然会进行逆文档频率计算。 CountVectorizer(binary=True) 呢?从理论上讲,将字数的 dtype 更改为 bool 和设置 binary=True 都不是一个单词是否在字符串中的指标吗?为什么不相等?
  • @EricTaw 在CountVectorizer 的情况下,你最终会得到等效的表示,是的,因为它是简单的计数。不过,数据类型最终会再次不同。
  • 在实践中似乎并非如此——请参阅我在帖子中的编辑。我的猜测是我误解了np.array_equal 并且有更好的方法来检查稀疏矩阵是否相同。
  • 啊,我可能是对的! np.array_equal(a, b) 返回False,但(a-b).nnz == 0 建议here 返回True
猜你喜欢
  • 1970-01-01
  • 2019-02-04
  • 2013-10-15
  • 2013-02-05
  • 2019-05-13
  • 2011-12-14
  • 1970-01-01
  • 2020-02-28
  • 2020-10-25
相关资源
最近更新 更多