拆分RDD进行K折叠验证:pyspark

时间:2016-04-19 02:12:33

标签: python-3.x apache-spark pyspark apache-spark-mllib apache-spark-ml

我有一个数据集,我想在其上应用朴素的贝叶斯。我将使用K-fold技术进行验证。我的数据有两个类,他们订购了,即如果我的数据集有100行,前50个是一个类,接下来50个是第二类。因此,我首先想要改组数据然后随机形成K形折叠。问题是,当我在RDD上尝试randomSplit时,它正在创建不同大小的RDD。我的代码和数据集的示例如下:

documentDF = sqlContext.createDataFrame([
    (0,"This is a cat".lower().split(" "), ),
    (0,"This is a dog".lower().split(" "), ),
    (0,"This is a pig".lower().split(" "), ),
    (0,"This is a mouse".lower().split(" "), ),
    (0,"This is a donkey".lower().split(" "), ),
    (0,"This is a monkey".lower().split(" "), ),
    (0,"This is a horse".lower().split(" "), ),
    (0,"This is a goat".lower().split(" "), ),
    (0,"This is a tiger".lower().split(" "), ),
    (0,"This is a lion".lower().split(" "), ),
    (1,"A mouse and a pig are friends".lower().split(" "), ),
    (1,"A pig and a dog are friends".lower().split(" "), ),
    (1,"A mouse and a cat are friends".lower().split(" "), ),
    (1,"A lion and a tiger are friends".lower().split(" "), ),
    (1,"A lion and a goat are friends".lower().split(" "), ),
    (1,"A monkey and a goat are friends".lower().split(" "), ),
    (1,"A monkey and a donkey are friends".lower().split(" "), ),
    (1,"A horse and a donkey are friends".lower().split(" "), ),
    (1,"A horse and a tiger are friends".lower().split(" "), ),
    (1,"A cat and a dog are friends".lower().split(" "), )
], ["label","text"])

from pyspark.mllib.classification import NaiveBayes, NaiveBayesModel
from pyspark.mllib.linalg import Vectors
from pyspark.ml.feature import CountVectorizer
from pyspark.mllib.regression import LabeledPoint

def mapper_vector(x):
    row = x.text
    return LabeledPoint(x.label,row)

splitSize = [0.2]*5
print("splitSize"+str(splitSize))
print(sum(splitSize))
vect = documentDF.map(lambda x: mapper_vector(x))
splits = vect.randomSplit(splitSize, seed=0)

print("***********SPLITS**************")
for i in range(len(splits)):
    print("split"+str(i)+":"+str(len(splits[i].collect())))

此代码输出:

splitSize[0.2, 0.2, 0.2, 0.2, 0.2]
1.0
***********SPLITS**************
split0:1
split1:5
split2:3
split3:5
split4:6

documentDF有20行,我想从这个数据集中获得5个不同的独有样本,这些样本具有相同的大小。但是,可以看出所有分裂具有不同的大小。我做错了什么?

编辑:根据zero323,我没有做错任何事。然后,如果我想在不使用ML CrossValidator的情况下获得最终结果(如上所述),我需要更改什么?另外,为什么数字不同?如果每个分割具有相同的权重,那么它们是否应该具有相同的行数?还有,还有其他方法来随机化数据吗?

1 个答案:

答案 0 :(得分:4)

你没有做错任何事。 randomSplit根本不提供有关数据分发的硬性保证。它正在使用BernoulliCellSampler(请参阅How does Sparks RDD.randomSplit actually split the RDD),精确分数可能因运行而异。这是一种正常行为,应该完全可以接受任何实际大小的数据集,其中差异应该在统计上无关紧要。

一方面,不是Spark ML已经提供了CrossValidator,可以与ML管道一起使用(例如,参见How to cross validate RandomForest model?)。