Scriptノード
Scriptノードでは、パイプライン内でカスタムPythonコードを記述できます。データ前処理、特徴量エンジニアリング、カスタム分析に使用します。
| プロパティ | 値 |
|---|---|
| タイプ | 処理ノード |
| 入力 | DataFrameまたはModel(オプション) |
| 出力 | DataFrameまたはModel |
| エディタ | Monaco(VS Code風) |
エディタ機能
Section titled “エディタ機能”ScriptノードはMonaco Editorを使用:
- Pythonシンタックスハイライト
- オートコンプリート
- エラーハイライト
- 行番号
- マルチカーソル
利用可能な変数
Section titled “利用可能な変数”スクリプト内で以下の変数が利用可能:
| 変数 | 型 | 説明 |
|---|---|---|
df | DataFrame | 入力データ(DataLoaderに接続時) |
model | sklearnモデル | 入力モデル(Trainerに接続時) |
np | module | NumPy(事前インポート済み) |
pd | module | Pandas(事前インポート済み) |
スクリプトは結果を特定の出力変数に代入する必要があります:
データを出力
Section titled “データを出力”# 入力: df(DataLoaderから)# 出力: df(変更されたDataFrame)
# 行をフィルタdf = df[df['age'] > 18]
# 新しいカラムを追加df['age_group'] = pd.cut(df['age'], bins=[0, 30, 50, 100], labels=['young', 'mid', 'senior'])
# 最終的な`df`の値が次のノードに渡されるモデルを出力
Section titled “モデルを出力”# 入力: model(Trainerから)# 出力: model(変更またはラップされたモデル)
# モデルプロパティにアクセスprint(f"Model type: {type(model).__name__}")print(f"Feature importances: {model.feature_importances_}")
# モデルを変更せずに通過# model = model(暗黙的)一般的なユースケース
Section titled “一般的なユースケース”データ前処理
Section titled “データ前処理”# 欠損値を補完df['age'].fillna(df['age'].median(), inplace=True)df['category'].fillna('unknown', inplace=True)
# または欠損値のある行を削除df = df.dropna()# 派生特徴量を作成df['total_spend'] = df['price'] * df['quantity']df['log_income'] = np.log1p(df['income'])df['name_length'] = df['name'].str.len()
# 日付特徴量df['date'] = pd.to_datetime(df['date'])df['day_of_week'] = df['date'].dt.dayofweekdf['month'] = df['date'].dt.month# ワンホットエンコーディングdf = pd.get_dummies(df, columns=['category', 'region'])
# ラベルエンコーディングfrom sklearn.preprocessing import LabelEncoderle = LabelEncoder()df['category_encoded'] = le.fit_transform(df['category'])データフィルタリング
Section titled “データフィルタリング”# 条件でフィルタdf = df[df['status'] == 'active']
# 日付範囲でフィルタdf['date'] = pd.to_datetime(df['date'])df = df[(df['date'] >= '2024-01-01') & (df['date'] <= '2024-12-31')]
# ランダム行をサンプリングdf = df.sample(frac=0.1, random_state=42) # 10%サンプル# 数値カラムを正規化from sklearn.preprocessing import StandardScalerscaler = StandardScaler()numeric_cols = ['age', 'income', 'score']df[numeric_cols] = scaler.fit_transform(df[numeric_cols])
# 対数変換df['log_revenue'] = np.log1p(df['revenue'])カスタム分析
Section titled “カスタム分析”# サマリー統計を生成print("Dataset Summary:")print(f"Rows: {len(df)}")print(f"Columns: {list(df.columns)}")print("\nNumeric stats:")print(df.describe())
print("\nMissing values:")print(df.isnull().sum())
print("\nClass distribution:")print(df['target'].value_counts())スクリプトは分離されたPythonサブプロセスで実行されます。スクリプトが失敗した場合:
- エラーメッセージが出力パネルに表示
- パイプラインはこのノードで停止
- エラーを修正して再実行
よくあるエラー
Section titled “よくあるエラー”| エラー | 原因 | 修正 |
|---|---|---|
NameError: name 'df' is not defined | DataLoaderが接続されていない | まずDataLoaderを接続 |
KeyError: 'column_name' | カラムが存在しない | df.columnsを確認 |
ModuleNotFoundError | パッケージがインストールされていない | pip install packageでインストール |
print出力
Section titled “print出力”全てのprint()出力はノードの出力パネルに表示:
print("Processing data...")print(f"Input shape: {df.shape}")
# 処理コード
print(f"Output shape: {df.shape}")print("Done!")出力:
Processing data...Input shape: (1000, 10)Output shape: (950, 12)Done!- GUI不可: matplotlibプロットは表示不可(可視化にはEvaluatorを使用)
- 入力不可: stdinからの読み取りやユーザー入力のプロンプト不可
- タイムアウト: スクリプトはデフォルトで5分後にタイムアウト
- メモリ: 利用可能なシステムメモリに制限
外部パッケージ
Section titled “外部パッケージ”インストール済みの任意のPythonパッケージをインポート可能:
import numpy as np # 事前インポート済みimport pandas as pd # 事前インポート済みfrom sklearn.preprocessing import StandardScalerfrom scipy import statsimport reベストプラクティス
Section titled “ベストプラクティス”- スクリプトを集中させる — 明確さのため1スクリプトに1つの変換
- コメントを追加 — スクリプトの動作を文書化
- 進行状況を表示 —
print()で何が起きているか表示 - エラーを処理 — リスクのある操作にはtry/exceptを使用
- 段階的にテスト — 各変更後に実行
例:完全な前処理スクリプト
Section titled “例:完全な前処理スクリプト”"""データ前処理スクリプト- 欠損値を処理- カテゴリカルをエンコード- 特徴量を作成- 数値をスケーリング"""
print("Starting preprocessing...")
# 1. 欠損値を処理print(f"Missing before: {df.isnull().sum().sum()}")df['age'].fillna(df['age'].median(), inplace=True)df['income'].fillna(df['income'].mean(), inplace=True)df = df.dropna(subset=['target'])print(f"Missing after: {df.isnull().sum().sum()}")
# 2. 特徴量エンジニアリングdf['income_per_age'] = df['income'] / (df['age'] + 1)df['is_high_income'] = (df['income'] > df['income'].median()).astype(int)
# 3. カテゴリカルをエンコードdf = pd.get_dummies(df, columns=['region', 'category'], drop_first=True)
# 4. 数値をスケーリングfrom sklearn.preprocessing import StandardScalerscaler = StandardScaler()numeric_cols = ['age', 'income', 'score', 'income_per_age']df[numeric_cols] = scaler.fit_transform(df[numeric_cols])
print(f"Final shape: {df.shape}")print(f"Columns: {list(df.columns)}")print("Preprocessing complete!")- DataLoader — 処理するデータを読み込み
- Trainer — 処理したデータで学習