Хотите создавать смарт-контракты, которые могут выполнять функции на основе прогнозной модели? Вы хотите, чтобы ваш проект полностью соответствовал модным словам? Что ж, этот урок создан специально для вас! Во-первых, это предполагает, что вы имеете некоторое представление о том, как использовать Python, Flask и Solidity.
Начнем с модели, которую мы будем запрашивать. Это микросервис Flask, который позволит нам создать API, который мы можем вызывать из Oracalize.
Сначала у нас есть игрушечная модель, на которой мы будем использовать линейную регрессию. Входные данные представляют собой набор из трех примеров с набором векторов в трехмерном пространстве:
[1.,1.,5.], [2.,2.,5.], [3.,3.,1.]
И значения, соответствующие этим векторам.
[0.,0.,1.]
Самое замечательное в sklearn - это то, что у него есть единый API для множества моделей. По сути, API предоставляет следующее.
- Выберите модель и инициализируйте ее необязательными аргументами
- Подгоните модель с помощью метода Fit
- выполнять прогнозы с использованием метода прогнозирования
Набор данных, который мы используем, полностью искусственный и адаптирован к используемому нами методу машинного обучения. В нем первые два вектора отображаются в ноль, а третий вектор - в один.
Тип машинного обучения, который мы будем выполнять, - это регрессия. Что делает регрессия, так это разделение набора точек прямой линией.
reg_model = linear_model.LinearRegression() reg_model.fit([[1.,1.,5.], [2.,2.,5.], [3.,3.,1.]], [0.,0.,1.])
Метод fit принимает два аргумента. Один из них - это обучающие данные, а другой - цели для обучающих данных.
Для краткости мы показываем как характеристики обучающих данных, так и целевые данные в качестве аргументов для соответствия без создания переменных.
pickle.dump(reg_model, open('some_model.pkl', 'wb'))
Здесь мы сохраняем модель в файл. Рекомендуется сохранять модели, особенно при работе с реальными данными, поскольку для изучения реальных наборов данных требуется время вычислений. Другой причиной может быть выполнение только логического вывода модели, а не ее повторное обучение.
Следующим шагом будет использование flask для предоставления API, который мы можем вызвать с помощью Orcalize.
@app.route('/prediction/api/v1.0/some_prediction', methods=['GET']) def get_prediction():
Здесь мы создаем маршрут, который будет использоваться Oracalize (вы также сможете использовать его из веб-браузера для тестирования).
feature1 = float(request.args.get('f1')) feature2 = float(request.args.get('f2')) feature3 = float(request.args.get('f3'))
Затем мы получаем три функции, анализируя строку URL-адреса запроса и сохраняя их.
Теперь мы создадим запрос с помощью Oracalize. Ниже приведен запрос, который мы будем использовать. Обратите внимание, что аргументы жестко запрограммированы в запросе, в части 2 мы будем использовать вычисление с помощью Docker для выполнения этого запроса.
json(https://6ee957cb.ngrok.io/prediction/api/v1.0/some_prediction?f1=4&f2=4&f3=4).result
Это указывает Oracalize запросить URL-адрес и проанализировать ответ JSON, чтобы получить результат.
Несколько замечаний по использованию Oracalize
- Лучше всего использовать версию 0.4.20, потому что в более поздних версиях Solidity есть критические изменения.
- Для Oracalize все запросы оплачиваются, даже если вы используете тестовую сеть, поэтому у вас есть реалистичные цены.
- В приведенном ниже синтаксисе и во многих, которые вы найдете в Интернете, используется относительный импорт из github. Если вы используете Truffle, вам придется загрузить API вручную.
- Если вы не знаете, что такое обратный вызов, функция __callback выполняется после выполнения запроса.
Разберем смарт-контракт. Он состоит из четырех основных частей.
pragma solidity 0.4.20; import "github.com/oraclize/ethereum-api/oraclizeAPI.sol"; //This contract was derived from the Orcalize documentation contract ExampleSklearnContract is usingOraclize {
Это стандартная инициализация смарт-контракта с помощью Oracalize. Мы импортируем и наследуем, чтобы сделать API доступным для нас.
string public inference_result; event LogConstructorInitiated(string nextStep); event LogInferenceUpdated(string price); event LogNewOraclizeQuery(string description);
Мы создаем то место, куда мы собираемся поместить результат и все события в нашем смарт-контракте.
function ExampleSklearnContract () payable{ LogConstructorInitiated("Contract created. Call updateInference() to get a result"); }
Здесь мы определяем конструктор и делаем его платным.
function __callback(bytes32 myid, string result, bytes proof) { require(msg.sender == oraclize_cbAddress()); inference_result = result; LogInferenceUpdated(inference_result); }
Мы определяем обратный вызов, который будет выполнен после завершения нашего запроса. Мы меняем объявленное ранее значение результата.
function updateInference() payable { if (oraclize_getPrice("URL") > this.balance) { LogNewOraclizeQuery("Oraclize query was NOT sent, please add some ETH to cover for the query fee"); } else { LogNewOraclizeQuery("Oraclize query was sent, standing by for the answer.."); oraclize_query("URL", "json(http://<your_url_here>/prediction/api/v1.0/some_prediction?f1=1&f2=1&f3=1).result"); } }
Здесь мы выполняем запрос Oracalize и убеждаемся, что можем за него заплатить. Если вы хотите использовать вышеуказанный контракт, обязательно измените ‹your_url_here› на свою конечную точку.
Ниже представлена закомментированная версия смарт-контракта, app.py и requirements.txt.
Ссылки
- App.py является производным от App.py из https://github.com/Soluto/python-flask-sklearn-docker-template
- Смарт-контракт основан на примерах кода из документации Oracalize по адресу http://docs.oraclize.it/#ethereum.