[[327915]] 【51CTO.com クイック翻訳】 データ サイエンティストとして、私たちは時々自分たちの仕事を忘れてしまいます。私たちは主に開発者であり、次に研究者であり、そして最終的には数学者になるかもしれません。私たちの第一の責任は、バグのないソリューションを迅速に開発することです。 モデルを構築できるからといって、私たちが神であるわけではなく、くだらないコードを書く自由が与えられるわけでもありません。 最初から、私は多くの間違いを犯してきましたが、機械学習エンジニアリングで最も一般的なスキルは何だと思うかを明らかにしたいと思いました。これは現在業界で最も不足しているスキルでもあると思います。 私は彼らをソフトウェアを理解していないデータ サイエンティストと呼んでいます。なぜなら、彼らの多くはコンピューター サイエンスの正式なトレーニングを受けたエンジニアではないからです。それが私です。 優秀なデータ サイエンティストと優秀な機械学習エンジニアを雇わなければならない場合、私は後者を採用します。 1. 抽象クラスの書き方を学びます。 抽象クラスの記述を開始すると、コード ベースをはるかにクリーンにできる方法がわかります。同じメソッドとメソッド名が適用されます。多くの人が同じプロジェクトに取り組む場合、各人が異なるアプローチを取り始めます。これは深刻な混乱を引き起こすでしょう。 - インポートOS
- abcからABCMeta、abstractmethod をインポートします
- クラス DataProcessor(メタクラス = ABCMeta):
- 「すべての準備に使用するベース プロセッサ。」 「」
- def __init__(self, 入力ディレクトリ, 出力ディレクトリ):
- self.input_directory = 入力ディレクトリ
- self.output_directory = 出力ディレクトリ
- @抽象メソッド
- def読み取り(自己):
- 「生データを読み取ります。」 「 」
- @抽象メソッド
- defプロセス(自己):
- "" "生データを処理します。このステップでは、必要なすべての機能を備えた生データフレームを作成する必要があります。統計またはテキストのクリーニングを実装しないでください。" ""
- @抽象メソッド
- def save(self):
- 「処理されたデータを保存します。」 「」
- クラスTrainer(メタクラス=ABCMeta):
- 「すべてのモデルに使用されるベーストレーナー。」 「」
- def __init__(自分自身、ディレクトリ):
- self.directory = ディレクトリ
- self.model_directory = os.path.join (ディレクトリ、 'モデル' )
- @抽象メソッド
- デフプリプロセス(自己):
- 「これは前処理されたデータを取得し、クリーンなデータを返します。これは統計またはテキストのクリーニングに関するものです。 」
- @抽象メソッド
- def set_model(self):
- 「ここでモデルを定義します。」 「」
- @抽象メソッド
- def fit_model(自己):
- 「これはベクトル化されたデータを受け取り、トレーニングされたモデルを返します。 」
- @抽象メソッド
- 定義:
- 「トレーニング済みのモデルとテスト データを使用してメトリックを生成します。 」
- @抽象メソッド
- def save_model(self, モデル名):
- "" "このメソッドは、必要な形式でモデルを保存します。" ""
- クラス Predict(メタクラス=ABCMeta):
- 「すべてのモデルに使用される基本予測子。」 「」
- def __init__(自分自身、ディレクトリ):
- self.directory = ディレクトリ
- self.model_directory = os.path.join (ディレクトリ、 'モデル' )
- @抽象メソッド
- def load_model(self):
- "" "ここでモデルをロードします。" ""
- @抽象メソッド
- デフプリプロセス(自己):
- 「これは生データを取得し、予測用のクリーンなデータを返します。」 「」
- @抽象メソッド
- def 予測(自己):
- 「これは予測に使用されます。」 「」
- クラス BaseDB(メタクラス=ABCMeta):
- "" " すべての DB コネクタに使用される基本データベース クラス。" ""
- @抽象メソッド
- get_connection(self)を定義します。
- 「これにより、新しい DB 接続が作成されます。 」
- @抽象メソッド
- close_connection(self)を定義します。
- 「これにより DB 接続が閉じられます。 」
2. トップシードを獲得する。 実験の再現性は重要であり、種は敵です。種を大切にしてください。そうしないと、トレーニング/テスト データの分割が異なり、ニューラル ネットワークの重みの初期化も異なります。これにより、一貫性のない結果が生じる可能性があります。 - def set_seed(引数):
- ランダムシード(args.シード)
- np.random.seed(args.seed)
- torch.manual_seed(args.seed)
- args.n_gpu > 0 の場合:
- torch.cuda.manual_seed_all(args.seed)
3. 数行から始めます。 データが非常に大きく、プログラミングの後期段階(データのクリーニングやモデリングなど)にある場合は、毎回膨大なデータをロードしないように nrows を使用します。実際に全体を実行せずにコードをテストしたいだけの場合は、このトリックを使用します。 このトリックは、ローカル PC の構成がデータ サイズを処理するのに十分ではないが、Jupyter/VS code/Atom でローカル開発を行う場合に役立ちます。 - df_train = pd.read_csv('train.csv', nrows=1000)
4. 失敗を覚悟する(成熟した開発者の証)。 後で問題が発生する可能性があるため、データ内の NA を常に確認してください。現在のデータに NA が含まれていない場合でも、将来の再トレーニング サイクルで NA が表示されなくなるわけではありません。とにかく確認してください。 - 印刷(長さ(df))
- df.isna().合計()
- df.dropna()
- 印刷(長さ(df))
5. 処理の進行状況を表示します。 大量のデータを処理しているとき、どれくらいの時間がかかるか、またプロセスのどこにいるのかがわかれば、間違いなく安心できます。 方法 1 — tqdm - tqdmからtqdm をインポート
- インポート時間
- tqdm.pandas()
- df[ 'col' ] = df[ 'col' ].progress_apply(lambda x: x**2)
- テキスト = ""
- のために 文字 tqdm ([ "a" , "b" , "c" , "d" ]):
- 時間.睡眠(0.25)
- テキスト = テキスト +文字
方法 2 — fastprogress - fastprogress.fastprogressからmaster_bar、progress_bar をインポートします
- から 時間インポート 睡眠
- mb = マスターバー(範囲(10))
- iが mbの場合:
- progress_bar(range(100), parent=mb)のjの場合:
- 睡眠(0.01)
- mb.child.comment = f '2番目のバーの統計'
- mb.first_bar.comment = f '最初のバーの統計'
- mb.write(f 'ループ {i} を終了しました。' )
6. パンダは遅くなることがあります。 pandas を使用したことがあるなら、特に groupby 操作を実行するときに、それがどれほど遅くなることがあるかご存知でしょう。処理速度を上げるための「素晴らしい」解決策を見つけるために頭を悩ます必要はありません。コードを 1 行変更して modin を使用するだけです。 - modin.pandasをpdとしてインポートします
7. 関数の時間を計ります。 すべての機能が同じように作成されるわけではありません。 すべてのコードが正常であっても、素晴らしいコードを書いたことを意味するわけではありません。いくつかのソフト エラーは実際にコードの実行速度を低下させるため、そのエラーを見つける必要があります。このデコレータを使用して関数の時間を計測します。 - インポート時間
- タイミングを定義する(f):
- "" "タイミング関数のデコレータ
- 使用法:
- @タイミング
- 定義関数(a):
- 合格
- 「」 「 」
- @ラップ(f)
- def wrapper(*args, **kwargs):
- 開始 =時間.時間()
- 結果 = f(*args, **kwargs)
- 終了=時間.時間()
- print( 'function:%r にかかった時間: %2.2f 秒' % (f.__name__, end - start))
- 結果を返す
- 返品ラッパー
8. クラウドにお金をかけないでください。 クラウド リソースを無駄にするエンジニアを好む人はいません。 一部のテストは数時間かかる場合があります。実験を追跡することは困難であり、クラウド インスタンスは使用されなくなるとシャットダウンされます。私自身もこの間違いを犯したことがありますし、インスタンスを何日も実行したままにしている人も見てきました。 実行の最後に関数を呼び出すだけで、問題は発生しません。 ただし、このアプローチを実装するには、メイン コードを try と use except でラップします。そうすることで、エラーが発生した場合にサーバーが実行を継続できない状態になります。はい、私もこの状況に対処したことがあります。 責任を持って二酸化炭素の排出をやめたほうがいいでしょう。 - インポートOS
- def run_command(cmd):
- os.system(cmd)を返す
- defシャットダウン(秒数=0、OS= 'linux' ):
- "" "指定された秒数後にシステムをシャットダウンします。コストを節約するために EC2 をシャットダウンするのに役立ちます。" ""
- os == 'linux'の場合:
- run_command( 'sudo シャットダウン -h -t sec %s' % 秒)
- elif os == 'windows'の場合:
- run_command( 'shutdown -s -t %s' % 秒)
9. レポートを作成して保存します。 モデリングの特定の段階を過ぎると、すべての貴重な情報はエラーとメトリックの分析からのみ得られるようになります。自分自身と上司のために、適切にフォーマットされたレポートを作成して保存するようにしてください。 結局のところ、経営陣はレポートを読むのが大好きですよね? - jsonをインポート
- インポートOS
- sklearn.metricsからインポート (accuracy_score、classification_report、
- 混乱行列、f1_スコア、fbeta_スコア)
- def get_metrics(y, y_pred, beta=2, average_method= 'macro' , y_encoder=None):
- y_encoderの場合:
- y = y_encoder.inverse_transform(y)
- y_pred = y_encoder.inverse_transform(y_pred)
- 戻る{
- '精度' : round(accuracy_score(y, y_pred), 4),
- 'f1_score_macro' : round(f1_score(y, y_pred, average=average_method), 4),
- 'fbeta_score_macro' : round(fbeta_score(y, y_pred, beta, average=average_method), 4),
- 'レポート' : 分類レポート(y, y_pred, output_dict= True ),
- 'report_csv' : 分類レポート(y, y_pred, output_dict= False )。置換( '\n' , '\r\n' )
- }
- def save_metrics(メトリック: dict、モデルディレクトリ、ファイル名):
- パス = os.path.join (モデルディレクトリ、ファイル名 + '_report.txt' )
- 分類レポートをcsvへ(メトリック[ 'report_csv' ], パス)
- メトリックス.pop( 'report_csv' )
- パス = os.path.join (モデルディレクトリ、ファイル名 + '_metrics.json' )
- json.dump(メトリック、オープン(パス、 'w' )、インデント=4)
10. 優れた API を作成します。 悪い結末を持つコードはすべて悪いです。 データのクリーニングとモデリングをうまく行っても、最終的には大きな混乱が生じることがあります。経験から、多くの人が適切な API、ドキュメント、サーバー構成の書き方を知らないことがわかりました。 以下は、負荷がそれほど高くない (例: 1000/分) 一般的な機械学習およびディープラーニングの展開に適したアプローチです。 Fastapi + uvicornの組み合わせを見てみましょう - 最速: I/O タイプの操作では fastapi が最も高速であるため、API を fastapi で記述します (https://www.techempower.com/benchmarks/#section=test&runid=7464e520-0dc2-473d-bd34-dbdfd7e85911&hw=ph&test=query&l=zijzen-7)。その理由は、こちら (https://fastapi.tiangolo.com/benchmarks/) で説明されています。
- ドキュメント: fastapi を使用して API を記述すると、http:url/docs で無料のドキュメントとテスト エンドポイントが提供されます → コードを変更すると fastapi によって自動的に生成および更新されます。
- ワーカー: uvicorn を使用して API をデプロイします。
4 つのワーカーを使用してデプロイするには、次のコマンドを実行します。負荷テストを通じてワーカーの数を最適化します。 - pip インストール fastapi uvicorn
- uvicorn メイン:app
原題: Python 開発者のための 10 の有用な機械学習プラクティス、著者: Pratik Bhavsar [51CTOによる翻訳。パートナーサイトに転載する場合は、元の翻訳者と出典を51CTO.comとして明記してください] |