あの時、Einstein DiscoveryのデータセットにSalesforceのレコードIDをそのまま説明変数として入れてしまった判断は、今となっては苦い記憶だ。
当時の判断と、なぜそうしてしまったのか
私が担当していたプロジェクトでは、案件の成約可能性を予測するEinstein Discoveryモデルを構築することになった。データエンジニアとして、私はSalesforceのOpportunityオブジェクトから主要なデータと、外部連携システムから取得した顧客の行動データを統合し、Discoveryに投入するデータセットを準備する役割を担っていた。 当時の私は、データセットの作成に際して「とにかく利用可能な情報を全て入れ込むべきだ」と考えていた。特にSalesforceのレコードID(例: `006xxxxxxxxxxxx`)は、各レコードを一意に識別するキーであり、データ統合の際の結合キーとしても頻繁に利用していたため、その重要性は認識していた。他のBIツールやデータウェアハウスでの分析では、IDをキーとしてドリルダウンしたり、特定のレコードに絞り込むことが多かったため、Discoveryでも何らかの「識別情報」として役に立つのではないか、という安易な発想があった。 また、Discovery自体が高度な機械学習プラットフォームであり、不要な特徴量は自動で無視してくれるだろう、という根拠のない期待も抱いていた。Data Prep (当時Dataflow) のRecipeで明示的に除外する手間を惜しんだのも事実だ。「後から問題があれば、そこで対応すればいい」という甘い考えがあった。結果として、作成したデータセットには、以下のような項目が説明変数として含まれていた。
- 案件ID (Opportunity.Id)
- アカウントID (Account.Id)
- 商談フェーズ (Opportunity.StageName)
- 商談金額 (Opportunity.Amount)
- リードソース (Opportunity.LeadSource)
- その他、カスタム項目や外部データ由来の行動履歴集計値...
モデル構築後の問題点
データセットをDiscoveryに投入し、モデルの学習が完了した。結果を見た時、私はすぐに異変に気づいた。 「最も予測に寄与する因子」として、上位にSalesforceの「案件ID」が浮上してきたのだ。 当初、私は「おお、さすがDiscovery、ユニークな識別子からも何か洞察を得たのか!」と一瞬勘違いした。しかし、よくよく考えてみると、これはビジネスロジックとして完全に破綻している。案件ID自体が直接的に成約可能性を高める因子であるわけがない。これは単なる識別子であり、そのIDによって予測が変わるというのは、モデルが過学習を起こしているか、あるいはデータセットに何らかの深刻な構造的問題があることを示唆していた。 チーム内でモデルの結果を共有した際も、ビジネスサイドからは「なぜ案件IDが最も重要なのか?これを見て何を改善しろと?」という当然の疑問が呈され、明確な回答ができなかった。モデルの洞察(Insights)を見ても、案件IDと成約率の関連性を示すグラフはただのノイズにしか見えず、真にビジネスに役立つ示唆は得られなかった。 この結果を受けて、私たちはモデルの信頼性が低いと判断し、一からデータセットの見直しとモデルの再構築を行う羽目になった。データエンジニアとしての反省と、今ならどうするか
この経験から、データエンジニアとしてEinstein Discovery、ひいては機械学習モデルのためのデータ準備において、いくつかの重要な教訓を得た。特徴量エンジニアリングの意識
ID列は、通常、モデルの学習には不適切だ。これは、各レコードに一意に割り当てられるため、モデルがそのIDに過度に依存し、汎用性の低いモデル(過学習)を生み出す可能性が高いからだ。当時の私は、データウェアハウスやBIツールでの経験から、IDを「分析の切り口」として捉えすぎていたが、機械学習においては「意味のある特徴量」と「単なる識別子」を明確に区別する必要があった。Data Prep (Recipe) での明示的な除外
「自動でやってくれるだろう」という期待は禁物だ。明示的に除外すべきものは除外する。当時使っていたData Prep (当時はDataflowだったが、現在はRecipeが主流) であれば、`drop`変換で簡単に不要な列を削除できたはずだ。
{
"action": "drop",
"parameters": {
"columns": ["Id", "Opportunity.Id", "Account.Id"]
}
}
あるいは、RecipeのGUI上で対象列のデータタイプを「識別子」として定義することもできる。これにより、Discoveryはモデル学習時にその列の扱い方を適切に判断してくれる。しかし、私の失敗は、そもそもその判断自体をDiscoveryに丸投げしようとした点にあった。
ビジネス要件と特徴量の関連付け
データセットを準備する前に、ビジネス側の予測したいこと、そしてその予測に寄与すると考えられる因子(特徴量)について、深く理解し、議論すべきだった。IDのような識別子は、特定のレコードを指し示すだけであり、そのレコードがなぜそうなるのか、という因果関係を説明するものではない。 今なら、データセット設計の初期段階で、以下を徹底する。- 目的変数の明確化: 何を予測したいのか?(例: 成約/失注)
- ビジネス仮説に基づく特徴量候補の洗い出し: どのような情報が予測に役立つか?(例: 案件金額、フェーズ移行日数、営業担当者の経験、顧客の業界など)
- 識別子の排除: ID列は結合キーとしてのみ利用し、説明変数からは原則として除外する。特にSalesforceのシステムIDは予測モデルにとってノイズでしかないことが多い。
- 高カーディナリティカテゴリカル変数の検討: レコードIDほどではないにせよ、数千、数万といったユニーク値を持つカテゴリカル変数(例: 顧客名、詳細な商品コード)も、ID列と同様の問題を引き起こす可能性があるため、適切にエンコーディングするか、集約するか、あるいは除外するかを慎重に判断する。
コメント
コメントを投稿