【发布时间】:2021-04-11 14:33:10
【问题描述】:
我想对机器学习算法进行交叉验证,但想检查每次迭代的模型估计。你知道 pyspark 上是否有可以让我创建 k-fold 数据集的功能吗?
我需要该 k-fold 数据集来运行每个算法并输出变量估计值。例如,如果是 5-fold CV,我需要准备好 5 个数据集来运行算法。
【问题讨论】:
标签: apache-spark machine-learning pyspark apache-spark-ml
我想对机器学习算法进行交叉验证,但想检查每次迭代的模型估计。你知道 pyspark 上是否有可以让我创建 k-fold 数据集的功能吗?
我需要该 k-fold 数据集来运行每个算法并输出变量估计值。例如,如果是 5-fold CV,我需要准备好 5 个数据集来运行算法。
【问题讨论】:
标签: apache-spark machine-learning pyspark apache-spark-ml
如果您只需要拟合模型并且使用 Spark ML,则可以使用 CrossValidator 并将 collectSubModels 设置为 true。例如:
cv = (CrossValidator()
.setEstimator(<your_estimator>)
.setEstimatorParamMaps(<your_param_maps>)
.setEvaluator(<your_evaluator>)
.setCollectSubModels(True))
cv_model = cv.fit(dataset)
models = cv_model.subModels
如果您真的想自己访问数据集,那么上述方法将行不通。您可以自己编写一个函数,在您的数据集上循环 n_folds 次,并根据随机数选择该折叠的数据。下面是一个示例:
import uuid
from pyspark.sql.functions import rand
def create_folds(df, n_folds, seed):
h = 1.0 / n_folds
rand_column_name = f"{uuid.uuid1()}_rand"
df = df.select("*", rand(seed).alias(rand_column_name)
result = []
for k in range(n_folds):
lb = k * h
up = (k + 1) * h
condition = (df[rand_column_name] >= lb) & (df[rand_column_name] < ub)
train_df = df.filter(~condition).drop(rand_column_name)
validation_df = df.filter(condition).drop(rand_column_name)
result.append((train_df, validation_df))
return result
datasets = create_folds(df, 5, 10)
# Accessing the first fold
train_df1 = datasets[0][0]
validation_df1 = datasets[0][1]
请注意,在上面的示例中,您获得的不是 5 个数据集,而是 10 个数据集。这是因为对于每一折,我们都在创建一个训练和验证数据集。
我的一位前同事实际上写了一个nice blog post,关于如何使用上述方法制作自己的 PySpark CrossValidator 类。
【讨论】: