はじめに
この記事では、データサイエンティストが最低限意識した方が良さそうなコードの書き方について紹介します。
お恥ずかしながら、自分は「運用するわけじゃないし、動けばいいでしょ~」精神でコーディングをしていました。しかし、上司にコードレビューをしていただく機会があり、最低限の可読性・保守性のあるコードの大切さとそんなコードを書くためのポイントについて教えていただきました。
この記事では、この上司のレビューからの学びや、コーディングをしている中で感じ取ったコツのエッセンスを共有していきたいと思います。エンジニアの方からすると初歩中の初歩のようなことだとは思いますが、コーディングがへたくそなデータサイエンティストのメモと思っていただければ幸いです。
そもそもデータサイエンティストにとって可読性の高いコードが必要なのはなぜか
これはずばり、分析業務で発生しがちな突然の変更・引継ぎや、分析レベルから運用への移行に簡単かつ迅速に対応できるようにするためです!
データサイエンティストにとってプログラミングはあくまで手段であり、かけられる時間もそこまで多くないこと、コードもnotebookで管理することが多いことから、可読性・保守性の高いコーディングはそこまで求められていないという事実があると思います。
しかし、データサイエンティストが携わる分析業務では、業務の引継ぎや業務内容がそのまま運用レベルに移行するようなことがそう少なくない頻度で起こるため、自分の作ったコードが人に見られる機会は少なくありません。そんな時、読みにくいコードが残されていた場合は理解や改修に大きな時間がかかってしまう一方で、読みやすいコードが残されていればスムーズに対応ができます。つまり、読みやすいコードを書くことは業務の効率化に直結するのです。 そのため、データサイエンティストにとっても可読性・保守性の高いコーディング技術は必要不可欠と言えます。
リーダブルコードのすすめ
1. 関数の作成
1-1. 機能ごとに関数化
まず最初にやるべきは、「この関数はこの機能」と一言で説明できるような1機能だけを備えた関数を作ることです。これにより、仮にプログラムに対して細かい変更があったとしてもひとつの関数を書き換えるだけで対応できることが多くなり、業務の効率が上がります。
1-2. 小さな関数を組み合わせ、大きな関数を作っていく
1-1で述べたような「1機能だけを持つ関数」が作れたら、これらの小さな関数を使った処理を複数行う「より大きな関数」を作っていきましょう。これを繰り返し、一つのプログラムができていくイメージとなります。
1-3. 重複した機能を持つ関数はなるべく一つに統一
分岐のある処理などを扱う際、「重複した処理はあるけど微妙に違うことをしなければならない…」ということが多々あります。このような場合、重複した処理はなるべく一つの関数に統合し、分岐の数を減らしましょう! こうすることで、把握すべき関数の数が減り、読みやすいコードとなります。自然と分岐が少なくなるので、コードを書く側の負担も減ります。
2. コメントを残そう
簡潔で良いので、処理の理由や関数の機能を要約するようなコメントを残しましょう(処理そのものを直訳するより、要約するイメージで行うと良いでしょう)。
「どんな処理・挙動をするのか」を分かってコードを読むのと、何も事前知識がない状態でコードを読むのには大きな違いがあります。
3. 定数の入力について
3-1. なるべく手動入力を避ける
データのインプットなど、どうしても手動で入力が必要になる箇所を除き、できるだけ自動で定数を取得するような仕様を意識しましょう。これにより、変更対応に強い(= 保守性の高い)コードとなります。
3-2.notebookの場合は定数の入力箇所を一か所にまとめる
「定数定義」のようなセルを作ってしまい、全定数を一か所に集約してしまいましょう。後程定数の変更が必要になった際、変更箇所が一目で分かるので、効率的に作業が進みます。
4. (Pandasを使う場合)簡潔なカラム処理を心がける
4-1. カラム単位での一括処理はapplyを使用
やむを得ない場合を除き、カラムに対して一括処理をかける場合はfor文ではなくapply文を使用しましょう。apply文の方が行数が少なく済むことが多いので読みやすく、処理速度も速いです。
4-2. カラム削除やカラム改名は最低限に
コードの途中でカラムが増減したり、名前が変わったりすることを繰り返すと読みにくいコードになってしまいます。テーブル(DataFrame)間の結合の仕方や、使用するカラムの処理を工夫することでできるだけカラムの役割や名前が変わらないようにしましょう。
4-3. notebookの場合、df.head()でDataFrameを確認するセルを作成する
処理の結果を確認するため、作業中のDataFrameをhead()で表示するセルを用意しても良いでしょう。複雑な処理をした場合など、可視化できる場所を用意しておくと親切です。ただ、この可視化操作は不要という考えの方もいるので、少し注意です。。
Appendix
もっと知りたい!という方は、ぜひかの有名な書籍「リーダブルコード」も読んでみてください。この記事では触れなかったものの、業務に役立つ大切なポイントが分かりやすくまとまっています。
まとめ
自分自身まだまだ未熟な点が多いですが、今後も読みやすい・変更しやすいコード作成を意識していきたいと思います。参考になれば幸いです。