我目前有2列的Spark数据框: 1)一列,其中每一行包含一个预测特征向量 2)包含要预测的值的列。
为了辨别在以后的模型中使用的最具预测性的功能,我使用了this article概述的P值向后消除功能。下面是我的代码:
num_vars = scoresDf.select("filtered_features").take(1)[0][0].__len__()
for i in range(0, num_vars):
model = LinearRegression(featuresCol="filtered_features", labelCol="averageScore")
model = model.fit(scoresDf)
p_values = model.summary.pValues
max_p = np.max(p_values)
if max_p > 0.05:
max_index = p_values.index(max_p)
drop_max_index_udf = udf(lambda elem, drop_index, var_count:
Vectors.dense([elem[j] for j in range(var_count) if j not in [drop_index]]), VectorUDT())
scoresDfs = scoresDf.withColumn("filtered_features", drop_max_index_udf(scoresDf["filtered_features"],
lit(max_index), lit(num_vars)))
num_vars = scoresDf.select("filtered_features").take(1)[0][0].__len__()
代码可以运行,但是唯一的问题是每次迭代都比上一次花费更长的时间。根据对this question的回答,似乎代码每次都在重新评估所有先前的迭代。
理想情况下,我想将整个逻辑馈入某种流水线结构中,这些结构会全部懒散地存储它们,然后在被调用时按顺序执行而不会重复,但是我不确定这是否有可能,因为Spark都没有估计器/转换器函数似乎适合此用例。
任何指导将不胜感激,谢谢!
答案 0 :(得分:0)
您正在循环内重复创建模型。这是一个耗时的过程,每个训练数据集和一组参数需要完成一次。尝试以下-
num_vars = scoresDf.select("filtered_features").take(1)[0][0].__len__()
modelAlgo = LinearRegression(featuresCol="filtered_features", labelCol="averageScore")
model = modelAlgo.fit(scoresDf)
for i in range(0, num_vars):
p_values = model.summary.pValues
max_p = np.max(p_values)
if max_p > 0.05:
max_index = p_values.index(max_p)
drop_max_index_udf = udf(lambda elem, drop_index, var_count:
Vectors.dense([elem[j] for j in range(var_count) if j not in [drop_index]]), VectorUDT())
scoresDfs = scoresDf.withColumn("filtered_features", drop_max_index_udf(scoresDf["filtered_features"],
lit(max_index), lit(num_vars)))
num_vars = scoresDf.select("filtered_features").take(1)[0][0].__len__()
一旦对模型感到满意,就可以保存它。当您需要评估数据时,只需阅读此模型并进行预测即可。