atai-newton-omega-model-data-prep について
atai-newton-omega-model を使うセンサ時系列向けのローカル前処理スキルです。欠損の診断、長いギャップの分割、時系列分割、センサー特徴量の整形を行います。
主な機能
- 01欠損値とサンプリング間隔の診断
- 02長いギャップでデータを分割
- 03補完と処理行のフラグ付け
- 04時系列順の訓練・テスト分割
- 05センサー埋め込みの統合と任意の次元削減
活用シーン
- 01不規則なタイムスタンプや NaN を含むセンサーデータの整備
- 02時系列評価での未来データ漏洩の抑制
- 03複数センサーの埋め込みを KNN 用特徴行列に整形
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ archetypeai/ agent-skills --skill atai-newton-omega-model-data-prepインストール後、Claude Code で/atai-newton-omega-model-data-prepを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/data_preprocessor.pydata_splitter.pyfeature_preparer.pyrequirements.txttests/__init__.pyconftest.pytest_data_preprocessor.pytest_data_splitter.pytest_feature_preparer.py詳細
Newton データ準備 — クリーン処理 → 分割 → 特徴量化
時系列センサーデータ用のモデリング前パイプラインです。組み合わせ可能な3つの構成要素により、生の多変量データフレームから、後続の KNN/Isolation Forest 分類器が必要とする (X, y, metadata) 配列を生成します。
出典。 ベンダー提供の3つのスクリプトは、Solutions Engineering の Lucas による作業を起源とし、実際の準備パイプラインでエンドツーエンドに使用されています。リポジトリ内のコピーを正とし、新しいリビジョンを取り込む必要がある場合は Lucas に連絡してください。
適用する場面
- ユーザーが生の多変量センサー CSV(1つ以上のセンサー、不規則なタイムスタンプ、NaN の欠損を含む)を持っており、
atai-newton-omega-modelで埋め込みを行う前に、データをクリーンアップする必要がある場合。 - ユーザーから「NaN を含む行は削除すべきですか?」「欠損区間はどう扱えばよいですか?」「時系列データに適した訓練/テスト分割は何ですか?」と尋ねられた場合。
- 分類器の性能が不自然に良すぎる、または悪すぎるため、時間的なデータリークが疑われる場合 —
DataSplitter(mode='oot')が解決策です。 - ユーザーが(Omega モデルから得た)センサーごとの埋め込みを持っており、KNN 用に単一の特徴量行列へまとめる必要がある場合 — それが
FeaturePreparerです。 - ユーザーが
atai-newton-omega-modelで説明されている「joint state」パターンをコードで実装したい場合。
実行前に読み取り専用の可否判定を行いたい場合は、外部の omega-1-4-preflight チェックを使用してください。Preflight はデータを変更しません。このスキルはデータを変更し、ブロック分割、補完、次元削減を行います。両者は相補的です。Preflight はデータセットを再利用できるかを判定し、このスキルはデータセットをクリーンアップします。
次の場合はこのスキルを使用しないでください:
- タスクが動画、画像、またはテキストを対象とする場合(
atai-newton-fusion-modelを使用してください)。 - データがすでに完全な場合(サンプリングが規則的で、NaN がなく、データリークのリスクもない場合) — パイプラインは何も行わずに終了するため、データフレームをそのまま後続のスキルに渡せます。
3つの構成要素
1. DataPreprocessor — 診断と欠損区間を考慮したブロック分割
references/data_preprocessor.py
「ブロック」とは、選択したすべてのセンサーにデータがあり、gap_threshold_samples を超える長さの NaN の連続区間がない、連続したセグメントです。長い欠損区間は別々のブロックに分割されます。長い欠損をまたいで補完すると、データを捏造することになるためです。
2段階での使用方法:
from data_preprocessor import DataPreprocessor
prep = DataPreprocessor(
timestamp_col='timestamp',
sampling_rate_minutes=1,
gap_threshold_samples=5, # NaN runs > 5 samples split into a new block
imputation_method='linear', # or 'time', 'ffill', 'bfill', 'spline' + kwargs
)
# Phase 1: diagnose (read-only). Decide gap_threshold from this.
report = prep.diagnose(df_raw, verbose=True, plot=True)
# Phase 2: build. Returns the cleaned df with added 'block_id' + 'imputed' columns.
df_clean = prep.build(df_raw)
diagnose() の戻り値は、サンプリングレートの CV(規則性)、(starts_at, ends_at, size) を含む上位 N 件の欠損区間、列ごとの null 数、そして列ごとの最大連続 null 数を網羅する、構造化された {'timestamp': {...}, 'nulls': {...}} レポートです。最大連続 null 数は、gap_threshold_samples を決めるうえで最も重要な数値です。plot=True を指定すると、差分のヒストグラムと欠損状況マップも生成されます。
build() は出力に次の2列を追加します:
block_id(int):その行が属する連続ブロックimputed(bool):この行のいずれかのセンサーが元々 NaN だった場合は True
長い欠損区間内の行は補完せず、完全に削除されます。連続区間がしきい値を超えてしまうためです。
重要なパラメーター:
gap_threshold_samples:_diagnose_nullsのmax_consecutive_nullに基づいて設定します。デフォルトの保守的な値は 5 です。ノイズの多いセンサーでは、より高い値に設定します。ただし、実際の停止区間をまたぐ値にはしないでください。imputation_method:デフォルトとして適切なのは'linear'です。サンプリングが完全には規則的でない場合は'time'を使用してください。補間すべきでないカテゴリ値のようなセンサーには、'ffill'/'bfill'のみを使用してください。drop_sensors:信頼性が低い、または顧客にとって重要でないことが分かっているセンサーを指定します。欠損区間の検出前に削除されるため、そのセンサーの NaN によって不要なブロック分割が発生しません。
2. DataSplitter — 時系列順の学習/テスト分割
時系列交差検証を誤った方法で行うと、誤った確信につながります。ランダム分割では未来の情報が学習セットに漏れますが、OOT 分割ではその心配はありません。
from data_splitter import DataSplitter
splitter = DataSplitter(mode='oot', test_size=0.3, timestamp_column='timestamp')
X_train, X_test, y_train, y_test, meta_train, meta_test = splitter.split(X, y, metadata)
既定では mode='oot' を使用してください。mode='random' は健全性チェック(「そもそも何か学習できているか?」)に限って使用し、本番の分割には使わないでください。
教師なしタスク(Isolation Forest など)では y を None にできます。その場合、y_train/y_test は None で返されます。
3. FeaturePreparer — 状態をまとめて特徴量化
references/feature_preparer.py
センサーごと・ウィンドウごとの埋め込みデータフレームを、各行があるウィンドウにおけるすべてのセンサーの全体状態を表す単一の (X, y, metadata) 行列に変換します(埋め込みを連結する方式で、Omega のノートでは「philosophy 2」と呼ばれることがあります)。オプションで L2 正規化、標準化、PCA による次元削減を行えます。
from feature_preparer import FeaturePreparer
preparer = FeaturePreparer(
normalize='l2', # or 'standardize', or None
reduce_dim=50, # or None to skip PCA
sensor_order=None, # None = alphabetical, fixed across train/test
)
# df_emb is the output of an Omega embedding step
# (see atai-newton-omega-model for how to produce it).
X, y, metadata = preparer.prepare(df_emb, label_column='machine_state')
重要なルール:
sensor_orderは学習用とテスト用で同じでなければなりません。既定値のままならアルファベット順になりますが、少しでも不安がある場合は明示的に固定してください。- 同じウィンドウのセンサー間で、ウィンドウごとのラベルが一致している必要があります。一致しないラベルが見つかると、クラスはエラーを発生させます。
reduce_dimは D 未満、かつ N 未満でなければなりません。データセットが小さい場合は PCA を省略してください。- 後続処理がコサイン距離に近い距離を使う KNN の場合は
normalize='l2'が適切な既定値です。後続処理がメトリックモデル/線形モデルの場合は'standardize'を使用してください。
パイプライン全体
# 1. Diagnose, then clean
prep = DataPreprocessor(timestamp_col='timestamp', sampling_rate_minutes=1, gap_threshold_samples=5)
report = prep.diagnose(df_raw, verbose=True)
df_clean = prep.build(df_raw)
# 2. Embed (see atai-newton-omega-model) — one row per (sensor, window) with an embedding column.
df_emb = embedding_generator.generate(
df_clean, data_columns=['sensor_a', 'sensor_b'], label_columns=['machine_state'],
)
# 3. Featurize into (X, y, metadata)
preparer = FeaturePreparer(normalize='l2', reduce_dim=50)
X, y, metadata = preparer.prepare(df_emb, label_column='machine_state')
# 4. Split out-of-time
splitter = DataSplitter(mode='oot', test_size=0.3)
X_train, X_test, y_train, y_test, meta_train, meta_test = splitter.split(X, y, metadata)
# 5. Hand to your classifier of choice (KNN / IsolationForest).
他のスキルとの組み合わせ
| スキル | 関係 |
|---|---|
atai-newton-omega-model | 同系列+後続処理 — Omega の埋め込み処理は DataPreprocessor.build() と FeaturePreparer.prepare() の間に入り、生成された (X, y, metadata) を使って、/query の Omega 埋め込みに対するウィンドウごとの KNN を実行します。このスキルはその前段(データのクリーンアップ)と後段(特徴量化)を担います。 |
atai-operational-state-monitoring-agent-data-prep | マネージド OSM エージェント向けの同系列スキル — ローカルの KNN ではなく OSM エージェントにデータを渡しますか?ラベル付き記録を、OSM プラットフォームが受け付けるロールファイル(正確なグリッド、状態ごとに 1 つの学習ファイル、連続したスコア付きファイル、プラットフォームのルールに照らした事前チェック)に変換します。必要に応じて、まずここで乱雑な生データをクリーンアップしてください。プラットフォーム側で埋め込みを行うため、FeaturePreparer は使用しません。 |
omega-1-4-preflight | 上流のゲート(外部リポジトリ) — 読み取り専用の静的チェックです。このスキルを実行する前に実行し、データセットをクリーンアップする価値があるか判断します。 |
よくある落とし穴
- 時系列データをランダム分割する。 ほとんどの場合、誤りです。
mode='oot'を使用してください。例外は、時間的順序を明示的に無視して、時間に依存しない効果だけを切り分けたいアブレーション実験です。 - 長いギャップをまたいで補間する。 「データを増やす」ために
gap_threshold_samplesを大きくしないでください。正解データを捏造することになります。補間の信頼性が保てないほどギャップが長い場合、その領域は別ブロックに分けるか、削除してください。 - ウィンドウごとのラベルが一致しない。
FeaturePreparer.prepare()がラベルの不一致でエラーになる場合、問題は上流にあります。埋め込み処理でのラベル伝播方法('last'/'first'/'mode')が、生データの行にラベルを割り当てた方法と一致していません。チェックを無効にするのではなく、そこで整合性を取ってください。 - 学習用とテスト用で
sensor_orderが異なる。 連結された全体状態ベクトルの順序が入れ替わり、予測が気付かないまま壊れます。sensor_orderを明示的に固定してください。 - 小さすぎるデータセットで PCA を使う。 PCA では、サンプル数と次元数の両方が成分数を上回る必要があります。サンプル数が約 100 未満の場合は省略してください。
ローカル環境のセットアップ
# In a virtualenv (system pythons are often PEP 668 "externally managed"):
python3 -m venv .venv && source .venv/bin/activate
pip install -r skills/atai-newton-omega-model-data-prep/references/requirements.txt
pip install matplotlib # optional: only for plot=True in diagnose()
Newton API キーは不要です。このスキルはローカルでのデータ加工のみを行います。
ファイル構成
skills/atai-newton-omega-model-data-prep/
├── SKILL.md ← this file
├── references/
│ ├── requirements.txt ← runtime deps (pip install -r requirements.txt)
│ ├── data_preprocessor.py ← gap-aware blocking + diagnostics
│ ├── data_splitter.py ← OOT / random train/test split
│ └── feature_preparer.py ← joint-state featurization + PCA
└── tests/
├── conftest.py ← shared fixtures
├── test_data_preprocessor.py
├── test_data_splitter.py
└── test_feature_preparer.py
テストの実行
pip install -r skills/atai-newton-omega-model-data-prep/references/requirements.txt pytest
pytest skills/atai-newton-omega-model-data-prep/tests/ -v
skills/atai-newton-omega-model-data-prep/** に変更を加えるすべての PR で、CI がテストスイートを自動的に実行します(.github/workflows/test-atai-newton-omega-model-data-prep.yml を参照)。