我使用PySpark分发机器学习操作,其中包括以下步骤:
基于列划分数据(~100列,除以一列具有50个唯一值,因此需要在此列上分发流程) 我正在使用sc.parallelize方法
在每个数据上,通过管道初始化分类器,并使用spark_sklearn中的GridSearchCV来并行化此操作。由于这需要它自己的sparkcontext,我在小函数内为此创建另一个spark上下文对象。
示例代码在
下面sc = SparkContext('local', appName="abc")
def sample():
## some code
## read data and extract text features using pipeline
## use grid search CV from spark_sklearn package -- this requires its own sparkcontext
sc1 = SparkContext('local', appName="xyz")
grid_search = sp_GridSearchCV(sc1, clf, parameters, n_jobs=-1, cv=cv, verbose=1, scoring='f1_macro')
grid_search.fit(X, y)
sc1.stop()
return grid_search
results = sc.parallelize(labels).map(sample).collect()
sc.stop()
我想知道这是否是正确的做法,如果不是最好的方式。我认为这个过程肯定会得到改善。例如,每次初始化sparkobject会增加额外的开销,可以最小化
任何指示都将不胜感激。谢谢!
答案 0 :(得分:2)
这不是Spark的工作方式。
创建SparkContext时,您正在设置群集,从YARN获取有关群集的所有信息。多少资源和东西。
SparkContext负责处理此资源,保存RDD,DataFrames,DataSet的元数据。它将在你的工人之间分配。您可以在下面看到:
您可以在this链接中查看有关它的更多详细信息。
但为什么这样做不会起作用,为什么如果它起作用你就会失去资源。
为什么它不起作用
在工作方调用spark上下文,您将创建一个新的“驱动程序”,根据spark架构,您可以在主节点中拥有驱动程序。
为什么它不会提高绩效
如果您使用动态分配来运行,那么Spark总是会尝试使用群集的所有资源。由于Catalysis Optimizer,这将创建一个执行计划,在大多数情况下比我们以前手动构建的计划更好。如果你能够在工作者端创建SparkContext,那么你只会为驱动程序丢失执行程序,从而丢失资源。
答案 1 :(得分:0)
我喜欢你的想法,但在你拥有Spark Context之后,把它想象成一个懒惰的单一机器,一次完成一项工作。通常的单机和普通单机之间的唯一区别火花环境单机是很棒的(ram /处理/协调/弹性)。
使用包含ParamGrid的函数发送地图几乎被认为是个坏主意。但上面的逻辑将帮助你:)