人工知能企業のエンジニアの開発記録

人工知能企業のエンジニアの模索の記録です。pythonを基とした開発や、スキルアップのためのライフハックおよびそれらへの挑戦を書き連ねます。

なぜドメイン駆動開発が必要か?エリックエヴァンスのドメイン駆動開発で勉強したこと(1〜3章)

久々の更新。今まで文章を書くのに時間をかけてダルかったけど書きダメを覚えたので再開。

今回は、機械学習pythonが関係ないです。 ただ優れた設計をしたくなったらドメイン駆動開発にたどり着いたので、有名なエリックエヴァンスに手を取ることに。 モチベーションとしては、その思想自体は前々から知っていたものの、qiitaの知識程度で使ってみたら失敗したことから。

ドメイン駆動開発がどんな意味を持つかが1章から3章に書かれていたので、気になった部分まとめです。

気になった部分をメモして、それをまとめただけなので読みづらいかも

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

この記事の対象読者

機械学習pythonというよりかはソフトウェアの設計です。

ドメイン駆動開発についてqiitaとかで見たことあるけど、正しい使い方やメリットがわからない人向けには参考になるかと。

ちなみに、ドメイン駆動開発の対処者に関しては、本書にも書かれていますが、 プロジェクトの開発リーダーが特にオススメなんじゃないかなと思いました。 ドメイン駆動開発は要件が複雑なアプリを設計する際に有効だということなので。 ただし、後述しますがコーダーも設計に関する知識も要するので、 ドメイン駆動開発を採用する場合は開発現場で回し読みするのがいいと思いました。

ドメイン駆動開発とは?

簡単に言えば、ビジネスロジック(要件定義だったり課題へのアプローチっていうイメージ)をわかりやすくするための設計。 もっと言えばプロジェクトに変わる非開発者(特にビジネスや課題の有識者、本書ではビジネスエキスパートと表現)でもわかりやすく機能をモデリングしようって話。

特に本書で議論されるレイヤードアーキテクチャは ビジネスエキスパートの要求(要件定義とか)と実装の都合(特に技術的すぎる部分)を切り離して、 後者を隠ぺい化しようっていう目的

っていう認識を前から持っていた。合っているかな?

クリーンアーキテクチャとかDDDに関するデザインパターンは結構議論されているから、技術者はそっから入った方がわかりやすいかも

ググれば以下のような記事が出るので後は先駆者の有志記事に任せます。

まだMVC,MVP,MVVMで消耗してるの? iOS Clean Architectureについて - Qiita

ちなみにアジャイル開発と相性が良さそうです。

ドメイン駆動設計のやり方

本書の一例をざっくり説明すると要件定義をしながらモデルの設計をしている感じです。 具体的にはうまく説明できる自信がないので省略。

本書で1章ではUMLを使ってモデルの設計をしていましたが、気をつける点は

  • モデルとコードは紐付ける(対応させる?)
  • モデルはドメインエキスパートと話しながら継続的に良くする。モデルは変化するもの。
  • モデリングのときはチームが理解できる単語を使う。使う図もUMLである必要は必ずしもない。
  • モデルの設計はブレストをしながらが効果的。要件の洗い出しのためか。
  • 知識豊富なモデルにする、出来たモデルは蒸留する
    • つまりドメイン知識は洗い出して、その後に本質ではない不要部分を切り捨てる

ドメインエキスパートとの会話が重要になるかと。

ドメイン駆動開発のいいところ

特に2番目が大きな効果を及ぼすかと

ドメイン駆動開発が生きないパターン

以下の条件が絡むと意味がなくなる

  • コーダーがモデルに対して責任を感じていない
  • アプリケーションに対してモデルを機能させる方法がわからない
  • コードを変更するとモデルが変わることを理解していない
  • モデリングする人が実装に携われない

ドメイン駆動設計のデメリット

  • モデル駆動設計は敷居が高い(学習コストが高い)
  • 開発に時間がかかる

ドメイン駆動開発を導入が困難な場合

特にわざわざドメイン駆動を使わなくてもいい場合はこのようなアーキテクチャが有効とか。

この印象から例えばMVCがこれに該当するのかなという印象

ドメイン駆動の使いどころ

本書を読んだ限りだと

  • 要件が固まっている
  • モデルが複雑になる

場合に有効という印象

逆に要件を分析するためにプロトタイピングしたりビジネスロジックが簡潔にできるのであれば使う必要はないかと。

OSX 上でwindowsを動かすために

てらです。

最近はまた一段と業務が忙しくなり、フロントエンジニアになったり画像系データサイエンティストになったり、インフラエンジニアになったりしているフルスタックエンジニアです。

元々のスキルセットがwebアプリケーションに傾倒していましたので、devops辺りに困りながら仕事しています笑

また、土日にこんなjupyter拡張機能を作っていたので見れくれると幸いです。

今回は、少し趣旨が外れて、windows向けアプリを作成のためのwindows環境の構築のお話をします。

pythonについてはほぼ書くつもりはないですが、pythonアプリ作成に直結し、また別の記事でpythonが絡む話をします。

なぜwindows10なのか

仕事で業務効率化アプリの話があって、使用する際のプラットフォームがwindwosになりそうということで。

機械学習モデルを組み込もうとした場合は必然的にpythonを使うことになります。 (学習だけをpythonでやってパラメータを別の言語で使うこともできるらしいが)

とすると、大抵は機械学習モデルをサーバーサイドに置いてAPIとして利用することとなります。 そうするとアプリの形態はweb(html/css/javascript)かネイティヴ(swift, java, kotlin, react nativeなど)となります。

しかしwindows向けのデスクトップアプリを作成する場合は大分話が違ってきました。 過去にそういう仕事があり、その時はUI作成にPyQtを使いましたが外部の情報含めてノウハウが非常に少なく相当苦労しました。

今回はそのリベンジの一環で、まずはwindows向けのアプリ開発環境を整える段階がこの記事です

作りたいアーキテクチャ

electron(html/css/javascript) + flask(python) 構成のアプリのビルド・テストが行えるwindowsを用意したいと思いました。 githubで見つけた、Electron as GUI of Python Applications(英語) というelectronを用いたpythonアプリケーション構築の紹介がありましたが、まさにこれに挑戦したい次第です。

本題のアーキテクチャですが以下のものが使える・できるものを用意しようと思いました。

  • pyinstaller(pythonwindowsアプリ化ツール)の使える環境
    • 今回はvenvかvenvをanaconda上で動かすことを想定
  • electronの使える環境
    • windows向けアプリがwindows上でしか作れないかは未調査だが一応。要nodejs
  • 出来れば上記のビルド用のwindows環境とテスト用のwindows環境が欲しい
    • vagrantでそれぞれの仮想環境を作成し、ansibleを仮想環境イメージの構築に使用
    • 特にGUIで使いたいということから、virtualbox利用を前提とするvagrantが適任と判断
  • windowsには詳しくないけど、上記の実行にPower Shellが必要?要調査

今回やったこと

vagrantでwindows10環境を構築しただけです。今回はosx High Serria上にvagrantを敷きました。 他にもやりたいことがある&windows向けのansibleの使い方がまだわからないので、 まだansibleに触ることはできていません。追々記事にしていこうと思います。

vagrantのインストール

virtualboxも事前に必要になります。 今回はvirtualboxvagrant共に公式サイトのインストーラーを使いましたが、brewでもインストールできます。 (インストールするまで気づかなかった)

参考記事まんまですが、brewの場合は

brew cask install virtualbox
brew cask install vagrant

で、caskが入っていない場合は先に

brew tap caskroom/cask

caskを用意

公式のインストーラーでVirtualboxをインストールした時は、High Serriaのセキュリティ機能でインストールができないので、 参考記事を見ながらセキュリティブロックを解除しました。

仮想環境の保存先を指定する

vagrantでwindows10のイメージをファイルにダンプしたら10Gぐらい使いました。

事前に容量を使うことは予測していましたが、vagrantで複数環境を用意する場合は、 10Gほどのものを複数用意することになるので、外付けHDDに環境を保存することにしました。

これも参考記事まんまで、以下を~/.bash_profileに追加 (/path/to/...の箇所は自分が保存したいパスに)

vboxmanage setproperty machinefolder /path/to/hdd/virtualbox
export VAGRANT_HOME=/path/to/hdd/vagrant.d

すぐにvagrantコマンドを使う場合は、忘れずに source ~/.bash_profile コマンドを。

windowsイメージを用意

vagrantをまともに使うのはこれが初めてでしたが、dockerと同様Vagrant Cloud(英語)というイメージのリポジトリがあるようで。

今回は、EdgeOnWindows10をベースとして利用。

公式にあったコマンドでVagrantファイルを用意

vagrant init Microsoft/EdgeOnWindows10 --box-version 1.0

イメージの設定

Vagrantで作成したwindows10をGUIで動かしたかったのでその設定。

同様のことをここここで紹介されていたので参考に

今回はGUI上で使うことも想定していますので、GUIで起動する設定をしました。必要事項としては

  • vb.gui = true (必要ないと書かれている場合もありましたが、一応入れました。)
  • vb.memory = 2048 (仮想環境で使えるメモリの指定。今回は2G)
  • vb.cpu = 2 (同様に使用するCPUの指定。今回は2)
  • vb.customize ["modifyvm", :id, "--vram" , "128"] (ビデオメモリの指定。GUIには必須?でGUI表示に使う。)

ちなみに使用するメモリを4G(4096)にした場合、メモリが片付いていないと止まるほど重くなったので、特にメモリを使う作業をしない限りは2G推奨です。

参考までに、私のosxのスペックは以下のようになります

- macbook air
- メモリ4G
- CPU Intel Core i5
- SSD 256G

実行

vagrant up

で起動できます。自動でGUIが起動すると思いますが、 自動で起動しない場合でも、VirtualBox上からGUI画面のウインドウを開くことができます。

f:id:TeraBytesMemory:20180304130703p:plain

こんな感じに起動します。

メモリ2Gに指定した時の画面ですが、少し動作が重かったです。

また、メモリ4Gで動かしていた時にAnacondaをインストールしましたが、その時はインストールに成功しました。

f:id:TeraBytesMemory:20180304130800p:plain

画像の通り、エンタープライズ版評価版です。Vagrant Cloudでは基本エンタープライズ版評価版のイメージしか上がっていない、というよりかはライセンスなしで使えるのがこれだけみたいですね。

90日しか使えない点に気をつけたいです。

参考記事

自分が使っているPython開発環境を晒す(3.データサイエンス編後編)

前回の続きです。

最近やりたいこともやるべきことも多くて手をつけづらかったですがようやく完結。 いよいよ機械学習の内容です。理論があまりわからなくても気軽に扱えるものから、 専門知識必須のガチフレームワークもあります。

例のごとくなので、専門的なライブラリほど 「こんなものがあるんだー」と興味を持ってもらえるぐらいでいいかと。

目次

機械学習

scikit-learn

pythonでは最も有名な機械学習ライブラリではないでしょうか。 ディープラーニング以前のアルゴリズムを網羅している他、機械学習の準備や評価に必要なAPIも揃えています。 ディープラーニングの時代になった今でも、scikit-learnにあるモデルが最適となる要件はたくさんありますし、 ディープラーニングを使う場合にも役に立つAPIもありますので、使う人も多いでしょう。

また、こちらも例のごとく裏ではcythonを用いていて、基本計算が早いです。 また、提供しているAPIメソッドもかなり単純に扱えるものとなっていますので、 機械学習の理論の知識が薄くても簡単に扱うことができます。(理解している方がチューニングはしやすいですが)

参考までに、機械学習をする際には前回の記事のグラフ描画ライブラリと一緒に使うと扱いやすくなります。

xgboost

世界中のデータサイエンティストが最強の機械学習モデルを競い合うkaggleで大人気のライブラリです。 kaggle内でも最強格かのような扱われ方をしており、優秀なモデルです。 元となるGradient Boostingというアルゴリズムにハイパフォーマンスなチューニングを加えたライブラリみたいです。

Gradient Boostingのアルゴリズムは正確には理解していませんが、特殊なチューニングを加えた決定木(?)に ブースティングという手法で複数の小さなモデル(弱学習器)を組み合わせて一つのモデルとして扱う(強学習器)アルゴリズムです。 あらゆるパターンを想定した小さなモデルができるため、ブースティングやそれと似たアルゴリズムは大抵良いモデルを作ります。

自分もkaggleを始めた時は好んで使っていました。scikit-learnと同じ要領で簡単に使えるのでこちらもおすすめです。 また、自分は使ったことないですが、LightGBMやcatboostというxgboostを意識してチューニングしたライブラリもあるので、 可能であればそちらも確認してみると良いでしょう。

参考

余談ですが、Rの実装もあるのでRが得意な人でも使えますし、Javaの実装もあるのでHadoopなどとも親和性が高いです。

pymc

自分は使ったことはないので、エアプ目線の解説で申し訳ないです。

ベイジアンモデルを組むためのライブラリです。 自分でベイジアンモデルを組むためのAPIが揃っているため、ベイジアンには嬉しいライブラリです。 理論がわからないと組めそうではないので、初心者向けではないです。 勝手にtensorflow(後述)のベイズ版って捉えていますが解釈合っていますかね?

これってHMMやCRF、LDAの派生モデルを組むのにも使えるのですかね?元自然言語処理専門としては非常に興味があります。

gpyopt

ベイズ最適化というアルゴリズムで、対象の関数の最適解(最大値もしくは最小値)を求めるためのライブラリです。 機械学習モデルをより高性能にするためのチューニングにも扱われますが、探索問題(最短で行き先全てを行くルートを探すなど) を解くための手法の一つとして役立ちます。

先述のscikit-learnでは基本分類(画像が犬か猫か見分けるなど)と回帰(様々な要因からアイスクリームの売り上げを予測するなど) を解くためのライブラリとは違う目的に使われるということで、これも覚えておきたいライブラリですね。

tensorflow

Googleオープンソースで開発したディープラーニングモデルを組むためのライブラリです。 こちらも理論をある程度知らないと扱うには難しいと思います。 ディープラーニングには必須なGPUによる計算を行う機能は当然のこと、有名なモデルをAPIとして提供しています。 ただし、これらの特徴は他のディープラーニングライブラリにも共通で、tensorflowの特徴として、提供するAPIの粒度が小さいことでしょうか。

この特徴はメリットにもデメリットにもなり

  • 新規モデルを組む時に融通が効き、自由にオリジナルモデルを組みやすい
  • 自分で書かなければいけないコード量が必然的に多くなり、気軽に扱いにくい
  • 理論がわかっていないと正しく組めないモデルもあり、上級者向け

といった特徴があります。自分としては理論が好きな人間なので、tensorflowを使うことが多いです。 特に、論文の成果は大抵Githubにtensorflowやpytorchなどで上げられていますので、 論文とコードを照らし合わせながら構造を理解したりチューニングしたりします。

他にも内部でtensorflowを使うがより簡単にディープラーニングモデルの組めるkerasや、 最近人気でわかりやすいコードが書けるpytorchといったライブラリもあるので、 自分にあったディープラーニングライブラリを探すことをお勧めします。

画像処理

ここからはケースによっては、機械学習を行うために必須となるライブラリ群の紹介となります。

opencv

C++で作られた昔からある画像処理ライブラリです。 pythonのラッパーも用意されており、pythonで扱うこともできます。

画像処理ライブラリの名の通り、プログラム上で画像を扱ったり加工したりするAPIが実装されています。 画像を機械学習可能な形式で読み込める他、画像の特徴(勾配、エッジ、コーナー)を抽出することもできます。 加工機能に関しては、抽出した特徴を画像で可視化したり、機械学習で検知した画像上の人などを囲うことにも扱えます。

pythonで扱う場合はpipでインストールできます。 opencvを直接ダウンロードしてコンパイルする方法もありますが、pipの方が断然簡単です。

pip install opencv-python
pip install opencv-contrib-python # 追加機能もあるが商用利用じには注意!

pillow

こちらはpythonでのみ提供されているライブラリで、opencvよりも気軽に使えるかと思います。 opencvとは異なり機械学習向けの機能は少ないですが、画像をプログラム上で読み込んだり加工するために使えます。 画像を機械学習可能な形式で読み込む機能もあり、jupyterとの親和性も高いので、画像処理関連でこちらを使う人もいます。

大した画像処理を使わない場合にはこちらを使うと良いでしょう。

自然言語処理

mecab

かなり有名だと思いますが、形態素解析(文中の単語を分けて、単語ごとの品詞などを抽出する)ライブラリです。 文章を機械学習モデルに使うときは大抵、単語レベルで扱うので自然言語処理にはほぼ必須です。 他にも、mecabを使って、係り受け解析や固有表現抽出を行うcabochaといものもあり、特徴を抽出する際にも扱います。

ただし、pythonで扱う際にはmecabをインストールしてからmecab-pythonというラッパーをインストールするなど、 少し面倒です。また、mecabを扱えない条件の場合には後述のjanomeを扱うといいでしょう。

また、neologdという現代語にも対応した辞書がありますので、そちらと一緒に使うと高性能になります。

janome

こちらもmecabと同様に形態素解析を行うライブラリですが、python純正のライブラリです。 自分が使う機会があまりないですが、mecabに依存していると困るって場合に使われることが多いみたいです。 機能は基本的にmecabと同じなので、拘る理由がない場合にはmecabで良いと思います。

ちなみに、janomeでもneologdを扱うこともできるらしいです(Githubwikiページ参照)

gensim

自然言語処理モデルがいくつか入っているライブラリです。 HDPやLDAといったクラスタリング(文書分類など)にも使える次元圧縮や word2vecやfasttextといった単語の意味を文脈で理解するword embedding手法が揃っているため、 単語や文章の特徴を抽出するために使えるものだと思っています。

特にword2vecとfasttextはいくつか学習済みのものがありますので、ケース次第でといったところでしょうか。

spacy

日本語には非対応ですが、英語、フランス語、スペイン語など欧米圏の言語処理に対して強いです。個人としてkaggleで使っていました。 形態素解析や固有表現抽出の機能を持つほか、

  • 単語の原型の情報( goes なら go に該当するとか)
  • 係り受け解析
  • テキスト分類
  • 単語や文の意味を示すベクトルへの変換をする

など現在までの自然言語処理技術がAPIとなっております。 また、ディープラーニングAPI(CNN、RNN)の機能もいつの間にか実装されていました。 ドキュメントを読んだだけですが、既存の機械学習および深層学習ライブラリと親和性が高いようです。

音声処理

ffmepg

こちらはpythonではなく、CLIツールです。動画や音声を加工する機能を持ち、 機械学習に使う場合にはデータを前処理する段階で音声や動画の切り出しやコマ分けをするのに使うことになるでしょう。 自分は音声処理をする時に使っていましたが、時間で切り出したり、無音部分を排除したりという機能があるので、 pythonのコードを書く前に軽く音声処理を試したい時に使っています。

librosa

音声処理のpythonライブラリです。 音声を波の時系列データ(一定時間ごとの音の大きさ)とサンプリング周波数(音を取る間隔) に分けて、音声を加工したり音声を可視化したりします。音声処理の理論をわかっていた方が扱いやすいですが、 知識が少なくても割と扱えます。音声処理はあまり知識がないですが、機械学習を行う際によく使われる処理がAPI となっていますので、音声処理屋には必須のpythonライブラリとなるでしょう。

AutoML

おまけとして書き加えました。この項もタイトルとは異なり使ったことはないですが気になったので。

最近Googleが公開した機械学習を行うSaaSです。 界隈ではすごく話題になっていますが、 データを投げるだけで勝手に機械学習をしてくれます。 このモデルを使ったり、精度を上げるためにチューニングしたりということは 全部向こうが勝手にやります。 前から機械学習を自動でやるAIを作る研究をGoogleで行われていたそうですが(参考記事は以下)、 いよいよ実用化といったところですね。

以下のqiitaの参考記事にもありますが現在はalpha版で画像分類だけみたいです。ゆくゆくは音声処理も実装されるとか。

このことを受けたのか以下のツイートも見かけました。

現状、評価に関しては人の目で行う必要があり、やはり基礎理論は必要ですが、 上記ツイートのようにプロフェッショナルの知識を持たない限りは、 AutoMLのようなプラットフォーム使った方が断然いい結果がでる未来はすぐ近くにあります。

機械学習を使ってみたい初心者もこっちの波に乗った方が良いでしょう。要注目です。

参考:

自分が使っているPython開発環境を晒す(3.データサイエンス編前編)

前回の続きです。

自分の中で週一でブログ書くって決めていたのですが、会社の技術ブログの記事 を書いていたので一週間遅れ。ちなみにあっちの記事は「フロントエンド開発環境を晒す」みたいにはなっています。

今回も予告通り、私のpythonデータサイエンス環境についてです。 python使っている人ならばご存知の通りデータ解析や機械学習に長けたライブラリやツールが豊富です。 pythonの華は機械学習にこそありますし、機械学習がしたくてpythonを使っている、勉強している人も多いでしょう。

本記事も例のごとく重く長い記事となり、自分で書いてても辛かったので前編後編に分けました。 前編は機械学習よりかは数値計算やグラフ可視化に重点を置いています。 機械学習に特化した内容は後編で書く予定です。待っていた方は申し訳ないですがもう少しお待ちを。

目次

データサイエンス環境

Jupyter Notebook

pythonデータサイエンティスト必須のインタプリタツールです。 ウェブブラウザ上のリッチなGUIpythonのコードを扱います。 Jupyter NotebookではIPYthon Notebook(.ipynb)という特殊なファイルを使って、pythonのコードがかけます。 中でipythonを使っているのでipythonのコマンドも使えます。 ipythonと比較すると

  • セルという単位に分けてpythonのコードを分けて実行でき、実行処理が追いやすいようなコードの分割ができる
  • セルのコードと実行結果は前述のIPYthon Notebook形式で保存され、プロトタイピングや実験に向いている
  • GUIベースで、読みやすいヘルプ機能、表やグラフの出力、音声ファイルの再生などができる
  • Markdownや数式が書けるセルを作成でき、コードスニペットや実行結果と組み合わせてレポートっぽいのが作れる
  • 環境設定次第では、htmlやlatexベースのpdfに変換できるので本当にレポートが作れる

特に表やグラフの可視化は可視化系で重宝しますし、機械学習においても画像・音声処理などでそのGUI機能は活躍します。 機械学習コンペのkaggleに参加しているデータサイエンティストもjupyterを使ったコードをアップロードしたりもします。

使えばわかると思いますがめっちゃ便利なので、使っていない人はいますぐインストールしましょう

pip install jupyter
jupyter notebook # で実行

グラフ描画・可視化

matplotlib

pythonでグラフ出力をするときに使います。 用途としては、通常の統計出力や、機械学習の学習結果を見る時が多いでしょうか。 具体的には、回帰分析の結果をプロットしたり、ディープラーニングモデルの学習状況を可視化したりですかね。

複数のグラフを書いたり、ラベルを可視化したりと欠かせない機能が多い分、結構操作が大変です。 自分もよく過去のコードを見直したり使いたい機能をググりながら使っています(チートシート欲しい)

pythonデータサイエンティスト必須ライブラリの一つと言いたいところですが、後述するもっと便利な描画ライブラリがあります。

seaborn

matplotlibのラッパーライブラリです。matplotlibで苦労して書いたグラフはseabornで1プロセスかつ綺麗に書けます。 matplotlibの入門を終えたらすぐこっちに移っていいかと。

plotly

最近はplotlyという超リッチなグラフ描画ライブラリがあるそうで、社内でも人気です。 今はこっちの方が主流なんですかね?今日軽く使ってみたところ、簡単にリッチなグラフがかけました。 javascriptも使われておりjupyterで超リッチなグラフ描画機能となっています。seabornより多機能です。

数値計算

numpy

言わずもがな有名な数値計算ライブラリ。python動的言語だから遅いだとか言われがちですが、 numpyはc言語で実装されており(cythonも使っている?)、pythonを通じた型推論により高速な行列演算をしてくれます。 python機械学習を高速で行ってくれる縁の下の力持ちです。 実際に、大抵の機械学習ライブラリでは依存ライブラリとして扱われています。

numpyではarrayという行列オブジェクトを使って計算を行います。 その機能は四則演算や内積外積、n乗、n乗根などといった基本的な数値計算から、 sin関数、cos関数、平均、標準偏差といった関数、行列同士の結合、ゼロ埋め、数値のフィルタリングなど 非常に多くの便利機能を備えています。

numpyもpythonデータサイエンティスト必須のライブラリです。

また、blaslapackという数値計算ライブラリに頼った計算もでき、導入すると更に速くなります。

pandas

こちらも有名で、表計算ライブラリとなります。 基本的にはDataFrameと呼ばれる表のオブジェクトを使ってデータ処理を行うものとなっています。

統計可視化や機械学習のための事前データ処理に優れており、中でnumpyが使われているため、 numpyの機能の一部をpandasで使えたり、numpyの要領で数値計算ができたりします。 列(データ)ごとで平均・標準偏差の計算といったnumpyの基本から、欠損値(データが無い場所)埋め、 自分で書く必要はあるもののlambda関数を使った列ごとの独自定義の演算や文字列の数値id化などができます。

また、DataFrameの表は基本的にラベルを持っており、Jupyter Notebookでは表として出力できたり、 seabornにそのままDataFrameの表を突っ込んでグラフ統計の出力ができたりと表計算ライブラリとして非常に優秀です。

csv、エクセル、hdf5といった表形式ファイルとも互換性がありインポート・エクスポートをする機能もあります。

これもpythonデータサイエンティスト必須のライブラリです。

SQL(NoSQL)

pythonではないですが、よくデータサイエンスに必要なスキルとして挙げられます。 小さいデータであれば前述のpandasでどうにでもなりますが、大きなデータはメモリに乗らず、データ処理ができません。 一方、SQLならばデータベースとしてHDD・SSD上で読み書きをするため大規模でもあまり考慮する必要がないです。

ただし、自分は業務でもビッグデータを扱った経験がなく、pandasで処理ができなかったり、逐次処理(バッチ処理)をしたいときに使うぐらいです。 ビッグデータを扱う場合にはHadoop、Hive、Sparkと組み合わせて使うのでしょうかね。

ちなみに自分がよく使うのはsqliteとmongodbです。前者は一つのファイルとして扱え共有しやすいから、 後者はいちいちデータ構造を定義しなくても良くリストや文字列が扱いやすい&ビルトインでmap-reduceが使えるからです。 webアプリケーションを作る場合には流石にMySQLPostgresql、elasticsearchを使います。

高速化・並列分散化

numba

関数にデコレータをつけるだけで、実行時に関数をコンパイルし、c言語並みの計算速度を出すことができます。 条件が限られますが、主にfor文内の数値計算を爆速にしてくれます。そのfor文の中にif文が入っていると高速化しづらいです。

自分の書いたコードが遅いと感じた時にこいつを使ってやると魔法のように爆速な計算ができるかもしれません。

cupy

有名な日本のディープラーニングライブラリであるChainerの内部で使われています。 その名の通り、cuda+numpyといった感じで、GPUを使って計算するnumpyです。 機能としてはnumpyと同じ関数やメソッドが実装されており、GPUを使ったより爆速な数値計算ができます。 自分の知る限りですと、基本的にはchainer内で使われているくらいのようです。 自分もchainer以外でも使ってみたい思って、なかなか実行に移せていないぐらいです。 ニッチな用途ですと、従来の機械学習のコードでnumpyをこいつに置き換えると遅い学習も早くできるだとかいう話があったような。

ただし使用する分にはGPUとcudaドライバが必須となります。

dask

並列処理のpandasという位置付けのライブラリです。中でpandasを使っており、pandas感覚で扱うことができます。 pandasの差異としては

  • 実行する計算は何個かのDataFrameに分割して並列で計算する
  • 分割して計算を行うのでメモリ効率がよく、メモリエラーを起こすような巨大なデータに対しても使える
  • 計算はすぐに実行はせず、各計算やメソッドの実行はタスクを登録するだけ。computeというメソッドを実行すると、登録したタスクを実行する
  • 登録したタスクは図として可視化できる

といったところです。並列処理の強みであるメモリ効率や単純な高速化に目が行きますね。

cython

pythonc言語に変換してコンパイルする特殊な言語です。こちらもnumba同様pythonコードの高速化に使います。 pythonのコードをまんまコンパイルできますが、cythonの型宣言を使うことでc言語並みのスピードを出すことができます。 用途としては、高速化というのが普通で、機械学習ライブラリにcythonが使われることもあります。 cythonさえインストールしていれば、ipythonやjupyter notebook上でコードをすぐにcythonコンパイルすることができ、 numbaと同様簡単な高速化が実現できます。

自分が使っているPython開発環境を晒す(2.Web開発編)

前回の続きです。 今回は予告通り、pythonのWeb開発で使っているものの説明です。 pythonでもweb開発のライブラリ・フレームワークが豊富でユーザー数も多いです。 python機械学習ライブラリが増えてきた結果、webアプリと機械学習は親和性が高いものとなりました(多分)。 機械学習を使ったwebサービス作りたい方に参考なれば幸いです。

今回は特に用語やコード設計について盛り込んでおり、初心者向けではないのでご了承ください。 特にわからないところは、見出しの単語をぐぐって初心者向けの記事を読んだ方がいいかと(小声)

目次

Django

pythonでは一番有名なウェブアプリケーションフレームワークでしょうかね。

主な特徴としては

  • サーバーアプリの基本であるMVCを使って開発できる
  • MVCに従ったアプリの基本構造を自動生成する
  • DBのテーブル管理をdjango側がやってくれる
  • Ruby on Railsと比べるとルールに従う必要が少ない分、コード量が増えたり技量が必要となる

といった、Railsほどではなくても優しく、大規模Webアプリ向けとなっています。

djangoをpipでインストールすると扱えるCLIでプロジェクトディレクトリを作成できます。 また、作成したプロジェクトディレクトリ直下にあるmanage.pyというスクリプトでWebアプリの開発・管理ができます。 公式チュートリアルを見ればわかりますが、 モデル用、ビュー用、ルーティング用のpythonファイルが作られ、サーバーアプリ開発入門者にも雰囲気が掴めるようになっています。

...とは言っても、

  • 実質、テンプレートがビュー、view.pyがコントローラになっていて、名前がややこしい
  • モデル(model.py)やコントローラ(view.py)を単一ファイルになっている

といったRailsよりも汚くなったり、実装をするのが難し買ったりします。

反面Railsとは異なり処理が隠蔽されていないので、import文で簡単にオレオレ構造が作れます。 上記を対処すると

  • model.pyをモデルごとにコードを分割して、modelディレクトリにまとめる
  • view.pyの名前をcontroller.pyにする

ぐらいでしょうか。また、書き方のコツとして、

  • コントローラはモデルのデータを(加工して)ビューに渡すだけ
  • モデルを太らせる(モデルを重点に機能を実装する)

といったところでしょうか。 今はReduxクリーンアーキテクチャ の登場によって、サーバー側は自然と上記の書き方をせざるえなくなりましたが、 登場前はMVCの考え方(捉え方を間違っていないか) の議論がされていました。今の時代でも、MVCについて正しい理解をし、コントローラの役割を意識してモデルを太らせることを意識すれば、自然と構造的かつ綺麗にかけます。

Django REST framework

DjangoAPIを書く場合に重宝します。以下の記事を読むと雰囲気が掴めると思います。

上記の記事では

  • SerializerでモデルのJSON出力の仕方を定義
  • ViewSetでモデルに対するクエリ処理と、定義したSerializerに準じたAPI出力

を解説していますね。特に、モデルの読み書きをJSON形式のREST APIにするだけならこれだけで簡単かつ綺麗に組めます。

リクエスト・レスポンスの定義やコントローラの処理を細かく描きたい場合にも、APIViewResponseといったAPIも提供されています。 英語ですが、公式チュートリアルをざっと読むだけでもしたい処理が簡単にできるようになるのではないでしょうか。 最近は、ビューの処理をフロントエンドで完結できるようになり、 自分もフロントエンドのルーティング以外はこれを使ったAPIしか書いていません。 Djangoを使う際はこれと合わせて使っています。

また、Django REST framework JWT という REST API にJWT認証機能をつけることができるライブラリもあります。 リリースするときを考えて、一緒に使いたいですね。

Flask

小・中規模のサーバーフレームワークです。自分はプロトタイピングによく使っています。 ほぼ公式のコードですが、以下の数行ですぐにサーバーアプリが作れます。

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
  app.run()

上記app.pyというファイル名で保存すれば、python main.pyコマンドを実行して http://localhost:5000 で起動できます。

上記のようにデコレータにパスやメソッドを指定し、返り値にAPIやhtmlの出力を返してやるだけでサーバーアプリが書けます。 flask標準でテンプレートのレンダリングjsonのアウトプットのラッパー関数がある他、ステータスコードやヘッダを自分で設定できたりもします。 ただし、flaskにはデータベースの操作・管理機能はないので、使いたい場合にはSQLAlchemyなどのライブラリを使いましょう。

また、viewの関数のコードをファイルに分割することができ、flaskでもMVCベースのアプリが書けます。 下記のSQLAlchemyを使えば、多少規模が大きいアプリでも問題なく扱えることができます。

参考:Flaskで大きいアプリケーションを作るときのTips

他にもbottleやtornadoなど他にも小規模webライブラリはありますが、自分はflaskでほぼ不便なくコーディングできて、主にこれを扱っています。 ユーザー数も多い方らしく、追加機能となるライブラリも豊富です。

Flask-RESTful

FlaskでREST APIを書く場合に重宝します。標準でもJSONAPIは書けますが

  • メソッドごとに処理を分けて書ける
  • リクエスト時のパラメータを argparse のように定義ができる
  • レスポンス出力のスキーマを定義できる

といったアプリの保守性に優れたコードを書くことができます。

また、FlaskのBlueprintを使わずともFlask-RESTfulのAPI定義をファイルごとに分割できますが、 Blueprintを使った構築も公式でサポートされています。フロントエンドもFlaskでパス通す場合はBlueprint使った方がいいです。

SQLAlchemy

pythonRDBを扱うときに便利なDBライブラリです。 基本的な機能としては

といったDjangoRDB操作と似たような機能を持っています。前述の通りFlaskのような小規模サーバーライブラリは標準でRDBの操作機能を持っていませんので、 SQLAlchemyなどに頼ることになります。メソッドチェーンの容量でSQLの処理を書き連ねることができ、 最後にデータ呼び出しはallメソッド、データ書き込みはcommitメソッドで実行することができます。

具体的な使い方は他の記事に任せますが、テーブルごとにソースファイルを分けるのが難しいです。 個人的には分けて使いたかったので、以下のstackoverflowに上っていた対処法を参考にテーブルの定義を分割しています。

python - SQLAlchemy classes across files - Stack Overflow

自分はFlaskでデータベースを使いたいときに使っています。

jinja2

DjangoやFlaskで扱われているテンプレートエンジンです。

ただし、上記のようにREST APIを出力するだけのサーバーアプリを書く場合には全く必要ないです。 実際に私もこれに頼ることはほとんどなく、フロントエンドにおいてVue.jsでのプロトタイピングの際に文法が競合してむしろ迷惑になります。

Vue.jsを使う場合はこれを参考にjinja2の文法を変えています。

pipを使わずとも大抵Djangoやflaskについています。

uWSGI

pythonサーバーアプリのデプロイをする際に用います。 早い話、こいつがサーバーアプリの面倒をみる役割を持っています。 こいつを使う際は、uWSGIの設定ファイルを用意して使い(必須ではないが使った方がいい)、 アプリのパスやプロセスIDファイル、ログファイルを設定することになります。 ちなみに私はuWSGIとnginxを組み合わせて使っていますが、最近はサーバーレスな構築できるようになりuWSGIだけで十分なケースも現れました。 EC2にuWSGIとnginxを載せた時は結構大変でしたので、サーバーレスでuWSGIだけを使うのが良いと思います。

API Blueprint

APIの仕様書を書くのに特化したマークアップ言語です。 基本はMarkDown準拠でAPIパスに対し、メソッドごとに仕様の説明やパラメータ、リクエスト・レスポンスのJSONスキーマの定義などをこれで書きます。

共同開発には必須となるでしょう。

また、apiaryというサービスを使えば、ウェブ上でAPI Blueprint準拠のドキュメントが書け、これをベースにAPIのモックが書けます。

社内のアプリ開発に関しては、少人数のスタートアップなので、基本自分だけで開発していました。 そのため、ほとんど使う機会はありませんでしたが、そろそろ共同開発することも増えてきて導入を検討しています。

自分が使っているPython開発環境を晒す(1.開発環境編)

記念すべき第一記事はpythonの開発に関して書くことにしました。 個人でpythonを書くという話はよく聞きますが、開発の業務でpythonを使うという例はまだまだ少ないようです。 統計分析や機械学習をする、機械学習モデルを組み込む必要があるからという限りで実用されている話は聞きますが、 例えばweb開発(pythonでもできる)なんかはやはりrubyphpが優勢でメジャーとなっていますね。

一方でAIブームに火がついてからは、pythonを中心に深層学習ライブラリが作られ、機械学習をしたい(もしくはしている) というケースも増えました。特に機械学習を導入する場合には、やはりpythonで開発ができた方が有利だと思っています。

ということでpythonを業務で使いたい人やpythonOSSにコミットしたい人もいるんじゃないかなーと思い この記事を書くことにしました。AIスタートアップに勤めている身なので、pythonで開発していますので、そのノウハウを公開します。

あまり入門者向けではないですが、pythonでの開発においては基本となるものを紹介します。 pythonを始めたばかりで、pythonではどうやって開発するの?と疑問に思っている人向けに書きました。 また、本記事でおまけとして勉強方法を載せましたので、入門者はまずそちらに目を通すと良いと思います。

本記事は開発環境編、web開発編、データサイエンス編の3編構成で公開する予定です。

目次

バージョン管理 - pyenv virtualenv

Macの場合は最初からpythonが入っていますが、古いバージョン(python2)なので非推奨です。 また、プロジェクトごとにpythonのバージョンと使うライブラリを設定できる pyenv-virtualenvというバージョン管理ツールがあるのでそれを使うのをお勧めします。

OSXならばHomebrewでインストールできますし、それ以外でもgit cloneですぐに導入できます。 詳しいインストール方法は以下のサイトで説明されています。

パッケージ管理 - pip

pythonのライブラリをインストールや依存関係の管理は、python用のパッケージマネージャであるpipを使います。 ライブラリだけではなく、pythonで書かれたツールや他にpythonに関連するものもこれを使うことになります。 pythonでの開発には欠かせないでしょう。

また、標準でeasy_installというインストーラCLIもありますが、pipの方がパッケージ管理において優れています。

基本的にはpip install some_libraryみたいにインストールコマンドを使うことになります。 また、プロジェクトのソースコードを共有する場合に、pyenv-virtualenvを使っていれば、 プロジェクトごとのライブラリの依存関係を再現できるようにpipでインストールしたライブラリ一覧を作成できます。

pip freeze > requirements.txt
pip install -r requirements.txt

上記のコマンドのように、pip freezeでインストールしたライブラリ一覧をrequirements.txtで出力し、 pip install -r requirements.txtrequirements.txtの一覧からライブラリをインストールします。 使えばわかると思いますが、依存関係にあるライブラリのバージョンも保存されるので再現性を担保しています。

pyenvを導入した場合には既に使用することができます。

コードチェック

flake8

flake8はpythonの型チェッカーです。エラーチェックとコーディングスタイルチェックができます。 pythonのコーディングスタイルであるPEP8のルール通りに書けているかを確認します。 コーディングの初心者でもPEP8のルールを守れば大体コードが綺麗になります。 pythonのlinterはいくつかありますが、使った中では一番使いやすかったです。

flake8の機能を拡張するlintツールもあり、flake8以外のlintツールが気になる方は以下の参考記事を読むと良いでしょう。

mypy

python3から型を宣言できるようになりました。しかしpython3自身には型チェックをする機能はありません。 mypyというlintツールが存在し、mypyで型チェックが可能です。 変数や引数の型指定だけではなく、javaで言うところのinterfaceが使えるみたいです(使いたいとは思っていますが、まだ試してもいません) ただし、mypyを使う風潮はまだ浸透していないようで、非公式の記事が少なかったり、ライブラリでの対応がされていなかったりします。

...と思いましたけど、どうやらpycharmという統合開発環境ではしっかりサポートされているらしいです。 mypyに関しては使い込んでからまた記事にしたいですね。

インタプリタ - ipython

python自体にインタプリタの機能が備わっていますが、ipythonというより便利なインタプリタがあります。 通常のpythonインタプリタとは異なり

  • シンタックスハイライトがされている
  • TABキーで自動補完ができる
  • インタプリタ内でシェルコマンドが使える(もちろんcdワークスペースとなるディレクトリの移動もできる)
  • 専用の文法が追加されている
    • オブジェクトの末尾に?をつけるとドキュメントが見れる
    • ベンチマークテストをするコマンドがある
    • その場でデバッガを起動できる

など便利な機能が揃っています。ちなみにカスタマイズもできるそうです。

pipでインストールできます。

pip install ipython

また、ipython以上に便利でGUIで使えるjupyterというツールもありますが、 データサイエンス編で紹介したいと思います。

仮想環境 - Docker

作成したアプリケーションを仮想環境上にデプロイする例もありますね。使ったことがある人もいると思います。 pythonで開発する場合も例外なく使えるケースがあります。特にDockerは不必要な依存関係を断ち切ったり、 再現性も担保できますからね。web開発以外にも、データサイエンスで使えることもあります。

OSXならhomebrewで、WindowsLinux公式のインストール方法(英語)を参照してインストールできます。

また、Docker上の仮想環境でGPUで計算を行うためにnivida-dockerという便利な拡張がありますが、 これもデータサイエンス編で紹介します。

テスト

nose

そもそもpythonで標準のテスト用ライブラリ(unittest)が存在しますが、自分はnoseを使っています。 出力結果の確認や実行時間のベンチマークテスト、カバレージ評価などテストに必要な機能はもちろん揃っています。

pipでインストールできます。

pip install nose

また、書いたテストを実行する場合にはnosetestsというコマンドでテストを実行できます。

実際に導入する場合には、後述のプロジェクト構成に載せた参考記事を読むと良いでしょう。

tox

プロジェクトによって複数のpythonのバージョンで動作をする必要がある場合にtoxが有効です。 toxは複数バージョンのテストを同時に行うことができます。tox.iniという設定ファイルに pythonのバージョンや依存パッケージ(requirements.txt)、使用するテストツールを書けば、 toxコマンドで複数バージョンにおけるテストを実行できます。 また、公式でjenkinsで使うための機能もあるようで、CIとの親和性も高いようです。

pipでインストールできます。

pip install tox

自分自身に関して言えば、実際に使ったことはないですが、要件定義の際に知っておくべきツールだと思いました。

プロジェクト構成

pythonアプリ開発をしたり、ライブラリを作って公開するには、どういうディレクトリ構成が良いか、 自分は以下の記事がとてもよくまとまっていると思いました。特に実務やOSS活動をする場合には 一読することをお勧めします。

プロジェクト構成以外にもパッケージの作り方やテストの書き方も記載されておりとても参考になります。

勉強方法

基礎

現在、検索すればpythonの入門講座をすぐに見つけることができ、簡単に勉強できるようになっています。 メジャーなものだとドットインストールとかが挙げられますね。 コーディングも初心者という方はpaiza learningProgateで勉強することをお勧めします。

発展

pythonでのコーディングができるようになり、pythonについてもっと勉強したいという方は やはり実際のpythonコードや公式ドキュメントに触れるとより力がつくと思います。

特に公式で導入されているユーティリティライブラもありますが、実際のところ知名度が低かったりし、 また新しいバージョンで導入された機能を勉強するためにも、公式のドキュメントを読むことはお勧めします。

公式ドキュメント

日本語のドキュメントも存在し、充実しています。英語に抵抗がある場合にはこちらを読むと良いでしょう。 初心者はチュートリアルpythonの基礎知識の確認および補完し、ライブラリーリファレンスでユーティリティライブラリを勉強すると良いでしょう。

github

実際のコードを読むといったらやはりgithubでしょう。 まずは、Github Trendingで有名なpythonライブラリに触れてみてはいかがでしょうか。

PEP (Python Enhancement Proposal)

コーディングやドキュメンテーション作法はPEP (Python Enhancement Proposal)で学べます。 会社のコーディング規則があったり、実際にそれが公開されているケースもありますが、いずれの場合でも基本はこれに従っています。 ゴリゴリ書く人は必読でしょうか。

終わりに

これを書くだけでもコンテンツ量が多いし、エディタやCIに関しても書きたかったけど力尽きた... 執筆し始めた時は網羅的なコンテンツになると思っていましたが、意外と失念していたものもありました。 余裕ができたらアップデートしたりします。

これがpythonで書くきっかけとなってくれれば幸いです。 また、「こっちの方が便利だぞ」みたいなコメントも遠慮なく受け付けています。

引き続き他の章を公開していく予定なので応援お願いします。