Prophet - это библиотека прогнозирования временных рядов, основанная на аддитивной модели, которая хорошо работает из коробки и устойчива к отсутствующим данным и сдвигам в тренде.

В типичном рабочем процессе машинного обучения после обучения модель развертывается, чтобы пользователи могли получать результаты модели из своих приложений через API. А в некоторых случаях среда развертывания может быть контролируемой средой с ограниченным доступом.

Я работал над проектом, в котором мы создавали модели Prophet в Watson Studio и должны были развернуть модели Prophet в Watson Machine Learning. Однако, начиная с Cloud Pak for Data 2.5, Prophet не является поддерживаемой средой, и ее невозможно развернуть в Watson Machine Learning.

Некоторые обходные пути, которые я пробовал, в том числе,

  1. Развертывание функции оболочки для Prophet в Watson Machine Learning - функции позволяют устанавливать библиотеки, вызывая pip install через подпроцесс
  2. Использование conda install в функции оболочки
  3. Компиляция Prophet в файл wheel, чтобы все зависимости были объединены вместе

К сожалению, описанные выше шаги не сработали, потому что Prophet зависит от PyStan, который является интерфейсом для Stan, а Stan требует компилятора C ++, который недоступен в среде развертывания в Watson Machine Learning.

Но еще не все потеряно.

В большинстве случаев обучение модели Prophet выполняется в среде разработки, такой как Jupyter Notebooks или сценарии Python, и редко в Watson Machine Learning, который используется для развертывания в этом случае.
Если вы прочитали документ и приняли посмотрите на исходный код, вы заметите, что модель была структурирована стандартным способом scikit-learn, функцией подбора и функцией прогнозирования. Если присмотреться внимательнее, функция прогнозирования, по сути, добавляет тенденции, компоненты сезонности и эффекты событий на основе параметров, оцененных с помощью функции соответствия.

Это означает, что если у нас есть подобранная модель и мы экспортировали параметры, прогнозирование просто применяет экспортированные параметры к их соответствующим функциям и складывает их.

Чтобы упростить этот процесс, я создал пакет Prophet Inference, который представляет собой урезанную версию Prophet, которая позволяет делать выводы только из подобранной модели Prophet. Этот пакет предназначен для использования в среде ограниченного развертывания.

Вот 3 шага, чтобы начать работу,

1. Установите Prophet Inference (https://github.com/randyphoa/prophet-inference)

pip install prophet-inference

2. Обучите модель Prophet и экспортируйте параметры модели.

# create and fit model
df = pd.read_csv("data.csv")
m = Prophet()
m.fit(df)
# export data to json using fbprophet_inference
model_json = fbprophet_inference.serialize.model_to_json(m)

Это параметры, которые экспортируются.

3. Импортируйте параметры модели и вызовите функции прогнозирования.

Помните, что это экземпляр Prophet, предназначенный только для вывода, и вам следует вызывать только функцию прогнозирования.

model = fbprophet_inference.serialize.model_from_json(model_json)
model.predict(df)

А вот и полный пример обучения и развертывания Prophet в Watson Machine Learning.

Есть много способов написать функцию, и это пример, в котором я сохранил свою экспортированную модель в Cloud Object Storage.

Создать и подогнать модель

df = pd.read_csv("data.csv")
m = Prophet()
m.fit(df)

Экспорт модели и сохранение в Cloud Object Storage

model_json = fbprophet_inference.serialize.model_to_json(m)
client_cos.put_object(Bucket="my-bucket", Key="model_json.json", Body=io.StringIO(model_json).getvalue())

Создать функцию-оболочку

Дополнительные сведения об использовании функций см. На странице https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/ml-functions.html.

Функции действительно гибкие, и вы можете делать что угодно - от предварительной обработки до вывода и постобработки - за один вызов функции.

def func():
    import subprocess
    subprocess.check_output("pip install fbprophet-inference --user", stderr=subprocess.PIPE, shell=True)
    subprocess.check_output("pip install boto3 --user", stderr=subprocess.PIPE, shell=True)
    
    import io
    import json
    import boto3
    import pickle
    import datetime
    import pandas as pd
    import fbprophet_inference
    from fbprophet_inference import ProphetInference, serialize
json.JSONEncoder.default = lambda self,obj: (obj.isoformat() if isinstance(obj, datetime.datetime) else None)    
    client_cos = boto3.client("s3", endpoint_url="", aws_access_key_id="", aws_secret_access_key="", region_name="ap-geo")
    
    model_json = client_cos.get_object(Bucket="cloud-object-storage-cpd-data", Key="model_json.json")["Body"].read().decode("utf_8")
    model = fbprophet_inference.serialize.model_from_json(model_json)
    
    def score(payload):
        date_from, date_to = payload["input_data"][0]["values"][0]
        df_pred = pd.date_range(start=date_from, end=date_to, freq="D").to_frame(name="ds")
        pred = model.predict(df_pred)[["ds", "yhat"]]
        return {"predictions": [ {"result": [pred.to_dict()]} ]}
    return score

Развертывание в Watson Machine Learning

FUNCTION_NAME = "function-prophet"
DEPLOYMENT_FUNCTION_NAME = "function-prophet-deploy"
        
meta_data = { 
    client.repository.FunctionMetaNames.NAME : FUNCTION_NAME,
    client.repository.FunctionMetaNames.RUNTIME_UID: "ai-function_0.1-py3.6"
}
function_details = client.repository.store_function(meta_props=meta_data, function=func)
function_uid = client.repository.get_function_uid(function_details)
meta_props = {
   client.deployments.ConfigurationMetaNames.NAME: DEPLOYMENT_FUNCTION_NAME,
   client.deployments.ConfigurationMetaNames.ONLINE: {}
}
deployment_details = client.deployments.create(function_uid, meta_props=meta_props)
deployment_uid = client.deployments.get_uid(deployment_details)

Вызов развернутой функции

scoring_payload = {
   client.deployments.ScoringMetaNames.INPUT_DATA: [{
        "fields": ["DATE_FROM", "DATE_TO"],
        "values": [["2016-01-21", "2016-02-03"]]
    }]
}
predictions = client.deployments.score(deployment_uid, scoring_payload)
pd.read_json(json.dumps(predictions["predictions"][0]["result"][0]))

Вы можете найти полную записную книжку по адресу https://github.com/randyphoa/prophet-inference/blob/master/python/notebooks/Prophet-WML.ipynb

Заключение

Prophet Inference позволяет вам легко делать прогнозы на подогнанных моделях Prophet в ограниченной среде развертывания. В сочетании с функциями он становится невероятно мощным, предоставляя вам гибкость для динамической загрузки моделей Prophet и выполнения прогнозов.

В Cloud Pak for Data 3.0 пользователи могут создавать собственные образы Docker на уровне ОС для Watson Studio. С нетерпением жду этой функциональности в Watson Machine Learning.