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

Python sklearn.naive_bayes.BernoulliNB数据大小的实际限制,python,scikit-learn,sparse-matrix,pytables,naivebayes,Python,Scikit Learn,Sparse Matrix,Pytables,Naivebayes,我手头有一个机器学习任务,我想尝试一下Bernoulli Naive Bayes。因为我需要很快产生一些有意义的结果,所以我想使用Python,更具体地说,sklearn。数据是“简单”的,但我有很多数据,因此我试图找出正确的方法,使我能够编写一个“快速且肮脏”的基于伯努林的原型,我可以应用于尽可能多的数据 详情如下: 功能是二进制的(True/False) 类也是二进制的(将其视为垃圾邮件过滤器) 特征向量的长度最多为30000。通过功能选择,它可能可以大大减少这一点,但现在让我们假设它有这么

我手头有一个机器学习任务,我想尝试一下Bernoulli Naive Bayes。
因为我需要很快产生一些有意义的结果,所以我想使用Python,更具体地说,
sklearn
。数据是“简单”的,但我有很多数据,因此我试图找出正确的方法,使我能够编写一个“快速且肮脏”的基于伯努林的原型,我可以应用于尽可能多的数据

详情如下:

  • 功能是二进制的(
    True
    /
    False
  • 类也是二进制的(将其视为垃圾邮件过滤器)
  • 特征向量的长度最多为30000。通过功能选择,它可能可以大大减少这一点,但现在让我们假设它有这么长
  • 我有多达200000个数据点可用于
    .fit()
    训练我的模型
  • 我还没有对实际数据进行预处理,所以我没有用于训练的实际特征矩阵和类向量,但在进行预处理时,我想知道我可以处理多大的数据块。我实际上是想重写下面的代码块,以便它可以使用
    nSamples
    nFeatures
    的指定值:

    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
    对象?

    您需要计算出这些数据中有多少可以存储在内存中

    如果你的矩阵是稀疏的,你不需要把它分成块。但它看起来不像你的

    分块处理数据
    BernoulliNB
    和许多scikit学习分类器都有一个
    部分拟合
    方法,可以实现这一点(请参阅):

    其中,
    iter\u batches
    是一个迭代器,它为您提供数据块。
    现在,您需要确保这些块适合内存

    它有多大? 您可以使用
    nbytes
    属性计算
    np.array
    的大小:

    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数组(您的数据已经进行了二值化)

    皮Tables 是否需要
    PyTables
    ?不,但是如果你愿意,你仍然可以用它。
    sklearn
    适用于numpy数组,但
    PyTables
    也适用于numpy数组,因此您可以使用它向
    partial_-fit
    循环提供数据块


    希望这能有所帮助。

    如果你对非
    sklearn
    解决方案持开放态度,我最近遇到了这个问题;我不完全理解算法,但它允许您使用非常小的内存处理非常大的数据集(据我所知,这就是您提到的大型数据集的问题)。看起来这个实现一次加载一行,并在此过程中更新一些参数:我在post响应的ML任务中尝试了这个方法,并获得了相当不错的(.77)AUC分数。应该很容易适应
    X = np.random.randint(2, size=(nSamples,nFeatures)).astype(np.int8)
    X.nbytes / 10 ** 6
    Out[12]: 60.0