読者です 読者をやめる 読者になる 読者になる

器用貧乏系エンジニアの憂鬱

このところ Inposter Syndrome *1 やエンジニアキャリア形成についてオンライン/オフラインで重ねて見聞きする機会があり、改めて言語化 (+可視化) しておきたいなと思ったのが筆を執った動機です。

タイトルは語感を拝借しただけで特に僕が憂鬱になっているわけではないです。お正月の読み物コンテンツとしてご家族でお楽しみください。

学び

  • matplotlib で レーダーチャートを描くのはかなり厳しい

器用貧乏系エンジニアとは

器用貧乏とは、新明解国語辞典第7版によると、以下のように定義されています。

「器用」なため、一つの事に集中出来なかったり 他から重宝がられて雑多な用に使われたりして、かえって、大成出来ないこと。

転じて、ビジネスにおけるスキルセットを評価する際に、いわゆる Generalist やオールマイティータイプの自己謙遜あるいは自嘲表現として用いられることがあります。これを更にエンジニアのコンテクストに転じたのが、器用貧乏エンジニアということとします。

この善し悪しは非常に難しいのですが、悪い面について個人的な経験から言うと、なまじある程度自分できるだろうという感覚 (慢心?) を持っているために何でも自分でやってしまい、プロフェッショナルに任せたり、誰かを頼ったほうが結果としてよいものができる機会を逸してしまうことがある、ということでしょうか。

良い面として、自立稼働できる範囲が広いためスピーディに物事を進められるということがあると思います。特に、コンピューター1台あれば製品を作り上げられるソフトウェア開発においてこれは顕著な部分です。

長所と短所は表裏一体と言いますから、自覚的であればよいのではないだろうかと思っています。

なお器用貧乏という言葉を取り上げた背景として、僕自身が学生時分から悪い面での器用貧乏を自覚することが多分にあったからです。これはいまだに引きずっていますので三つ子の魂なんとやらですね。

自尊心の消失

仮に、次のような Generalist タイプの A = Annie がいたとします。数値がいくらかということは本質ではないのですが 5つのパラメータのポイントは5に振ってあります。

f:id:iktakahiro:20170101203024p:plain:w400

エンジニアの評価指標としては大味過ぎるうえに全然MECEでもなく、かつ綺麗に同レベルなスキルを持っているというのも現実的ではないのですが、あくまで例ですので大目に見てください。

Annie が自分自身を「器用貧乏である = 専門性がない」と感じるのは、例えば次のような Specialist B = Barbara と比べたときでしょう。

f:id:iktakahiro:20170101202905p:plain:w400

Annie と Barbara のパラメータの合計はともに25なのですが、Barbara の場合特定の領域で 9ポイントと高いスコアを持っていて、つまりこの部分が専門性ということになります。

Annie の強みは 1人で何役もこなすことができる点にあるので、組織の立ち上がり時期など不確定要素が大きい場面で重用されることがあります。

いっぽう何らかの難しい問題に取り組む場合、例えば Front End の領域においてレベル8以上ないと解決出来ない課題にぶつかった場合、Generalist タイプが何人いても歯が立たない ということになってしまい、その道の Specialist である Barbara さんが求められます。それ故に、取り組むべき課題領域がある程度明らかになってきた段階、言い換えると分業化が進められる段階においては、各分野の Specialist タイプを揃えるのがよいのだとも言われます。

もちろん最初期から高い専門性が必要な場合もあるでしょうし、組織形成の方法論についてはさまざまありますのであくまで一例です。ただいずれにしても、一定以上の成熟をした組織においては Specialist タイプが求められることが多い傾向にあると (おそらく一般に) 考えられており、そのため Generalist にとって、Specialist ではないことが負の面として捉えられるのだと思います。

下位互換の溜息

以下のようなパラメータをもった Generalist C = Charlotte がいたとします。Charlotte はすべてのパラメータを7に振ってあります。

f:id:iktakahiro:20170101210604p:plain:w400

Annie からみると Charlotte はスペック的に 上位互換 にあたり、Annie は「Charlotte とに比べたら自分は何もできない」という下位互換的な劣等感を感じるかも知れません。この「何もできない」という感覚は結構強力で、人を後ろ向きにさせるに充分な威力を持っているように思います。

※ ちなみにここでグラフを重ねて見せたりするとちょっと気が利いた感じになると思うんですが綺麗に見せるための実装コストが高くて断念しました。厳しい。

また厄介な問題として 実際 に Charlotte が実在しなかったとしても Annie は同じように考えるかも知れない、ということがあります。非実在フルスタックエンジニア とも言うべき幻像を勝手に見繕ってひとりでに劣等感に浸っているというケースですね。これがポジティブな謙虚さの獲得に働けばよいのですが、そうでない場合、典型的な Inposter Syndrome に陥る危険をはらんでいます。

専門性と Identity の分裂

専門性をもつ Barbara にも勝てない相手がいます。さらに上位の専門性をもつ Specialist D = Dorothy です。

f:id:iktakahiro:20170101231739p:plain:w400

さて、Barbara は Dorothy に負けているとは感じつつ、自分の得意領域については引き続き認められる傾向が強いのではないでしょうか。

実際は専門領域ですらあいつに負けた!きぃっ!となる人が多くいるのかも知れません。ただ、Generalist/Specialist の自己承認の獲得プロセスと、「私はこれが得意」という Identity を持っているかどうか、という2つは無関係ではないように思えます。器用貧乏を自覚 -- それが事実ではなかったとしても -- しているタイプは Identity が弱いからこそ他人と比較して落ち込みがちであるという理屈です。

器用貧乏の生存戦略

ここまでにいくつもプロットしておいてなんなのですが、実際の人の技能というものは単純にプロットできないケースがままあります。単位時間あたりの何某、ということであれば定量的に観測したり比較できるのですが...またそもそも、スキルの大小ではなくあるビジネスの目標における貢献度や達成度という指標で評価される場合*2もありますから、結局のところ何を指標に定めるかということによって自己肯定感も変化するものと思われます。

ともかく、なんとか器用貧乏を脱出するというのが一手なのでしょうけれど、パラメータを振り直すわけにもいかず、なかなか脱出できないからこその器用貧乏という側面もあって、じゃあどうしていこうかということで以下に生存戦略を整理してみました。

軸を加える

器用貧乏を自認するタイプの1つの生存戦略として 別のパラメータを加えてみる、ということがあると思います。

これまで5軸しかなかったパラメータセットに第6の軸を加えてみます。

f:id:iktakahiro:20170101232730p:plain:w400

Communication という軸はちょっとベタすぎたかも知れませんが、ともかく我々の住む世界では、ロールプレイングゲームのように「力・魔力・素早さ」といった単純なパラメータが固定的に決まっているわけではなく、求められる能力が刻々と変わります。別の視座を持ってみることで、自分の強みを見つけられる可能性があります*3

総合力で勝負する

総合力をそのまま強みとすることもできると思います。自身の体験なのですが、Webサービスの画面遷移について考えているとき、RDB のテーブル設計とREST API の URI パターン、そして SPA の Routing 設定という3つを一気通貫で考えると実装がとてもシンプルになるのではないかと気付いたことがありました*4。この発見はごく個人的なことだったかも知れませんが、複数の領域に取り組んでいなければ得られなかった気付きだったと思っています。

じつにさまざまなものが Commodity 化してしまう昨今、横断的活用能力のようなものが強みになりやすくなっている時代であるとも思います。

ロールを変える

ロールを変えてみる。器用貧乏と観測しているスキルセットはあくまで特定集団 (e.g. プログラマ) と比較した場合であるはずですから、集団を変えてみるということです。これは「軸を加える」とほとんど同じ試みであると思います。

ただ、いわゆる狭義のソフトウェアエンジニアであることやコードを書き続けることにこだわりを持っている場合ロールの変更は容易ではないかも知れず、これは引き続き向き合うべき課題であるように感じます。また、ロールの変更先が無専門によって成り立つというわけでもないでしょうから結局同じ問題に突き当たる可能性もあります。

鶏口牛後 という故事がありまして、Annie であれば Barbara も Charlotte もいない環境を見つけて生きていくということも選択肢としてはありなのかなとは思います。ただ、その場合も 非実在 Charlotte が常に存在しますので逃げられない気はしますね。Charlotte 手強い。

卑屈になるのをやめよう

みんなちがって、みんないい。

ということに尽きると思うんですが、「人それぞれに価値があるのです」と表明しているその人自身にぶっちぎりの専門性があったりして...みたいなところありますよね。

ただ、隣の芝は青い理論と言いますか、Charlotte や Dorothy にも悩みはあるかも知れないよね、ということと、例え多くの技能が実際にプロットできてしまったとしても、それらと人格はやっぱり別もの、ということはある程度真理な気がしており、このくだりの情報量全然ない感じですけれど、まぁそんなに気にしないでいいんじゃないかなというスタンスで生きていくのがよいのではないでしょうか。

matplotlib と レーダーチャートの話

最後に matplotlib の話します?

公式ドキュメントにレーダーチャート作成のサンプルが一応あるんですが

これコード量が多くて参考にするのが結構しんどいんですよね。D3.js のサンプルも似たような感じっぽいのでこんなもんなのでしょうか。Excel だと一瞬で作図できた気がしますが。

重ね合わせなくてレーダーチャート描いた意味があったのか果たして、という逡巡もあったのでちょっとだけ頑張ってみたのが以下です。

f:id:iktakahiro:20170102012747p:plain:w350

レーダーチャート作成の専門性を持ちたい人生だった。

関連するかも知れない書籍

タイトルがまさにという感じですが原著がとっても有名ですね。

SOFT SKILLS ソフトウェア開発者の人生マニュアル

SOFT SKILLS ソフトウェア開発者の人生マニュアル

環境を変えることに後ろめたさを感じている人向け。この話はまたどこかでしたいです。

西の魔女が死んだ (新潮文庫)

西の魔女が死んだ (新潮文庫)

*1:http://syobochim.hatenablog.com/entry/2016/09/21/130400 とか

*2:前者は職能、後者は実績などとされます

*3:しかしこれ実は Communication の Specialist なのでもはや Generalist じゃないじゃんというツッコミはできますね...。Charlotte が実は Communication 能力が著しく低かったという仮定のほうが妥当だったかも知れません

*4:その一部を整理したのが右記の資料でした Go 言語と React で考える「いい感じなURL設計」入門

いまこそ Python に "再"入門!! - 技術評論社『科学技術計算のための Python 入門』

積ん読消化週間ということで『中久喜 健司 (2016). 科学技術計算のための Python 入門 - 開発基礎、必須ライブラリ、高速化, 技術評論社』(以下、本書) を拝読しましたのでレビューを掲載します。

科学技術計算のためのPython入門 ――開発基礎、必須ライブラリ、高速化

科学技術計算のためのPython入門 ――開発基礎、必須ライブラリ、高速化

総評

本書の最大の特徴は、Python の文法や言語仕様の解説と、Python を分析ツールとしてみたときの用法がとてもバランスよく散りばめられている点です。

本書の内容は、大きく2つに別れます。Python の言語仕様や、開発するうえでの基礎知識を得られる前半と、いわゆる PyData パッケージ群について学べる後半です。前者については、動くコードを書くことを求めるあまり Python やプログラミング言語自体への理解がおざなりだったと考えている Python ユーザーに適した内容です。後者は、NumPy や SciPy などの有名な PyData 系パッケージを理解するための足がかりとなる内容で、これから本格的にデータ分析ツールとして Python を使い込んでいこうとするユーザーに役立つ内容です。

対象読者について

近年 Python の人気により、基礎から応用までの文法書は多く出版されています。データ分析に対する需要も引き続き高いようで、統計解析や機械学習関連本の刊行も活発です。後者にフォーカスを当てた書籍においても、副題に「Python 〜」と添えられていたり、サンプルコードが Python であるケースが目立ちます。

既存の書籍の傾向として、Python の文法にフォーカスを当てた書籍ではデータ分析の話題に触れられることは稀で、反対にデータ分析系の書籍においては、Python の文法に関しては概要に触れるだけにとどめられることが多いように思われます。これはもちろん、両者ともに奥深いものであるためいずれかにウェイトを置く必要があるからでしょう。

本書は「文法書」に近い構成です。分析手法や統計アルゴリズムはほぼ登場しません*1。本書後半のパッケージ紹介においても、著名な機械学習パッケージである scikit-learn の解説は省かれています。これが意図的なものであるのは、以下に本書 v頁より引用する想定読者からも明らかです。

本書の想定読者は、これから科学計算技術やエンジニアリングに Python を使い始めてみようと考えている方々で、たとえば以下のような方々です。

  • Python がどのような言語で何ができるのかを学びたい方

  • Python で科学技術計算を行ってみたい方

  • Python によるハイパフォーマンスプログラミングの基礎知識を学びたい方

  • Python の文法に加えて、実践的なプログラム構築法を学びたい方

今回のレビューとしても、上記がそのまま本書をおすすめできる読者層です。Python や科学技術計算といったワードから、例えばディープラーニングについて解説されているかのようなことを連想し期待するとミスマッチになります。

また、これは意見の分かれるところとは思いますが、プログラミング言語自体への入門としてはより平易な他の書籍を探すほうがよいでしょう。変数やデータ型などの基礎から解説されているため入門書とできないこともないのですが、全体的にフォーマルな解説で敷居高く感じられる読者がいるであろうことも否めません。

以下、各章について簡単にレビューします。

第1章 - Python の現状とその人気

導入部分で、技術的な内容よりも、「なぜ Python が使われるのか?」について紙面を割いている章です。「Python は最近人気である」「教育分野で利用が進んでいる」といった一般に聞くことがある内容を、論拠を示して解説しています。やはり一般に弱点とも言われる実行速度についてなどの言及もあり、「Python ってどうなの?」と聞かれた場合の回答としてはこの章を示せば充分なほどです。

第2章 〜 第3章 - 科学計算実装の流れ

「ロケットシミュレータ」を実装するという目的設定のもと、コーディングから静的コード解析、デバッグについて触れられているのが2章です*2。ユニットテストにも言及があるなど実践的でよいのですが、力学についての用語やそれなりの量のコードがいきなり登場するため、平易な内容を期待していた読者は多少面食らうかも知れません。実際、シミュレータ部分は読み飛ばしても全体の理解にはさほど影響がないので、次に進んでしまうのも一手です。

ユニットテストについては標準の unittestdocstring、サードパーティパッケージ nose についての解説があります。これら以外の選択肢としては pytest がよいでしょう。

3章は 定番ツールとも言える IPythonJupyter Notebook、IDE として Spyder が登場します。

本書の内容を学ぶにあたっては Jupyter Notebook の利用が最適でしょう。IDE が必要な方には JetBrains 社の高機能 IDE PyCharm をおすすめします。

www.jetbrains.com

第4章 〜 第6章 - 一歩進んだ Python 文法解説

4章から、Python の文法や言語仕様の解説が始まります。変数や関数の定義、データ型や予約語など、通常プログラミング言語の解説に必要な内容が掲載されていると考えて問題ありません。加えて、リストの状態による shallow copydeep copy の違い関する解説など、Python の Tips がいくつか取り上げられています。

本書中のコードですが、一部変数や関数への lowerCamelCase の採用*3や Single/Double Quote の揺れ*4など気になるものが若干ありました。命名については数学的慣例に基づいたことに依るものもあるように見えましたが、本書中で PEP 8 についての言及もあったことですし、一応この点に留意してコードを参考にするのが宜しいと思います。

また、文字列のフォーマットについて全体的に %演算子 を利用したコードが採用されています。この方法は古い方法であり非推奨とされているので、format() 関数を利用するほうがよいでしょう。

# %演算子
print("%d からカウントダウンします" % m)

# format 関数
"{0} からカウントダウンします".format(m)

余談ですがつい先日リリースされた Python 3.6 から新しい文字列フォーマットの方法*5が増えていますね*6

# Python 3.6 からの新しい方法
f"{m} からカウントダウンします"

第7章 〜 第10章 - PyData 定番パッケージの紹介

第7章からは、いわゆる PyData パッケージの解説です。NumPySciPymatplotlib, pandas の4つに1章ずつ割かれています。いずれも多機能なパッケージであるため、より深い知識を身につけるには専用の解説書や公式ドキュメントの参照が求められます。本書はこれらパッケージの導入として考えるとよいでしょう。

matplotlib の割り付けの指定はとても参考になる解説でした。

第11章 〜 第12章 - パフォーマンス向上のための Tips

11章および12章については、実行速度の高速化についてのトピックです。特に大きなデータを扱う場合に実行速度は重要な点ですから、関心を持たれる方も多いと想像します。本書では、高速化のためのアプローチを4つに大別しています。

  1. ボトルネックの解消 => コードの最適化
  2. 処理の並列化
  3. ライブラリの利用
  4. JIT コンパイラの利用

「1. ボトルネックの解消」として for 文を極力控えるなどの Python における代表的なパフォーマンスに関する注意事項のほか、メモリの利用に関する解説があります。

「2. 処理の並列化」は、multi thread/multi process についての内容が扱われています。一見並列処理による処理速度の実行が期待される multi thread への注意点がありつつ、I/O バウンドのときは multi thread を検討してもよいよというアドバイスは端的でよいと思いました。

「3 .ライブラリの利用」は、パフォーマンス向上の解法として Cython を利用することを紹介する内容です。C言語で実装したライブラリを Python から利用する方法も解説されています。

「4. JIT コンパイラの利用」では代表的な JIT コンパイラ Numba についての解説があります。

Numba は Pure な Python コードに多少手を入れるだけでパフォーマンスを大きく向上させられる可能性があるのでおすすめの方法です。

本書中に別解として Numexpr も登場します。

github.com

まとめ - 文法解説、パッケージ紹介、パフォーマンス Tips のバランスのよい構成

ここまで見てきたように、Python の言語仕様に踏み込みながら、PyData パッケージの導入も担うという点で希有なバランスを保つ本書です。多少でも Python の知識があると読み易いレベル感でもあるため、既に Python ユーザーである読者が 再入門 する際の手引きとして最適です。他のプログラミング言語ユーザーが Python を学ぶための一冊として利用するのもよいでしょう。

高度な分析ツールの普及により、便利なパッケージに手を伸ばしがちな昨今です。いまいちど、本書を片手にプログラミング言語としての Python の特性を確認してみるのもよいかも知れません。

関連するかも知れない書籍

  • NumPy と pandas について深掘りしたいなら

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

  • 機械学習について知りたいんだ!という人向け

Python機械学習プログラミング 達人データサイエンティストによる理論と実践 (impress top gear)

Python機械学習プログラミング 達人データサイエンティストによる理論と実践 (impress top gear)

*1:ロケットシミュレータのくだりや SciPy の章で若干登場します

*2:この設定は著者のバックグラウンドによるもと思われます

*3:157頁 myFunc など

*4:155頁 など

*5:PEP 498 -- Literal String Interpolation | Python.org

*6:そういえば ECMAScript 2015 の template literal っぽいですね

悩める Web スクレイパーのための一冊 - 技術評論社『Python クローリング & スクレイピング』

このたび、縁あって『加藤耕太 (2016). Python クローリング & スクレイピング データ収集・解析のための実践開発ガイド, 技術評論社』(以下、本書) を恵贈賜りました。

著者並びに出版社の皆様にお礼とご慰労をかねまして、僭越ながら本エントリにて一読後のレビューを掲載いたします。

Pythonクローリング&スクレイピング -データ収集・解析のための実践開発ガイド-

Pythonクローリング&スクレイピング -データ収集・解析のための実践開発ガイド-

なお読者の益となるようなるべく公正な目線でレビューします。掲載されているコードの厳密な正確性については本レビューの対象外とします。

総評

体系的に「スクレイピングとは」「クローラーとは」について学ぶにはとてもよい書籍です。本書の優れているところは、特に基礎編ともいえる前半部分で、ある事柄を説明するにあたり前提となる事柄をできるだけ丁寧に解説しているところです。

エラーハンドリングや取得先のデータ構造が変わってしまった場合の対応など、継続的に運用しないと見えてこない "悩み" とその対策がナレッジとして紹介されていることも「実践開発」という副題に則しています。

本書は、最初により原始的な方法 (e.g. UNIXコマンドによるデータ取得) を説明した上で、中盤以降で高度なライブラリ (e.g. Requests) を紹介する流れを取っています。これはおそらく、Python やそのライブラリの便利さを読者に実感させるという意図によるものだと思います。

通読することで、Python に限らない一般的な Webリソースの活用の手段を学べるとともに、実運用に耐えうるクローラーシステムを Python で開発するための前提知識を得られるでしょう。

こんな人に特におすすめ

以下の要望をお持ちの方には特におすすめできます。

  • Webスクレイピングやクローラーについて基礎から応用までしっかり学びたい。
  • 一度 〜 数回のデータ収集ではなく継続的にデータを収集するクローラーを開発、運用したい。

以下の方は、本書の内容が自分に合っているか確認してから購入するとよいかも知れません。

  • とにかく最短で Web ページのスクレイピングを行いたい。いますぐにだっ!
  • 特定のパッケージを使うことがすでに決まっていて (e.g. Beautiful Soup)、その範囲に限定した知識を得たい。
    • ただし Scrapy については相応に誌面が割かれているのでこの限りではありません。

ある程度予備知識がある状態で、クローリングとスクレイピングの要所を掴みたいという方にとっては冗長と感ぜられる章も存在するでしょう。この理由は、本書が対象としている技術を体系的に取り扱っているためであり、本書の欠点ではありません。

続いて各章毎に簡単にレビューしていきます。

第1章 クローリング・スクレイピングとは何か

1章では、そもそもクローリング・スクレイピングとはなにか、というトピックについて、Python すら用いず解説がはじまります。

  • wget コマンドによるデータの取得
  • cutgrepsed コマンドによるデータの抽出や加工

各種コマンドの扱いに馴染みのない方は目を通してみるとよいでしょう。そうでない方は飛ばしてしまって差し支えない章です。

第2章 Python ではじめるクローリング・スクレイピング

2章の冒頭で Python のインストールや venv による環境構築、Python 自体のデータ構造や文法に関する最低限の解説があります。Python の標準ライブラリである urllib を使ったデータの取得と、re を使った正規表現によるスクレイピングの方法が紹介されています。

実際、この組み合わせは実用的ではないのですが、高度なパッケージの用法に移る前に前提となる知識を解説するという目的で取り扱われているのだと思います。

第3章 強力なライブラリの活用

3章は Python に明るいユーザーにとっては想像がつくであろう、RequestsBeautiful Souplxml といった定番の 3rd パーティパッケージが登場します。これらのパッケージを使って、あらためて HTML をスクレイピングするという構成です。

前章で正規表現による不都合を感じた読者は便利さを体験できる章であると思います。

また、本書からデータベースの扱いも始まり、MySQL および MongoDB の導入方法の解説があります。

データベースについては、本書では macOS ならびに Ubuntu に直接インストールする方法が取られているのですが、Docker の利用がより手軽かなと思いました。ただし本書の構成からすると、Docker を採用するには「Docker とは」という項目について紙面を割く必要が生じるため、見送ったのかなという気もします。Docker の知識がさほどなくても、Kitematic を利用すれば GUI で簡単に導入できますので利用を検討してみるとよいでしょう。

また、そもそもデータベースではなく CSV (TSV など含) ファイルとして保持しておけばよいという考え方もあります。僕の場合なんらかデータを収集する場合は概ね CSV ファイルにしておいて、データの抽出や並べ替え、集計などの操作を行いたい場合には pandas に読み込んで処理しています。もちろんこれはデータをどう管理したいかということに依ります。個人で気軽に扱いたいのであれば別途ツールの導入の必要ない CSV もよいと思います。

第4章 実用のためのメソッド

4章は実際運用するにあたって考慮すべきポイントがまとめられた章です。

特筆すべきは著作権について触れられている点でしょうか。(あくまで法律の専門家ではない者の見解であると前置きしつつ) 読者にこの点を喚起するのは適切であるように思います。

後半はエラーハンドリングや、クローリング先のデータ構造が変わってしまった場合の対処などが解説されています。

アドホックにデータを収集して終わり、というケースでは HTML構造の変化に遭遇することはないのですが、クローラーを一定期間運用していると、突然データが収集できなくなるとういことはありがちです。REST API などと違いフォーマルな仕様が提供されない Web スクレイピングにおいては、最初からある程度 robust な設計にしておくことが大切ですね。

第5章 クローリング・スクレイピングの実践とデータの活用

5章は、WikipediaTwitter のデータ、財務省が公開している国債金利データなどを扱う内容です。いわゆる「オープンデータ」についても言及があります。Python パッケージという観点では、あらたに pandasmatplotlib が登場します。

5章については、自分の用途と合致する例がある箇所を重点的に読むのに適した構成です。「実践」と称されているとおり、この章から情報量が一気に増えます。1つ1つの要素技術を詳しく解説するというよりも、さまざまな用途を想定しより多くのアプローチを紹介するという方針のように見えます。

JavaScript の解釈が必要な場合の手段として SeleniumPhantomJS の利用が主たるものとして紹介されています。

僕自身この領域はさほど馴染みがないので調べて見たところ、いわゆる Headless ブラウザやレンダリングエンジンの関連ライブラリ・パッケージがまとめられている GitHub のレポジトリがありましたので以下に掲載します。

github.com

本書の内容含め勉強になりました。

第6章 フレームワーク Scrapy

6章はおまちかね (?) の Scrapy を解説する章です。

github.com

Beautiful Soup でお手軽な クローラーシステムを作ったことはあるけれども Scrapy までは手が出せていない、というユーザーは一定数いるように感じます。 本章で、Scrapy の実装や設定についてひととおり解説がありますので、実は Scrapy を重点的に知りたい方にもこの書籍はおすすめできます。

ちなみに Scrapy が Python 3 に正式に対応したのは 2016年5月でしたが、執筆時期を考えるとぎりぎりのタイミングだったでしょうか*1

本書中の Scrapy のサンプルコードは複雑ではない Class と Method を使った例ですので写経は容易です。データが欠損していそうなときを想定したハンドリングにも言及があります。こうした Tips が含まれているあたり実用的でいいですね。

6章の後半部分は Elasticsearch の活用や、OpenCV を使った画像解析に話題が及びます。ケースとしては非常に面白いのですが、Scrapy とは独立した話でもあるので、関心のある読者は目を通すとよいでしょう。

第7章 クローラーの継続的な運用・管理

最終章となる7章では、クローラーシステムの実行環境とその運用に関するトピックを扱っています。実行環境の1例として Amazon Web ServiceEC2 が選択されています。サーバーへのデプロイ方法や、サーバー上での Python 環境の構築などについても解説に含まれます。

また、cron からメールを通知してみるという例の中で、Postfix (いわゆる SMTPサーバー) が登場します。

Postfix について、システム通知という限られた用途で Postfix のようなミドルウェアを運用・保守していくことは費用対効果がよくないと思いますので、メール通知が必要なのであれば Python スクリプト内から Amazon SES のような外部の SMTP サーバーを利用するのが無難だと考えています*2。あるいは、ジョブ実行を管理している何らかのツール (e.g. Rundeck) に委ねるか、ログ監視系のサービスやツールでエラーログを拾うなどするのも一案だと思います。

クローリング処理とスクレイピング処理を疎結合にするための手段として、Message Queue (以下、MQ) を介したジョブのコントロール方法が解説されています。具体的には Redis を MQ のデータストアとして採用しています。

システムに MQ を採用すること自体に少しハードルを感じる読者もいるのではないかと想像します。本書では図解付きで MQ の動作を解説しており分かりやすい内容になっています。別解として Amazon SQS の紹介もありますので手に馴染みそうなほうに挑戦してみてもよいでしょう。

AWS Lambda の登場以後、クローラーシステムの実行環境としていわゆる Serverless Architecture に分類されるクラウドサービスを活用するケースも見られるようになってきました*3。本書ではそうした環境については触れられていませんが、ここまでで得られた知識は他の環境においても充分活かせるものと思われます。

まとめ

本文中にも pandas や matplotlib など PyData*4 関連パッケージの利用例がありますが、クローラー開発が行えるばかりでなくその後のデータ分析のフェーズまで単一の言語で完遂できる Python の便利さを改めて感じる書籍でもありました。

Web サイトのスクレイピング、クローリング自体は古典的な試みです。近年はデータを分析したいという目的があって、必要なデータソースを収集するために当該技術が必要になるというケースが多くなってきているようです。関連技術の勉強会やハンズオンはとても盛況だと聞いています。注目の高まるクローラー開発技術ですが、システムとしては単純なバッチ処理よりも考慮事項が多く、実装者や運用者の悩みの種にもなりがちです。

本書は、クローリングとスクレイピング技術について順を追って学ぶことができ、実運用を見据えたいくつかの示唆を得られる構成になっています。クローラー運用に悩みを抱えている方にも、スクレイピング技術についてじっくり学びたい方にもおすすめの一冊です。

関連するかも知れない書籍

スクレイピングのまえに Python 勉強しなきゃ、という方向け。

Pythonスタートブック

Pythonスタートブック

拙著 (共著) で恐縮ですが、Python の豊かなライブラリたちはクローラーと組み合わせて活用できるはず。

Python ライブラリ厳選レシピ

Python ライブラリ厳選レシピ

  • 作者: 池内孝啓,鈴木たかのり,石本敦夫,小坂健二郎,真嘉比愛
  • 出版社/メーカー: 技術評論社
  • 発売日: 2015/10/17
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログ (1件) を見る

*1:謹んでお慶び申し上げます

*2:Amazon SES については 7章後半の節「クラウドを活用する」で言及があります

*3:AWS Lambdaで作るクローラー/スクレイピング

*4:データ分析やデータ活用に Python ならびに Python ライブラリを利用しようという人類の営みの総称

Go 言語 Webフレームワークはこれを使おう 2016年12月版

この記事は Qiita Advent Calendar 2016 Go (その2) 10日目の記事です。

Go言語の Web アプリケーションフレームワーク (以下、Web フレームワーク) は、群雄割拠の時代を経てわずかばかりまとまってきた印象があります。今回、Go言語の Web フレームワーク を選定するさいの参考になればと思い、あらためていくつかのフレームワークの特長や最近の動向をまとめました。

結論

現時点では iris または Echo の選択をおすすめします。

追記 2016-12-10 17:13

結論を、Echo をおすすめ、と訂正いたします。

記事を公開したあとで、iris はレポジトリの運営方針などに問題があるというご意見を見かけました。あわせて、以下のリソースをご紹介いただきました。

b.hatena.ne.jp

参照先 URL が直接投稿できない模様です*1。上記の URL 経由で掲載しておきます。

ご指摘のとおり、残念ながら iris は現状ではおすすめできないパッケージとなってしまっているようです。最近の動向、、といいつつこの点を抑えられいなかった点についてとても反省しています。いちど公開してしまった内容なので、紹介記事は削除せずに追記という形式で情報を更新いたしました。ご意見くださり誠にありがとうございました。

追記ここまで

選定と推薦の根拠

  • 主観
  • GitHub Trending, Star, Issue
  • プロダクトでの使用経験 (Gin, Echo)

現在、株式会社ユーリエ のプロダクト eurie Desk 開発における主たる言語として Go言語を利用しています。プロダクション環境での利用をつうじて得た知見を判断材料の1つにしています。

今回の候補一覧

他にも伝統的なパッケージがいくつか存在しますが、開発の状況やその他理由により選外としました。

前提として RESTful API (以下、REST API) の実装に採用することを念頭に置いていますので、HTML Template Engine に関連した情報は登場しません。掲載していないものがよくないというわけではありませんのであしからず。

Gin

github.com

Gin は古くから人気のあったパッケージの1つです。一時期開発が停滞していましたが Contributor 増員後はそこそこの頻度で開発が続いています。Microframework ながらかゆいところに手が届く実装で、Echo や iris の機能開発の参考にされていた印象があります。

REST API の Request Body を Struct に Bind するさい、Struct に定義した binding タグ の内容にもとづき値の Validation を行うが特長です。

type User struct {
    Name  string `json:"name" binding:"required"`
    Age   uint   `json:"age" binding:"gte=0,lte=130"`
    Email string `json:"email" binding:"required,email"`
}

上記の Struct を以下のように利用します。

func PostUser(c *gin.Context) {

    user := new(model.User)
    if err := c.BindJSON(user); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"message": err.Error()})
        return
    }

    c.JSON(http.StatusCreated, gin.H{"status": "ok"})
}

以下の JSON を POST で送付します。

{
    "name" : "Your Name.",
    "age": 30,
    "email": "invalid.com"
}

この場合 Email の書式が不正なため エラー "Key: 'User.Email' Error:Field validation for 'Email' failed on the 'email' tag" が生じます。

処理としては go-playground/validator を利用しているというシンプルなアプローチです。Gin を利用しない場合でもこの実装は参考になると思います。

// https://github.com/gin-gonic/gin/blob/master/binding/json.go#L19
func (jsonBinding) Bind(req *http.Request, obj interface{}) error {
    decoder := json.NewDecoder(req.Body)
    if err := decoder.Decode(obj); err != nil {
        return err
    }
    return validate(obj)
}

Validation に関する補足

ところで、Struct の binding タグによる Validation を行う場合には、以下の課題があります。結論からいうと、ある程度の規模以上のアプリケーションではこの方法の採用はおすすめできません。

  • 可読性が悪い
  • タグは build 時に Check されないためミスのもとになる
    • go vet で検出する方法はあります*2
  • POST/PUT で Struct を共有する場合かつ Validation の内容が異なる場合、複数タグを付与して使い分けるなど更に可読性が悪くなる
    • 僕が以前取り入れていた方法*3はあまりよくありませんでした

Model の構造や Validation の要件がごく単純な場合には手軽に利用できます。

最近の動向

12月3日に v1.1 がリリースされています。

Gin は 僕が Go 楽しいと思ったきっかけの Product なので、今後も人気が続くといいなぁと思っています。

Echo

Echo は、Gin の開発停滞期に人気が急上昇した印象のある Web フレームワークです。公式サイトのドキュメントが詳しく、Web アプリの汎用的な課題を解決できるミドルウェアがバンドルされています。

echo.labstack.com

たとえば、Cross-Origin Resource Sharing の設定を行える CORS Middleware) や、Request Header に含まれる JWT を Parse する JWT Middleware などが便利なミドルウェアの一例です。

ミドルウェアに関する補足

ミドルウェアの実装と活用は Echo に限った話ではないのですが、ここで補足しておきます。典型的な汎用処理は、データベースのトランザクションの管理です。

const (
    TxKey = "Tx"
)

func TransactionHandler(db *sql.DB) echo.MiddlewareFunc {
    return func(next echo.HandlerFunc) echo.HandlerFunc {
        return echo.HandlerFunc(func(c echo.Context) error {
            tx, _ := db.Begin()

            c.Set(TxKey, tx) // echo.Context にトランザクションの pointer をセットして、後続の処理の中で取り出せるようにしています

            if err := next(c); err != nil {
                tx.Rollback() // このミドルウェア以後でエラーが発生した場合はロールバックします
                return err
            }
            helper.Logger.Debug("Transaction has been committed.")
            tx.Commit() // エラーが発生しなかった場合はコミットします

            return nil
        })
    }
}

実装したミドルウェアを、以下のようにセットします。

e := echo.New()
e.Use(middleware.TransactionHandler())

e.POST("/users", api.PostUser())
e.PUT("/users/:id", api.PutUser())

このようにしておくとすべてのエンドポイントが 1 Request = 1 Transaction で管理されます*4

ロギングや 認証周り、例外発生後の共通処理などをミドルウェアとして実装しておくとコアロジックの実装に集中できるようになります。

最近の動向

v3.0.0 がリリースされています*5Let's Encrypt との連係など、TLS 関係が強化されています。

v2 までは、valyala/fasthttp パッケージを取り込み高いベンチ—マークを誇っていたことでも知られていました。メジャーアップデートとなる v3 からは fasthttp への 依存が取り払われ、標準の net/http パッケージのみのサポートとなりました。プロジェクトをシンプルに保つことが目的とアナウンスされています *6

Echo には現時点で REST API を開発するに充分な機能が備わっており安定して利用できます。

iris

追記 2016-12-10 17:13

結論に追記したとおり、iris のおすすめは取り下げさせていただきます。以下は、参考情報としてご覧いただければと思います。

追記

github.com

iris は非常に開発が活発な Web フレームワークで、GitHub の Trending にもたびたび登場していた時期がありました。比較的後発ですがバージョンが 5.0 まであがっています。ベンチマーク最速をうたっている*7のが特長でしょうか。後発らしく (?) Go の v1.7 以上が動作要件です。

GitBook で書かれた丁寧なドキュメントが用意されていることも特長の1つです。

また、サンプル集が多く用意されています。

github.com

Echo も充分にドキュメントが揃っていますが、iris はさらに充実している印象です。このドキュメントに書かれているコードををひととおり動作させることで、いくつかの重要な要素技術 (例えば CORS や セキュリティに関する HTTP Header の仕様についてなど) についても触れることができます。そうした観点から、REST API を初めて実装してみようとされているかたにも iris はおすすめできるかも知れません。ただし日本語情報はほぼ皆無と言えますのでその点は気にとめておいてください。

最近の動向

上述のとおり、最新のバージョンは v5.0 です。v4系を LTS (Long-Term Support) として維持するようです。この手の Go のパッケージで LTS を宣言しているものはあまり見たことがないかも知れません。

また、Echo が v3 から依存関係を解消した fasthttp を iris は v4 から採用していることも動きとしては面白いと思います。

まとめ

今回取り上げた 3つの Web フレームワークはいずれも癖がなく使いやすいものです。もしも将来的に移行の必要が生じた場合でも、現実的なコストで行える程度だと考えています。いずれを選んでも宜しいと思いますが、結論で述べたとおり、ドキュメントの充実度や継続可能性も踏まえ今回は Echo と iris をおすすめ Web フレームワークとしました。

Go 言語のエコシステムは現在成長著しく、じつにさまざまな OSS パッケージが日々登場しています。Web フレームワークの勢力図が半年後にまたどのように変化しているか楽しみです。

推薦図書

和書で Go言語の基本文法を学びたいかたには下記をおすすめします。

改訂2版 基礎からわかる Go言語

改訂2版 基礎からわかる Go言語

洋書ですが次の書籍も評判がよいようです。

The Go Programming Language (Addison-Wesley Professional Computing Series)

The Go Programming Language (Addison-Wesley Professional Computing Series)

Redash の次にくるのは superset!! - Airbnb 謹製の BI ツールが OSS で

Redash (re:dash) 流行ってますね。

redash.io

最近 Github をにわかに賑わせている OSS が superset です。

github.com

superset とは

公式説明によると

data exploration platform

とのことですが、僕の感覚的にはこれはつまり、いわゆる Business Intelligence (以下 BI) Tool です。そう、Tableau のような。

  • OSS (Apache 2.0)
  • サーバーサイドは Python で書かれている
  • さまざまなデータソースに対応 (MySQL, Redshift、SparkSQL など)
  • グラフ描画の種類が豊富
  • Role や Permission についてある程度細かく設定可能
  • Airbnb Engineering チーム謹製

superset ざっと見

インストール方法は公式ドキュメントのとおりです。

あるいは Docker image を利用します。

f:id:iktakahiro:20161125193456p:plain:w600

初期設定をすませて、SQLite 上に展開されているサンプルデータセットを使ったダッシュボードにアクセスしてみると

f:id:iktakahiro:20161125193621p:plain:w700

ふぁっ!? (二度見

f:id:iktakahiro:20161125193719p:plain:w700

ふぁー (椅子からすべり落ちる

...

ごく簡単な利用方法としては、対象のデータソース (最も単純な場合、データーベースの中の1テーブル) を選択し、Filter や Group By 対象のカラムを選択し、描画したいグラフのパターンを選択してグラフを生成します。

例えば以下は、サンプルデータセットの誕生日データの円グラフです。

f:id:iktakahiro:20161125194031p:plain:w500

グラフの種類を選択できます。

f:id:iktakahiro:20161125194101p:plain:w300

棒グラフに変更。

f:id:iktakahiro:20161125194122p:plain:w500

謎の Words Cloud。

f:id:iktakahiro:20161125194145p:plain:w500

SQL 記述の支援ツールもついていて、クエリ結果はその場で確認できます。

f:id:iktakahiro:20161125194243p:plain:w500

Redash の違いと superset の可能性

superset をまだ使い込んでいるわけではないうえでの感想である点をご了承ください。

印象としては、Redash はなにはともあれ SQL が起点だったのに対して、superset は GUI でできることが非常に多いです。視覚表現も豊かで (実用度はさておき) 楽しくなるようなダッシュボードを組み立てられます。

重複する部分もあるとは思うのですが、

  • Redash: いちど SQL から組み立てた指標とグラフを定期的にモニタリングしていくのに便利
  • superset: Filter や Group By をいじりながら、インタラクティブにデータを探索してくのに便利

という使い分けになるのかなぁという気がしています。

サービスやプロダクトの改善のために社内でダッシュボードを構築する気運は高まるいっぽうです。BI 界隈の動きとしては、ここ数年勢いの止まらない Tableau の他にも、Google Data StudioAmazon QuickSight など大型のツールも登場してきています。

superset は OSS ということもあり、社内ダッシュボード構築をまず始めてみるにはこれでいいのでは!? と思わせるようなインパクトがあります。

流行ると思います。

IPythonデータサイエンスクックブック ―対話型コンピューティングと可視化のためのレシピ集

IPythonデータサイエンスクックブック ―対話型コンピューティングと可視化のためのレシピ集

Tableau 10.0 Best Practices

Tableau 10.0 Best Practices

Swagger 定義ファイルから そこそこいい感じの静的 REST API ドキュメント作成する

tech

REST API のドキュメンテーションはサービス開発における課題として認知されており、解決に向け近年さまざまな試みが行われています。OPEN API および Swagger はその有力な動きの1つです。

長いものには巻かれろ (?) ということで、今回は Swagger 定義ファイルをベースとした REST API ドキュメントの生成方法をまとめます。

結論

swagger2markup-cliasciidoctor を組み合わせて HTML ファイルを生成するのがよさそうです。

課題の共有

Swggger 定義ファイルからドキュメントを生成する手順はいくつか存在します。

  • swagger-ui を利用する
  • swagger-codegen で HTML を出力する

swagger-ui はリッチで美しいドキュメントを提供してくれます。しかしインタラクティブな API ドキュメントが必要ない場合、ドキュメント公開のためだけに Node アプリケーションの動作環境を維持しておくことはやや気が重く、できれば静的ファイルとして配置しておきたいところです。

そこで、swagger-codegen の利用が検討できます。

github.com

swagger-codegen は、Swagger 定義ファイルからサーバーサイド / クライアントのコードを出力するためのものですが、HTML 形式のドキュメントも出力できたりします。

swagger-codegen generate -i sample.yaml -l html -o output/

しかしながら、インターネットの歴史と伝統のかほりがほのかに醸し出される成果物となっており、このままでは公開しがたい感が否めません。

f:id:iktakahiro:20161122203315p:plain:w400

swagger-codegen で HTML を出力する場合、テンプレートを指定できます。選択肢としては、多少モダンな htmlDocs2 を指定するか、テーマを作成するかです。

今回は swagger-codegen による HTML出力以外のカジュアルな選択肢が必要な状況であるとして、話を進めます*1

手順

そこそこいい感じの静的 API ドキュメント生成の手順は以下のとおりです。

  1. Swagger 定義ファイルから Asciidoc を生成する
  2. Asciidoc から HTML ファイルを生成する

カスタマイズなしで以下のような API ドキュメントが生成できます。

f:id:iktakahiro:20161122200815p:plain:w600

そこそこ良い感じだ。

Swagger to Asciidoc

まずは Swagger 定義ファイルを Asciidoc に変換します。

github.com

swagger2markup の 実行例は以下のとおりです。

$ java -jar swagger2markup-cli-1.1.0.jar convert -i sample.yaml -f api-doc

実行すると api-doc.adoc が出力されます。

= Simple API


[[_overview]]
== Overview
A simple API to learn how to write OpenAPI Specification


=== Version information
[%hardbreaks]
_Version_ : 1.0.0

Asciidoc to HTML

続いて Asciidoc を HTML に変換します。asciidoctor を利用します。

github.com

asciidoctor の実行例は以下のとおりです。

$ asciidoctor -a toc=left api-doc.adoc

実行すると api-doc.html が出力されます。

-a オプションに toc=left を指定することで サイドバーに Table of Contents が出力されたレイアウトを選択できます。

ここで紹介した一連のビルドプロセスを CI に反映して、Amazon S3 などに Deploy できるようにしておけばよいでしょう。

付録

その他の REST API ドキュメンテーションツール/サービス

Product Description
Apiary 国内で認知度が高いっぽい API ドキュメンテーション + Mock 生成できるクラウドサービス。噛めば噛むほど渋い思いをするらしい (?)。
RAML YAMLっぽいなにか からコードやドキュメントを生成するツール群。RESTful API Modeling Language で RAML とのこと。

一時期は群雄割拠感もあった API ドキュメンテーションツール界隈ですが、ここ2年くらいで淘汰が進んできた印象です。RAML は設計がモダンな感じなので普及して欲しいです*2

Swagger 定義ファイルの学習

最近見つけたのですが Swagger 定義ファイルの構造を学ぶにあたり、次の記事が非常にわかりやすいです。

apihandyman.io

ごく単純でフラットな記述から、Swgger の機能を利用して重複部分を徐々に省いていくという構成になっていて、公式ドキュメントではまったく把握出来ない全体像を見事に解説しています。

Web API: The Good Parts

Web API: The Good Parts

*1:テーマ作成については別の機会で

*2:と言いつつ Swagger に巻かれる勢