【问题标题】:Spark Data Frame Random SplittingSpark 数据帧随机拆分
【发布时间】:2017-03-10 16:34:15
【问题描述】:

我有一个 spark 数据框,我想以 0.60、0.20、0.20 的比例将其分为训练、验证和测试。

我使用了以下代码:

def data_split(x):
    global data_map_var
    d_map = data_map_var.value
    data_row = x.asDict()
    import random
    rand = random.uniform(0.0,1.0)
    ret_list = ()
    if rand <= 0.6:
        ret_list = (data_row['TRANS'] , d_map[data_row['ITEM']] , data_row['Ratings'] , 'train')
    elif rand <=0.8:
        ret_list = (data_row['TRANS'] , d_map[data_row['ITEM']] , data_row['Ratings'] , 'test')
    else:
        ret_list = (data_row['TRANS'] , d_map[data_row['ITEM']] , data_row['Ratings'] , 'validation')
    return ret_list
​
​
split_sdf = ratings_sdf.map(data_split)
train_sdf = split_sdf.filter(lambda x : x[-1] == 'train').map(lambda x :(x[0],x[1],x[2]))
test_sdf = split_sdf.filter(lambda x : x[-1] == 'test').map(lambda x :(x[0],x[1],x[2]))
validation_sdf = split_sdf.filter(lambda x : x[-1] == 'validation').map(lambda x :(x[0],x[1],x[2]))
​
print "Total Records in Original Ratings RDD is {}".format(split_sdf.count())
​
print "Total Records in training data RDD is {}".format(train_sdf.count())
​
print "Total Records in validation data RDD is {}".format(validation_sdf.count())
​
print "Total Records in test data RDD is {}".format(test_sdf.count())
​
​
#help(ratings_sdf)
Total Records in Original Ratings RDD is 300001
Total Records in training data RDD is 180321
Total Records in validation data RDD is 59763
Total Records in test data RDD is 59837

我的原始数据框是 ratings_sdf,我用它来传递一个映射器函数来进行拆分。

如果您检查训练、验证和测试的总和,则不等于拆分(原始评级)计数。这些数字在每次运行代码时都会发生变化。

剩余的记录去哪了,为什么总和不相等?

【问题讨论】:

    标签: python apache-spark pyspark


    【解决方案1】:

    TL;DR如果你想拆分DataFrame,请使用randomSplit method

    ratings_sdf.randomSplit([0.6, 0.2, 0.2])
    

    您的代码在多个层面上都是错误的,但有两个基本问题使其无法修复:

    • Spark 转换可以被评估任意次数,并且您使用的函数应该是引用透明且无副作用的。您的代码多次评估 split_sdf,并且您使用有状态的 RNG data_split,因此每次结果都不同。

      这会导致您描述的每个孩子看到父 RDD 的不同状态的行为。

    • 你没有正确初始化 RNG,因此你得到的随机值不是独立的。

    【讨论】:

    • 我只有 11 个值,我确实在 [0.6, 0.3, 0.1] 上进行了拆分,但将其划分为 [6,5,0] 或 [8,3,0] 我没有需要零,因为 11 仍然可以划分为 [6,3,2] 有没有办法检查在训练、测试和有效拆分后不为零
    • @vipin 除了在每个项目上调用count 吗?并不真地。但是如果你有 11 条记录,无论如何使用 Spark 没有多大意义,而且如果你想要特定的分布,你总是可以拆分本地数据并在以后并行化它。在“真实”大小的数据上,这通常不是问题 - given how randomSplit works 你不太可能得到像这样相对较大且平衡的分数的空拆分..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 2017-04-17
    • 2021-04-08
    相关资源
    最近更新 更多