当前位置: 代码迷 >> python >> 如何解决没有全局变量的pickle的限制?
  详细解决方案

如何解决没有全局变量的pickle的限制?

热度:58   发布时间:2023-06-16 14:14:53.0

我目前有这段代码

def predict(features):
    probabilities = _classifier.predict_proba(features * _weights).ravel()
    label = np.argmax(probabilities)
    margin = 2 * probabilities[label] - np.sum(probabilities)
    return label, margin

def run_estimator(weights, X_train=X_train, y_train=y_train, X_test=X_test, y_test=y_test, optimization=True):
    classifier = get_classifier(weights, X_train=X_train, y_train=y_train)

    global _classifier
    global _weights 
    _classifier = classifier
    _weights = weights

    with Pool(processes=8) as pool:
        labels, margins = zip(*pool.imap(predict, X_test))

我想传递classifierweights实例以直接predict方法,而无需全局变量,并且创建一个大的可迭代传递给imap 如何以最干净的方式实现这一目标?

注意:在run_estimator方法内创建函数将不起作用,因为传递给imap的可调用对象应该是可选取的,只有在根级别声明的函数才可以。

也许就是这样,为每对实例_classifier_weights定义一个局部函数predictor

def predict(features,_classifier,_weights):
    probabilities = _classifier.predict_proba(features * _weights).ravel()
    label = np.argmax(probabilities)
    margin = 2 * probabilities[label] - np.sum(probabilities)
    return label, margin

from functools import partial

def run_estimator(weights,
                  X_train=X_train,
                  y_train=y_train,
                  X_test=X_test,
                  y_test=y_test,
                  optimization=True,
                  partial = partial
                  predict = predict):

    classifier = get_classifier(weights, 
                                X_train=X_train,
                                y_train=y_train)

    predictor = partial(predict,
                        _classifier = classifier,
                        _weights = weights)

    with Pool(processes=8) as pool:
        labels, margins = zip(*pool.imap(predictor, X_test))

编辑

通过简化示例进行测试,以下解决方案比前面的解决方案节省了22%的时间:

def predict(features,_classifier=None,_weights=None):
    probabilities = _classifier.predict_proba(features * _weights).ravel()
    label = np.argmax(probabilities)
    margin = 2 * probabilities[label] - np.sum(probabilities)
    return label, margin

def run_estimator(weights,
                  X_train=X_train,
                  y_train=y_train,
                  X_test=X_test,
                  y_test=y_test,
                  optimization=True,
                  predict = predict):

    classifier = get_classifier(weights, 
                                X_train=X_train,
                                y_train=y_train)

    predict.func_defaults = (classifier, weights)

    with Pool(processes=8) as pool:
        labels, margins = zip(*pool.imap(predict, X_test))

这项工作不会:

def predict(fcw):
    features, classifier, weights = fcw
    probabilities = classifier.predict_proba(features * weights).ravel()
    label = np.argmax(probabilities)
    margin = 2 * probabilities[label] - np.sum(probabilities)
    return label, margin

def run_estimator(weights, X_train=X_train, y_train=y_train, X_test=X_test, y_test=y_test, optimization=True):
    classifier = get_classifier(weights, X_train=X_train, y_train=y_train)

    classifier = classifier
    weights = weights

    wrapped_predict = lambda x: predict(x, classifier, weights)

    with Pool(processes=8) as pool:
        labels, margins = zip(*pool.imap(wrapped_predict, (X_test, classifier, weights)))