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

dee*_*eef 5 python scikit-learn

我很新sckit-learn,很困惑,因为TfidVectorizer有时会为同一个文档返回一个不同的向量.

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

我在跑:

vectorizer = TfidfVectorizer(ngram_range=(1, 2), token_pattern=r'\b\w+\b', min_df=1)

X = vectorizer.fit_transform(corpus)
Run Code Online (Sandbox Code Playgroud)

初始化TfidVectorizer并使其适合语料库中的文档.corpus是一个文本字符串列表.

之后,如果我这样做:

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

test == list(X.toarray()[0])
Run Code Online (Sandbox Code Playgroud)

结果是False.

如果我打印的第20项的list(X.toarray()[0])test,分别可以看到他们是关闭的一小部分,我希望他们是相同的.

[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]
Run Code Online (Sandbox Code Playgroud)

[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]
Run Code Online (Sandbox Code Playgroud)

但如果我这样做:

test_1 = list(vectorizer.transform([corpus[0]).toarray()[0])
test_2 = list(vectorizer.transform([corpus[0]).toarray()[0])
test_1 == test_2
Run Code Online (Sandbox Code Playgroud)

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

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

ldi*_*rer 0

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

不过我认为值得尝试去理解这种现象。

可能发生的是舍入错误。有时会发生这些错误,因为计算机上的数字不是无限精度的:典型的 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())
Run Code Online (Sandbox Code Playgroud)

输出:

float64
500399.674621732032392
500399.674621731741354
Run Code Online (Sandbox Code Playgroud)

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

a = a.astype(np.float32)
print(a.dtype)
print("%.15f" % a.sum())
b = np.random.permutation(a)
print("%.15f" % b.sum())
Run Code Online (Sandbox Code Playgroud)

我们得到:

float64
500214.871674167399760
500214.871674167283345
float32
500214.937500000000000
500215.000000000000000
Run Code Online (Sandbox Code Playgroud)

您可以看到错误要高得多:这是因为 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)
Run Code Online (Sandbox Code Playgroud)

抱歉我没有回答你的问题;)。也许您的情况中错误的原因并不完全是我所解释的,我写这篇文章是因为我认为如果您熟悉这些错误,您一开始就不会问这个问题。

无论如何希望这有帮助!