OpenAL：アクティブラーニング戦略の評価と解釈

[NeurIPS 2022 Workshop on Human in the Loop Learning](https://neurips-hill.github.io/)に採用された我々の研究成果を発表します! 我々の研究の全体像については、論文と[OpenAL ](https://github.com/dataiku-research/OpenAL)GitHubリポジトリを参照ください。

アクティブラーニング（AL）は、その有用性が実際に証明されているにもかかわらず、主に2つの欠点があります：
- **異なる研究の結果を比較するのが複雑** 文献は膨大であり、論文によって検証に一貫性がない。AL手法の中には、同じようなタスクでも、使用するモデルによって性能が異なるものさえある。
- **その結果、与えられたタスクに対して最適なサンプラーを選択することが困難** ほとんどの論文は精度のみを報告しており、異なるAL戦略がどのように振る舞うかについて直感を働かせることが困難です。

これらの制限に対処するために、我々はOpenALを紹介します。OpenALは、オープンソースの柔軟なフレームワークで、現実的なタスクの集合に対してサンプリングAL戦略を効率的に実行し、比較することができます。提案するベンチマークでは、解釈可能な指標と統計分析手法による補強により、あるサンプラーがいつ、なぜ他のサンプラーより優れているかを理解することができます。最終的には、実務者が独自のALサンプラーをサブミットすることで、簡単にベンチマークを拡張することができます。

## 最もシンプルなAPI
ALの実験は、3つの連続したステップに分解することができます:
- **初期条件を作成** データセットをすべてのフォールドで学習用とテスト用に分割し、初期ラベル付きサンプルを選択する
- **実験条件を作成** ALの反復回数とバッチサイズを選択する
- **さまざまな方式でベンチマークを実行**

これらの各ステップの実行は、OpenALのシンプルなワンライナーで可能です。例えば、実験者が実験のバッチサイズを変更したいが、初期条件は同じにしたい場合、非常に迅速に実行することができます。
> ic = load_initial_conditions(dataset_id)
> ep = load_experiment(dataset_id, ic)
> run(ep, methods)

このブログ記事は論文を補完するもので、別のパッケージのサンプラーを使ってベンチマークのタスクを実行する方法について説明しています。このチュートリアルに対応するノートブックは[こちら](https://github.com/dataiku-research/OpenAL/blob/main/Adding%20a%20sampler%20from%20sklearn-activeml%20into%20OpenAL.ipynb)で入手できます。
同じような目的を持ちつつ画像に焦点を当てた研究を、百度(Baidu)が最近のNeurIPSで [an extension of their DeepAL framework](https://arxiv.org/abs/2203.13450) along with a [comprehensive benchmark ](https://github.com/SineZHAN/deepALplus)として発表しています。

#### サンプラーのインターフェース
サンプラーを追加するには、まずOpenALが使用する内部インターフェースに準拠する必要があります。[cardinal](https://dataiku-research.github.io/cardinal/)で定義されたインターフェースを使用します。つまり、サンプラーは、ラベル付きデータを入力とするfitメソッドと、ラベルなしデータを入力とするselect_samplesメソッドを持たなければなりません。この例では、DiscriminativeALサンプラーを使用します:

    class WrappedDAL(BaseQuerySampler):
        def __init__(self, batch_size: int, classifier):
            super().__init__(batch_size)
            self.classifier = classifier    def fit(self, X: np.ndarray, y: np.ndarray = None):
            self.X, self.y = X, y
            return self    def select_samples(self, X: np.array) -> np.array:
            X_ = np.vstack([X, self.X])
            y_ = np.hstack([np.full(X.shape[0], MISSING_LABEL), self.y])        qs = DiscriminativeAL(greedy_selection=True)        return qs.query(X=X_, y=y_, discriminator=self.classifier,
                        batch_size=self.batch_size)

次に、データセット1502のベンチマークの初期条件と実験パラメータを単純にロードします:

    ic = load_initial_conditions(‘1502’)
    ep = load_experiment(‘1502’, ic)gen_method = lambda params: WrappedDAL(
        params[‘batch_size’], SklearnClassifier(params[‘clf’]))
    run(experimental_parameters, {‘DAL’: gen_method})


## 結果
OpenALは結果をCSVファイルとして自動的に保存し、オリジナルのプロットを更新します。元の実験のグラフを見ることで、それらを視覚化することができるのです!
> acc_plt = ’experiment_results/1502/plots/plot-Accuracy.png’
display(Image(filename=acc_plt))

識別サンプラーはランダムよりも優れており、性能的にはK-Meansに近いことがわかります。これは、どちらのサンプラーもモデルの不確実性に依存しないという事実と一致します。ひとつ注意すべき点は、バッチ全体を選択するために1つの分類器を学習させるDiscriminativeALの貪欲版を用いていることです。非貪欲版Aはより高性能ですが、各サンプルを選択した後に1つのモデルを学習させるので法外です（このデータセットではバッチサイズは245です）。妥協案としては、25サンプルごとにモデルを再トレーニングして10回のトレーニングで済むようにすることでしょう。
![dftt-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1196881/fe6e6333-409e-4a4a-b868-cee0f2a88b28.png)


## データ活用の現場から
NLP、アクティブラーニング、グラフニューラルネットワークなど、DataikuのMLエキスパートによる最新コンテンツを[こちら](https://medium.com/data-from-the-trenches)からご覧いただけます。

原文：OpenAL: [*Evaluation and Interpretation of Active Learning Strategies*](https://blog.dataiku.com/evaluation-interpretation-active-learning-strategies)