2017-01-27 5 views
3

ライブデータを使用して本番環境で展開する必要のあるscikit-learnで機械学習モデルを作成しました。機能は次のようになります。Python:機械学習の予測を本番環境でより速く実行する方法を教えてください。

date   event_id user_id  feature1 feature2 featureX... 
    2017-01-27 100  5555  1.23  2   2.99 
    2017-01-27 100  4444  2.55  5   3.16 
    2017-01-27 100  3333  0.45  3   1.69 
    2017-01-27 105  1212  3.96  4   0.0 
    2017-01-27 105  2424  1.55  2   5.56 
    2017-01-27 105  3636  0.87  4   10.28 

したがって、毎日異なるイベントがあります。イベントが始まる前に、私は基本的にデータベースからそれらを引いて、データフレームでこれを保存して漬けscikitモデルを使って予測を計算します。

df_X = df.drop(['date', 'event_id', 'user_id'], axis=1) 
loaded_model = joblib.load("model.joblib.dat") 
prediction = loaded_model.predict_proba(df_X) 

その後、私は戻ってDFに予測と一致してへの出力として送信します必要に応じてAPIまたはファイル

イベントが開始されると、featureXが常に更新され、APIから取得されます。更新を行うには、それぞれevent_iduser_idを通過するループを使用し、featureX値でdfを更新し、再計算して出力に再度送信してください。私はこのような何かをやっていることについては

# get list of unique event ids 
events = set(df['event_id'].tolist()) 

try: 
    while True: 
     start = time.time() 
     for event in events: 
      featureX = request.get(API_URL + event) 
      featureX_json = featureX.json() 

      for user in featureX_json['users']: 
       df.loc[df.user_id == user['user_id'], 
         'featureX'] = user['featureX'] 

     df_X = df.drop(['date', 'event_id', 'user_id'], axis=1) 
     df['prediction'] = loaded_model.predict_proba(df_X) 

     # send to API or write to file 

     end = time.time() 
     print('recalculation time {} secs'.format(end - start)) 

except KeyboardInterrupt: 
    print('exiting !') 

これが私のために正常に動作しますが、全体の予測アップデートがサーバに約4秒を取り、私はそれが1秒の下にする必要があります。私は、私が必要とするスピードアップを得るためにwhile loopで何が変わるのか理解しようとしていますか?

JSONのサンプルがevent_id = 100 URL http://myapi/api/event_users/<event_id>のために、要求に応じて追加されました:

{ 
    "count": 3, 
    "users": [ 
     { 
      "user_id": 4444, 
      "featureY": 34, 
      "featureX": 4.49, 
      "created": "2017-01-17T13:00:09.065498Z" 
     }, 
     { 
      "user_id": 3333, 
      "featureY": 22, 
      "featureX": 1.09, 
      "created": "2017-01-17T13:00:09.065498Z" 
     }, 
     { 
      "user_id": 5555, 
      "featureY": 58, 
      "featureX": 9.54, 
      "created": "2017-01-17T13:00:09.065498Z" 
     } 
    ] 
} 
+0

あなたは 'featureX_json'のためのサンプルデータセットを提供することはできますか? – MaxU

+1

@MaxU質問にサンプルデータセットを追加しました。 – sfactor

答えて

1
# get list of unique event ids 
events = df['event_id'].unique().tolist() 

try: 
    while True:  # i don't understand why do you need this loop... 
     start = time.time() 
     for event in events: 
      featureX = request.get(API_URL + event) 
      tmp = pd.DataFrame(featureX.json()['users']) 

      df.loc[(df.event_id == event), 'featureX'] = \ 
       df.loc[df.event_id == event, 'user_id'] \ 
        .map(tmp.set_index('user_id').featureX) 

     df_X = df.drop(['date', 'event_id', 'user_id'], axis=1) 
     df['prediction'] = loaded_model.predict_proba(df_X) 

     # send to API or write to file 

     end = time.time() 
     print('recalculation time {} secs'.format(end - start)) 

except KeyboardInterrupt: 
    print('exiting !') 

デモ:event_id == 100

ためは、最初のあなたのJSONオブジェクトからDFを作成してみましょう:

tmp = pd.DataFrame(featureX_json['users']) 

In [33]: tmp 
Out[33]: 
         created featureX featureY user_id 
0 2017-01-17T13:00:09.065498Z  4.49  34  4444 
1 2017-01-17T13:00:09.065498Z  1.09  22  3333 
2 2017-01-17T13:00:09.065498Z  9.54  58  5555 

は今、私たちはfor user in featureX_json['users']:ループを取り除くことができます。

In [29]: df.loc[df.event_id == 100, 'featureX'] = \ 
      df.loc[df.event_id == 100, 'user_id'].map(tmp.set_index('user_id').featureX) 

In [30]: df 
Out[30]: 
     date event_id user_id feature1 feature2 featureX 
0 2017-01-27  100  5555  1.23   2  9.54 # 2.99 -> 9.54 
1 2017-01-27  100  4444  2.55   5  4.49 # 3.16 -> 4.49 
2 2017-01-27  100  3333  0.45   3  1.09 # 1.69 -> 1.09 
3 2017-01-27  105  1212  3.96   4  0.00 
4 2017-01-27  105  2424  1.55   2  5.56 
5 2017-01-27  105  3636  0.87   4  10.28 
関連する問題