あるチュートリアルでは、Pythonでカスタムデータ型を扱い、不正なデータを許容し、スキーマの進化に対応できるJSONシリアライゼーションプロセスを構築する方法を詳細に説明しています。 目的は、ファイル、プロセス、マイクロサービス、API間でデータセットを流通させ、パイプラインが最初の異常で停止しないようにすることです。
記事によると、機械学習エンジニアの時間のうち、モデルアーキテクチャの記述に費やされるのはほんの一部です。残りは、データの「配管作業」(「data plumbing」)、つまりデータのクリーニング、前処理、変換に費やされます。この作業の一部は、データをシリアライズ(テキストに変換して保存または送信)し、その後デシリアライズ(Pythonオブジェクトに再構築)することです。
根本的な問題は、JSONフォーマットが基本的な型しか認識しないという制限にあります。Enum、set、Path、またはdatetimeを含む実験設定辞書は、json.dumps()を呼び出すとすぐに「TypeError: Object of type ModelType is not JSON serializable」というエラーメッセージでエラーを引き起こします。
カスタムエンコーダー
最初のステップは、json.JSONEncoderを継承し、そのdefault()メソッドを再定義するクラスを定義することです。問題のある型ごとに、isinstance()の形式の条件で実行する変換を指定します。これにより、datetimeはISO形式の値を持つ辞書に変換され、setはリストに、Pathは文字列に、Enumはその値に変換されます。
重要な詳細があります:エンコーダーは、リストに変換されたsetなど、元の性質を失う可能性のあるオブジェクトに「__type__」というキーを追加します。引数clsを介してjson.dumps()に渡されると、サンプル辞書はエラーなくシリアライズされ、datetimeは「2026-09-28T14:26:10.328310」の形式で表示されます。
エラー耐性のあるデコーダー
逆方向では、robust_decoder関数が引数object_hookを介してjson.loads()に渡されます。この関数はネストされた各辞書に対して呼び出され、キー「__type__」が存在する場合に元のオブジェクトを再構築します。変換はtryブロック内に配置され、ValueErrorとTypeErrorを捕捉します。
不正なデータの場合、関数はloggingモジュールを介して警告を記録し、処理を中断せずに生の値を返します。記事では、この動作をフォールバック値や特定のエラー辞書に置き換えることができると説明しています。デシリアライズ後、日付はdatetimeとして、リストはsetとして正しく認識されます。
スキーマの進化に対応する
モデルのメタデータスキーマは頻繁に変更されます:ハイパーパラメータが追加されたり、廃止されたり、一部のメトリクスが名前変更されたりします。これに対応するため、著者はload_experiment_config()というファクトリ関数を提案しています。この関数は、デコーダーを使用してJSONをロードし、get()を使用してデフォルト値を適用します。
例では、古い設定に存在しないハイパーパラメータ「learning_rate」にデフォルト値0.001が割り当てられています。同じ原則は、あらゆる新しいパラメータに適用できます。記事では、ロード時に廃止されたフィールドを削除する可能性にも言及しています。元の設定に適用すると、ロードは期待される型を復元します:識別子の整数、変数のset、パスのPosixPath、タイムスタンプのdatetime、学習率のfloatです。





