我对sckit-learn
相当新并且感到困惑,因为TfidVectorizer
有时会为同一文档返回不同的向量。
我的语料库包含> 100个文档。
我正在跑步:
vectorizer = TfidfVectorizer(ngram_range=(1, 2), token_pattern=r'\b\w+\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]
VS。
[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
期间返回的向量)。
为什么,在我的第一个例子中,向量是不同的?我在这里做错了吗?
答案 0 :(得分: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())
输出:
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)
抱歉,我没有回答你的问题;)。也许你的案子中错误的原因并不完全是我所解释的,我写这篇文章是因为我认为如果你熟悉这些错误,你首先就不会问这个问题。
希望无论如何都有帮助!