高斯混合模型:Spark MLlib和scikit-learn之间的区别

20

我正在尝试对数据集样本使用高斯混合模型。 我既使用了MLlib(与pyspark一起),也使用了scikit-learn,结果非常不同,scikit-learn的结果看起来更加真实。

from pyspark.mllib.clustering import GaussianMixture as SparkGaussianMixture
from sklearn.mixture import GaussianMixture
from pyspark.mllib.linalg import Vectors

Scikit-learn:
local = pd.DataFrame([ x.asDict() for x in df.sample(0.0001).collect() ])
model1 = GaussianMixture(n_components=3)
model1.fit([ [x] for x in local['field'].tolist() ])

model1.means_
array([[7.56123598e+00],
   [1.32517410e+07],
   [3.96762639e+04]])

model1.covariances_
array([[[6.65177423e+00]],
   [[1.00000000e-06]],
   [[8.38380897e+10]]])

MLLib:

model2 = SparkGaussianMixture.train(
    sc.createDataFrame(local).rdd.map(lambda x: Vectors.dense(x.field)),
    k=3,
    convergenceTol=1e-4,
    maxIterations=100
)

model2.gaussians
[MultivariateGaussian(mu=DenseVector([28736.5113]), sigma=DenseMatrix(1, 1, [1094083795.0001], 0)),
 MultivariateGaussian(mu=DenseVector([7839059.9208]), sigma=DenseMatrix(1, 1, [38775218707109.83], 0)),
 MultivariateGaussian(mu=DenseVector([43.8723]), sigma=DenseMatrix(1, 1, [608204.4711], 0))]

然而,我有兴趣将整个数据集通过模型运行,但我担心这将需要并行化(因此使用MLlib),以在有限的时间内获得结果。 我是否做错了什么/遗漏了什么?

数据

完整的数据具有极长的尾部,并且如下所示: enter image description here

而数据则明显呈现出接近于一个聚集在scikit-learn附近的正态分布:

enter image description here

我正在使用Spark 2.3.0 (AWS EMR)。

编辑:初始化参数:

local = pd.DataFrame([ x.asDict() for x in df.sample(0.0001).collect() ])
model1 = GaussianMixture(n_components=3, init_params='random')
model1.fit([ [x] for x in local['field'].tolist() ])

model1.means_
array([[2.17611913e+04],
   [8.03184505e+06],
   [7.56871801e+00]])

model1.covariances_
rray([[[1.01835902e+09]],
   [[3.98552130e+13]],
   [[6.95161493e+00]]])

scikit-learn默认使用k-means来初始化权重,这可能是相关的。 - Shaido
@shaido更新了带有随机初始化的scikit-learn的帖子。没有改变任何东西。 - ixaxaar
1
你能发布一份数据集的快照吗?或者先提供一个虚拟数据开始吗? - Gambit1614
1
你有没有统计学上的理由,不能只对数据集进行子采样呢? - Jeff Ellen
1
@MohammedKashif,恐怕我不能这样做,但我可以尝试生成一些类似的数据,让我试试... - ixaxaar
显示剩余6条评论
2个回答

2
这并不是一个Python问题,它更像是一个机器学习/数据验证/数据分割的问题。你必须并行化你的工作,但是如何并行化很重要。你可以研究一些模型中的8位量化和模型并行性,以帮助你在不牺牲数据质量或保真度的情况下及时地在大型数据集上训练模型。
这里有一篇关于量化的博客文章:https://petewarden.com/2016/05/03/how-to-quantize-neural-networks-with-tensorflow/ 这里有一篇关于模型并行性和8位量化的博客文章,来自Tim Dettmers的博客:http://timdettmers.com/2017/04/09/which-gpu-for-deep-learning/

以及相关论文:https://arxiv.org/pdf/1511.04561.pdf

虽然你需要记住的是,根据GPU上的FP操作,你可能不会从这条路线中看到实质性的好处:https://blog.inten.to/hardware-for-deep-learning-part-3-gpu-8906c1644664

希望对你有所帮助,但你的情况可能有所不同。

此外,您可能想了解数据折叠,但我现在无法记住细节或读过的论文。 我会在想起来时记录下来。


1

我真的不知道scikit-learnSpark中使用了哪种类型的EM算法,但我确定如果它们使用SEM(随机期望最大化),它应该比EM收敛得更快。(请看这里)。

然而,始终建议采用多个起始技术以避免鞍点或局部极大值。

我真的不明白你的图表,它们在不同的比例尺上,第二个是第一个的缩放吗?无论如何,我建议你通过BIC(贝叶斯信息准则)选择k的数量,并通过此度量选择组件的数量。


为这种特定情况提供一些代码示例! - cccnrc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接