sklearn.naive_bayes.BernoulliNB的数据大小的实际限制

时间:2015-08-31 15:33:14

标签: python scikit-learn sparse-matrix pytables naivebayes

我手边有机器学习任务,我想尝试一下Bernoulli Naive Bayes。由于我需要很快产生一些有意义的结果,我想使用Python,更具体地说, sklearn 即可。数据简单"但我有很多,所以我试图找出正确的方法,让我写一个快速而肮脏的#34;基于BernoulliNB的原型,我可以应用尽可能多的数据。

详情如下:

  1. 功能为二进制( True / False
  2. 类也是二进制的(将其视为垃圾邮件过滤器)
  3. 特征向量的长度最多为30,000。它可能能够通过功能选择大大减少这一点,但是现在让我们假设它很长
  4. 我可以使用多达200,000个数据点来.fit()训练我的模型
  5. 我还没有对实际数据进行预处理,所以我没有用于训练的实际特征矩阵和类向量,但是当我在进行预处理时,我想弄清楚有多大的数据块我可以处理。我基本上要做的是重写以下代码块,以便它可以使用nSamplesnFeatures的指定值:

    from sklearn.naive_bayes import BernoulliNB
    import numpy as np
    
    nSamples = 200000
    nFeatures =  30000
    
    # Don't care about actual values yet, just data size
    X = np.random.randint( 2, size = ( nSamples, nFeatures ) )
    Y = np.random.randint( 2, size = ( nSamples, ) )
    
    clf = BernoulliNB()
    clf.fit( X, Y )
    
    res = clf.predict_proba( X[2] )
    

    a)什么是"最佳做法"接近这个?
    b)我需要合并PyTables吗? c) sklearn可以使用PyTables个对象吗?

1 个答案:

答案 0 :(得分:2)

您需要弄清楚这些数据中有多少可以适合内存。

如果您的矩阵稀疏,则不需要将其分块。但它看起来并不像你的那样。

以块的形式处理数据

BernoulliNB和许多scikit-learn分类器都有一个partial_fit方法就可以做到这一点(参见this more complete example):

clf = BernoulliNB()
   all_classes = [0, 1]
   for X_train, y_train in iter_batches:
       clf.partial_fit(X_train, y_train, classes=all_classes)

其中iter_batches是一个为您提供数据块的迭代器 现在你需要确保这些块适合内存。

它有多大?

您可以使用np.array属性

来计算nbytes的大小
from sklearn.naive_bayes import BernoulliNB
import numpy as np

nSamples = 2000
nFeatures =  30000
X = np.random.randint(2, size=(nSamples,nFeatures))
X.nbytes / 10 ** 6
Out[11]: 480.0

所以这里的X数组内存大约为480MB 请注意,如果您有布尔变量并在加载数据时正确指定类型,则可以大大减少占用空间:

X = np.random.randint(2, size=(nSamples,nFeatures)).astype(np.int8)
X.nbytes / 10 ** 6
Out[12]: 60.0

虽然np.bool仍然是1字节(8位)。

您也可以手动计算这些数字:数组大约为nSamples * nFeatures * 1 / 10 ** 6 MB。

其余的取决于您可用的RAM。整个X数组为6GB,但您需要考虑scikit-learn需要的RAM。 "那应该不是很多"我有信心可以说;) 不要忘记将binarize=None传递给BernoulliNB构造函数,以避免复制您的X数组(您的数据已经二值化)。

PyTables

您需要PyTables吗?不,但如果您愿意,仍然可以使用它。 sklearn适用于numpy数组,PyTables也是如此,因此您可以使用它将数据块提供给partial_fit循环。

希望这有帮助。