2023/05/11

機械学習での最初の予想結果

 新馬用って考えは、その時点でその馬のレース経験は当たり前ですが何もない状態なので予想ファクターとしては、競馬場、トラック、距離、天候、馬場、父馬、騎手勝率、調教師勝率を使うものとして試したんですが、このファクターのまま新馬戦以外にも試してみようと試みたんですが、CSVの出力が2時間半掛かりました😔 なので学習時間も10分ではなく30分に伸ばして試してみたのですが、

予想[1374] 的中[315] (22.93%) 購入[¥807,100] 払戻[¥346,290 (42.91%)]

でした。ああ、学習用に準備したCSVは2004年1月1日~2022年12月31日で、検証は2023年1月1日~2023年4月30日です。まあ、これじゃどうしようもないレベルだけど、実はまあ新馬用に先に試したのは学習用は同じ期間で検証は今年はまだ新馬戦ないので昨年1年間で試してたんです。

予想[301] 的中[130] (43.19%) 購入[¥196,700] 払戻[¥395,930 (201.29%)]

まあ、これがたまたまってか検証が学習期間に含まれているのが微妙な気もするけど、悪くないな~って事で新馬戦以外もあわてて試しました。新馬戦以外はやはり前走とかのデータを入れ込んで行うんですが、これが上手く出来るのかがね~😓 で、ファクター増えてのCSV出力が更に時間長くなるのも気になるので準備は慎重にやらなきゃですね。

ああ、検証なんですが、これまだ手抜きなんです。同着とか諸々考えずにざっくりと作りました。単勝、複勝、馬連、ワイド、馬単、三連複、三連単各1点買いです。同着考慮してないので、同着あったりしたレースは的中判定が出来てないかと思うので、実際には結果が違うんですけどね。あと、的中は全券種どれか1つでも当たっていれば当然的中となってます。三連単的中してればまあ他全て当たってるのかな。

2022/12/04中山5R

1着 14番 予想タイム[2'05"42]
2着 13番 予想タイム[2'05"44]
3着 5番 予想タイム[2'05"75]
4着 6番 予想タイム[2'05"88]
5着 10番 予想タイム[2'05"89]
6着 9番 予想タイム[2'05"90]
7着 2番 予想タイム[2'05"95]
8着 7番 予想タイム[2'05"96]
9着 4番 予想タイム[2'06"24]
10着 3番 予想タイム[2'06"47]
11着 8番 予想タイム[2'06"50]
12着 1番 予想タイム[2'06"62]
13着 12番 予想タイム[2'06"75]
14着 11番 予想タイム[2'07"13]
単勝[14] ¥320 複勝[14] ¥150 馬連[13-14] ¥850 ワイド[13-14] ¥400
馬単[14→13] ¥1,340 三連複[5-13-14] ¥5,570 三連単[14-13-5] ¥19,370

こんな感じです。それと、参考までにこのレースの勝ちタイムは2'5"0でした。ビリは7番の馬で2'7"4。これが良い結果が出てるのかどうなのかはなんともですけどね。4着は3番、5着は10番でした。

AutoML:自動機械学習(2)

今朝方体調不良で目が覚めた。ここ数日の肌寒さが気にはなっていたが特に対処しなかったのがたたったかな😨 くしゃみ、鼻水が止まらなくて寝てられなかった。とはいえ、先に進める必要があるので作業は続けてます。

前回進捗状況観る為にってやつですが、あれだと何が何だか分からない出力がだらだらと出るだけで、まあ、チュートリアルではなんであんなの入れているのか不明だけど、実際にはその続きが書かれているのかなぁ。

public class AutoMLMonitor : IMonitor
{
    private readonly SweepablePipeline _pipeline;

    private readonly List<TrialResult> _completedTrials;

    private readonly RichTextBox _richTextBox;

    public IEnumerable<TrialResult> GetCompletedTrials() => _completedTrials;

    public AutoMLMonitor(SweepablePipeline pipeline, RichTextBox rtbLog)
    {
        _pipeline = pipeline;
        _completedTrials = new List<TrialResult>();
        _richTextBox = rtbLog;
    }

    public void ReportBestTrial(TrialResult result)
    {
        return;
    }

    public void ReportCompletedTrial(TrialResult result)
    {
        var trialId = result.TrialSettings.TrialId;
        var timeToTrain = result.DurationInMilliseconds;
        var pipeline = _pipeline.ToString(result.TrialSettings.Parameter);
        _completedTrials.Add(result);
        // Console.WriteLine($"Trial {trialId} finished training in {timeToTrain}ms with pipeline {pipeline}");
        _richTextBox.AppendText($"Trial {trialId} finished training in {timeToTrain}ms with pipeline {pipeline}" + Environment.NewLine);
    }

    public void ReportFailTrial(TrialSettings settings, Exception exception = null)
    {
        if (exception.Message.Contains("Operation was canceled."))
        {
            // Console.WriteLine($"{settings.TrialId} cancelled. Time budget exceeded.");
            _richTextBox.AppendText($"{settings.TrialId} cancelled. Time budget exceeded." + Environment.NewLine);
        }
        // Console.WriteLine($"{settings.TrialId} failed with exception {exception.Message}");
        _richTextBox.AppendText($"{settings.TrialId} failed with exception {exception.Message}" + Environment.NewLine);
    }

    public void ReportRunningTrial(TrialSettings setting)
    {
        return;
    }
}

これが本来使うもので、ああ、実際には相変わらずConsole.WriteLineだったのでRichTextBoxに出力する様に修正してます。で、これをAutoML実行前に、

var monitor = new AutoMLMonitor(pipeline, rtbLog);
experiment.SetMonitor(monitor);

としておけばいい感じです。AutoMLの実行も

var cts = new CancellationTokenSource();
TrialResult experimentResults = await experiment.RunAsync(cts.Token);

って感じに変更なんですが、この部分がいまいちよく分かってないけど真似しておく😉 AutoMPが終わったら

var completedTrials = monitor.GetCompletedTrials();

mlContext.Model.Save(experimentResults.Model, data.Schema, $"ShinbaTime.zip");

てな感じで保存しておかないと無駄になるのでしておきます。保存しておけば、

DataViewSchema predictionPipelineSchema;
ITransformer predictionPipeline = mlContext.Model.Load($"ShinbaTime.zip", out predictionPipelineSchema);

predictionEngine = mlContext.Model.CreatePredictionEngine<ShinbaTime, ShinbaTimePrediction>(predictionPipeline);

とすれば使えます。予測したいサンプル準備して

yoso = predictionEngine.Predict(inputData);

まだまだやる事は多いけど、一時は全ての苦労が水の泡かと思ったけどなんとかなったかな😁

2023/05/10

あくまでも憶測かな

 今月初め、突然の起動不能に遭遇した事は書きましたが、その後も妙な現象を経験してます。まあ、そもそも動作不安定な事があったりしますので、このPC自体8月で丸5年。今回の原因と思われるというか、疑わしいのはやはり起動ドライブとして使っているSSDです。


健康状態「正常」だけど96%ってのが徐々に劣化がって判断も有かな? 流石にここまでずっとHDDでこのPCから導入してるSSDは初心者😅 的確な判断は無理だけど、HDDなら、ん?ってなると新たなドライブ用意してってしてましたが、現在繋げているHDD3台全てもう10年とかかな😥 そもそも、月曜日には一度Amazonの買い物かごに入れて...ポイ活に関連して週末まつ事にして保留。ああ、ちと余談ですがSSDって生物で日々値段が変わるので機種特定に至っていません。今のが500GBなので同サイズで検討中。まあ、お買い得なのは4,000円未満ですね。まあ、この際なんですが、3つ繋いでるHDDも不安材料ではあるのでHDDの2TB~4TB辺りのお手頃な奴にしたいとは思ってます。

今後の収入の目途がたたない現状での微妙な決断が必要な状態では贅沢は出来ませんので、SSD 500GBとHDD 2TBで9,000円程度で明後日には発注して土曜日に総取替後のOSクリーンインストール及び現状レベルの復元。こんな状態でも開発継続とか😖 日曜日に笑顔で競馬予想して全てを補えれば良いんだけどね~。



AutoML:自動機械学習

ここまでの苦労を無駄にしない為に、モデルビルダーでやる事を自前でMicrosoft.ML.AutoMLを使ってやってみようと、チュートリアル通りに進めてみます。既にCSV出力部分はここまで書いた様に出来上がってるしCSVファイル自体もあるので、これをソースとして使う。まずは、InferColumnsメソッド使ってテキストローダーの準備をする。

ColumnInferenceResults columnInference = mlContext.Auto().InferColumns(path, labelColumnName: "Souha", groupColumns: false);

これは説明ではCSVから数行読み取り、カラム毎のデータの種類を推測してるらしい。で、今回はモデルビルダーの時にも指定してましたが、

// 競馬場コード
columnInference.ColumnInformation.NumericColumnNames.Remove("JouCD");
columnInference.ColumnInformation.CategoricalColumnNames.Add("JouCD");

// トラックコード
columnInference.ColumnInformation.NumericColumnNames.Remove("TrackCD");
columnInference.ColumnInformation.CategoricalColumnNames.Add("TrackCD");

// 天候コード
columnInference.ColumnInformation.NumericColumnNames.Remove("Tenko");
columnInference.ColumnInformation.CategoricalColumnNames.Add("Tenko");

// 馬場状態コード
columnInference.ColumnInformation.NumericColumnNames.Remove("Baba");
columnInference.ColumnInformation.CategoricalColumnNames.Add("Baba");

// 繁殖登録番号_父
columnInference.ColumnInformation.NumericColumnNames.Remove("Chichi");
columnInference.ColumnInformation.CategoricalColumnNames.Add("Chichi");

これらのカラムは数値だけどカテゴリ別なだけで特段数値的な要素ではないのでその為の変更を入れる。で、テキストローダーを準備してデータビューを読み込む。

TextLoader loader = mlContext.Data.CreateTextLoader(columnInference.TextLoaderOptions);

IDataView data = loader.Load(path);

読み込んだデータビューの内、TrainTestSplitメソッドでトレーニングと検証に使うデータの割合を指定。パイプライン定義して、最適な予測方法を探す指示をする訳です。

TrainTestData trainValidationData = mlContext.Data.TrainTestSplit(data, testFraction: 0.2);

SweepablePipeline pipeline =
    mlContext.Auto().Featurizer(data, columnInformation: columnInference.ColumnInformation)
        .Append(mlContext.Auto().Regression(labelColumnName: columnInference.ColumnInformation.LabelColumnName));

AutoMLExperiment experiment = mlContext.Auto().CreateExperiment();

experiment
    .SetPipeline(pipeline)
    .SetRegressionMetric(RegressionMetric.RSquared, labelColumn: columnInference.ColumnInformation.LabelColumnName)
    .SetTrainingTimeInSeconds(300)
    .SetDataset(trainValidationData);

SetTrainingTimeInSecondsで秒数で時間指定(チュートリアルでは60秒でしたが5分にしてみた)して待つ訳ですが、進捗状況観る為に、

mlContext.Log += (_, e) => {
    if (e.Source.Equals("AutoMLExperiment"))
    {
        if (this.InvokeRequired)
        {
            this.logMessage = e.RawMessage + Environment.NewLine + Environment.NewLine;
            this.Invoke(new Action(this.OutputLog));
        }
        else
        {
            this.rtbLog.AppendText(e.RawMessage + Environment.NewLine + Environment.NewLine);
        }
    }
};

これ、チュートリアルではInvokeとか無しに単純にConsole.WriteLineしてるんですが、コンソールアプリじゃないので、RichTextBoxにログ表示させているんですがそのままではエラー出ます。で、その回避策としてInvoke使ってます。AutoMLの実行は、

TrialResult experimentResults = await experiment.RunAsync();

でしますが、これawaitしてるので、ログ出力が別スレッドからだとエラー起こす訳で↑のInvokeって事です。で、この一連のメソッド定義にもasyncが必要になる。ここまではスムーズに書き上げて実際に実行するとだらだらと何やらログが出て終わります。

ここから更に色々と修正加えるっぼいので一旦ここまでです。

2023/05/09

衝撃の新事実!

 ソースとなるCSVファイルは、まあ、簡単に出来上がり、早速モデルビルダー試してプロジェクトに入れ込んだ。で、衝撃の新事実は、プロジェクトに自動でモデルビルダーが入れ込む最適なモデル用のパッケージがターゲットとしてx64のみ😱 JRA-VANがもういつから言ってるのか分らない位前からJV-Linkの64ビット対応する予定ではあるが難航してるという事で未だに32ビットのままなので現在のプロジェクトも当たり前にx86ターゲットです。なので、モデルビルダーで最適なモデル入れてビルドしようとするとビルドエラーが出てどうしようもなくなるので、この苦労も一旦プロジェクトから削除orz

即座にJRA-VANがJV-Linkの64ビット化を完了するのは期待薄なのでどうするべきか。まあ、考えられる方法は現在のプロジェクトから64ビットアプリとして作る予想エンジンを別プロセスとして起動してその予想を受け取って使うとか。ただ、SQLite自体は基本2つのプロセスからのアクセスとか想定外となるので面倒な話です。JV-Link使ってSQLiteにデータ取り込んだ後、基本的に別プロセスに切り替えてそちらで作業する。でも、リアルタイムでオッズなんかも欲しいとかなると問題になるし考えたくないね。参りました。ああ、(3)の時に書いたチュートリアルが使ってたFastTreeRegressionTrainerって多分、別NuGetパッケージに入ってる奴で、Microsoft.ML.FastTreeとかがあるから、それ入れれば使えるのかも。まあ、なんにしても、基本的にCSVソースにする時には使うっぽい説明が書かれてる気がする。が、既にもう削除してるし、ML.NETどうしようか検討します。

ソースとしてはSQLiteからは無理な現状らしい

 アイビー先生の力も借りてみましたが、とっかかりの時点で使うInferColumnsメソッドがそもそもまあCSVが基本でSQLiteとかのデータ読込には対応してないので、前回リストに入れたものをデータビューにとかは出来ない。って事は、まあね、ソースをSQLiteからCSVとして抜き出して、それを元にすれば...ってこれするなら単純にモデルビルダーで行けるじゃんorz なのでautoMLについて調べる気力が失せました😨

なので、ちと方向転換して何をCSVとして吐き出すかがキーになりそうで、それを検討しながらまたCsvHelperのお世話になるんですが、既に忘れてます😖 出力用のクラスを

internal class STSrc
{
    public string JouCD { get; set; }
    public byte TrackCD { get; set; }
    public short Kyori { get; set; }
    public byte Tenko { get; set; }
    public byte Baba { get; set; }
    public long Chichi { get; set; }
    public float KishuSyoritsu { get; set; }
    public float ChokyosiSyoritsu { get; set; }
    public float Souha { get; set; }
    public STSrc
    (
        string JouCD,
        byte TrackCD,
        short Kyori,
        byte Tenko,
        byte Baba,
        long Chichi,
        float KishuSyoritsu,
        float ChokyosiSyoritsu,
        float Souha
    )
    {
        this.JouCD = JouCD;
        this.TrackCD = TrackCD;
        this.Kyori = Kyori;
        this.Tenko = Tenko;
        this.Baba = Baba;
        this.Chichi = Chichi;
        this.KishuSyoritsu = KishuSyoritsu;
        this.ChokyosiSyoritsu = ChokyosiSyoritsu;
        this.Souha = Souha;
    }
}

として、このマッピング用に

internal class STTable : ClassMap<STSrc>
{
    private STTable()
    {
        Map(c => c.JouCD).Index(0).Name("競馬場コード");
        Map(c => c.TrackCD).Index(1).Name("トラックコード");
        Map(c => c.Kyori).Index(2).Name("距離");
        Map(c => c.Tenko).Index(3).Name("天候コード");
        Map(c => c.Baba).Index(4).Name("馬場状態コード");
        Map(c => c.Chichi).Index(5).Name("繁殖登録番号_父");
        Map(c => c.KishuSyoritsu).Index(6).Name("騎手勝率");
        Map(c => c.ChokyosiSyoritsu).Index(7).Name("調教師勝率");
        Map(c => c.Souha).Index(8).Name("走破タイム");
    }
}

と準備して、

List<STSrc> st = new List<STSrc>();

をリーダーループ前に宣言して、

kaisaibi = rs.GetDateTime("KAISAIBI");
jouCD = rs.GetString("JOUCD");
rno = rs.GetByte("RNO");
tracdCD = rs.GetByte("TRACKCD");
ketto = rs.GetInt32("KETTO");
syoritsu = GetSyoritsu(cmdCK, kaisaibi, jouCD, rno, ketto, tracdCD);
// データクラス
STSrc shinbaTime = new STSrc(
                        jouCD,
                        tracdCD,
                        rs.GetInt16("KYORI"),
                        rs.GetByte("TENKO"),
                        rs.GetByte("BABA"),
                        GetChichi(cmdU, ketto),
                        syoritsu.Kishu,
                        syoritsu.Chokyosi,
                        rs.GetFloat("SOUHA")
                        );
st.Add(shinbaTime);

と回してリスト作ったら、

var path = @"ShinbaTime.csv";
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    HasHeaderRecord = true
};
using (StreamWriter sw = new StreamWriter(path, false))
using (var csv = new CsvWriter(sw, config))
{
    csv.Context.RegisterClassMap<STTable>();

    csv.WriteRecords(st);
}

とすればCSV出力は完了する。

CSVが出来たのでまあ普通にモデルビルダーが動かせるので試してみた。

Microsoftが使う機械翻訳が酷い

 英語のドキュメントを読むのは、コンピュータ関連なら相変わらずそんなに不自由なく出来ますが、Microsoftが自社のドキュメントを日本語で公開する際に使用する機械翻訳が本当に酷い。これ、chatGPTなりに沿った最近のBingの様にやり直して欲しいものです。今回のML.NET関連のチュートリアルからML.NET 自動機械学習 (AutoML) API を使用する方法を読む必要があり、読んでみれば分かると思いますが本当に酷いものです。多分日本人には理解不能なレベル。で、まあ、How to use the ML.NET Automated Machine Learning (AutoML) APIが原文かと思いますが、こっちの方がはるかに理解しやすいです。これを参考にしながら進めないと先に進めないので理解出来るように努力してみます。

若干気になるのは、このMicrosoft.ML.autoML NuGet packageの最新バージョンが0.20.1とか、まだまだ使うべきかためらうレベルのバージョンな気がしなくもないです。Microsoft.MLの方は2.0.1とかなので特に問題はない気がします。まあ、それでもプレリリースではないので、ここまで来たら乗り掛かった舟かなぁ😅

2023/05/08

Machine Learning:機械学習(3)

本日一連の動作が出来るまで来ましたが、最初の時に書いた データクラスなんですが、これ、まあ、頭の片隅にml.netのチュートリアルを観てた時だったか何かで単精度実数ってのが全てに使われる的な話があったんですが、気にせずに普通のクラスを書きました。しかし、動かしてみるとそれが原因でエラーになり思い出す始末。で、クラスメンバー全てfloat型に修正してどうにか動く所までは来ました。

トレーニングパイプラインの所がJouCDが文字列だから的なのが、データクラス全てをfloat型にしたので必要なくなり、抜けもありました。機械学習タスクを追加しなきゃならない所が抜けてましたので、

var pipeline = mlContext.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName: "Souha")
    .Append(mlContext.Transforms.Concatenate("Features",
            "JouCD", "TrackCD", "Kyori", "Tenko", "Baba", "Chichi", "KishuSyoritsu", "ChokyosiSyoritsu"))
    .Append(mlContext.Regression.Trainers.LbfgsPoissonRegression());

って感じに変更。あっ、データクラス修正時に追加項目がありちょっとその辺りも変わってます。本当は、FastTreeRegressionTrainerをってチュートリアルには書かれていますが、その通りに真似しようとしてもそんなトレーナー無いよって😖 でまあ、選択可能な3つ位あるRegressionから上記のもので試しました。

検証で、検証期間のデータをまたリストに読み込んでdataView用意して、

var predictions = model.Transform(dataView);

として予測して、

var metrics = mlContext.Regression.Evaluate(predictions, "Label", "Score");

で、評価なか。metrics.RSquaredとmetrics.RootMeanSquaredErrorが結果らしい。

しかし、結局の所、自分のものに出来ていないので本来のモデルビルダー利用して簡単に出来るらしい事が出来てないorz モデルビルダーはautoMLをサポートしていて、さまざまな機械学習アルゴリズムと設定が自動的に探索され、シナリオに最適なものを見つけるのに役立つらしい。モデルビルダー使ったチュートリアル動画観てると確かに5個位の結果の中から一番良いものが選択出来るようになっていて、そのシナリオのコーディングを使う的な話になってた感じ。先はまだまだ長そうです😓

2023/05/07

Machine Learning:機械学習(2)

 週末の予想なんかしながらだと微妙に作業は捗りません😓 しかも、先日のクリーンインストール後の後遺症なのか競馬ソフトが全体的におかしいな~って思って色々調べたり。まあ、そもそも、自分に落ち度があるとは思うけど微妙な部分が判明。いやね、先日のトラブルの原因は特定出来てはいないものの、起動ドライブには余分なものは入れないのが鉄則。JV-Linkもしかりです。で、これ、当たり前に毎回入れ直したりしてもD:ドライブに入れるんですが、これには連動せずにどこにデータをセーブするかを指定する所があるのを思い出しました。単純にTARGETなんかでJV-Link設定とかあるので設定ダイアログ開くと「データの保存設定」としてデータ保存場所の指定が出来るんですが、そこがD:にインストールしてもデフォルトではC:トライブに。しかも、これが隠しになってるので分かり辛い😖 本日たまたまコースデータの読込で今まで何の問題も無かった東京芝2400mとかが表示されなくて、あれ?ってなってデバックしてると上手く表示されるコースでも画像データのPATHがC:ドライブなんで、ほんと、あれれ?ってなりますよね。で、まあ、クリーンインストール後にその辺りの設定しなおしを忘れてたのが原因でしたが...JV-Linkのアンインストールからの再インストールとこのセーブ先の指定やら、D:ドライブに既に存在しているフォルダを名前変更しておいて作り直しのとかね。権限の問題でってのも引っかかるので一応ね。

で、前置き長くなりましたが本題ね。アイビー先生を極限まで問いただしたらやっと教えてくれました😁 前回書込みした最後の

mlContext = new MLContext(seed: 0);

なんですが、'seed: 0'の部分理解してませんので一旦無しに😉 データリーダーからデータを読み込んでリストに格納すればいいって事で

List<ShinbaTime> data = new List<ShinbaTime>();

と宣言しておいて、いつものリーダーループで

ShinbaTime shinbaTime = new ShinbaTime();

shinbaTime.JouCD = rs.GetString("JOUCD");
shinbaTime.TrackCD = rs.GetByte("TRACKCD");
shinbaTime.Kyori = rs.GetInt16("KYORI");
shinbaTime.Tenko = rs.GetByte("TENKO");
shinbaTime.Baba = rs.GetByte("BABA");
shinbaTime.Souha = rs.GetFloat("SOUHA");
data.Add(shinbaTime);

てな感じで読み込んでセットして、リストからデータビューを作成するのに

IDataView dataView = mlContext.Data.LoadFromEnumerable(data);

ってします。で、トレーニングパイプラインを作成するんですが

var pipeline = mlContext.Transforms.CopyColumns(outputColumnName: "Label", inputColumnName: "Souha")
    .Append(mlContext.Transforms.Categorical.OneHotEncoding(outputColumnName: "JouCDEncoded", inputColumnName: "JouCD"))
    .Append(mlContext.Transforms.Concatenate("Features", "JouCDEncoded", "TrackCD", "Kyori", "Tenko", "Baba"));

JouCDが文字列なのでこれを数値にするのにOneHotEncodingを使うらしい。で、要素全てを'Features'にまとめるってのも一気に指定(それがConcatenateね)。やれやれ、で、パイプラインでデータビューをトレーニングしてモデルを作成するのに

model = pipeline.Fit(dataView);

までで、今日はおしまい😉 まだまだ、大変です。

2023/05/05

Machine Learning:機械学習

 どうやら、人工知能の下位カテゴリに入るらしい機械学習ですが、この節目に挑んでみましょう。って事で、もう今回のプロジェクト作り始めた時から手を出そうとは思っていたけど、なかなか手が出ない。ってか、本家Microsoftのチュートリアルの方は微妙なアクセントがある方で見ていても若干違和感はある。まあ、それでもざっくりと理解はしたつもりです。その程度の英語の理解力はまだ残っているかと思います。しかし、実際にコーディングに取り掛かろうとml.netを何だっけ? モデルビルダー使ってとか、行き成りテキストかSQL Serverかの2択とかね😖 こちらはSQLiteなんでどうすんだよって感じになる。いや、別に入力が何でも出来るのは普通。しかもこのml.netってオープンソースでごにょごにょってやつなのでMicrosoftには縛られていない筈。

で、まあ、本来分かりやすくあちこちにチュートリアルで使われるコンソールアプリケーションですが、今時コンソールアプリを作る人って少数派では? なのに普通に探すとそんなんばっかりです。自分自身はWindowsフォームアプリ作ってるので回り道は避けたいのでプロジェクトのフォームの1つとして実装してみようと今日から本腰を入れて取り掛かってみます。

using Microsoft.ML.Data;

これをまず入れるんですが、これが既に名前空間'Microsoft'には'ML'とかないよってorz 参照が足りてないんですね。で、NuGetパッケージマネージャーでMicrosoft.MLを入れろって事で入れます。次にデータクラスを作成するって。まあね、今回はまだまだ最初なので簡単な物にして今後色々とって事で😉

public class ShinbaTime
{
    [LoadColumn(0)]
    public string JouCD;
    [LoadColumn(1)]
    public byte TrackCD;
    [LoadColumn(2)]
    public short Kyori;
    [LoadColumn(3)]
    public byte Baba;
    [LoadColumn(4)]
    public float Souha;
}
public class ShinbaTimePrediction
{
    [ColumnName("Score")]
    public float Souha;
}

こんな感じでしてみます。で、これはプロジェクトに新しいクラスとして"ShinbaTime.cs"って事で追加してみました。最初はフォームのローカルクラスとして定義してみたけど、チュートリアルではクラスとして追加するってなってるので。更にチュートリアルではこのクラスのPredictionの方をusingでってなってるので真似してみるとそんなのいらねえって😓 コンソールアプリケーションでは必要でWindowsフォームアプリでは不要って事じゃないと思うけど、なんだろね~。で、フォームのローカル変数として、

MLContext mlContext;

を定義して、Loadイベントで

mlContext = new MLContext(seed: 0);

ってな感じで初期化する。今日はここまでにします。

2023/05/04

Microsoft Rewards 5回目

 先日の突然のPC起動不能で、OSのクリーンインストールを余儀なくされた訳ですが、流石にほぼ戻ってきた感じです。で、まあ、今回のクリーンインストール後に画面な真ん中にEdgeの検索バーみたいなものが勝手に表示されているのはEdgeの新しい機能なのか全く理解してませんが、3日連続で検索すると3,100ポイント貰えるっていうのでダメ元で検索してましたが、5月1日のクリーンインストール後何日目かは上手く検索がカウントされなくて本日「おめでとうございます。3日間のチャレンジを終了し、3,100ポイント獲得しました」って事で一気にポイントが増えて5回目のAmazonギフト600円分を申請し数時間後にはメールが届いて無事にアカウントに登録しました。

もうどのタイミングだったか忘れましたが、デイリーストリークはリセットされちゃいました。普通に日課のMicrosoft Rewardsサイトを開けると何やらエラーが表示され、200をどこまで超えてたか忘れましたが開き直したりで無事に表示されるとポイントは消えませんでしたがストリーク値は0に。で、まあ、今は6だったりします。Amazonギフト残高も4,900円程になりポイントも合わせると6千円分超えた。もう少し貯めたらPS5用の増設SSDでも買おうかなっとSSDの値下がりチェックしながら検討します。2TBならもう12,000円程度まで下がってるし、4TBがお手頃になればな~っと😉

2023/05/03

ツールチップの最大表示文字制限

少し前からってか、元々他の所でもツールチップで情報表示する様にしたりしてました。でも、今回のはテキストの長さが最大6,800バイトと長めなので不安はあった。実際コーディングしてテストするとハングとまでは行かないものの該当する所にマウス持っていくとしばらく反応しなくなる。で、アイビー先生にツールチップに表示出来る文字数の制限とかあるか訊ねても特に制限ないよ的な回答。でも、明らかに長い時間待たされた挙句に何も表示されないとか😖 ふとね、やはり長さが問題で、最大値になる事は少ないんじゃないかと思い、テキストをツールチップに設定する前にTrim()してやると普通に表示される様になりました。マイクロソフトの公式でも少し眺めてみたものの制限には触れられていませんでした。いや、まあ、実際に制限は無いのかもしれないけど、現実問題として通常の利用では考えられない時間待たされた後に表示される様なら、そこは制限設けてリーズナブルな時間内で表示出来る所にしてほしいものです。

で、長いツールチップが他の場所でも表示されて非常に見づらい。これも何やら本来はコントロールの幅になるとかならないとかって何処かで見た気もしますが、画面の端から端までorz 更に検索するとこれを自前でコントロールする方法もあるけど面倒なんです。なので今回はこのまま他の開発続行します。

2023/05/01

突然のPC起動不能

 本日普通に朝起きてPC起動する。スマホ見たりしてたので、ふと、モニターに目を向けるとASUSマザーのロゴのままで、ん?リセットボタン押して再び試みるもやはりマザーのログで止まる😖まあ、今年8月で丸5年になるPCなのでそろそろ問題あっても不思議はないものの突然のトラブル。昨日まで新たに入れた2つのソフトが数日ぶっ通しでセットアップ作業していて、これが無条件に起動ドライブにインストールされ、そこにデータベース構築とかねぇ。しかも、数日動かして予想すら出来ない状態のまま、なんだこれ?って感じのソフトでした。やはりインストール先が指定出来ない様なソフトは入れないのが吉かも。いや、別に犯人が確定してる訳じゃないので...あくまでも怪しいってのとトリガー引いたかな~ってね。

まあ、そんなんで、今朝からOSのクリーンインストールとなり作業してます。SSDが年数的にも微妙な気はするけど、それ言ったら3つ繋いでるHDDなんかはそれ以前から使っていてるものなので、それらもねぇ。更にPCだってと考え出したらきりがないです。おいおい、予算組んで検討しなきゃですね。

追記
書き込んで確認すると4月30日ってorz 今日は既に5月1日です。なんだろ?このグーグルのブログシステムが前にも日付違ってたりしたんだけど原因不明です。