2016-08-01 45 views
19

我的工作的最終結果應該是一個Python函數,它將JSON對象作爲唯一的輸入並返回另一個JSON對象作爲輸出。爲了更具體一些,我是一名數據科學家,我所講的功能是從數據中獲得的,它提供了預測(換句話說,它是一種機器學習模型)。如何(以何種形式)共享(傳遞)Python函數?

所以,我的問題是如何將這個功能提供給將要整合到網絡服務中的「技術團隊」。

目前我面臨的問題很少。首先,技術團隊不一定在Python環境中工作。所以,他們不能將我的功能「複製並粘貼」到他們的代碼中。其次,我想確保我的功能與我的環境相同。例如,我可以想象,我使用了技術團隊沒有的一個庫,或者他們的版本與我使用的版本不同。

ADDED

作爲一個可能的解決方案我考慮下。我啓動了一個Python進程,它監聽套接字,接受傳入的字符串,將它們轉換爲JSON,將JSON提供給「已發佈」函數,並將輸出JSON作爲字符串返回。這個解決方案有缺點嗎?換句話說,將Python函數「發佈」爲偵聽套接字的後臺進程是一個好主意嗎?

+0

嘗試查看'pex'工具https://github.com/pantsbuild/pex – Compadre

+1

您可以嘗試站起來使用Django服務器並使用Django REST框架http://www.django-rest-framework。組織/。你可以控制環境,那些知道如何編寫代碼的人可以編輯功能。那些不能簡單地調用URL並使用curl或類似來回傳遞JSON數據的人。這可以輕鬆地集成到更高級別的Web服務中。 – Josh

+0

關於問題2,您可能需要編寫一些單元測試。如果單元測試通過了Web團隊,那麼應該很好。 – user1157751

回答

9

你有正確的想法與使用套接字,但有大量的框架正在做你想要的。像hleggs,我建議你結賬Flask來構建一個微服務。這會讓其他團隊將HTTP請求中的JSON對象發送到您的應用程序並返回JSON對象。無需知道底層系統或需要額外的要求!

下面是一個燒瓶應用程序的模板答覆和使用JSON

from flask import Flask, request, jsonify 

app = Flask(__name__) 

@app.route('/', methods=['POST']) 
def index(): 
    json = request.json 
    return jsonify(your_function(json)) 


if __name__=='__main__': 
    app.run(host='0.0.0.0', port=5000) 

編輯迴應:直接內嵌我的代碼爲每Peter Britain的建議

+1

還有兩個想法...... 1)如果你直接嵌入你的代碼而不是鏈接到外部要點,你的答案會更好(並且它通常被封裝在SO上)。2)OP的問題的版本控制方面如何? –

+0

「@ app」表示法的含義是什麼?這是我第一次在Python中看到類似的東西。另外,請建議使用HTTP ** S **而不是HTTP。 – ray

+0

我不確定這個答案是完全的主要問題:你如何分配一個Python函數? –

-1

我猜你有3種可能性:

  • 將python函數轉換爲javascript函數:

假設「技術團隊」使用JavaScript的Web服務,您可以嘗試到您的Python函數直接轉換到使用empythoned一個Javascript功能(這將是很容易的網頁上集成)(基於emscripten

這種方法的缺點是每次你需要更新/升級你的python函數時,你還需要再次轉換爲Javascript,然後檢查&驗證函數是否繼續工作。

  • 簡單的API服務器+ JQuery的

如果轉換方法是不可能的,我同意@賈斯汀鍾,你可以使用FLASK

越來越JSON作爲輸入> JSON到您的函數參數>運行python函數>將函數結果轉換爲JSON>提供JSON結果

假設您選擇FLASK解決方案,「tech-team」只需發送一個異步。 GET/POST請求包含所有參數爲JSON obj,當他們需要從你的python函數獲得一些結果時。

  • 的WebSocket服務器+ socket.io

您還可以使用採取的WebSocket看看派遣到web服務(看瓶+的WebSocket爲貴方& socket.io爲Web服務端)。

=>當您需要以低成本和延遲向很多用戶推送/接收數據時,websocket確實非常有用(不確定websocket將會最適合您的需求)

問候

0

你的任務是(在通用)約productionizing機器學習模型,其中模型的消費者可能不會在同樣的環境,將其用於開發模型中的一個來工作。過去幾年來,我一直在努力解決這個問題。許多公司都面臨着這個問題,並且由於數據科學家和開發人員之間的技能,目標以及環境(語言,運行時間)不匹配而導致問題惡化。根據我的經驗,提供以下解決方案/選項,每種解決方案都有其獨特的優點和缺點。

  • 選項1:建立模型的預測一部分用在Python(例如,瓶)的輕量級工具的獨立Web服務。你應該儘可能地將模型開發/訓練和預測部分分開。您開發的模型必須被序列化爲某種形式,以便Web服務器可以使用它。

    • 您的機器學習模型的更新頻率是多少?如果不是非常頻繁地執行,那麼序列化的模型文件(例如:Python pickle文件)可以保存到Web服務器可訪問的公共位置(比如s3),並加載到內存中。獨立的Web服務器應該提供用於預測的API。
    • 請注意,使用Flask暴露單個模型預測會很簡單。但是,如果需要擴展此Web服務器,使用正確的庫集對其進行配置,傳入請求的身份驗證都是非平凡的任務。只有你有開發團隊準備好幫助這些,你才應該選擇這條路線。

    • 如果模型經常更新,版本化模型文件將是一個不錯的選擇。因此,實際上,您可以通過檢查整個模型文件來檢查任何版本控制系統是否過大。 Web服務器可以在啓動/更新時對此文件進行反序列化(pickle.load),並將其轉換爲可以調用預測方法的Python對象。

  • 選項2:使用predictive modeling markup language。 PMML專爲此目的而開發:獨立於環境的預測建模數據交換格式。因此數據科學家可以開發模型,將其導出到PMML文件。然後,用於預測的Web服務器可以使用PMML文件進行預測。您一定要檢查the open scoring project,它允許您通過REST API公開機器學習模型,以部署模型和進行預測。

    • 優點:PMML是標準化格式,開放評分是一個成熟的項目,具有良好的發展歷史。
    • 缺點:PMML可能不支持所有型號。如果您的技術團隊選擇的開發平臺是JVM,則開放評分主要是有用的。從Python導出機器學習模型並不簡單。但R對將模型導出爲PMML文件提供了很好的支持。
  • 選項3:有some vendors offering dedicated solutions for this problem。您將必須評估許可成本,硬件成本以及採用此路線的產品的穩定性。

無論您選擇哪個選項,請考慮支持該選項的長期成本。如果您的工作處於概念驗證階段,基於Python燒瓶的Web服務器+ pickled模型文件將是最佳路線。希望這個答案可以幫助你!

0

正如其他答案中提到的,最好的選擇是創建一個簡單的Web服務。除了Flask,你可能想嘗試一下非常簡單的一個文件web框架bottle。您的服務可能看上去那樣簡單:

from bottle import route, run, request 

@route('/') 
def index(): 
    return my_function(request.json) 

run(host='0.0.0.0', port=8080) 

爲了保持環境相同的檢查virtualenv,使孤立的環境中,避免與已安裝的軟件包,並pip衝突包的確切版本安裝到虛擬環境。

2

我你的問題的理解歸結爲:

我如何可以共享一個Python庫與我的團隊的其他成員,可能不以其它方式使用Python?

我怎樣才能確保我的代碼和它的依賴是接收團隊將運行?

而且接收團隊可以在任何地方輕鬆地安裝東西嗎?

這是一個簡單的問題,沒有直截了當的答案......正如你剛纔提到的,這可能集成在一些web服務中,但你不知道這個服務的實際平臺。

你也問:

作爲一個可能的解決方案我考慮下。我啓動了一個Python進程,它監聽套接字,接受傳入的字符串,將它們轉換爲JSON,將JSON提供給「已發佈」函數,並將輸出JSON作爲字符串返回。這個解決方案有缺點嗎?換句話說,將Python函數「發佈」爲偵聽套接字的後臺進程是一個好主意嗎?

在最簡單的情況下,對於開始,我會說沒有一般。啓動諸如HTTP服務器(內置Python)的網絡服務器是非常容易的。但是一項服務(即使符合「微」條件)意味着基礎設施,意味着安全等。

  • 如果您期望的端口在部署計算機上不可用,該怎麼辦? - 重新啓動機器時會發生什麼?
  • 服務器在出現故障時將如何啓動或重新啓動?
  • 你還需要最終提供一個新貴或systemd服務(在Linux上)?
  • 您的簡單套接字或網絡服務器是否支持多個併發請求?
  • 是否存在暴露套接字的安全風險?

等等當我部署時,我對「簡單」套接字服務器的使用經驗是,它們最終並不是那麼簡單。

在大多數情況下,首先避免重新分配套接字服務會更簡單。如果你願意,這裏提出的方法可以用來在後期以更簡單的方式打包整個服務。

我建議改爲簡單的命令行界面很好的安裝

的一套東西要考慮最小的是:

  1. 提供一個可移植的機制來調用許多操作系統的功能
  2. 確保您打包功能,使得它可以與所有的正確安裝依賴
  3. 可以很容易地安裝,當然提供一些文檔!

步驟1.最簡單的共同點是提供一個接受路徑到JSON文件和吐出JSON上的標準輸出一個命令行界面。 這可以在Linux,Mac和Windows上運行。

在這裏說明應在Linux或Mac工作,並需要爲Windows小幅調整(僅適用於configure.sh腳本進一步下跌)

一個最小的Python腳本可以是:

#!/usr/bin/env python 

""" 
Simple wrapper for calling a function accepting JSON and returning JSON. 
Save to predictor.py and use this way:: 
    python predictor.py sample.json 
    [ 
     "a", 
     "b", 
     4 
    ] 
""" 

from __future__ import absolute_import, print_function 
import json 
import sys 


def predict(json_input): 
    """ 
    Return predictions as a JSON string based on the provided `json_input` JSON 
    string data. 
    """ 
    # this will error out immediately if the JSON is not valid 
    validated = json.loads(json_input) 
    # <....> your code there 
    with_predictions = validated 
    # return a pretty-printed JSON string 
    return json.dumps(with_predictions, indent=2) 


def main(): 
    """ 
    Print the JSON string results of a prediction, loading an input JSON file from a 
    file path provided as a command line argument. 
    """ 
    args = sys.argv[1:] 
    json_input = args[0] 
    with open(json_input) as inp: 
     print(predict(inp.read())) 


if __name__ == '__main__': 
    main() 

你可以通過將路徑傳遞給JSON文件來最終處理大量輸入。

第2步。包裝你的功能。在Python中,這是通過創建setup.py腳本實現的。這需要照顧從Pypi安裝任何相關的代碼。這將確保您所依賴的庫的版本是您期望的版本。這裏我添加了nltk作爲依賴關係的一個例子。加你的:這可能是scikit-learn,pandas,numpy等。這setup.py還自動創建一個bin/predict腳本,這將是你的主要命令行界面:

#!/usr/bin/env python 
# -*- encoding: utf-8 -*- 

from __future__ import absolute_import, print_function 
from setuptools import setup 
from setuptools import find_packages 


setup(
    name='predictor', 
    version='1.0.0', 
    license='public domain', 
    description='Predict your life with JSON.', 
    packages=find_packages(), 
    # add all your direct requirements here 
    install_requires=['nltk >= 3.2, < 4.0'], 
    # add all your command line entry points here 
    entry_points={'console_scripts': ['predict = prediction.predictor:main']} 
) 

此外作爲對Python的常見和製作安裝代碼更簡單,我創建了「Python包」目錄中移動預測中這個目錄。

第3步。您現在想包裝易於安裝的東西。一個簡單的configure.sh腳本來完成這項工作。它安裝virtualenv,pipsetuptools,然後在與項目相同的目錄中創建virtualenv,然後在其中安裝預測工具(pip install .基本上與python setup.py install相同)。通過這個腳本,您可以確保將要運行的代碼是您想要使用正確的依賴關係運行的代碼。此外,您確保這是一個對目標系統具有最小依賴性和影響的獨立安裝。這是用Python 2測試的,但在Python 3上也應該很有可能。

#!/bin/bash 
# 
# configure and installs predictor 
# 

ARCHIVE=15.0.3.tar.gz 
mkdir -p tmp/ 
wget -O tmp/venv.tgz https://github.com/pypa/virtualenv/archive/$ARCHIVE 
tar --strip-components=1 -xf tmp/venv.tgz -C tmp 
/usr/bin/python tmp/virtualenv.py . 
. bin/activate 
pip install . 
echo "" 
echo "Predictor is now configured: run it with:" 
echo " bin/predict <path to JSON file>" 

在最後你有一個完全配置的,孤立的,易於安裝的代碼用一個簡單的高度便攜的命令行界面。 您可以在此小型回購中看到它:https://github.com/pombredanne/predictor 您只需克隆或獲取回購的zip或tarball,然後閱讀README並開始業務。

請注意,對於更復雜的應用程序,包括出價的依賴關係,以便於安裝,而不依賴於網絡,您可以檢查此https://github.com/nexB/scancode-toolkit我也維護。

如果你真的想公開一個Web服務,你可以重新使用這個方法,並用一個簡單的Web服務器打包(比如Python標準庫或者瓶子或燒瓶或者gunicorn內置的那個)並且提供configure.sh將其全部安裝並生成命令行以啓動它。

相關問題