【问题标题】:ScikitLearn model giving 'LocalOutlierFactor' object has no attribute 'predict' Error给出“局部异常因子”对象的 Scikit Learn 模型没有属性“预测”错误
【发布时间】:2018-10-05 10:22:11
【问题描述】:

我是机器学习领域的新手,我已经使用 ScikitLearn 库构建和训练了一个机器学习模型。它在 Jupyter 笔记本中运行良好,但是当我将此模型部署到 Google Cloud ML 并尝试使用 Python 提供服务时脚本,它会引发错误。

这是我的模型代码中的一个 sn-p:

更新:

from sklearn.metrics import classification_report, accuracy_score
from sklearn.ensemble import IsolationForest
from sklearn.neighbors import LocalOutlierFactor

# define a random state
state = 1

classifiers = {
    "Isolation Forest": IsolationForest(max_samples=len(X),
                                       contamination=outlier_fraction,
                                       random_state=state),
    # "Local Outlier Factor": LocalOutlierFactor(
    # n_neighbors = 20,
    # contamination = outlier_fraction)
}

import pickle
# fit the model
n_outliers = len(Fraud)

for i, (clf_name, clf) in enumerate(classifiers.items()):

    # fit te data and tag outliers
    if clf_name == "Local Outlier Factor":
        y_pred = clf.fit_predict(X)
        print("LOF executed")
        scores_pred = clf.negative_outlier_factor_
        # Export the classifier to a file
        with open('model.pkl', 'wb') as model_file:
            pickle.dump(clf, model_file)
    else:
        clf.fit(X)
        scores_pred = clf.decision_function(X)
        y_pred = clf.predict(X)
        print("IF executed")
        # Export the classifier to a file
        with open('model.pkl', 'wb') as model_file:
            pickle.dump(clf, model_file)
    # Reshape the prediction values to 0 for valid and 1 for fraudulent
    y_pred[y_pred == 1] = 0
    y_pred[y_pred == -1] = 1

    n_errors = (y_pred != Y).sum()

# run classification metrics 
print('{}:{}'.format(clf_name, n_errors))
print(accuracy_score(Y, y_pred ))
print(classification_report(Y, y_pred ))

这是 Jupyter Notebook 中的输出:

隔离森林:7

0.93

               precision    recall  f1-score   support


         0       0.97      0.96      0.96        94
         1       0.43      0.50      0.46         6

  avg / total    0.94      0.93      0.93       100

我已将此模型部署到 Google Cloud ML-Engine,然后尝试使用以下 python 脚本提供它:

import os
from googleapiclient import discovery
from oauth2client.service_account import ServiceAccountCredentials
credentials = ServiceAccountCredentials.from_json_keyfile_name('Machine Learning 001-dafe42dfb46f.json')

PROJECT_ID = "machine-learning-001-201312"
VERSION_NAME = "v1"
MODEL_NAME = "mlfd"
service = discovery.build('ml', 'v1', credentials=credentials)
name = 'projects/{}/models/{}'.format(PROJECT_ID, MODEL_NAME)
name += '/versions/{}'.format(VERSION_NAME)

data = [[265580, 7, 68728, 8.36, 4.76, 84.12, 79.36, 3346, 1, 11.99, 1.14,655012, 0.65, 258374, 0, 84.12] ]

response = service.projects().predict(
    name=name,
    body={'instances': data}
).execute()

if 'error' in response:
  print (response['error'])
else:
  online_results = response['predictions']
  print(online_results)

这是该脚本的输出:

预测失败:sklearn 预测期间出现异常:“LocalOutlierFactor”对象没有“预测”属性

【问题讨论】:

  • 你上面显示的python脚本,不要在任何地方使用LocalOutlierFactor。您确定在 Google 上使用的是相同的脚本吗?
  • 为什么要更改代码?只需在 google ml 上发布内容即可。
  • google ml 仍然返回相同的错误。

标签: python scikit-learn google-cloud-platform google-cloud-ml


【解决方案1】:

LocalOutlierFactor 没有predict 方法,只有一个私有的_predict 方法。这是来自源头的理由。

def _predict(self, X=None):
    """Predict the labels (1 inlier, -1 outlier) of X according to LOF.
    If X is None, returns the same as fit_predict(X_train).
    This method allows to generalize prediction to new observations (not
    in the training set). As LOF originally does not deal with new data,
    this method is kept private.

https://github.com/scikit-learn/scikit-learn/blob/a24c8b46/sklearn/neighbors/lof.py#L200

【讨论】:

  • 嗨@Bert,你能给我提供源链接吗?请!
  • 那么,我怎样才能将它集成到我的模型中?
  • 嗨@Bert,这对我来说也是另一个令人困惑的地方,我使用Isolation Forest分类器,它是predict方法,那为什么它指向Local Outlier Factor
  • 抱歉,我不熟悉 Google Cloud ML-Engine。也许您有一个剩余的 LOF 模型或之前运行的代码,或者没有完全部署 IF。它肯定是在尝试在 LocalOutlierFactor 对象上调用 predict()。
  • 嗨@Bert,现在我已经从我的模型中删除了 te=he 'Local Outlier Factor` 并生成了一个新的pickle 文件并再次上传,但我仍然遇到同样的错误。
【解决方案2】:

看起来这可能是 Python 版本的东西(尽管我不清楚为什么 scikit learn 在 Python 2 和 Python 3 中的行为不同)。我能够在本地(在同一台机器上)验证我的 Python 2 安装在 Python 3 成功时重现了上述错误(两者都使用 sci-kit learn 0.19.1)。

解决方案是在部署模型时指定python版本(注意最后一行,如果省略,默认为“2.7”):

gcloud beta ml-engine versions create $VERSION_NAME \
    --model $MODEL_NAME --origin $DEPLOYMENT_SOURCE \
    --runtime-version="1.5" --framework $FRAMEWORK
    --python-version="3.5"

【讨论】:

  • 我已经用Python 3.5 创建了我的模型版本,我的模型代码也是用python 3.6编写的
  • 只是为了验证:您使用--python-version="3.5" 创建了模型并且仍然收到报告的错误消息?
【解决方案3】:

令人惊讶的是,问题是runtime version,当您将模型版本重新创建为:

gcloud beta ml-engine versions create $VERSION_NAME  --model $MODEL_NAME --origin $DEPLOYMENT_SOURCE --runtime-version="1.6" --framework $FRAMEWORK --python-version="3.5"

使用 Runtime 版本 1.6 而不是 1.5,至少将其转换为运行模型。

【讨论】:

  • 您更新的代码可能实际上不是部署在 Google Cloud ML 引擎中的代码(主要是因为错误消息指的是在您的代码中注释掉的类)。您可以尝试将您的新模型(只有IsolationForest 分类器)上传到gcs 并尝试使用上述命令重新部署它吗?
【解决方案4】:

我参与了一个看起来非常相似的项目。我得到了同样的错误。我的问题是 if 语句中的拼写错误。

问候 洛伦兹

【讨论】:

  • 这不提供问题的答案,如果您能识别出具体的错字,请在您的答案中指出。
猜你喜欢
  • 2020-09-27
  • 2022-06-16
  • 2019-06-18
  • 2021-12-14
  • 2019-07-03
  • 2018-01-09
  • 2015-07-03
  • 2013-05-20
  • 2015-11-02
相关资源
最近更新 更多