Python 在PySpark中对数据帧的选定部分训练机器学习模型

Python 在PySpark中对数据帧的选定部分训练机器学习模型,python,apache-spark,machine-learning,dataframe,pyspark,Python,Apache Spark,Machine Learning,Dataframe,Pyspark,我需要在数据集上运行一个随机林。数据集位于如下组织的数据框中: training_set_all = sc.parallelize([ ['u1', 1, 0.9, 0.5, 0.0], ['u1', 0, 0.5, 0.1, 0.0], ['u2', 1, 0.3, 0.3, 0.8], ['u3', 1, 0.2, 0.2, 0.6], ['u2', 0, 0.0, 0.1, 0.4], ... ]).toDF(('status', 'user

我需要在数据集上运行一个随机林。数据集位于如下组织的数据框中:

training_set_all = sc.parallelize([
    ['u1', 1, 0.9, 0.5, 0.0],
    ['u1', 0, 0.5, 0.1, 0.0],
    ['u2', 1, 0.3, 0.3, 0.8],
    ['u3', 1, 0.2, 0.2, 0.6],
    ['u2', 0, 0.0, 0.1, 0.4],
    ...
]).toDF(('status', 'user', 'product', 'f1', 'f2', 'f3'))
基本上有一个
用户
,类-目标变量-(1或0),然后是三个数字浮点特性。实际上,每个用户都有自己的培训集,并且都包含在单个数据帧中

我需要逐个用户地训练模式,以便从该
training\u set\u all
中选择与用户u1相关的部分,训练模型,然后转到u2,对所有用户执行相同的操作,依此类推

我可以通过在用户上运行for循环,过滤属于用户的行的训练集,然后在这些行上训练来解决这个问题。但我很乐意避免for循环,因为它们在Spark编程模型中似乎不是一个好的元素

需要一个包含(类、特征)的标签点,并且需要5个参数,如树的数量

因此,我尝试了一种map reduceByKey方法,如中所示(请记住,我需要传递到
LabeledPoint

这显然失败了,因为我没有向分类器提供所有必需的参数

因此,为了通过考试,我尝试了以下方法:

def train():
    return RandomForest.trainClassifier(data, 2, {}, 3)

stuff = training_set_all \
    .map(lambda row: (row[0], LabeledPoint(row[1], [row[3], row[4], row[5]]))) \
    .reduceByKey(train)
这会出错

异常:您似乎正在尝试广播RDD或 从操作或转换中引用RDD。RDD转换 操作只能由驱动程序调用,而不能在其他 转变;例如,rdd1.map(lambda x:rdd2.values.count()* x) 无效,因为值转换和计数操作 无法在rdd1.map转换内部执行。更多 有关详细信息,请参阅SPARK-5063

这是对问题的直言不讳


我如何在培训集中与用户相关的部分选择性地应用模型,而不使用for循环?

我不确定我是否理解您在这里要做什么Martina。你能解释一下你认为你的代码应该做什么吗?代码应该在用户u1上训练模型,然后是u2,依此类推,所以每次使用数据帧中属于一个用户的行。你可以在整个数据帧上应用分类器。尽管如此,这里似乎存在一些严重的编程问题。对不起,这一点不是很清楚。我甚至无法想象用户如何拥有自己的训练集和随机森林。@eliasah我看不到。如果大数字足以证明RDD的合理性,那么在用户上循环可能是最好的选择。如果不是,那么Scikit+Joblib可能是一个更好的选择。我不确定我是否理解你在这里试图做什么,Martina。你能解释一下你认为你的代码应该做什么吗?代码应该在用户u1上训练模型,然后是u2,依此类推,所以每次使用数据帧中属于一个用户的行。你可以在整个数据帧上应用分类器。尽管如此,这里似乎存在一些严重的编程问题。对不起,这一点不是很清楚。我甚至无法想象用户如何拥有自己的训练集和随机森林。@eliasah我看不到。如果大数字足以证明RDD的合理性,那么在用户上循环可能是最好的选择。如果不是,那么Scikit+Joblib可能是更好的选择。
def train():
    return RandomForest.trainClassifier(data, 2, {}, 3)

stuff = training_set_all \
    .map(lambda row: (row[0], LabeledPoint(row[1], [row[3], row[4], row[5]]))) \
    .reduceByKey(train)