sklearn.naive_bayes.BernoulliNB 数据大小的实际限制
Practical limits to data size for sklearn.naive_bayes.BernoulliNB
我手头有一个机器学习任务,我想尝试使用伯努利朴素贝叶斯。
由于我需要很快产生一些有意义的结果,我想使用 Python,更具体地说,sklearn
。数据是 "simple" 但我有很多,所以我试图找出正确的方法,让我可以编写一个基于 "quick and dirty" BernoulliNB 的原型,我可以将其应用于尽可能多的数据尽可能。
详情如下:
- 特征是二元的(
True
/ False
)
- 类 也是二进制的(将其视为垃圾邮件过滤器)
- 一个特征向量最大长度为30000。它可能能够通过特征选择显着减少这一点,但现在让我们假设它这么长
- 我有多达 200,000 个数据点可用于
.fit()
训练我的模型
我还没有对实际数据进行预处理,所以我没有实际的特征矩阵和 class 用于训练的向量,但是在进行预处理时,我想弄清楚有多大我可以处理的数据块。我基本上想做的是重写以下代码块,以便它可以使用 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) "best practices" 方法是什么?
b) 我需要加入 PyTables
吗?
c) sklearn
可以使用 PyTables
对象吗?
您需要弄清楚这些数据中有多少可以放入内存。
如果你的矩阵是稀疏的,你不需要把它分成块。不过看起来不像你的。
正在分块处理数据
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
是一个为您提供数据块的迭代器。
现在您需要确保这些块适合内存。
它有多大?
您可以使用 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
A np.bool
仍然是 1 个字节(8 位)。
您也可以手动计算这些数字:数组大约 nSamples * nFeatures * 1 / 10 ** 6
MB。
其余取决于您可用的 RAM。整个 X
数组为 6GB,但您需要考虑 scikit-learn 所需的 RAM。
"That should not be a lot" 是我可以自信地说的所有内容 ;).
不要忘记将 binarize=None
传递给 BernoulliNB
构造函数以避免复制 X 数组(您的数据已经二值化)。
PyTables
你需要PyTables
吗?不,但如果您愿意,您仍然可以使用它。
sklearn
适用于 numpy 数组,但 PyTables
也适用,因此您可以使用它向 partial_fit
循环提供数据块。
希望这对您有所帮助。
我手头有一个机器学习任务,我想尝试使用伯努利朴素贝叶斯。
由于我需要很快产生一些有意义的结果,我想使用 Python,更具体地说,sklearn
。数据是 "simple" 但我有很多,所以我试图找出正确的方法,让我可以编写一个基于 "quick and dirty" BernoulliNB 的原型,我可以将其应用于尽可能多的数据尽可能。
详情如下:
- 特征是二元的(
True
/False
) - 类 也是二进制的(将其视为垃圾邮件过滤器)
- 一个特征向量最大长度为30000。它可能能够通过特征选择显着减少这一点,但现在让我们假设它这么长
- 我有多达 200,000 个数据点可用于
.fit()
训练我的模型
我还没有对实际数据进行预处理,所以我没有实际的特征矩阵和 class 用于训练的向量,但是在进行预处理时,我想弄清楚有多大我可以处理的数据块。我基本上想做的是重写以下代码块,以便它可以使用 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) "best practices" 方法是什么?
b) 我需要加入 PyTables
吗?
c) sklearn
可以使用 PyTables
对象吗?
您需要弄清楚这些数据中有多少可以放入内存。
如果你的矩阵是稀疏的,你不需要把它分成块。不过看起来不像你的。
正在分块处理数据
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
是一个为您提供数据块的迭代器。
现在您需要确保这些块适合内存。
它有多大?
您可以使用 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
A np.bool
仍然是 1 个字节(8 位)。
您也可以手动计算这些数字:数组大约 nSamples * nFeatures * 1 / 10 ** 6
MB。
其余取决于您可用的 RAM。整个 X
数组为 6GB,但您需要考虑 scikit-learn 所需的 RAM。
"That should not be a lot" 是我可以自信地说的所有内容 ;).
不要忘记将 binarize=None
传递给 BernoulliNB
构造函数以避免复制 X 数组(您的数据已经二值化)。
PyTables
你需要PyTables
吗?不,但如果您愿意,您仍然可以使用它。
sklearn
适用于 numpy 数组,但 PyTables
也适用,因此您可以使用它向 partial_fit
循环提供数据块。
希望这对您有所帮助。