VSCodeと.NETの環境でAi開発をしてみた

# 環境
* Mac OS Sonoma 14.5
* Visual Studio Code
* .NET 9
# 事前準備
ML.NETのインストール方法
```
dotnet new console -n MLNetExample
cd MLNetExample
```
とりあえずこれだけで勝手にパッケージは入ります
# 何をしているのか
* ML.NETコンテキストの作成
* 学習用データのロード
* データ処理と学習パイプラインの作成
* モデルのトレーニング
* テストデータで予測
* サンプルテキストを予測
# 実際のコード
``` cs:Program.cs
using System;
using Microsoft.ML;
using Microsoft.ML.Data;

class Program
{
    static void Main()
    {
        // ML.NETのコンテキストを作成
        MLContext mlc = new MLContext();

        Console.WriteLine("文章を入力してください");

        // データをロード
        string dataPath = "sentiment.csv";
        IDataView dataView = mlc.Data.LoadFromTextFile<Schemas.SentimentInput>(
            path: dataPath,
            hasHeader: true,
            separatorChar: ',');

        // データ処理と学習パイプラインの作成
        var pipeline = mlc.Transforms.Text.FeaturizeText("Features", nameof(Schemas.SentimentInput.Text))
            .Append(mlc.BinaryClassification.Trainers.SdcaLogisticRegression(
                labelColumnName: nameof(Schemas.SentimentInput.Label), 
                featureColumnName: "Features"));

        // モデルのトレーニング
        ITransformer model = pipeline.Fit(dataView);

        // テストデータで予測
        PredictionEngine<Schemas.SentimentInput, Schemas.SentimentOpuput>? predictionEngine = mlc.Model.CreatePredictionEngine<Schemas.SentimentInput, Schemas.SentimentOpuput>(model);

        // サンプルテキストを予測
        Schemas.SentimentInput sample = new Schemas.SentimentInput { Text = Console.ReadLine() ?? "" };
        Schemas.SentimentOpuput result = predictionEngine.Predict(sample);

        Console.WriteLine($"テキスト: {sample.Text}");
        Console.WriteLine($"感情: {(result.Prediction ? "ポジティブ" : "ネガティブ")}");
        Console.WriteLine($"確信度: {result.Probability:P2}");
    }
}

class Schemas
{
    // 入力データクラス
    public class SentimentInput
    {
        [LoadColumn(0)]
        public string Text { get; set; }

        [LoadColumn(1)]
        public bool Label { get; set; }
    }

    // 出力データクラス
    public class SentimentOpuput : SentimentInput
    {
        [ColumnName("PredictedLabel")]
        public bool Prediction { get; set; }

        public float Probability { get; set; }
    }
}
```
これが処理のコードで、
```csv:sentiment.csv
Text,Label
彼が大好きなんだ！, 1
奴のことは大嫌いだ！, 0
これ、美味しいね！, 1
本当に酷いサービスだ, 0
本当に気持ち良かった, 1
ごめん、気持ち悪い, 0
物を買うことはとっても楽しい, 1
気持ち悪いって言われた、悲しい, 0
あの公演は楽しい, 1
交際がバレた、悲しい, 0
世界に平和が訪れた、嬉しい！, 1
怒られた、悲しい, 0
有名人に会えた、最高！, 1
誰あの人、怖い, 0
Aiが動作するとワクワクするよ, 1
失敗したらムカムカするけどね, 0
この料理、美味しい, 1
恋人が重症だ、悲しい, 0
なんとか一命を取り留めたみたい。希望が見えてきた, 1
結局死んだ、絶望だ, 0
彼のギャグは面白い、最高, 1
彼の話には苛立った, 0
最高の気分, 1
ゲームで連敗した、屈辱的だよ, 0
今日は本当にありがとう, 1
後輩がクソみたいな態度をとってきたんだよ、ふざけんな, 0
あの発言には元気をもらった, 1
なんだあの発言は、嫌悪感を抱いたぞ, 0
良き天気、心安らかなり, 1
人生が不安でたまらない, 0
新たな制度で安心できた, 1
なんなんだよ、クソが！, 0
沢山の猫に囲まれて幸せ, 1
緊張する, 0
彼のおかげで自信が持てた, 1
ストレスが溜まった, 0
笑っちゃいそう, 1
```
こっちが学習させる文章と感情のデータです。`0`がネガティブ、`1`がポジティブです
## スキーマについて
まず、下の方にある`Schemas`というクラスについて
このクラスにはinputとoutputの2つのスキーマが定義されていて、outputはinoputから継承されています。
`[ColumnName(0)]`の部分ではスキーマに感情分析のデータがマッピングされています簡単にいうと、
|   |文章 |感情 |
|---|---|---|
|1  |彼が大好きなんだ！| 1 |
|2  |奴のことは大嫌いだ！| 0 |
|3  |これ、美味しいね！| 1 |
| |.|
| |.|
| |.|

このようなデータを含むように設計されています
`output`はモデルが予測した感情データが入ります
## new MLContext()
ML.NETのコンテキストを新たに生成します。インスタンス化です。
## データのロード
csvファイルをロードしています。`IDataView`というデータ型ですパイプラインのデータを格納しています
##　パイプラインの作成
モデリング段階です。型はよくわからず、自動指定してもジェネリック関係でエラーを吐くので仕方なく`var`で定義しました
## ITransformer model = pipeline.Fit(dataView)
`ITransFormer`というデータ型でモデルに先ほどの`IDataView`を読み込ませます
## データ予測
スキーマから必要なデータのみを抽出して学習します
## サンプルテキストを予測
先ほど抽出したデータとテキストのデータを予測して出力します
# 最後に
csvファイルの内容などをもっと増やせば正確にシュミレートできると思います