研究でPythonを使うときに気を付けていること

最終更新日: 2021年12月13日

この記事は fMRILab Advent Calendar 2021 の 12/13 分の記事です。


研究でPythonを使い始めて約3年となりました。
まだまだアマチュアではありますが、今までの学習過程や現段階でのTipsを書いておきたいと思います。

Pythonの学習過程

Pythonと出会ったのは学部3年の講義(生命情報学)の中でした。基本的な文法はそこで学習した覚えがあります。

Pythonを本格的に使い始めたのは、研究室に所属してからです1
私の研究テーマでは機械学習を使うことが多いので、まずは数値計算や機械学習のライブラリを扱えるようになることを目指しました。以下書籍が非常に参考となりました。

Reference Book
Pythonではじめる機械学習 ―scikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎
Andreas C. Muller (著), Sarah Guido (著), 中田 秀基 (翻訳), オライリージャパン (2017/5/25)

この頃は何でもかんでもjupyter notebook(ipynb)を使って、出力を見つつトライ&エラーを繰り返していましたね…。
次に、当時バズり始めていた深層学習ライブラリのPytorchも勉強しました。以下書籍が非常に参考となりました。

Reference Book
つくりながら学ぶ! PyTorchによる発展ディープラーニング
小川雄太郎 (著), マイナビ出版 (2019/7/29)

その後は、Nilearn, brainIAKなどといった、fMRI解析専用のPythonライブラリを掘るようになりました。
各種ライブラリのTutorialやExampleをひたすら動かしてみるのも勉強になりましたね(ここら辺で1年?)。

以降は、ネット記事や以下書籍などで安全性の高い書き方を吸収してきました。 競技プログラミングや機械学習コンペなども勉強になった気がします。

Reference Book
Effective Python 第2版 ―Pythonプログラムを改良する90項目
Brett Slatkin (著), 石本 敦夫 (監修), 黒川 利明 (翻訳), オライリージャパン; 第2版 (2020/7/16)
基本的な文法 → numpy/pandas/sklearn → pytorch → nilearn/brainiak → Effective Python といった感じでしょうか。

研究+PythonのTips

研究でPythonを使うとき、個人的に気を付けていることを箇条書きで書いていこうと思います。

  • コードスタイルPEP8にできるだけ従う。
    • 共有する時の可読性や再利用性を高めるため。
    • レイアウトについては、フォーマッタが便利です。
      • autopep8, yapf, blackなどが有名でしょうか?2
  • メインとなる部分には型ヒント・Docstringを書く。
    • 明日の自分は他人であると思って、可読性を高めておく。
    • コードをレビュー・公開する時にも、あったら嬉しい(感想)。
  • jupyter notebook(ipynb)を本番コードで使わない。
    • jupyter notebook環境でインタラクティブ(対話的)に書くのは、プロトタイプ・メソッドのテスト・スクリプト実行などに留める。
    • 以下のデメリットが考えられる。
      • グローバル変数の頻用は危険。研究でもバグの危険性は最小限にすべきだと思う。
      • 複数スクリプトでのコードの再利用性が低い3
      • ブラウザ環境下では、補完やヒントにアクセスしにくい。
      • 差分管理が困難。GitHub等で管理できない。
  • 実行環境の再現性を高く保つ。
    • せっかく公開されているコードでも、実行環境の違いで正しく動かなくては勿体ない。
    • ハードウェアまでは保証できないが、主要ライブラリのバージョンくらいは指定しておく。
      • dockerの利用→公式イメージの利用4
  • 乱数シードに気を付ける。
  • 中間生成物はできるだけ保存する。
    • 研究では、解析"途中"のデータを後から確認したくなることは多いと思います。
      • 締め切り直前やrebuttalとか。
    • ストレージの許す限りそのまま保存しておきます5
  • ログを残す。
    • これも解析ミスに気づきやすくするため。
    • 標準loggerやそのラッパーライブラリで十分だと思います。
  • 全て手続き型で書かず、クラスや関数を使う。
    • グローバル変数を避け、クラス変数で保持する。
      • グローバル変数の意図しない変更は、重大な解析ミスになる可能性がある6
    • 区分的な処理に単体テスト7を書くと、なお良いのではないか。
  • ディレクトリ構成を考える。以下は私の現在の構成例。
    root
    |-- README.md
    |-- .gitignore
    |-- .devcontainer/ # Dockerファイルや環境設定ファイル
    |-- .vscode/       # vscode(ide)の設定ファイル
    |-- data/          # データの保存(前処理済みデータ等)
    |-- results/       # 結果の保存
    |-- scripts/       # メイン処理のスクリプト
    |   `-- lib/       # 共通処理のライブラリ
    |-- bash/          # 一括処理用のbashスクリプト
    |-- reports/       # レポート関係
    |   |-- figures/   # レポートに使う図の保存
    |   `-- scripts/   # 図を作るスクリプト等
    `-- notebooks/     # ipynbファイルや実験的なスクリプト
Pythonは所謂ラッパーとして使うことが主でありますが、複数のライブラリを安全に橋渡しできるよう工夫することが重要だと思います。

その他、参考になるリンク


  1. 指導教員や先輩が使っていた影響が大きかったです。
  2. 私はblackを使っています。設定が(ほぼ)必要なく、気軽に導入できる所が好きです。
  3. 基本コピペになってしまう。Jupyter notebook で他の notebook の特定のセルをインポートする - Qiita などの方法もありますが、煩雑だと思います。
  4. vscode - remote containerが最高です。
  5. 私はMATファイルを多用しています。参考:PythonでMATファイルを使う
  6. クラス変数を使っても完全に防げるわけではないですが…。
  7. 標準ライブラリのunittestが便利。