在用于填充稀疏矩阵的Eigen文档中,建议使用triplet filling method,因为它比对涉及二进制搜索的coeffRef
进行调用要有效得多。
但是,对于填充SparseVectors
,并没有关于如何有效地进行填充的明确建议。
此SO answer中建议的方法使用coeffRef
,这意味着对每个插入都执行二进制搜索。
是否有推荐的有效方法来构建稀疏向量?我是否应该尝试创建一行SparseMatrix
,然后将其存储为SparseVector
?
我的用例是读取LibSVM文件,其中可以有数百万个非常稀疏的功能和数十亿个数据点。我目前将它们表示为std::vector<Eigen::SparseVector>
。也许我应该只改用SparseMatrix
?
编辑:我尝试过的一件事是:
// for every data point in a batch do the following:
Eigen::SparseMatrix<float> features(1, num_features);
// copy the data over
typedef Eigen::Triplet<float> T;
std::vector<T> tripletList;
for (int j = 0; j < num_batch_instances; ++j) {
for (size_t i = batch.offset[j]; i < batch.offset[j + 1]; ++i) {
uint32_t index = batch.index[i];
float fvalue = batch.value;
if (index < num_features) {
tripletList.emplace_back(T(0, index, fvalue));
}
}
features.setFromTriplets(tripletList.begin(), tripletList.end());
samples->emplace_back(Eigen::SparseVector<float>(features));
}
这将使用三元组列表方法创建一个SparseMatrix
,然后从该对象创建一个SparseVector
。在我的具有〜1.4M功能和极高稀疏性的实验中,这比使用SparseVector
和coeffRef
慢了两个数量级,而我绝对没想到。