デノイザーの夜明け:表形式のデータ補完のためのマルチ出力MLモデル

デノイザーの夜明け:表形式データ補完のためのマルチ出力MLモデル

Jon TysonさんによるUnsplashでの写真

欠損値の扱いは、データサイエンスにおける基本的な問題です。欠損値が無視できない場合、または何らかの理由で除外できない場合は、それらを補完すること、つまり欠損値を他の値で置き換えることができます。欠損値の補完には、いくつかのシンプルな(しかし単純化された)手法と、いくつかの高度な手法(より正確ですが複雑でリソースを消費する可能性があります)があります。本記事では、シンプルさと有用性のバランスを追求するための新しい表データ補完手法を紹介します。

具体的には、非構造化データに関連する通常のノイズ除去の概念を使用して、どのようにマルチ出力の機械学習アルゴリズムをタブularデータの補完器に変換するかを見ていきます。まず、ノイズ除去、補完、マルチ出力アルゴリズムの基本的な概念について説明し、その後、ノイズ除去を使用してマルチ出力アルゴリズムを補完器に変換する方法の詳細について説明します。次に、この新しい手法が業界の実例でどのように応用されるかについて簡単に見ていきます。最後に、ジェネラティブAIとファウンデーションモデルの時代における表データのノイズ除去ベースの補完の将来的な重要性について議論します。説明のために、コードの例はPythonのみで表示されますが、概念的なアプローチ自体は言語に依存しません。

ノイズ除去から補完へ

ノイズ除去とは、データからノイズを取り除くことです。ノイズ除去アルゴリズムは、ノイズの多いデータを入力として受け取り、ノイズを可能な限り減らすためのいくつかの処理を行い、ノイズ除去されたデータを返します。ノイズ除去の典型的な使用例は、音声データからノイズを除去したり、ぼやけた画像を鮮明にしたりすることです。ノイズ除去アルゴリズムは、ガウスフィルタや中央値フィルタからオートエンコーダまで、いくつかのアプローチを使用して構築することができます。

ノイズ除去の概念は、非構造化データ(音声、画像など)を含むユースケースに主に関連している傾向がありますが、構造化された表データの補完も密接に関連しています。表データの欠損値を置き換える(または補完する)方法は多岐にわたります。たとえば、データを単にゼロ(または与えられたコンテキストでの等価な値)で置き換えるか、数値データの場合は関連する行または列の統計量(平均、中央値、最頻値、最小値、最大値)で置き換えることができますが、これによりデータが歪み、MLトレーニングワークフローの前処理ステップとして使用される場合、このような単純化された補完は予測性能に悪影響を与える可能性があります。 K最近傍法(KNN)や関連ルールマイニングなどの他の手法は、より良い結果を得ることができるかもしれませんが、トレーニングの概念を持たず、テストデータで直接動作するため、テストデータのサイズが大きくなると速度に問題が発生する場合があります。これは、高速なオンライン推論を必要とするユースケースにおいて特に問題となります。

ここで、欠損値を持つ特徴を出力とし、残りの特徴を予測子(または入力)として使用する単一出力モデルを単純にトレーニングすることができます。欠損値のある複数の特徴がある場合、それぞれのために単一出力モデルを構築することは手間がかかるばかりでなく、費用もかかるため、一度にすべての関連する特徴の欠損値を予測するマルチ出力モデルを構築することを試みることができます。重要なのは、欠損値をノイズと考えることができる場合、ノイズ除去の概念を適用して表データを補完することができるかもしれないということです。これが、以下のセクションで展開する鍵となる洞察です。

マルチ出力の機械学習アルゴリズム

その名の通り、マルチ出力(またはマルチターゲット)アルゴリズムは、複数の出力/ターゲット特徴を同時に予測するためのモデルのトレーニングに使用することができます。Scikit-learnのウェブサイトでは、分類と回帰のためのマルチ出力アルゴリズムについての素晴らしい概要が提供されています(こちらを参照してください)。

一部の機械学習アルゴリズムは、マルチ出力モデリングをすぐに利用できるようになっていますが、他のアルゴリズムは、ネイティブで単一出力モデリングのみをサポートしている場合があります。Scikit-learnなどのライブラリでは、フィットや予測などの通常の関数を実装するラッパーを提供し、これらをハンダウンの下で独立して個別の単一出力モデルに適用することで、単一出力アルゴリズムをマルチ出力モデリングに活用する方法が提供されています。以下の例コードは、Scikit-learnで線形サポートベクターレグレッション(Linear SVR)の実装をラップし、MultiOutputRegressorラッパーを使用してマルチ出力の回帰モデルに変換する方法を示しています。

from sklearn.datasets import make_regressionfrom sklearn.svm import LinearSVRfrom sklearn.multioutput import MultiOutputRegressor# おもちゃのデータセットを作成RANDOM_STATE = 100xs, ys = make_regression(    n_samples=2000, n_features=7, n_informative=5,     n_targets=3, random_state=RANDOM_STATE, noise=0.2)# Linear SVRをラップしてマルチ出力モデリングを有効にするwrapped_model = MultiOutputRegressor(    LinearSVR(random_state=RANDOM_STATE)).fit(xs, ys)

このようなラッピング戦略は、少なくともマルチアウトプットの使用ケースで単一の出力アルゴリズムを使用することができるようにするが、出力特徴間の相関や依存関係を考慮していない場合があります(つまり、予測された出力特徴のセットが全体として意味を成すかどうか)。対照的に、ネイティブでマルチアウトプットモデリングをサポートするいくつかのMLアルゴリズムは、出力間の関係を考慮しているようです。例えば、Scikit-learnの決定木を使用して入力データに基づいてn個の出力をモデル化する場合、すべてのn個の出力値が葉に格納され、分割基準にはすべてのn個の出力値を1つのセットとして考慮するための基準が使用されます。たとえば、それらの平均値を取ることで(こちらを参照してください)。次の例コードは、マルチアウトプットの決定木回帰モデルを構築する方法を示しています。外見上は、単一のSVRモデルをラッピングしてトレーニングするために示された手順と非常に似ていることに気づくでしょう。

from sklearn.datasets import make_regressionfrom sklearn.tree import DecisionTreeRegressor# おもちゃのデータセットを作成RANDOM_STATE = 100xs, ys = make_regression(    n_samples=2000, n_features=7, n_informative=5,     n_targets=3, random_state=RANDOM_STATE, noise=0.2)# 決定木モデルを使用してマルチアウトプットモデルを直接トレーニングするmodel = DecisionTreeRegressor(random_state=RANDOM_STATE).fit(xs, ys)

表形式データ補完のためのデノイザーとしてのマルチアウトプットMLモデルのトレーニング

デノイジング、補間、マルチアウトプットMLアルゴリズムの基本をカバーしたので、これらのビルディングブロックを組み合わせる準備ができました。一般的に、ノイズ除去を使用して表形式データを補完するためにマルチアウトプットMLモデルをトレーニングする手順は以下のとおりです。前のセクションのコード例とは異なり、次の手順では明示的に予測子とターゲットを区別しません。これは、表形式データ補完の文脈では、特徴量がデータに存在する場合は予測子として機能し、欠損している場合はターゲットとして機能するためです。

ステップ1:トレーニングデータセットと検証データセットの作成

データをトレーニングセットと検証セットに分割します。たとえば、80:20の分割比率を使用します。これらのセットをそれぞれdf_trainingおよびdf_validationと呼びましょう。

ステップ2:トレーニングデータセットおよび検証データセットのノイズ/マスクされたコピーの作成

df_trainingとdf_validationのコピーを作成し、これらのコピーのデータにノイズを追加します。たとえば、ランダムに値をマスクすることでノイズを追加します。これらのマスクされたコピーをそれぞれdf_training_maskedおよびdf_validation_maskedと呼びましょう。マスキング関数の選択は、最終的にトレーニングされるインピュータの予測精度に影響を与える可能性があるため、次のセクションでいくつかのマスキング戦略を見てみましょう。また、df_trainingのサイズが小さい場合は、行をある倍率kでアップサンプリングすることが意味を成す場合があります。つまり、df_trainingがn行m列の場合、アップサンプルされたdf_training_maskedデータセットはn*k行(および以前と同じm列)になります。

ステップ3:デノイジングベースのインピュータとしてのマルチアウトプットモデルのトレーニング

選択したマルチアウトプットアルゴリズムを選択し、ノイズ/マスクされたコピーを使用して元のトレーニングデータを予測するモデルをトレーニングします。概念的には、model.fit(predictors = df_training_masked, targets = df_training) のようなことを行います。

ステップ4:マスクされた検証データセットにインピュータを適用する

トレーニングされたモデルにdf_validation_maskedを渡してdf_validationを予測します。概念的には、df_validation_imputed = model.predict(df_validation_masked) のようになります。一部のフィッティング関数は、フィッティングプロセス中に検証エラーを計算するための引数として直接検証データセットを取ることがあります(たとえば、TensorFlowのニューラルネットワークの場合)。その場合は、予測子としてノイズ/マスクされた検証セット(df_validation_masked)を使用し、ターゲットとして元の検証セット(df_validation)を使用して検証エラーを計算することを忘れないでください。

ステップ5:検証データセットの補完精度の評価

df_validation_imputed(モデルが予測した値)とdf_validation(グランドトゥルース)を比較して、補完精度を評価します。評価は列ごとに行うことができます(特徴ごとの補完精度を判断するため)または行ごとに行うことができます(予測インスタンスごとの精度をチェックするため)。列ごとに膨張した精度結果を得ないようにするために、df_validation_maskedで補完する対象の列値がマスクされていない行は、精度を計算する前にフィルタリングすることができます。

最後に、上記の手順を実験してモデルを最適化することができます(たとえば、別のマスキング戦略を使用したり、異なるマルチ出力の機械学習アルゴリズムを選択したりすることができます)。

以下のコードは、手順1〜5を実装するためのおもちゃの例を示しています。

import pandas as pdimport numpy as npfrom sklearn.datasets import make_classificationfrom sklearn.tree import DecisionTreeClassifier# おもちゃのデータセットを作成RANDOM_STATE = 100data = make_classification(n_samples=2000, n_features=7, n_classes=1, random_state=RANDOM_STATE, class_sep=2, n_informative=3)df = pd.DataFrame(data[0]).applymap(lambda x: int(abs(x)))###### Step 1: トレーニングデータセットとバリデーションデータセットを作成する#####TRAIN_TEST_SPLIT_FRAC = 0.8n = int(df.shape[0]*TRAIN_TEST_SPLIT_FRAC)df_training, df_validation = df.iloc[:n, :], df.iloc[n:, :].reset_index(drop=True)###### Step 2: トレーニングデータセットとバリデーションデータセットのノイズ/マスクされたコピーを作成する###### 各値のマスクの決定をコイントス(ベルヌーイイベント)としてフレーム化したランダムなマスキングの例def random_masking(value): return -1 if np.random.binomial(n=1, p=0.5) else valuedf_training_masked = df_training.applymap(random_masking)df_validation_masked = df_validation.applymap(random_masking)###### Step 3: ノイズ除去ベースの補完器として使用するためのマルチ出力モデルをトレーニングする###### マスクされたデータを元のデータのモデル化に使用するmodel = DecisionTreeClassifier(random_state=RANDOM_STATE).fit(X=df_training_masked, y=df_training)###### Step 4: マスクされたバリデーションデータセットに補完器を適用する#####df_validation_imputed = pd.DataFrame(model.predict(df_validation_masked))###### Step 5: バリデーションデータセットでの補完精度を評価する###### 膨張した結果を考慮した基本的なトップ1の精度メトリックをチェックするfeature_accuracy_dict = {}for i in range(df_validation_masked.shape[1]):    # マスキングが必要な特徴量iの行インデックスのリストを取得    masked_indexes = df_validation_masked.index[df_validation_masked[i] == -1]    # 特徴量iについて、マスキングされた行のみの補完精度を計算    feature_accuracy_dict[i] = (df_validation_imputed.iloc[masked_indexes, i] == df_validation.iloc[masked_indexes, i]).mean()print(feature_accuracy_dict)

データマスキングの戦略

一般的に、トレーニングデータとバリデーションデータをマスキングするためにいくつかの戦略を採用することができます。大まかに言えば、次の3つのマスキング戦略を区別することができます:網羅的、ランダム、ドメイン駆動型。

網羅的マスキング

この戦略では、データセットの各行に対して可能なマスキングの組み合わせをすべて生成します。データセットにn行とm列がある場合、網羅的マスキングは、行内のmつの値の各マスキングの組み合わせに対して最大で2^ m行を展開します。行の最大の組み合わせの総数は、パスカルの三角形のm行目の合計に相当しますが、特定のユースケースには有用でないいくつかの組み合わせを省略することも選択することができます(たとえば、すべての値がマスクされている組み合わせ)。したがって、最終的なマスクされたデータセットは、最大でn *(2^ m)行とm列になります。網羅的戦略は非常に包括的であるという利点がありますが、mが大きい場合には非常に実用的ではないかもしれません。なぜなら、結果として得られるマスクされたデータセットが現在のほとんどのコンピュータで簡単に処理できるほど小さくないかもしれないからです。たとえば、元のデータセットがわずか1000行と50列しかない場合、網羅的にマスクされたデータセットはおおよそ10¹⁸行(つまり、10の18乗行)になります。

ランダムマスキング

その名前が示すように、この戦略はランダムな関数を使用して値をマスクします。たとえば、データセット内の各値をマスクする決定を、確率pの独立したベルヌーイイベントとしてフレーム化する単純な実装が考えられます。ランダムマスキング戦略の明らかな利点は、網羅的なマスキングとは異なり、マスクされたデータのサイズが管理可能であることです。ただし、特に小規模なデータセットでは、十分に高い補完精度を達成するために、ランダムマスキングを適用する前にトレーニングデータセットの行をアップサンプリングして、より多くのマスキングの組み合わせを反映させる必要があるかもしれません。

ドメイン駆動型マスキング

この戦略は、補完器が利用されるドメインやユースケース内で欠損値のパターンに近づけるようにマスキングを適用することを目指しています。これらのパターンを見つけるためには、定量的な観測データを分析することや、ドメインの専門家からの洞察を取り入れることが役立つ場合があります。

実用的な応用

この記事で議論されているノイズ除去ベースの補完手法は、他のアプローチが単純すぎるか、複雑でリソースを消費する可能性がある場合に、実践的な「中間的な方法」として提供されます。データクリーニングにおける前処理手法としての役割に加えて、表形式のデータのノイズ除去ベースの補完は、特定の実用的なケースにおいて、コアな製品機能の駆動手段としても利用される可能性があります。

オンラインフォームのAI支援入力補完は、産業界におけるそのような例です。さまざまなビジネスプロセスのデジタル化の進展に伴い、紙ベースのフォームはデジタルなオンライン版に置き換えられています。求職申し込み、購買依頼の作成、企業の出張予約、イベントへの登録などのプロセスでは、通常、オンラインフォームに情報を入力する必要があります。このようなフォームの手動入力は、入力が必要なフィールドが多い場合には退屈で時間がかかり、誤りが生じる可能性があります。しかし、AIアシスタントの助けを借りれば、利用可能な文脈情報に基づいてユーザーに入力推奨を提供することで、このようなオンラインフォームの入力作業は、簡単で迅速かつ正確に行うことができます。たとえば、ユーザーがフォームの一部のフィールドを入力し始めると、AIアシスタントは残りのフィールドに最も適切な値をリアルタイムで推測し、ユーザーに提案することができます。このようなユースケースは、ノイズ除去ベースの複数出力補完問題として容易にフレーム化することができます。ノイズ/マスクされたデータは、現在のフォームの状態で与えられます(一部のフィールドが入力され、他のフィールドが空または欠落している)。目標は、欠損しているフィールドを予測することです。このモデルは、予測精度やユーザーが感じるエンドツーエンドの応答時間など、さまざまなユースケースの要件を満たすために必要に応じて調整できます。

生成AIと基盤モデルの時代における関連性

最近の生成AIと基盤モデルの進歩に加えて、2022年末のChatGPTの登場以来、非技術者の間でもその潜在能力に対する認識が高まっています。将来、ノイズ除去ベースの補完手法がどのような関連性を持つのかという疑問は妥当です。たとえば、大規模言語モデル(LLM)は、表形式のデータの補完タスクを扱うことが考えられます。実際、文の欠損トークンの予測は、Bidirectional Encoder Representations from Transformers(BERT)などのLLMのトレーニングに使用される典型的な学習目標です。

しかし、ノイズ除去ベースの補完手法や現在存在する他の表形式データの補完手法が、生成AIと基盤モデルの時代においてすぐに廃れることはないと考えられます。その理由は、2010年代後半の状況を考慮することによって理解することができます。この時点で、ニューラルネットは以前はロジスティック回帰、決定木、ランダムフォレストなどのより単純なアルゴリズムに頼っていたいくつかのユースケースにおいて、技術的に実現可能で経済的に適した選択肢となりました。ニューラルネットは、十分な大規模なトレーニングデータが利用可能で、ニューラルネットのトレーニングと保守のコストが妥当と見なされる高級なユースケースでは、これらの他のアルゴリズムを置き換えましたが、多くの他のユースケースには影響を与えませんでした。実際、ニューラルネットへのアクセスが容易になったことで、より安価なストレージや計算リソースへのアクセスも向上し、他のより単純なアルゴリズムも恩恵を受けました。この観点から、コスト、複雑さ、説明可能性の必要性、リアルタイムユースケースの高速応答時間、事前トレーニング済みモデルの外部プロバイダーのポテンシャルな寡占化の脅威など、さまざまな要素は、ノイズ除去ベースの表形式データの補完などの実践的なイノベーションが生成AIと基盤モデルと有意義に共存する未来を示唆しています。

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more