Jack of all trades

master of none. 多芸は無芸を地で行く、自作自演何でも屋。

SQL Server 2017 CTP2.0上でChainerを使用する

先日のエントリで、SQL Server 2017 CTP2.0のMachine Leaning ServicesでPythonのコードを実行する手順を紹介しました。

sadynitro.hatenablog.jp

SQL Server Management Studioで外部スクリプトとしてPythonのコードを実行し、さらにGoogleの提供するオープンソース機械学習ライブラリであるTensorFlow*1をインストールしてPythonのコードで使用するところまで実践しました。

github.com

今回はTensorFlowを使ってさらに…と思っていたんですが、最近の興味と先日の de:code のセッション内容もあってChainerを使ったあれこれを実践してみる方向に切り替えました。

1. Chainerのインストー

ChainerはPreferred Networksが提供するオープンソースの深層学習フレームワークです。最近IntelMicrosoftとの協業でさらに注目度は上がっているように思います。

github.com

先のエントリでTensorFlowをインストールした時と同じく、SQL ServerPython Serviceのフォルダに移動してpipによるインストールを試みます。

cd C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\PYTHON_SERVICES\Scripts
pip install --ignore-installed --upgrade chainer

2. Chainerの動作確認

とりあえずSSMS上でChainerを利用するPythonコードを書いてちゃんと動作することを確認します。

execute sp_execute_external_script
@language = N'Python',
@script = N'
import numpy as np
import chainer.functions as cf

x = np.arange(-1, 4, 2).astype(''f'')
y = cf.sigmoid(x).data

print(x)
print(y)
'

numpy.arangeで適当に生成した配列に対してシグモイド関数を適用するだけのコードです。

f:id:sadynitro:20170614232359p:plain

どうやらちゃんと動いているようです。

3. 外部スクリプトに対するInput・Outputを使用する

SQL Serverのテーブルに対して、pythonのコードにデータを読み込む、pythonのコードからデータを書き込む操作がよくわからなかったのですが、 ちょっと前にポストされた以下の記事に書いてあったのでこれに沿って試してみます。

blogs.msdn.microsoft.com

サンプルデータとしてRatingという名前のテーブルを作りました。

f:id:sadynitro:20170616201606p:plain

お店の口コミサイトのデータみたいなイメージですね。

では、このテーブルのデータをpythonのコードで読み込むために以下のコードを実行します。

execute sp_execute_external_script
  @language = N'Python'
 ,@script = N'
print(InputDataSet)
'
,@input_data_1 = N'SELECT * FROM Rating'
GO

すると以下のようなエラーメッセージが。

メッセージ 39004、レベル 16、状態 20、行 1
'sp_execute_external_script' に HRESULT 0x80004004 を指定して実行中に、'Python' スクリプト エラーが発生しました。
メッセージ 39019、レベル 16、状態 1、行 1
外部スクリプトエラーが発生しました: 
Traceback (most recent call last):
  File "<string>", line 2, in <module>
  File "C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\PYTHON_SERVICES\lib\site-packages\revoscalepy\computecontext\RxInSqlServer.py", line 522, in rx_sql_satellite_pool_call
    exec(inputfile.read())
  File "<string>", line 3, in <module>
  File "C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\PYTHON_SERVICES\lib\site-packages\revoscalepy\computecontext\RxInSqlServer.py", line 474, in rx_sql_satellite_call
    rx_native_call("SqlSatelliteCall", params)
  File "C:\Program Files\Microsoft SQL Server\MSSQL14.MSSQLSERVER\PYTHON_SERVICES\lib\site-packages\revoscalepy\RxSerializable.py", line 19, in rx_native_call
    ret = px_call(functionname, params)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x91 in position 0: invalid start byte

Invalid BXL stream

文字コード絡みのエラーの様なので、日本語データの入った列を除外してみます。

execute sp_execute_external_script
  @language = N'Python'
 ,@script = N'
print(InputDataSet)
'
,@input_data_1 = N'SELECT UserId, ShopId, Rating FROM Rating'
GO

今度はうまくいったようです。テーブルのデータを読み込んで標準出力に出力できています。

f:id:sadynitro:20170616202126p:plain

上記のエラーについては現状解決できていません。どなたかご存じであればご教示いただけると幸い…。

4. SQL Server上のテーブルデータをInputとしてChainerで処理する

とりあえずSQL Serverのテーブルデータを扱えることを確認できたので、これをInputとしてChainerで処理させるコードを試してみます。 InputDataを抽出するクエリでShopId=2のRatingに絞り込み、その平均値をChainerで計算しています。

execute sp_execute_external_script
  @language = N'Python'
 ,@script = N'
import numpy as np
import chainer.functions as cf

r = np.array(InputDataSet.Rating).astype(''f'')

result = cf.average(r)

print(result.data)
'
,@input_data_1 = N'SELECT Rating FROM Rating WHERE ShopId = 2'
GO

f:id:sadynitro:20170616205732p:plain

無事に算出されました。ShopId=2のお店の平均評価は約2.86となっています。

まとめ

SQL Server 2017 CTP2.0上でChainerが実行できることを確認できました。
また、SQL Serverのテーブルデータを利用した処理を記述することもできたので、SQL Serverに蓄積したデータを学習データとして機械学習のモデル構築とか、 もしくは学習済みモデルを搭載してSQL Serverのデータから予測をしたり、分類したりすることもできそうです。

*1:公式サイトでは「for Machine Intelligence」と表現されています。読みは「テンサーフロー」中の人が言ってるんだから間違いない。異論は認めますん。