使用identific在python中获取对象

2024-05-19 00:40:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一组python函数,它们使用不同的算法执行类似的任务(寻找局部极小值)。它们的工作方式是一个函数(扫描器)扫描一个搜索空间以选择该空间中的点/坐标。然后它使用第二个函数(记分器)来评估模型在这些点/坐标处的值。扫描器会看到记分器返回的值类型,并相应地选择下一个点。这一直持续到用户定义的迭代次数

现在,我为这组优化程序添加了一个新函数,使其更全面。这是hyperopt库中的fmin函数。我在使用fmin函数时面临的问题是,它会对scoring函数进行pickle处理。我使用的评分函数是一个部分填充函数,已经填充了四个输入。这四个参数是traintestvalidationevaluator。前三个是spark数据帧,不能被pickle

obj_calc = partial(_obj_calc, train=train, test=test, validation=validation, evaluator)
fmin(obj_calc, space, trials=trials, algo=tpe.suggest, max_evals=num_iter, rstate=rstate)

这里fmin是scanner函数,obj_calc是记分器

_obj_calc函数如下所示

def _obj_calc(train, test, validation, evaluator, *args):
    model = XGBoostClassifier()
    params = {param_names[i]:args[i] for i in range(len(args))}
    model.setParams(**params)
    model.fit(train)
    train_score = evaluator.evaluate(model.transform(train))
    test_score = evaluator.evaluate(model.transform(test))
    validation_score = evaluator.evaluate(model.transform(validation))
    return validation_score

直到现在我还能够使用部分函数,因为我使用的其他优化器都没有尝试pickleobj_calc。但是在混合中加入fmin意味着我需要改变我的方法

因此,我不再将spark数据帧部分填充到函数中,而是传递它们的对象id并使用该id获取对象

obj_calc = partial(_obj_calc, train_id=train_id, test_id=test_id, validation_id=validation_id, evaluator_id=evaluator_id)
fmin(obj_calc, space, trials=trials, algo=tpe.suggest, max_evals=num_iter, rstate=rstate)


def get_object_from_id(object_id):
    import ctypes
    return ctypes.cast(object_id, ctypes.py_object).value


def _obj_calc(train_id, test_id, validation_id, evaluator_id, *args):
    model = XGBoostClassifier()
    params = {param_names[i]:args[i] for i in range(len(args))}
    train = get_object_from_id(train_id) # fetch object from id
    test = get_object_from_id(test_id)
    validation = get_object_from_id(validation_id)
    evaluator = get_object_from_id(evaluator_id)
    model.setParams(**params)
    model.fit(train)
    train_score = evaluator.evaluate(model.transform(train))
    test_score = evaluator.evaluate(model.transform(test))
    validation_score = evaluator.evaluate(model.transform(validation))
    return validation_score

但是在阅读了this post之后,按对象的id获取对象听起来不是个好主意

有什么更好的方法来解决这个问题


Tags: 函数testidobjmodelobjectevaluatorargs

热门问题