データサイエンティストとしてPythonコードを再利用可能な形式で管理する方法

入門/解説

1.データサイエンティストとしてPythonコードを再利用可能な形式で管理する方法まとめ

・gitを使うまでもないような小規模なプロジェクトでコードを管理する際の初心者用tips
・大規模開発では推奨されない事もあるやり方だが必要になるケースも確かに存在する
・自分のプロジェクトの進め方に合わせて管理方法も進化させていくのが望ましい

2.Pythonコードを簡易に管理するやり方

以下、www.kdnuggets.comより「Managing Your Reusable Python Code as a Data Scientist」の意訳です。元記事は2021年6月、Matthew Mayoさんによる投稿です。

タイトル読んでgitの話なのかな、と思ったら全然違って、ある程度プログラミング経験のある人であったらむしろ自然にやってそうな事を改めて書いている感じも受けました。

むしろこういう管理をしていると多人数での大規模開発が難しくなるのでgitを使いましょう、的な流れなのかなぁ、とも感じたのですが、逆に言えば少人数で小規模でやってる場合にgitを使うのは「gitで削減できるコスト」>「gitに皆が習熟するコスト」+「gitを管理するコスト」が成立しない場合は確かにあります。

実際、元サイトでも7月度のシルバーランクとの事で人気ランキングの上位でした。一言でデータサイエンティスト/機械学習エンジニアと言っても様々な経歴/職務の方がいるので、解析や研究、レポーティングがメインで自分で手を動かしてコードを書く事があまりない方にとっては、gitを使わないやり方として参考になる記事かもしれません。

色々な布地をツギハギして服にした感が出ているアイキャッチ画像のクレジットはPhoto by Utopia By Cho on Unsplash

以下は、データサイエンティストとして自分の再利用可能なPythonコードを管理するために私が決めたいくつかのアプローチです。最も一般的な使い方から一般的でない使い方までを提示しており、初心者を対象としています。

貴方自身のコードを管理する手法にはさまざまなやり方があり、適切な手法は要件、好み、技術的ノウハウ、役割、およびその他の多くの要因によって異なります。

経験豊富な開発者は、コードを複数の言語、プロジェクト、ユースケースにまたがって整理するための非常に計画的な方法を知っているかもしれません。

しかし、独自のコードを書く事はめったにないデータアナリストは、必要性がないため、はるかに場当たり的で不十分なやり方かもしれません。

これは、良い悪いの問題ではありません。単にあなたにとって何がうまく使いこなせるか、そして何が適切かという問題です。

ここで私が言っている「コードの管理」とは、具体的には自分が作成したさまざまなコードを整理、保存、および呼び出す方法です。貴方自身が書いたコードを長い時間をかけて改築して行く際、コードの管理をしてくれるプログラミングツールがあると有用な事がわかります。

プログラミングはすべて「自動化」と見なせるため、コードを作成する人として、同様のタスクを繰り返し実行していることに気付いた場合、そのタスクに関連付けられた「コードの呼び出し」部分を何らかの方法で自動化したいとの欲求が出て来る事は理にかなっています。

これは、あなたがサードパーティのライブラリを既に使用している理由でもあります。サポートベクターマシンを使用する時に、最初からサポートベクターマシンを再実装する必要はありません。代わりに、ライブラリ(おそらくScikit-learn)を利用する事ができます。歳月を重ねてコードを完成させてきた多くの人々の共同作業を利用する事ができます。

このアイデアを個人のプログラミングに拡張することは意味があります。あなたはすでにこれを行っているかもしれませんが(そうでない場合は)、データサイエンティストとして自分の再利用可能なPythonコードを管理するために私が決めたいくつかのアプローチを、最も汎用的なコードの再利用方法として以下に示します。

(1)本格的なライブラリの作成

これは現在、最も一般的に行われているアプローチであり、最も「プロフェッショナル」なやり方と言う事もできます。ただし、これだけでは常に正しい選択になるわけではありません。

大半のユースケースで同じ事をやっていて、定期的に使用していることがわかった場合は、これが最適な方法です。これは、再利用したい機能が簡単にパラメータ化できる場合にも意味があります。つまり、呼び出すたびに定義できる変数を使用して一般化された関数を記述および呼び出すことにより、タスクを何度も処理できます。

たとえば、文字列内でn番目に出現する部分文字列を見つけたいと思うことがよくありますが、Python標準ライブラリ内にこのために利用できる関数はありません。したがって、文字列と部分文字列を受け入れる単純なコードと、入力として何番目を探すかを示すnがあり、このn番目の位置から始まる文字列を返します。(stackoverflow.comで11年前に話題になっています)

def find_nth(haystack, needle, n):
    start = haystack.find(needle)
    while start >= 0 and n > 1:
        start = haystack.find(needle, start+len(needle))
        n -= 1
    return start

私は多くのテキスト処理を扱っているので、この処理を他の多くのテキスト処理関数と一緒にまとめて、他のPythonライブラリと同様に自分のコンピューター上でいつでも利用可能なライブラリとしているので、このライブラリを他のライブラリと同じようにインポートできます。ライブラリを作成する手順は簡単ですが、やや長いので、ここでは取り上げませんが、medium.comなどに沢山の記事があります。

ライブラリをtextprocの名称で格納した後、find_nth関数を簡単に、何度でもインポートして使用できます。関数をコードとし、使用するすべてのプログラムに貼り付ける必要はありません。

from textproc import find_nth

segment = line[:find_nth(line, ',', 4)].strip()

また、ライブラリを拡張して関数を追加したり、既存のfind_nthコードを変更したりする場合は、ライブラリ内のコードだけを修正して、他のプログラムはそれを再インポートするだけで済みます。

(2)プロジェクト固有の共有スクリプトの作成

もしかしたら、あなたは本格的なライブラリは必要ないかもしれません。再利用したいコードは、現在取り組んでいるプロジェクト以外では汎用性がないようですが、特定のプロジェクト内で再利用する必要があるケースなどです。この場合、関数を1つのスクリプトにまとめて、そのスクリプトを名前でインポートするだけで済みます。それはあまり望ましくはない代替手法ですが、しばしば必要なものです。

私が過去に携わった大学院の仕事では、教師なし学習、特にk-meansクラスタリングに関連する多くのコードを書かなければなりませんでした。重心の初期化、データポイントと重心間の距離の計算、重心の再計算など、さまざまなアルゴリズムを使用してこれらのタスクの多くを実行するための関数となるものを作成しました。

これらのアルゴリズム関数の一部のコピーを含む別のスクリプトを保持することは望ましくないことがすぐにわかりました。そのため、それらを独自のスクリプトに移動してインポートしました。ライブラリとほぼ同じように機能しましたが、このプロセスはこのプロジェクトのみを対象としていました。

すぐに、さまざまな重心初期化関数と距離計算関数、およびデータのロードと処理関数のスクリプトができました。このコードがすべて、よりパラメータ化され、汎用的に有用になるにつれて、コードは最終的に正当なライブラリに組み込まれました。

これは、少なくとも私の経験では、物事が通常どのように進行するかによると思われます。

まずスクリプトを使って今使用する必要のある関数を記述し、それを使用します。プロジェクトが拡張されるか、同様のプロジェクトに移動すると、同じ機能が便利であることがわかります。そのため、その関数は独自のスクリプト内に抽出され、使用するためにインポートされます。このスクリプトの有用性が短期間ではなく継続し、その関数がより一般的で長期的に使用されていることがわかった場合、その関数は既存のライブラリに追加されるか、新しいライブラリの基礎になります。

ただし、単純なスクリプトをインポートする際のもう1つの便利な点は、Jupyter Notebookを使用する場合です。Jupyter Notebookで行われていることの多くは、その場限りの、探索的で実験的な性質を持っているので、私はJupyter Notebookをモジュールとして他のJupyter Notebookにインポートするのが好きではありません。

複数のノートブックが抜粋したコードを定期的に使用していることがわかった場合、そのコードは同じフォルダーに保存されているスクリプトに抽出し、ノートブックにインポートする事ができます。このアプローチは私にとってはるかに理にかなっており、あるノートブックが依存しているノートブックが有害な方法で編集されていないことを知ることで、より安定性が増します。

(3)タスク固有のテンプレートを持つ

同じタスクのいくつかを何度も何度も実行することがよくありますが、それらはパラメーター化に適していないか、パラメーター化できるが、それだけの価値があるよりも多くの労力を費やしているタスクです。

そのような場合、私はコードテンプレート(code templating)またはボイラープレート(boiler-plating)を採用しています。これらは、この記事で出来る事なら避けるべきとしたかった単なるコードのコピーと貼り付けですが、正しい選択である場合もあります。

たとえば、適切な用語がないのですが、Pandas DataFrameにコンテンツを「リスト化」する必要があります。もし、列の数を指定できるように関数を記述していれば、使用する列を入力として受け取る事ができます。しかし、多くの場合、出力も微調整する必要があります。これらをすべて関数に記述するには時間がかかりすぎます。

この場合、簡単に変更できるスクリプトテンプレートを作成し、同様のテンプレートのフォルダーに保存しておくだけです。これは、CSVファイルからPandas DataFrame、目的のHTML出力に至るlistify_dfの抜粋です。

import pandas as pd

# Read CSV file into dataframe
csv_file = 'data.csv'
df = pd.read_csv(csv_file)

# Iterate over df, creating numbered list entries
i = 1
for index, row in df.iterrows():
	entry = '<b>' + str(i) + \
			'. <a href="' + \
			row['url'] + \
			'">' + \
			row['title'] + \
			'</a> + \
			'\n\n<blockquote>\n' + \
			row['description'] + \
			'\n</blockquote>\n'
	i += 1
	print(entry)

この場合、明確なファイル名とフォルダー構成は、これらのしばしば役に立つコードの断片を管理するのに役立ちます。

(4)短い1行プログラムでコードの断片を呼び出す

最後に、おそらく定期的に繰り返し使うコードの断片がたくさんあります。さて、なぜあなたはそうするのでしょうか?

必要に応じて、テキスト拡張ツールを使用して短い「フレーズ」を挿入する必要が出て来る場合があります。

LinuxのDesktop用ツールであるAutoKeyを使用すると、トリガーキーワードを関連付ける事が出来、それらのキーワードが入力されたときに挿入される自動的に短いフレーズを挿入するように設定できます。

たとえば、特定のタイプのすべてのプロジェクトに同じライブラリを多数インポートする事はありませんか?

私は良くやります。

たとえば、#nlpimportと入力すると、特定のタスクで作業するために必要なすべてのインポートを設定できるようにしています。これを入力すると、トリガーキーワードとして認識され、次のように置き換えられます。

import sys, requests

import numpy as np
import pandas as pd

import texthero
import scattertext as st

import spacy
from spacy.lang.en.stop_words import STOP_WORDS

from datasets import load_metric, list_metrics
from transformers import pipeline
from fastapi import FastAPI

一部のIDEにはこれらの機能があることに注意してください。私自身は、汎用的な栄光のテキストエディターを使用してコーディングしているため、私の場合はAutoKeyが必要になります。(そしてこれは非常に便利です)。

同等な事ができるIDEを既にご利用の場合は、すばらしいです。重要なのは、同じコードを何度も入力する必要はないということです。

以上が、データサイエンティストとして再利用可能なPythonコードの管理に取り組む際の概要です。

お役に立てば幸いです。

3.データサイエンティストとしてPythonコードを再利用可能な形式で管理する方法関連リンク

1)www.kdnuggets.com
Managing Your Reusable Python Code as a Data Scientist

2)github.com
autokey / autokey

タイトルとURLをコピーしました