チュートリアル: ML.NET モデル ビルダーを使用して Web アプリケーションで Web サイトのコメントのセンチメントを分析する

ここでは、Web アプリケーション内部でコメントからセンチメントをリアルタイムで分析する方法を学習します。

このチュートリアルでは、Web サイトのコメントのセンチメントをリアルタイムで分類する ASP.NET Core Razor Pages アプリケーションの作成方法について説明します。

このチュートリアルでは、次の作業を行う方法について説明します。

  • ASP.NET Core Razor Pages アプリケーションを作成する
  • データを準備して理解する
  • シナリオを選択する
  • データを読み込む
  • モデルをトレーニングする
  • モデルを評価する
  • モデルを使用して予測を行う

このチュートリアルのソース コードは、dotnet/machinelearning-samples リポジトリにあります。

前提条件

前提条件の一覧とインストール手順は、モデル ビルダーのインストール ガイドを参照してください。

Razor Pages アプリケーションを作成する

ASP.NET Core Razor Pages アプリケーションを作成します。

  1. Visual Studio で、[新しいプロジェクトの作成] ダイアログを開きます。
  2. [新しいプロジェクトの作成] ダイアログで、[ASP.NET Core Web アプリ] プロジェクト テンプレートを選択します。
  3. [名前] テキスト ボックスに「SentimentRazor」と入力し、[次へ] ボタンを選択します。
  4. [追加情報] ダイアログで、すべての既定値をそのままにして、[作成] ボタンを選択します。

データを準備して理解する

Wikipedia detox データセットをダウンロードします。 Web ページが開いたら、そのページを右クリックして、 [名前を付けて保存] を選択し、コンピューター上の任意の場所にファイルを保存します。

wikipedia-detox-250-line-data.tsv データセットの各行は、ユーザーが Wikipedia に残した異なるレビューを表します。 最初の列は、テキストのセンチメントを表し (0 は無害、1 は有害)、2 番目の列はユーザーが残したコメントを表します。 列はタブで区切られます。 データは次のようになります。

Sentiment SentimentText
1 ==無礼== なんて無礼な。Carl のその画像をアップロードし戻しておくのが身のためだぞ。
1 == OK! == それなら、WILD ONES WIKI をぶっ壊す!!!
0 この情報がお役に立てば幸いです。

Model Builder 構成ファイルを作成する

ソリューションに機械学習モデルを初めて追加する際には、mbconfig ファイルを作成するよう求められます。 mbconfig ファイルでは、セッションを再度開けるように Model Builder で行ったすべての操作が記録されます。

  1. ソリューション エクスプローラーで、 [SentimentRazor] プロジェクトを右クリックし、 [追加]>[機械学習モデル] を選択します。
  2. ダイアログで、Model Builder プロジェクトに SentimentAnalysis.mbconfig という名前を付け、[追加] を選択します。

シナリオを選択する

Model Builder シナリオの画面

モデルをトレーニングするには、モデル ビルダーによって提供される機械学習シナリオの一覧から選択する必要があります。

このサンプルのタスクはテキスト分類です。 Model Builder 拡張機能の [シナリオ] ステップで、[テキスト分類] シナリオを選択します。

環境を選択する

Model Builder は、さまざまな環境でシナリオの選択に応じてトレーニングできます。

環境として [ローカル (GPU)] を選択し、[次のステップ] ボタンをクリックします。

注意

このシナリオでは、GPU 環境で最適に動作するディープ ラーニング手法を使用します。 GPU がない場合は [ローカル (CPU)] 環境を選択しますが、トレーニングの所要時間が大幅に長くなると予想されるため注意してください。 Model Builder での GPU の使用の詳細については、「Model Builder ガイド」の GPU サポートに関する情報を参照してください。

データを読み込む

モデル ビルダーは、SQL Server データベースか、csv 形式または tsv 形式のローカル ファイルという 2 つのソースからデータを受け取ります。

  1. Model Builder ツールのデータ ステップで、データ ソースのドロップダウンから [ファイル] を選択します。
  2. [ファイルの選択] テキスト ボックスの横にあるボタンを選択し、エクスプローラーを使用してファイルを参照し、wikipedia-detox-250-line-data.tsv ファイルを選択します。
  3. [予測する列 (ラベル)] ドロップダウンで [センチメント] を選択します。
  4. [テキスト列] ドロップダウンから [SentimentText] を選択します。
  5. [次のステップ] ボタンを選択して、Model Builder の次のステップに進みます。

モデルをトレーニングする

このチュートリアルで感情分析モデルのトレーニングに使用する機械学習タスクは、テキスト分類です。 モデル トレーニング プロセスにおいて、Model Builder は NAS-BERT ニューラル ネットワーク アーキテクチャを使用してデータセットのテキスト分類モデルをトレーニングします。

  1. [Start Training](トレーニング開始) を選択します。

  2. トレーニングが完了すると、[トレーニング] 画面の [トレーニング結果] セクションにトレーニング プロセスの結果が表示されます。 トレーニング結果が表示されるのに加え、SentimentAnalysis.mbconfig ファイルの下に 3 つの分離コード ファイルが作成されます。

    • SentimentAnalysis.consumption.cs - このファイルには、ModelInputModelOutput のスキーマのほか、モデルを使用するために生成された Predict 関数が含まれています。
    • SentimentAnalysis.training.cs - このファイルには、モデルをトレーニングするために Model Builder によって選択されたトレーニング パイプライン (データ変換、トレーナー、トレーナー ハイパーパラメーター) が含まれています。 このパイプラインを使用して、モデルを再トレーニングできます。
    • *SentimentAnalysis.zip - これは、トレーニング済み ML.NET モデルのシリアル化された zip ファイルです。
  3. [次のステップ] ボタンを選択して、次のステップに進みます。

モデルを評価する

トレーニングの手順の結果が、最良のパフォーマンスだった 1 つのモデルになります。 Model Builder ツールの評価ステップでは、出力セクションに、最もパフォーマンスの高いモデルによって使用されたトレーナーと、評価メトリックが含まれます。

満足できる評価メトリックが得られなかった場合にモデルのパフォーマンスを向上させる簡単な方法としては、より多くのデータを使用することが考えられます。

満足できる場合は、[次のステップ] リンクを選択して、Model Builder の [使用] ステップに進みます。

使用プロジェクトのテンプレートを追加する (省略可能)

Model Builder の使用ステップには、モデルを使用するためのプロジェクト テンプレートが用意されています。 このステップは必須ではなく、ニーズに応じた別の方法でモデルの使用方法を選択することもできます。

  • コンソール アプリケーション
  • Web API

予測を行うコードを追加する

PredictionEngine プールの構成

1 つの予測を作成するには、PredictionEngine<TSrc,TDst> を作成する必要があります。 PredictionEngine<TSrc,TDst> はスレッド セーフではありません。 さらに、アプリケーション内で必要なすべての場所にそのインスタンスを作成する必要があります。 アプリケーションの規模が拡大すると、このプロセスが管理不能になる可能性があります。 パフォーマンスとスレッド セーフを向上させるには、依存性の挿入と PredictionEnginePool サービスを組み合わせて使用します。これにより、アプリケーション全体で使用する PredictionEngine<TSrc,TDst> オブジェクトの ObjectPool<T> が作成されます。

  1. Microsoft.Extensions.ML NuGet パッケージをインストールします。

    1. ソリューション エクスプローラーで、プロジェクトを右クリックし、 [NuGet パッケージの管理] を選択します。
    2. [パッケージ ソース] として [nuget.org] を選択します。
    3. [参照] タブを選択して、「Microsoft.Extensions.ML」を検索します。
    4. リストでパッケージを選択して、 [インストール] ボタンを選択します。
    5. [変更のプレビュー] ダイアログで [OK] ボタンを選択します。
    6. 一覧表示されているパッケージのライセンス条項に同意する場合は、 [ライセンスへの同意] ダイアログで [同意する] ボタンを選択します。
  2. SentimentRazor プロジェクトの Program.cs ファイルを開きます。

  3. Microsoft.Extensions.ML NuGet パッケージと SentimentRazorML.Model プロジェクトを参照する次の using ステートメントを追加します。

    using Microsoft.Extensions.ML;
    using static SentimentRazor.SentimentAnalysis;
    
  4. 以下のように、Program.cs ファイル内にアプリケーションの PredictionEnginePool<TData,TPrediction> を構成します。

    builder.Services.AddPredictionEnginePool<ModelInput, ModelOutput>()
        .FromFile("SentimentAnalysis.zip");
    

センチメント分析ハンドラーの作成

予測は、アプリケーションのメイン ページ内で行われます。 このため、ユーザー入力を受け取り、PredictionEnginePool<TData,TPrediction> を使用して予測を返すメソッドを追加する必要があります。

  1. Pages ディレクトリにある Index.cshtml.cs ファイルを開いて、次の using ステートメントを追加します。

    using Microsoft.Extensions.ML;
    using static SentimentRazor.SentimentAnalysis;
    

    Program.cs ファイル内に構成された PredictionEnginePool<TData,TPrediction> を使用するには、使用するモデルのコンストラクター内に挿入する必要があります。

  2. Pages/Index.cshtml.cs ファイル内の IndexModel クラス内の PredictionEnginePool<TData,TPrediction> を参照する変数を追加します。

    private readonly PredictionEnginePool<ModelInput, ModelOutput> _predictionEnginePool;
    
  3. IndexModel クラスのコンストラクターに変更を加え、PredictionEnginePool<TData,TPrediction> サービスを挿入します。

    public IndexModel(ILogger<IndexModel> logger, PredictionEnginePool<ModelInput, ModelOutput> predictionEnginePool)
    {
        _logger = logger;
        _predictionEnginePool = predictionEnginePool;
    }
    
  4. PredictionEnginePool を使用して、Web ページから受け取ったユーザー入力から予測を行うメソッド ハンドラーを作成します。

    1. OnGet メソッドの下に、OnGetAnalyzeSentiment という新しいメソッドを作成します。

      public IActionResult OnGetAnalyzeSentiment([FromQuery] string text)
      {
      
      }
      
    2. ユーザーからの入力が空白または null の場合、OnGetAnalyzeSentiment メソッド内で、"ニュートラル" センチメントを返します。

      if (String.IsNullOrEmpty(text)) return Content("Neutral");
      
    3. 入力が有効な場合は、ModelInput の新しいインスタンスを作成します。

      var input = new ModelInput { SentimentText = text };
      
    4. PredictionEnginePool<TData,TPrediction> を使用してセンチメントを予測します。

      var prediction = _predictionEnginePool.Predict(input);
      
    5. 次のコードを使用して、予測された bool 値を有害または無害に変換します。

      var sentiment = Convert.ToBoolean(prediction.PredictedLabel) ? "Toxic" : "Not Toxic";
      
    6. 最後に、センチメントを Web ページに返します。

      return Content(sentiment);
      

Web ページの構成

OnGetAnalyzeSentiment によって返される結果は、Index Web ページに動的に表示されます。

  1. Pages ディレクトリ内にある Index.cshtm を開いて、その内容を次のコードに置き換えます。

    @page
    @model IndexModel
    @{
        ViewData["Title"] = "Home page";
    }
    
    <div class="text-center">
        <h2>Live Sentiment</h2>
    
        <p><textarea id="Message" cols="45" placeholder="Type any text like a short review"></textarea></p>
    
        <div class="sentiment">
            <h4>Your sentiment is...</h4>
            <p>😡 😐 😍</p>
    
            <div class="marker">
                <div id="markerPosition" style="left: 45%;">
                    <div>▲</div>
                    <label id="markerValue">Neutral</label>
                </div>
            </div>
        </div>
    </div>    
    
  2. 次に、wwwroot\css ディレクトリ内の site.css ページの末尾に css スタイル コードを追加します。

    /* Style for sentiment display */
    
    .sentiment {
        background-color: #eee;
        position: relative;
        display: inline-block;
        padding: 1rem;
        padding-bottom: 0;
        border-radius: 1rem;
    }
    
    .sentiment h4 {
        font-size: 16px;
        text-align: center;
        margin: 0;
        padding: 0;
    }
    
    .sentiment p {
        font-size: 50px;
    }
    
    .sentiment .marker {
        position: relative;
        left: 22px;
        width: calc(100% - 68px);
    }
    
    .sentiment .marker > div {
        transition: 0.3s ease-in-out;
        position: absolute;
        margin-left: -30px;
        text-align: center;
    }
    
    .sentiment .marker > div > div {
        font-size: 50px;
        line-height: 20px;
        color: green;
    }
    
    .sentiment .marker > div label {
        font-size: 30px;
        color: gray;
    }
    
  3. その後、入力を Web ページから OnGetAnalyzeSentiment ハンドラーに送信するコードを追加します。

    1. wwwroot\js ディレクトリ内にある site.js ファイルで、getSentiment という関数を作成し、OnGetAnalyzeSentiment ハンドラーへのユーザー入力を使用して GET HTTP 要求を作成します。

      function getSentiment(userInput) {
          return fetch(`Index?handler=AnalyzeSentiment&text=${userInput}`)
              .then((response) => {
                  return response.text();
              })
      }
      
    2. その下に、updateMarker という別の関数を追加して、センチメントが予測されると、Web ページ上のマーカーの位置を動的に更新します。

      function updateMarker(markerPosition, sentiment) {
          $("#markerPosition").attr("style", `left:${markerPosition}%`);
          $("#markerValue").text(sentiment);
      }
      
    3. updateSentimentというイベント ハンドラー関数を作成し、ユーザーから入力を取得し、getSentiment 関数を使用してそれを OnGetAnalyzeSentiment 関数に送信し、updateMarker 関数でマーカーを更新します。

      function updateSentiment() {
      
          var userInput = $("#Message").val();
      
          getSentiment(userInput)
              .then((sentiment) => {
                  switch (sentiment) {
                      case "Not Toxic":
                          updateMarker(100.0, sentiment);
                          break;
                      case "Toxic":
                          updateMarker(0.0, sentiment);
                          break;
                      default:
                          updateMarker(45.0, "Neutral");
                  }    
              });
      }        
      
    4. 最後に、イベント ハンドラーを登録し、id=Message 属性を使ってそれを textarea要素にバインドします。

      $("#Message").on('change input paste', updateSentiment)        
      

アプリケーションの実行

アプリケーションがセットアップされたので、アプリケーションを実行します。アプリケーションはブラウザー内で起動します。

アプリケーションが起動したら、テキスト領域に「このモデルには十分なデータがありません!」と入力します。 正常であれば、予測されるセンチメントとして [有害] が表示されます。

予測済みセンチメント ウィンドウの実行中ウィンドウ

注意

PredictionEnginePool<TData,TPrediction> によって、PredictionEngine<TSrc,TDst> のインスタンスが複数作成されます。 モデルを初めて使用して予測を行うときには、モデルのサイズに応じた数秒程度の時間がかかります。 通常、以後の予測は瞬時に完了します。

次のステップ

このチュートリアルでは、次の作業を行う方法を学びました。

  • ASP.NET Core Razor Pages アプリケーションを作成する
  • データを準備して理解する
  • シナリオを選択する
  • データを読み込む
  • モデルをトレーニングする
  • モデルを評価する
  • モデルを使用して予測を行う

その他のリソース

このチュートリアルで説明しているトピックについて詳しくは、次のリソースを参照してください。