如何在没有全局变量的情况下解决pickle的限制?

时间:2014-03-09 18:48:10

标签: python multithreading pickle

我目前有这段代码

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的可调用函数应该是可选的,并且只有在根级别声明的函数才是。

2 个答案:

答案 0 :(得分:2)

也许是这样,为每个实例predictor_classifier定义部分函数_weights

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))

答案 1 :(得分:1)

这不会起作用:

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)))