scikit TfidfVectorizer.transform() 为同一文档返回不同的结果



我对sckit-learn相当陌生,并且感到困惑,因为TfidVectorizer有时会为同一文档返回不同的向量。

我的语料库包含>100个文档。

我正在运行:

vectorizer = TfidfVectorizer(ngram_range=(1, 2), token_pattern=r'bw+b', min_df=1)
X = vectorizer.fit_transform(corpus)

初始化TfidVectorizer并将其调整到语料库中的文档。 corpus是文本字符串的列表。

之后,如果我这样做:

test = list(vectorizer.transform([corpus[0]]).toarray()[0])
test == list(X.toarray()[0])

结果是 False .

如果我分别打印list(X.toarray()[0])test的前 20 项,你可以看到它们偏离了一小部分,而我希望它们是相同的。

[0.16971458376720741, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

与。

[0.16971458376720716, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]

但如果我这样做:

test_1 = list(vectorizer.transform([corpus[0]).toarray()[0])
test_2 = list(vectorizer.transform([corpus[0]).toarray()[0])
test_1 == test_2

结果是 True .上面,我基本上计算了两次向量,这就是我认为我在第一个示例中所做的(因为 X 保存了fit_transform期间返回的向量)。

为什么在我的第一个例子中,向量不同?我在这里做错了什么吗?

正如评论中提到的,这很可能是一个舍入错误,可能不值得担心

然而,我认为值得尝试理解这种现象。

可能发生的是舍入误差。有时会发生这些错误,因为计算机上的数字不是无限精确的:典型的numpy浮点数将存储在64位上。

它们具有有限精度的事实意味着加法不再是结合的:a + (b + c) 并不总是精确地 (a + b) + c。

让我们尝试在实际中展示此行为:

import numpy as np
a = np.random.random(size=1000000)
print(a.dtype)
print("%.15f" % a.sum())
b = np.random.permutation(a)
print("%.15f" % b.sum())

输出:

float64
500399.674621732032392
500399.674621731741354

现在,如果我们扩展上面的脚本以尝试使用 32 位上的浮点数:

a = a.astype(np.float32)
print(a.dtype)
print("%.15f" % a.sum())
b = np.random.permutation(a)
print("%.15f" % b.sum())

我们得到:

float64
500214.871674167399760
500214.871674167283345
float32
500214.937500000000000
500215.000000000000000

您可以看到误差要高得多:这是因为 32 位上的浮点数不如 64 位上的浮点数精确。

现在,如果您认为这很棒并且想知道更多,numpy 会通过 np.finfo 函数为您提供有关存储浮点数的详细信息:

In [10]: np.finfo(np.float32)
Out[10]: finfo(resolution=1e-06, min=-3.4028235e+38, max=3.4028235e+38, dtype=float32)

对不起,我没有;)回答你的问题。也许您案例中错误的原因并不完全是我解释的,我写这篇文章是因为我认为如果您熟悉这些错误,您就不会首先问这个问题。

希望这无论如何都有帮助!

相关内容

  • 没有找到相关文章

最新更新