2018年1月9日火曜日

【Googleクラウド・機械学習編】Python3でJSONパラメータをpostする

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。 

2018年になりました。本年も宜しくお願いします。 

さて、2017年から引き続き、最近流行の機械学習について勉強中です。

 リクエスト送信プログラム作成


さて、現在はGoogleクラウドの「CLOUD NATURAL LANGUAGE API」を検証中なわけですが、
その為には「リクエスト送信プログラム」を作らなければなりません。

ちょっと実行するだけならネット上に転がっているリクエスト送信支援ツールを使えば良いですが、
手元の大量データを送り込んだりとか、独自のカスタマイズを施す為には自前開発が必要不可欠です。

私はJavaエンジニアですので、プログラムもJavaで作るのが一番簡単な道です。
アンドロイドアプリでWebAPIのリクエストプログラムとか作ったこともありますし。
しかし、新年も始まったことですし、ここは志を高く持ってPythonで作ることにチャレンジしていきたいと思います。

 作成プログラム


目標


CLOUD NATURAL LANGUAGE APIに対する最も基本的な疎通確認レベルのPOST送信。

条件


言語はPythonとする。バージョンは3。

結論を言いますと、もの凄く苦労しました。
この記事はJavaだったら30分で作れたはずのプログラムを6時間も悪戦苦闘した奮闘記となります。

Python開発の困難点


1.Python2の情報が混ざっている


前の記事で書きましたが、Pythonは「Python2」と「Python3」で互換性がありません。

JavaだったらJava1.5で書いたソースは概ねJava8でも動作します。
(完全互換ではないのはミソ。以前に予約後の問題でJavaのバージョンを上げたら動かなくなったことがありました。とはいえ、殆どOKなので苦労はしません)

Pythonの場合は全然ダメです。
「バージョン間で互換性」は、まあハッキリ言って程度問題でして、「完全互換を保証するものではないが、大体は流用OK」くらいの言語が多いです。

でも、Python2とPython3は雰囲気が似ているだけの別物というくらい全然動きません。
そして、伝統的にはPython2が長く使われており、Python3は最新鋭です。

よって、「Python post送信」とかで検索すると、Python2とPython3の情報が混ざって出てくるんです。
私が必要としているのはPython3ですから、Python2の情報は罠でしか無い。
これが厄介です。

ちなみに調べている中で偶然知ったのですが、「Perlは互換性に強い」そうですね。

Perl...
相当古くから根付いている言語ですが、Perlは互換性が強い故に、何十年も前からサーバを引っ越ししつつ代々引き継がれているようなソースでも問題無く動くそうな。

「何十年も維持するプログラムだったらPerlが良い」

という記事を見ました。

なるほど。
こういうブログをやっていると最新情報ばかりに目が行ってしまいますが、業務系システムでは恒久的保守をどう行っていくかも重要な能力です。

「古い技術であっても侮ってはならない」という教訓になりました。

2.情報が少ない


やっぱりですね、少ないですよ、情報が。
無くは無いですが。

まず日本語の情報だけでは全然足りないので、英語情報に手を伸ばすことは当然
しかし、英語情報も踏まえても、イマイチ必要な情報が見つからない。

JavaとかPHPとか、長年の蓄積がある言語と比べると、ネット上における情報量の差というものを肌で感じます。
これは大きなリスクです。

仮に会社の案件としてPythonを採用したとすると、体制を構築するのは至難でしょう。

JavaとかPHPだともうネット上に情報が溢れているので誰でも何とかなるのですが、Pythonはそうは行きません。
強力な少数精鋭の体制以外では対応出来ないと思います。

これをチャンスと見るか、リスクと見るかは見解が分かれる所だと思います。

3.デタラメ


これが一番厄介!!

ネットに嘘が書いてある!!

嘘ではないにしても説明不足だったりとか、肝心な情報が抜けている記事が多い。
(もしくは、昔はそのソースで動いたのかもしれませんが、今では動かないとか)

情報源の少なさ故に淘汰されていないからなのでしょう。
ネットの技術情報は量が質を生むものです。
大量の情報が溢れかえって切磋琢磨し淘汰された結果、役に立つ情報が検索結果の上の方に来るのがネット界。

現在のPythonはまだ発展途上で、その段階に到っていません。
ノイズでしかない情報が溢れている。
これも大きなリスクです。

成果物ソース


そんなこんなで苦労しましたが、ひとまずリクエストの正常送信までは確認出来ております。

import urllib.request
import urllib.parse
import json

#送信先URL
url="https://language.googleapis.com/v1/documents:analyzeEntities?key={My_API_KEY}"

#送信するJSONパラメータ
body = {
  'document': {
    'type': 'PLAIN_TEXT',
    'content': '株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。\n\n仕事はシステムエンジニア。\n特技は空手道初段です。\n\n家族は妻が一名ほどいます。\n\n好きなお酒はウイスキーです。\n\n仲良くして下さい。'
  },
  'encodingType': 'UTF8'
}
#JSONパラメータをバイト変換
body = json.dumps(body).encode("utf-8")

#リクエストヘッダー
header = {
    "content-type": "application/json"
}

try:
    #送信実行
    request = urllib.request.Request(url, data=body,  headers=header)
    with urllib.request.urlopen(request) as response:
        #結果を出力
        response_body = response.read().decode("utf-8")
        print(response_body)

except urllib.error.HTTPError as e:
    #エラーだった場合、エラー原因を出力
     print('ERROR!!')
     print(e.code)
     print(e.read())


どうです?
私はこれを見ると「あっ、綺麗だな💛」と思います。

Javaだったらもっとゴチャゴチャですもん。
InputStreamだとか、OutputStreamだとか、close処理とか……。

比べて、要は


  • urllib.request.Request.urlopen(url, data=body,  headers=header)


で完結するPythonは如何に綺麗か。

確かによく洗練された言語だと思います。

私はまだ使い始めたばかりですが、慣れれば確かに他の言語より使い勝手が良いんじゃないかな、という感触は感じられましたね。

まとめますと、


  • 言語そのものが持つパフォーマンスは優れている。
  • 枯れておらず、情報がまだ少ないのがリスク。


というのが私の所感です。

なので、


  • プロジェクトのメイン言語として採用するのはハイリスク過ぎる。
  • 社内用のちょっとしたツール開発用なら、生産性も高くノウハウ蓄積にも適している。


こういう使い方でスキルアップしていきたいなぁ、と思うところです。

次回


次回は上記ソースの解説と、作成過程で蹴躓いた箇所の説明、デバック解説です。

同じ原因でハマっている人が検索から飛んできてくれたら嬉しいですね。

0 件のコメント:

コメントを投稿