fso*_*ety 4 python numpy matrix scipy scikit-learn
我目前想要使用余弦相似度和python中的Tfidf功能来计算所有对文档的相似度.我的基本方法如下:
from sklearn.feature_extraction.text import TfidfVectorizer
#c = [doc1, doc2, ..., docn]
vec = TfidfVectorizer()
X = vec.fit_transform(c)
del vec
Y = X * X.T
Run Code Online (Sandbox Code Playgroud)
工作得很好,但不幸的是,不是我的大数据集.X具有维度,(350363, 2526183)
因此输出矩阵Y应该具有(350363, 350363)
.由于tfidf功能,X非常稀疏,因此很容易适合内存(仅约2GB).然而,在运行一段时间后,乘法会给我一个内存错误(即使内存不满但我想scipy是如此聪明以至于期望内存使用).
我已经尝试过使用dtypes而没有任何成功.我还确保numpy和scipy将他们的BLAS库链接起来 - 虽然这对csr_matrix点功能没有影响,因为它在C中实现.我想可能使用像memmap这样的东西,但我不确定那.
有没有人知道如何最好地接近这个?
尽管X
稀疏,但X * X.T
可能不会注意到它在给定的行对中只需要一个非零公共元素.你正在使用NLP任务,所以我很确定在几乎所有文档中都会出现大量的单词(如前所述 - 它不一定是所有对的一个单词,而是一个(可能是不同的)结果你获得了一个元素矩阵,它有大约122,000,000,000个元素,如果你没有200GB的ram,它看起来不可计算.尝试对单词进行更多的积极过滤以强制稀疏(删除许多常用词)350363^2
X * X.T
通常,您将无法计算大数据的Gram矩阵,除非您强制执行稀疏性X * X.T
,因此大多数向量的对(文档)都具有0"相似性".它可以通过多种方式来实现,最简单的方法是设置一些门槛T
下,你把<a,b>
作为0
和自己计算的点积,并创造所产生的稀疏矩阵当且仅当一个条目<a,b> > T
您可能需要查看random_projection
scikit-learn 中的模块。在约翰逊Lindenstrauss引理说,随机投影矩阵是保证维持成对距离高达一些宽容eta
,这是一个超参数,当你计算出所需的随机投影的数量。
长话短说,SparseRandomProjection
这里看到的scikit-learn类是为您执行此操作的转换器。如果在X上运行它,vec.fit_transform
您应该会看到功能尺寸的相当大的减少。
的公式sklearn.random_projection.johnson_lindenstrauss_min_dim
表明,要保留高达10%的公差,您只需johnson_lindenstrauss_min_dim(350363, .1)
10942个特征。这是一个上限,因此您可以花更少的钱就可以逃脱。即使是1%的公差,也只需要johnson_lindenstrauss_min_dim(350363, .01)
1028192个功能,这仍然比您现在拥有的功能要少得多。
编辑:尝试简单-如果您的数据是dtype ='float64',请尝试使用'float32'。仅此一项就可以节省大量空间,尤其是在您不需要双精度的情况下。
如果问题是您也不能在内存中存储“最终矩阵”,我建议您在HDF5Store中使用数据(如在使用pytables的熊猫中所见)。该链接具有一些不错的入门代码,您可以迭代地计算点乘积的大块并写入磁盘。我最近在一个45GB数据集的项目中广泛使用了此方法,如果您决定采用这种方法,可以提供更多帮助。