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)