久しぶりにWMware入れてみようとダウンロードしました。ここ最近はPlayerが個人が無料で利用出来るって事で使ってたんですが、今はProも個人は無料😁 ちょっとビックリでしたが、まあ、ダウンロードしてインストール。
なんか随分スムーズになった感じがします。ちょっと遊んでみようかと思いますが、やる事もあるので程々に😉
久しぶりにWMware入れてみようとダウンロードしました。ここ最近はPlayerが個人が無料で利用出来るって事で使ってたんですが、今はProも個人は無料😁 ちょっとビックリでしたが、まあ、ダウンロードしてインストール。
先日からちょいょいやらかしてます。夜勤明けに忘れたり、先週末はひたすらコーディングが気になり、すっかり忘れました。そんな訳で今のストリークが3だったりします😓 それでも継続は力? 本日Amazonギフト600円分頂きました。前回5月14日から49日での達成です。前回が40日での達成だったので大幅に伸びたのはやらかしてるからですね。でも、継続します。ああっ、楽天はもっと貯めないと交換出来ないので今回は諦めた。でも、今後は検討してみようかと思います。しかし、現時点で確認しても楽天は無くなってる。どうも不安定ですね。
頑張って書いてるんですが時間掛かってます。やる事が多過ぎて時短は厳しい😓
今後この画面にLightGBMやTensorFlow使った予測も入れ込めれば64bit化した恩恵が更に深まる。この辺りは優先的に進めたいと思ってます。特にTensorFlowの予測に期待しているので早い段階で使える事が確認出来れば学習も同時に進められるので効率も良いかも。
BIGって発売当初からほぼ買ってます。まあ、色々とね。これまで末等の数百円とかはありました。普通のBIGは確か末等の次は千円程度の当りもあったかとおもいますが、それなんかも当りって感じではなく、まあ、宝くじの下1桁的な感覚のものですよね。だって開始当初は今の数百円の末等は無く、千円程度が末等だった記憶です。でまあ、今回当たったのは、高額ではないのですが、
開発もしてますよ。
WinUI3のデータグリッドでは基本的にDataGridTextColumnを使いますが、文字の色や背景、ツールチップを追加等は派生クラスをいちいち定義するのが結局一番効率が良いのかな?例えばタイム型データマイニングだと
internal class DataGridTextColumnTimeDM : DataGridTextColumn { protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) { Border border = new Border { HorizontalAlignment = HorizontalAlignment.Stretch, // セル内で均等に広がる VerticalAlignment = VerticalAlignment.Stretch, // 上下も均等に広がる Padding = new Thickness(5) // 適度な余白 }; TextBlock textBlock = new TextBlock { TextAlignment = TextAlignment.Center, // テキストを中央揃え HorizontalAlignment = HorizontalAlignment.Center, // 左右中央揃え VerticalAlignment = VerticalAlignment.Center // 上下中央揃え }; if (dataItem is RaceDetailInfo item) { textBlock.Text = item.TimeDM; // 現在のテーマを取得 var theme = Application.Current.RequestedTheme; // 文字色を変更 switch (item.TimeDMRank) { case 1: border.Background = new Microsoft.UI.Xaml.Media.SolidColorBrush(SaraD64Constants.BackColor1); textBlock.Foreground = new SolidColorBrush(Colors.Black); break; case 2: border.Background = new Microsoft.UI.Xaml.Media.SolidColorBrush(SaraD64Constants.BackColor2); textBlock.Foreground = new SolidColorBrush(Colors.Black); break; case 3: border.Background = new Microsoft.UI.Xaml.Media.SolidColorBrush(SaraD64Constants.BackColor3); textBlock.Foreground = new SolidColorBrush(Colors.Black); break; default: // その他 textBlock.Foreground = new SolidColorBrush(theme == ApplicationTheme.Dark ? Colors.White : Colors.Black); break; } // ツールチップ追加 ToolTipService.SetToolTip(textBlock, item.TimeDMToolTip); } border.Child = textBlock; // Border に TextBlock を含める return border; } }
ああ、現在のテーマチェックして一応ダークモードとライトモードで切り替えは自分でやる必要があるっぽい。まっ、テーマ的に全て色を統一してれば自動にって方法があるのかもですが、これまで色にあくまでも近い形にしたいので深く考えずに少しだけ考慮しておこうかと。ただ、実際自分はダークモードしか使わないので、一通り形になった時に念のためにライトモードは試してからリリースしなきゃだなぁっと。
まだまだ全然途中ですが、
滅茶苦茶堅そうだけど、まあ、グランプリだしちょっとだけ参戦😉
ああ、13年程度使ってきた三菱の冷蔵庫が...製氷機能がダメだ。まあ、この冷蔵庫は問題多過ぎで、買った時から気になってたけど、氷庫の裏側に氷が頻繁に落ちる。オフシーズンに氷をあまり使わないとカビが発生する。現在の三菱の冷蔵庫もこの氷が裏側に落ちるらしいので選択肢から排除。うちは元々パナで3台程度ハズレ引いたのでパナも除外してます。残るは日立か東芝か?悩む所ですが、東芝が気になるのは問い合わせ先。フリーダイヤルがあるんですが、携帯電話はナビダイヤル。以前もここに書いた気がするけど、このナビダイヤルに掛けさせる企業の姿勢が本当に疑問。こちらがかけ放題や無料通話アプリでもナビダイヤルは課金されます。なら、普通の固定電話番号を用意してくれた方がどうとでもなる。フリーダイヤルは携帯番号認識して撥ねられる。固定電話なんて既に解約済みです。時代にマッチしない企業にはあまり関わり持ちたくないんですよねぇ。
Windowsフォームアプリでは
var columnNames = new string[] { "umaban", "bamei", "kishu", "choukyosi", "tansho", "fukusho", "bataijyu", "mark", "chaku" }; var columnHeader = new string[] { "馬番", "馬名", "騎手", "調教師", "単勝", "複勝", "馬体重", "印", "着順" }; var columnWidth = new int[] { 30, 201, 88, 88, 60, 130, 60, 30, 30 }; for (int i = 0; i < columnNames.Length; i++) { DataGridViewColumn tbCol = new DataGridViewTextBoxColumn(); tbCol.Name = columnNames[i]; tbCol.HeaderText = columnHeader[i]; tbCol.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter; tbCol.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; tbCol.ReadOnly = true; tbCol.SortMode = DataGridViewColumnSortMode.NotSortable; dgv.Columns.Add(tbCol); dgv.Columns[columnNames[i]].Width = columnWidth[i]; }
って感じでC#で定義してたりしました。素人的にWin UI3でデータグリッド使うにはxamlで
<Grid Grid.Row="1"> <controls:DataGrid x:Name="RaceDetailGrid" AutoGenerateColumns="False" HeadersVisibility="Column" CanUserResizeColumns="False" SelectionMode="Single" RowHeight="30" CanUserSortColumns="False" > <controls:DataGrid.Columns> <controls:DataGridTextColumn Header="馬番" Binding="{Binding Umaban}" Width="60"/> <controls:DataGridTextColumn Header="馬名" Binding="{Binding Bamei}" Width="200"/> <controls:DataGridTextColumn Header="服" Binding="{Binding Fuku}" Width="80"/> <controls:DataGridTextColumn Header="騎手" Binding="{Binding Kishu}" Width="120"/> <controls:DataGridTextColumn Header="調教師" Binding="{Binding Chokyosi}" Width="120"/> <controls:DataGridTextColumn Header="単勝" Binding="{Binding Tansho}" Width="80"/> <controls:DataGridTextColumn Header="複勝" Binding="{Binding Fukusho}" Width="140"/> <controls:DataGridTextColumn Header="馬体重" Binding="{Binding Bataiju}" Width="100"/> <controls:DataGridTextColumn Header="印" Binding="{Binding Mark}" Width="60"/> <controls:DataGridTextColumn Header="着順" Binding="{Binding Chaku}" Width="80"/> </controls:DataGrid.Columns> </controls:DataGrid> </Grid>
としてみてたのですが、今後こんなの増えてくるとってのと今回カスタム列タイプも試したのでその為にもスマートに定義が出来ればと思い、Copilotに質問ぶつけて得た方法は
public class DataGridColumnDefinition { public string Header { get; set; } public string BindingPath { get; set; } public int Width { get; set; } public string ColumnType { get; set; } // 列の種類を文字列で管理 }
として定義用クラスを用意し、
private void DesignRaceDetailGrid(DataGrid dataGrid) { var columnDefinitions = new List<DataGridColumnDefinition> { new DataGridColumnDefinition { Header = "馬番", BindingPath = "Umaban", Width = 60, ColumnType = "Text" }, new DataGridColumnDefinition { Header = "馬名", BindingPath = "Bamei", Width = 200, ColumnType = "Text" }, new DataGridColumnDefinition { Header = "服", BindingPath = "Fuku", Width = 80, ColumnType = "Text" }, new DataGridColumnDefinition { Header = "騎手", BindingPath = "Kishu", Width = 120, ColumnType = "Text" }, new DataGridColumnDefinition { Header = "調教師", BindingPath = "Chokyosi", Width = 120, ColumnType = "Text" }, new DataGridColumnDefinition { Header = "単勝", BindingPath = "Tansho", Width = 80, ColumnType = "Text" }, new DataGridColumnDefinition { Header = "複勝", BindingPath = "Fukusho", Width = 140, ColumnType = "Text" }, new DataGridColumnDefinition { Header = "馬体重", BindingPath = "Bataiju", Width = 100, ColumnType = "Text" }, new DataGridColumnDefinition { Header = "印", BindingPath = "Mark", Width = 60, ColumnType = "Text" }, new DataGridColumnDefinition { Header = "着順", BindingPath = "Chaku", Width = 60, ColumnType = "Text" }, }; foreach (var column in columnDefinitions) { DataGridColumn dataGridColumn; switch (column.ColumnType) { case "Text": dataGridColumn = new DataGridTextColumn { Header = column.Header, Binding = new Binding { Path = new PropertyPath(column.BindingPath) }, Width = new DataGridLength(column.Width, DataGridLengthUnitType.Pixel) }; break; default: throw new InvalidOperationException($"未対応の列タイプ: {column.ColumnType}"); } dataGrid.Columns.Add(dataGridColumn); } }
定義しやすさとメンテしやすさと思ってしてみました。
自分自身も期待している部分もあるのでちょっとだけ頑張ってはいるんですが、例えば、アプリの終了です。こんなのこれまでWindowsアプリだろうと、言っちゃえばDOSや他のOSなんかでも普通に終了的にすれば問題無いのに、Win UI3だと違うっぽいです。これで昨晩かなり時間を費やしました。
基本的にWin UI3なら
Application.Current.Exit(); // アプリケーションを終了
とすれば良いってCopilotとかに言われてしても、終了時にエラーが出るしまつorz まあ、そんなのはいつもの事なので、更に突っ込んだ質問ぶつけてもなかなか良い回答は得られずでしたが、結局の所
Process.GetCurrentProcess().Kill(); // アプリを強制終了
とすれば、一応エラー無しで終われる事を確認しました。が、なんでそんな事に時間費やすんだろうって疑問はねぇ^^; まあ、なにやらリソースが解放されてないのがって事ではって話だが、そんなの勝手に処理しろよってね。でまあ、
定義的な話は別として、JRA-VANの有料サービス契約してJV-Linkを使ってデータ取得するのは基本なんです。自分が感じた感覚的な話ではありますが、JRA-VANはソフトウェア開発においては素人の集団でほぼ役に立たないJRAからの天下り的なメンバーなんだと感じます。いや、あくまで外野の感じたフィーリングからなので、実際にはどうなのかは知りませんのであしからず。
そんな事は別にしてJRA-VANが提供するData Labのデータ提供を活用してデータ取得するにはJV-Linkの利用を強要してるのは既成事実。これが32bit環境を強要しているのも事実。何度かここでも書いてますが、AutoMLやLightGBM、多分TensorFlowもなんだと思いますが64bitを要求してます。で、Data-Labの提供データを利用するアプリとしては32bitに制限されるので、ここまではアプリ本体を32bitで行いData-LabのデータをSQLiteに蓄積して利用する方向で、64bitが必要な部分に関しては外部プロセスとして連携する事で実現してきました。
最近やってた事はTensorFlowでの機械学習なんですが、これの実装でまた外部? もう外部多過ぎだよねぇっと考えて、単にJV-Link経由でデータ取得する部分のみ32bitで外部プロセスとしておけば、残りのアプリ本体は64bitで行けるんじゃないかって話です。
で、ここまでWindowsフォームアプリの開発してきました。これってそもそもの始まりは、多分Visual Basicなんだと思います。MS-DOSの時代にMS-DOSに乗せる形で起動してたWindows Version 2.1辺りとかまではアプリ開発も非常にハードルが高く、Cなんかで苦労して色々する所を、記憶的には曖昧ですが、Windows 95辺りでMS-DOSから独立(?)して単独なOSとして動くようになり、アプリ開発をビジュアル的な行える様にしたのがVBの始まりだったと思います。これに慣れているとWin UI3とかでって本当に原始的? この辺りは流石MSです(笑) 最先端OSのWindows 11的なアプリにはWin UI3を使う事でって事の様なんですが、これが本当に地味なもので、ここ最近は何度もトライして挫折の繰り返しorz ただ、今回はちょっと本腰入れての取り組みなので今日も1日やってました。
思う所があり、今ならまだ間に合う? いや、年齢的にね、ここで気合い入れればまだやり遂げられる? JRA-VANのJV-Linkの64bit化について公式は相変わらずの無反応。諸々が64bitでないと動かない為に外部プロセスとして実装試みてきましたが、これが間違った対応だったんじゃないかと思えてきました。JV-Linkを使ってデータ取得する部分は確かに32bitでなければ動きませんが、その取得したデータを64bitのアプリに渡す32bitの外部プロセスを作って64bitアプリから利用するって考えれば、全てがスムーズに行える様に思えてきました。
まあ、64bit化してアプリを作り直すならWindowsフォームアプリではなく、最近のWindows11的なアプリにしていく必要があるかなぁって事でWin UI3になる訳です。これまでにも何度かWin UI3はいじってみたのですが、Windowsフォームに比べたら、まあ所謂Visualって事ではなくコード書くんかい!ってなものね。これが本当に面倒な気がしてますが、楽に開発出来ないのか知りたいです。なので、まっさらな状態からやる事になるので、しばらくは「さらだ」の開発は「さらだ64」目指すので頓挫する可能性もありますし、ちょっと時間頂く事になるかと思います。ってここに書くのも微妙ですが、サポートサイトに書いちゃうと確定事項的に後戻りも出来なくなる気がするので、あえてこちらに書きます。ユーザー様の何人かはこちらにも着て頂いているかと思うので😅
朝から色々やってたら、結局Win5の締切に間に合わずですが、まあ、当たらんから良いか(笑)
継続は力とはよく聞きますが、諦めずにやれる事を続けてきてます。そもそもの原因は自分の理解不足なのは承知してます。更にCopilotに振り回されても耐えられる忍耐と多分知力かなぁ。まあ、なんにしてもRMSEが38辺りでって問題は突破出来た。簡単に言えば、層の構築方法に問題があった模様です。
って事で、本来のデータを使った訓練スタートしてます。相変わらずのサイズなので38分/epochで50epochsを試してますので32時間弱かな。明日夜には終わる予定なので、そこまで無難に訓練されていれば良いのですが、数値的に問題があったりしたら中断するかもです。現時点では3epochがRMSE 18辺りなんですが、少なくとも明日朝にはRMSE 2未満になっている事を期待したいかな。
で、まあ、これが順調に終わったと仮定すると、新馬戦用、通常用、順位予測の3本建てのモデルが揃うってか、そもそも新馬戦用と通常用が出来た時点で、これを使った順位予測用学習データ出力にしなければならなくて、それを使って順位予測の訓練をする必要もある。この辺りをまとめて外部プロセスとしてLightGBMでも作った感じのものをTensorFlow用にも作成してアプリに同胞出来る様に仕上げる訳ですが、ダービーには間に合わないorz
それでもそれ仕上げるのとUI変更なんかもこれから徐々に進めてもう少しだけ良いものになればと思ってます。まだまだやる事が山ほど有るな😓
追記 2025.5.25 7:44
あと少しで29epochが終わりますがRMSEはやっと16未満になる辺り。ただ、じりじりと下がってはいるので回数が必要なんだと。順位の時だったか500epochを5日半とか掛けてやりましたが、この通常用でやると13日ちょい掛かるって2週間ぶん回すのはキツイなぁ。電気代もそうだけど、このポンコツPCにトドメ刺しそう。しかもね、これ、そこまでやって本当に良い結果が得られる保証は無い。単純計算では2週間このポンコツ(750W電源使用)回すと7千円以上の電気代になるっぽい。アイドル状態ではなく、機械学習してるとほぼPCのファンがうるさい状態って事はかなり電気は消費してると思われますしね。
こちらにも何度も書いてますが、Microsoft Rewardsはほぼ欠かさず参加してます。夜勤で、人数調整の為に半日有休で帰宅して、日付が変わっているので本日分の「日々のセット」内のクイズで
何をどうするとこんな事になるんだろ? 40年以上前に"Where are you from?"ってアメリカ人に聞かれて"From Japan."と答えると"Hong Kong?"って...遥か遠くのアジアの話ならってのも本来微妙だけど、自国の話でしょ? いや、もしかしてこの問題作ったのはMicrosoftとは無関係でアメリカとは無縁の場所の方が?
TensorFlowの理解が全く進まない。
これが現時点の問題で、5epoch辺りで収束してそれ以上改善されない。先週はこれに挑んで、まあ、こんなグラフ出力までしても何の改善方法も見つけられない。昨夜久しぶりに新馬戦用の訓練もしてました。20時間弱で500epochsをこなし、見てる限りはRMSE 2.0辺りまで行ってましたが、最終的な表示は8.9とかだったかな? これはなんか計算方法間違えてるのかは疑問だが、それでも500回でもまだモデル自体は収束ってまあ、確かになかなかそれ以上は進まない感じながらもじりじりとで、たった5回程度で収束方向ってのとは違う。
今回改めて新馬戦用の訓練を実行したのは、Anacondaの仮想環境の再構築ってか、そもそも以前ちょっと試してダメだったGPUの力を少し試すってのをね、まあ、うちのPCは今年の夏には丸7年になるポンコツで、NVIDIA GeForce GTX 1050Tiに4GBメモリなZOTAC ZTGTX1050TI-4GD5MINI001/ZT-P10510A-10って18,800円のグラボしか載ってないのでほぼ助けにはならないのは覚悟でCUDAとcuDNNを以前インストールしたらVisual Studioの動きに支障があったのでアンインストールして放置してたんですが、
をインストールして仮想環境を再構築しました。今回は一応NVIDIA公式のCUDA Installation Guide for Microsoft Windowsを参考に
conda install cuda -c nvidia
としてAnaconda側でもCUDAを入れて
python -m pip install --upgrade setuptools pip wheel
とする事で
python -m pip install nvidia-pyindex
これが出来る様になるらしい。で、仮想環境を構築する準備が出来たので仮想環境をPython 3.9で作成して
をpip使って入れて、新馬戦用はこれで足りますが、通常版ではグラフ出したりするので更に
も入れてます。
でも、ここまでしても流石にグラボの恩恵はほぼ感じられない😞
層毎のユニット数調整では顕著な変化は見られなかったので新たな試みとして
をCopilotの助言を元に施してみました。
from tensorflow.keras.layers import Activation, BatchNormalization x = Dense(256)(merged_features) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(0.3)(x) x = Dense(128)(x) x = BatchNormalization()(x) x = Activation('relu')(x) x = Dropout(0.3)(x) x = Dense(64)(x) x = BatchNormalization()(x) x = Activation('relu')(x) uma_networks.append(x)
これが特徴量の正規化追加した部分で
from tensorflow.keras.optimizers import Adam # 学習率を指定 initial_learning_rate = 0.001 lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay( initial_learning_rate, decay_steps=10000, decay_rate=0.9, staircase=True) optimizer = Adam(learning_rate=lr_schedule) # モデルをコンパイル model.compile(optimizer=optimizer, loss='mse', metrics=['mae', root_mean_squared_error])
これがExponentialDecayを利用して
としているらしい。50epochsで既に開始して、今までだとRMSE 38辺りが限界値的に得られた程度だったんですが、7epoch辺りで到達してここから更に良くなるかが気になる所です。まあ、CopilotにはDropout(0.3)はちょっと大きいのでDropout(0.2)にしてみてはってアドバイスも頂いてるので、それも試そうとは思ってます。
ここ最近はTensorFlowに労力全て持っていかれて他に手が回らない状態が続いてます。やりたい事は山ほどあるけどってのと、やはり現在のPCの能力の低さが痛いです。
まあ、そんな中でも久しぶりに現在のLightGBMの今年の検証をしてみました。2025.1.1~2025.5.11分です。
1,227R | 1点 | 芝(529R) | ダート(652R) | 障害(46R) | 8頭以下(48R) | 9~12頭(265R) | 13頭以上(914R) | 多点 |
単勝 | 23.63% (87.19%) |
21.36% (98.07%) |
25.15% (78.68%) |
28.26% (82.61%) |
47.92% (136.87%) |
28.30% (85.06%) |
21.01% (85.20%) |
53.14% (85.47%) |
複勝 | 51.26% (83.46%) |
48.02% (85.44%) |
53.53% (82.15%) |
56.52% (79.35%) |
66.67% (92.71%) |
55.85% (81.55%) |
49.12% (83.53%) |
85.82% (80.81%) |
枠連 | 13.43% (92.55%) |
11.09% (86.00%) |
15.17% (99.32%) |
12.82% (60.00%) |
-- (--) |
14.72% (66.98%) |
12.36% (95.21%) |
27.83% (80.83%) |
馬連 | 9.13% (71.43%) |
6.62% (53.91%) |
11.04% (86.92%) |
10.87% (53.48%) |
10.42% (33.96%) |
11.70% (71.70%) |
8.32% (73.33%) |
19.48% (68.45%) |
ワイド | 19.89% (76.42%) |
16.07% (63.40%) |
22.09% (83.97%) |
32.61% (119.13%) |
29.17% (51.67%) |
26.42% (74.68%) |
17.51% (78.23%) |
39.61% (72.15%) |
馬単 | 5.54% (75.24%) |
4.73% (87.73%) |
5.98% (65.32%) |
8.70% (72.17%) |
10.42% (67.08%) |
7.55% (89.47%) |
4.70% (71.54%) |
19.48% (69.32%) |
三連複 | 4.07% (49.41%) |
3.59% (24.52%) |
4.29% (67.87%) |
6.52% (73.91%) |
10.42% (63.96%) |
7.92% (65.81%) |
2.63% (43.88%) |
11.74% (56.12%) |
三連単 | 0.81% (21.65%) |
0.76% (15.33%) |
0.92% (28.31%) |
0.00% (0.00%) |
4.17% (93.75%) |
1.89% (48.30%) |
0.33% (10.14%) |
11.74% (52.80%) |
総合 | 52.97% (69.45%) |
50.28% (63.94%) |
54.91% (73.98%) |
56.52% (67.73%) |
72.92% (77.14%) |
56.98% (72.94%) |
50.77% (67.63%) |
86.31% (62.51%) |
1,272R | 1点 | 芝(548R) | ダート(678R) | 障害(46R) | 8頭以下(48R) | 9~12頭(268R) | 13頭以上(956R) | 多点 |
単勝 | 21.31% (81.12%) |
18.07% (88.14%) |
23.30% (74.16%) |
30.43% (100.22%) |
37.50% (100.83%) |
24.25% (90.63%) |
19.67% (77.47%) |
50.79% (89.18%) |
複勝 | 50.47% (84.58%) |
47.45% (86.04%) |
52.36% (83.11%) |
58.70% (88.70%) |
62.50% (86.67%) |
58.21% (94.63%) |
47.70% (81.65%) |
84.75% (82.22%) |
枠連 | 12.06% (87.98%) |
9.81% (78.37%) |
13.66% (94.01%) |
12.82% (104.10%) |
-- (--) |
13.43% (62.76%) |
11.09% (90.72%) |
26.00% (74.86%) |
馬連 | 8.25% (70.29%) |
6.20% (66.48%) |
9.88% (75.37%) |
8.70% (40.87%) |
10.42% (33.96%) |
10.82% (74.48%) |
7.43% (70.94%) |
18.79% (107.09%) |
ワイド | 18.63% (74.61%) |
16.06% (72.17%) |
20.06% (76.00%) |
28.26% (83.26%) |
33.33% (59.79%) |
26.49% (87.16%) |
15.69% (71.84%) |
39.62% (81.72%) |
馬単 | 4.32% (58.28%) |
3.28% (58.70%) |
4.87% (56.99%) |
8.70% (72.17%) |
10.42% (67.08%) |
5.22% (71.57%) |
3.77% (54.11%) |
18.79% (111.78%) |
三連複 | 3.38% (40.63%) |
3.47% (29.69%) |
3.39% (49.66%) |
2.17% (37.83%) |
14.58% (96.04%) |
5.22% (45.56%) |
2.30% (36.46%) |
10.30% (48.55%) |
三連単 | 0.71% (44.70%) |
0.36% (8.21%) |
1.03% (77.23%) |
0.00% (0.00%) |
4.17% (93.75%) |
0.37% (5.11%) |
0.63% (53.34%) |
10.30% (47.10%) |
総合 | 52.20% (67.58%) |
49.45% (60.70%) |
53.98% (73.24%) |
58.70% (65.15%) |
66.67% (76.88%) |
59.70% (66.49%) |
49.37% (67.07%) |
85.06% (67.29%) |
決して褒められたレベルではないのは確かです。まあ、だからTensorFlowに期待して作業進めてるんですがね。
追記 2025.5.18 10:36
比較としてモデルビルダーも載せておきます。
1,227R | 1点 | 芝(529R) | ダート(652R) | 障害(46R) | 8頭以下(48R) | 9~12頭(265R) | 13頭以上(914R) | 多点 |
単勝 | 21.35% (84.25%) |
17.58% (75.60%) |
24.69% (93.17%) |
17.39% (57.39%) |
31.25% (125.00%) |
22.64% (77.25%) |
20.46% (84.15%) |
49.47% (77.12%) |
複勝 | 51.02% (85.97%) |
45.75% (78.36%) |
55.06% (92.71%) |
54.35% (78.04%) |
60.42% (91.67%) |
56.23% (84.83%) |
49.02% (86.01%) |
85.90% (83.74%) |
枠連 | 12.01% (77.44%) |
9.57% (66.93%) |
13.27% (73.78%) |
20.51% (260.77%) |
-- (--) |
15.09% (99.40%) |
10.50% (67.09%) |
27.03% (91.36%) |
馬連 | 7.17% (59.21%) |
5.29% (45.82%) |
8.44% (61.18%) |
10.87% (185.22%) |
10.42% (79.37%) |
10.19% (88.49%) |
6.13% (49.66%) |
19.32% (76.03%) |
ワイド | 20.95% (86.59%) |
18.15% (80.95%) |
23.31% (90.05%) |
19.57% (102.39%) |
35.42% (96.04%) |
27.92% (94.94%) |
18.16% (83.67%) |
40.34% (80.47%) |
馬単 | 3.83% (54.95%) |
2.65% (46.18%) |
4.91% (64.48%) |
2.17% (20.65%) |
6.25% (117.92%) |
4.91% (71.55%) |
3.39% (46.83%) |
19.32% (71.10%) |
三連複 | 5.05% (78.08%) |
4.73% (92.31%) |
5.52% (71.15%) |
2.17% (12.83%) |
6.25% (32.92%) |
7.55% (73.09%) |
4.27% (81.90%) |
13.77% (74.77%) |
三連単 | 0.73% (41.21%) |
0.38% (59.77%) |
1.07% (29.05%) |
0.00% (0.00%) |
0.00% (0.00%) |
0.38% (5.17%) |
0.88% (53.82%) |
13.77% (76.23%) |
総合 | 52.73% (70.90%) |
47.64% (68.26%) |
56.60% (71.94%) |
56.52% (86.34%) |
68.75% (77.56%) |
57.74% (74.34%) |
50.44% (69.14%) |
86.63% (77.05%) |
1,272R | 1点 | 芝(548R) | ダート(678R) | 障害(46R) | 8頭以下(48R) | 9~12頭(268R) | 13頭以上(956R) | 多点 |
単勝 | 19.42% (73.78%) |
15.15% (61.15%) |
23.01% (85.90%) |
17.39% (45.65%) |
33.33% (126.25%) |
22.01% (71.31%) |
17.99% (71.84%) |
48.98% (75.59%) |
複勝 | 48.51% (82.84%) |
42.15% (76.51%) |
53.10% (88.41%) |
56.52% (76.09%) |
62.50% (93.13%) |
53.73% (86.27%) |
46.34% (81.36%) |
85.46% (84.03%) |
枠連 | 12.15% (80.00%) |
10.44% (81.52%) |
13.35% (77.97%) |
12.82% (95.64%) |
-- (--) |
17.91% (109.85%) |
9.94% (67.70%) |
25.74% (86.78%) |
馬連 | 7.86% (79.50%) |
6.39% (65.73%) |
9.14% (92.57%) |
6.52% (50.87%) |
12.50% (94.37%) |
12.69% (104.14%) |
6.28% (71.84%) |
18.71% (77.90%) |
ワイド | 20.60% (93.10%) |
17.52% (82.79%) |
23.16% (101.80%) |
19.57% (87.61%) |
33.33% (85.42%) |
27.99% (99.25%) |
17.89% (91.76%) |
39.15% (85.33%) |
馬単 | 4.01% (86.53%) |
3.65% (82.96%) |
4.57% (95.28%) |
0.00% (0.00%) |
8.33% (140.21%) |
6.34% (115.34%) |
3.14% (75.75%) |
18.71% (71.69%) |
三連複 | 5.11% (94.65%) |
4.20% (84.23%) |
6.19% (109.50%) |
0.00% (0.00%) |
6.25% (37.50%) |
7.46% (99.48%) |
4.39% (96.17%) |
13.92% (96.15%) |
三連単 | 0.86% (55.42%) |
0.73% (83.89%) |
1.03% (36.17%) |
0.00% (0.00%) |
0.00% (0.00%) |
1.49% (84.22%) |
0.73% (50.13%) |
13.92% (102.51%) |
総合 | 50.39% (80.73%) |
44.34% (77.28%) |
54.72% (85.98%) |
58.70% (43.49%) |
68.75% (82.41%) |
56.34% (96.23%) |
47.80% (75.82%) |
85.93% (91.96%) |
若干ではあるがモデルビルダーの方が回収率が良いので買うならこちらかな😅
結局良い結果が得られないままで、時間だけが過ぎていく。そこで、そもそも最初から2004年~2024年という21年分のデータを学習させているのも時間が掛かる一因な訳でこれを2004年~2010年の7年分にして試す事にしてみました。って事で今はCSVデータ出力中でそんな中でもCopilotに質問ぶつけて各層のユニット数調整のアドバイスをもらってみた。
x = Dense(256, activation='relu')(merged_features) x = Dropout(0.3)(x) # 過学習防止 x = Dense(128, activation='relu')(x) x = Dropout(0.3)(x) x = Dense(64, activation='relu')(x) uma_networks.append(x)
馬毎はこんな感じとし、
# 結合後のネットワーク全体 x = Dense(512, activation='relu')(final_features) # 隠れ層 x = Dropout(0.3)(x) # 過学習防止 x = Dense(256, activation='relu')(x) # 隠れ層
結合後もちょい調整してみる事にしました。CSVデータ出力し終えたら試します。
追記 2025.5.17 14:56
ちょっとした手違いから時間が余分に掛かってしまいました。まあ、Visual Studio Community2022もVersion 17.14.0がリリースされたので先にアップデートも済ませて訓練開始してみると、10分/epochに短縮されてますのでこれで色々試せればと思います。
そもそも理解してるとは思っていませんが、取敢えずモデルの訓練が出来る様になったので50epochsで試してました。ああ、これ、35分/epochなんで50epochsだと29時間です😨 初トライではあまり良い結果が出ず、RMSEが確か39とかだった記憶なんですが、Copilotにあまり精度が上がらないけどって相談してみると
from tensorflow.keras.optimizers import Adam # 学習率を指定 optimizer = Adam(learning_rate=0.01) # 例えば 0.01 に変更 # モデルをコンパイル model.compile(optimizer=optimizer, loss='mse', metrics=['mae', root_mean_squared_error])
とする事で学習率が指定出来るとの事で試しました。そもそもデフォルトでは0.001らしいです。でも、結果的にはそれ程改善された訳では無かったです。そこで、まあ、そもそも特徴量が爆発的に増えてますので層毎の指定を大幅に変更し、馬毎の部分を
x = Dense(1024, activation='relu')(merged_features) x = Dropout(0.3)(x) # 過学習防止 x = Dense(256, activation='relu')(x) x = Dropout(0.3)(x) x = Dense(64, activation='relu')(x)
として、より複雑(?)にして50epochsスタートしてみました。これ、結果わかるの29時間以上後なので...
追記 2025.5.14 21:17
そもそも当初はどうだったのかが分からんと比較出来ないですね😓
x = Dense(64, activation='relu')(merged_features) x = Dropout(0.3)(x) # 過学習防止 x = Dense(32, activation='relu')(x) x = Dropout(0.3)(x) x = Dense(16, activation='relu')(x)
これ、新馬戦用からコピーしてそのままだったんですが、そもそも新馬戦用ももう少し変更は必要ですね。
ああっ、そいえばWindowsに緊急のUpdateが来てるんだったけど、訓練スタートしちゃったから後日だなorz
追記 2025.5.15 21:23
終わるまで我慢出来なくて中断しました。思えば、上記なんですが、馬毎にしてるので馬毎は確か533特徴量なんてす。なので流石に1024は違うだろうって判断です。まあ、残り10epochsでやはりRMSE 38辺りだったのも中断の決め手です。
x = Dense(128, activation='relu')(merged_features) x = Dropout(0.3)(x) # 過学習防止 x = Dense(32, activation='relu')(x) # x = Dropout(0.3)(x) # x = Dense(16, activation='relu')(x)
時短になるかもって事で1つの層を削ってみたけど、これは効果無い感じorz いや、まだ1つ目も終わってないが訓練始まるとそのepochの残り時間とかが出るので単純にどの程度掛かるのか分かるんだが、38分とかだったので変わってないなっと。明日朝時点でRMSEがどの程度かで、今回の修正が意味あるのか分かるかも?
前回は4月5日でしたので今回は40日目です。大分早かったのはスマホ側で1,000ポイント付いたりしたからですね。今回は5,250ポイントを楽天660ポイントにしました。よくよく計算してみたらこちらの方がAmazonより還元率は良かった。
歳には勝てないかもorz コーディングとかは頑張ってしてますが、肉体的には本日午前中に庭に除草剤捲いたりしてたんです。その後、腰が伸びないorz 痛いです😭
やっと!ああっ、前回書き込みから1週間ですが、ひたすらコード書きorz いっぱい勉強させて頂きました。通常版用CSVデータ出力を仕上げる際、一気に書き上げるも見た事のないエラーでCopilotに質問すると、メソッドが大き過ぎたりするとなりますよって事でシェイプアップ(笑) その際、クラスのメンバーに名前をプログラム的にアクセスする方法を教えてもらいました。
public void SetUmaBareiSexBlinker(int umaNo, byte barei, byte sex, byte blinker) { // プロパティ名を動的に生成 string[] suffixes = { "Barei", "Sex", "Blinkers" }; byte[] values = { barei, sex, blinker }; foreach (var (suffix, value) in suffixes.Zip(values)) { string propertyName = $"Uma{umaNo}{suffix}"; PropertyInfo prop = typeof(MSouhaCKSrc).GetProperty(propertyName); if (prop != null && prop.PropertyType == typeof(byte)) { prop.SetValue(this, value); } } }
こんな感じでクラスのメソッドに書いておけば、メンバーに簡単に値がセット出来る様になるので楽でした。この例は全てが同じ型の場合ですが型が違う場合は
public void SetUmaPrev<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> (int umaNo, int mae, T1 jouCD, T2 tuki, T3 kai, T4 nichi, T5 trackCD, T6 course, T7 Kyori, T8 waku, T9 tousu, T10 tenko, T11 baba, T12 barei, T13 sex, T14 kinryo, T15 blinker, T16 kishu, T17 juni, T18 corner1, T19 corner2, T20 corner3, T21 corner4, T22 ato4, T23 ato3, T24 date, T25 chakuSa, T26 timeSa, T27 souha ) { var properties = new (string suffix, object value)[] { ("PrevJouCD", jouCD), ("PrevTuki", tuki), ("PrevKai", kai), ("PrevNichi", nichi), ("PrevTrackCD", trackCD), ("PrevCourse", course), ("PrevKyori", Kyori), ("PrevWaku", waku), ("PrevTousu", tousu), ("PrevTenko", tenko), ("PrevBaba", baba), ("PrevBarei", barei), ("PrevSex", sex), ("PrevKinryo", kinryo), ("PrevBlinkers", blinker), ("PrevKishu", kishu), ("PrevJuni", juni), ("Prev1Corner", corner1), ("Prev2Corner", corner2), ("Prev3Corner", corner3), ("Prev4Corner", corner4), ("PrevAto4Furlong", ato4), ("PrevAto3Furlong", ato3), ("PrevDate", date), ("PrevChakusa",chakuSa), ("PrevTimeSa", timeSa), ("PrevSouha", souha) }; foreach (var (suffix, value) in properties) { string propertyName = $"Uma{umaNo}{suffix}{mae}"; PropertyInfo prop = typeof(MSouhaCKSrc).GetProperty(propertyName); if (prop != null && prop.PropertyType.IsAssignableFrom(value.GetType())) { prop.SetValue(this, value); } else { Debug.WriteLine($"プロパティ {propertyName} の型が一致しません。"); } } }
こんな感じにすれば行けるらしい😉 で、まあ、無事にCSVデータ出力は...1回大体3~4時間なんですが、1回目出力後にバグ発見して再度出力しなおして大体4時間程度。そのデータをPythonのTensorFlowで学習させる為にPythonでのコーディングとデバッグ。新馬戦用とは別次元のコードの長さ(4,019ステップ)ですが、無事に訓練スタートまでこぎつけました。流石にデータの大きさ(CSVデータファイルは1.5GB程度)からepochsは50でスタートしました。これ、40分/epochなのでそれでも33時間掛かるので明日の22時過ぎまで掛かります。もし、500epochsとかやると14日弱。順位で確か2,000epochsとかやってますが、これだと...ギャ~!55.5日ですorz ダメだ、終わってる! ちょっと最低限の学習である程度の成果が見込める所で一旦勝負掛けてPCを最新にして...夢だなwww
まだ現役だった頃のテキストエディターの定番といえばMIFESでした。DOSでも使ったし、Windowsになっても利用してました。最新版とか購入するのもありかもですが、まあ、そこまでのこだわりも無く、最近はサクラエディター利用してます。しかし、そもそもVisual Studioにキーボードマクロがあればそれはそれで使い勝手も良いかなと思い、少し前にも検索した記憶も無くも無いけど...
Text Macros for Visual Studio 2019-2022なんてのがある事をCopilotに教えてもらいました。ただ、教えてもらったのは良いんですが、今新馬戦用のモデルの訓練中でどうだろ?天皇賞出走前に500epochsスタートして今152とかまで来たので5時間で150とすると2~3分かなぁ。残り350epochs×3minだと17.5時間って明日13時過ぎだorz
いや、何ってインストール指示しても全てのVisual Studioが終了しないとインストールされないから...Visual Studioのデバッグモードでモデルの訓練してるのでどうしようもないです。まあ、終わったらインストールしてどんな感じか試してみます。
追記 2025.5.5 9:17
想定よりも大分モデルの訓練が早く終わってText Macrosをインストールして早速試しました。簡単な編集をキーボードマクロとして登録して単発実行とかは問題ないし、繰り返しも出来たのですが、ちょっと当初Copilotがこれ案内してくれた時の注意点としてコピペがちょっと問題ある的な話だったんですが、実際コピペするキーボードマクロ自体は単発的には問題無かったです。で、調子に乗って400回とかしたんですが、これがヤバいです。多分Visual Studioを終了させないとダメかもなんですが、もう1時間以上我慢してます。Visual Studioの場合、編集する度に色々チェックして色分けしたりしてくれるので、多分その処理が間に合わない。ってか、そもそもこれを試したソース自体も悪かった。今は確認出来ないけど...って書いてたら、反応が戻った😂
まあ、このコピペが問題起こすのもPower Toolが関連してるってうちはPower Toysは入れてるんですが、その事を言っているのか不明ですが、このソース既に4万行超えてるのでちょっとした編集すら重いのでこれは仕方のない現象かもです。いや、今CsvHelper用のクラス定義してるんですが、これが1頭分で533項目が18頭ってそれだけで1万弱あるし、同一ファイルに新馬戦用や順位予測用も入ってるので、このファイル構成も考え直さなきゃダメかもですね。
これ、少し前ってかVisual Studio 2022の目玉だった? 正確な記憶が残ってませんが、ここの所も別にサボってた訳じゃなくひたすらコード書いてたのでこちらにはあまり書き込む余裕が無かったんです。でも、登場当初よりも更に磨きかけて助けてくれる様になってきた気がします。
その昔はキーボードマクロなんかで少しでも楽して大量のコードの記述してたんですが、ストラクチャーやクラスのメンバーなんかのあまり覚えてない部分でも候補だしてくれるので、そこから選択すれば可能なのは本当に助かってますが、Copilotなんかのサポートも入れ込んだものになってきたのか入力が格段に効率アップしてます。
PythonのTensorFlowで訓練したモデルのC#での利用って事で進めてますが、また無駄な時間の浪費になるのも覚悟で...いや、結局外部プロセスでの実装を選択したんですが、この際なので...まあ、そもそも順位予測には走破タイムの予測を入れてます。テスト的に行った訓練にはモデルビルダーの学習モデルが吐き出した走破タイム予測を利用してますが、どうせやるなら、その走破タイムの予測もTensorFlowにした方が筋が通るかなって事でね。まずは新馬戦学習用CSV出力のMシリーズでの書き直し。AutoMLにしてもモデルビルダーにしても、走破タイムの予測は個々の馬で予測させて来ましたが、どうなるかは未知ですが、レース毎に出走馬全てを一括で走破タイムの予測を行う事がTensorFlowでは可能なので試してみようと必死にコーディング中。出来ればある程度の形にGW中に仕上げられれば、最悪微調整なんかはその後でもと思って進めてます。
まあ、ズッコケたら日の目を見ずにお蔵入りですけどね😓
モデル訓練も2つ程終わらせてるので実際に利用可能か試し始めました。簡単に利用するにはML.NETでロードして利用がと思い調べて試してます。
これらがまず必要なのはわかりインストール。
using Microsoft.ML; using Microsoft.ML.Data; namespace TFCheck; class Program { static void Main(string[] args) { var mlContext = new MLContext(); // Load the model var modelPath = @"TFMJuniFullCK"; var tensorFlowModel = mlContext.Model.LoadTensorFlowModel(modelPath); // 入力と出力のスキーマを確認 var schema = tensorFlowModel.GetInputSchema(); Console.WriteLine("Input Schema:"); foreach (var column in schema) { Console.WriteLine($"Name: {column.Name}, Type: {column.Type}"); } } }
こんな単純なのが最初動かない。少し調べると何のことはないです。この所では珍しくない事でx86がサポートされてない。自力でx86用にビルドすれば可能のようですがそこまでするのは面倒が多過ぎる。が、ちょっと悩むなぁ。苦労してビルドしてうまく行くならアプリにも組み込めます。逆にx64で行くならまた外部プロセスにする事になる。
モデル訓練が順調に走ってる事は事前に色々Copilotにも相談しながら進めてたので問題無かったんですが、コード自体は更に続いて予測、結果表示、保存と進んでいくんですが、訓練までしかテストしないまま訓練スタートさせて、今回はなんと5.5日の予定だったのが、まあそれよりちょっと早く(?)昨夜終わったんです。が!その後の予測でエラー!となり、保存まで行かなかったのでここまでの苦労は全て無駄にorz いや、全くの無駄かといえば、ここまでやるとかなり訓練されるのは分かったし、ここまでやってもEarlyStoppingにならないのでもっと長くやれば更にって事なのは分かりました。
現在保存まで行ける筈の修正込みでEpochs=50で訓練中。ああ、訓練済みのモデルロードして更に訓練も出来る筈なのでその辺りも試そうとは思います。
しかし、今回の訓練でのPC連続稼働で電気代はザックリな計算で2,700円を無駄にした。750Wの電源つけてるPCだからって本当に750W使ってるかは別として24時間で540円程度。別に訓練とかしてなくても週末なんかだと朝起きて寝るまで18時間程度PCは動かしてるので、それだけで400円程電気代掛かってると再認識すると...いや、でもPCは必要だから😓
以前ここにApple Intelligenceの事を昨年暮れに書いてますが、実はその後に何度となく言語設定変更してImage Playgroundで遊んでたんですが、確かハングする感じがあり、まっ、対処方法はアンインストールして入れなおせば直るかなぁって単純に考えてアンインストールしました。で、App Storeで検索すれば出てきて出来る筈が出てくるのは似たアプリばかりで本物が出てこない。
まあ、ちょっとインチキではないが、本来まだ日本語では利用出来ないものを利用してたのでiOS 18.4で日本語対応して直るだろう思ってたんですが...App Storeで見つけられない。確かにSiriなんかは画面の周りが光る新しいものに変わってるのに。で、AppleのFAQなんかも見たり、CopilotやSiriに質問ぶつけたりしたけど解決出来ないのでAppleのサポートに直接問い合わせしました。しかし、サポートでもなぜApp Storeで検索出来ないか原因が分からずでした。そのうちに修正されると思いますって言われてました。
で、数日前にiOS 18.4.1がリリースれたのでアップデート。特に何が修正されたとか確認はしてませんでしたが、ダメ元でApp Storeで検索すると出てくれました😍
先日書いたPythonでTensorFlow使ってモデルの訓練したってやつは、まあ、さらだでもやった順位予測の一番シンプルなファクター(特徴量)数の31個だったので、まあ、Epochsを50程度で本当にさらっと学習させられるものでした。
でまあ、TensorFlowの基本的な流れは出来たのでCSVデータもRaceJuniFullCKと同等なものを出力させてファクター数も230個と格段に増やしました。
# 入力データ(特徴量) X = data[[ "JouCD", "KaisaiTuki", "KaisaiKai", "KaisaiNichi", "TrackCD", "Course", "Kyori", "Tousu", "Tenko", "Baba", "KyosouShubetu", "KyosouJouken", "JuuryoShubetu", "StandardDeviation", "Uma1Barei", "Uma1Sex", "Uma1Blinkers", "Uma1Kinryo", "Uma1Kyakusitu1", "Uma1Kyakusitu2", "Uma1Kyakusitu3", "Uma1Kyakusitu4", "Uma1Kishu", "Uma1Chokyosi", "Uma1Souha", "Uma1DeviationValues", "Uma2Barei", "Uma2Sex", "Uma2Blinkers", "Uma2Kinryo", "Uma2Kyakusitu1", "Uma2Kyakusitu2", "Uma2Kyakusitu3", "Uma2Kyakusitu4", "Uma2Kishu", "Uma2Chokyosi", "Uma2Souha", "Uma2DeviationValues", "Uma3Barei", "Uma3Sex", "Uma3Blinkers", "Uma3Kinryo", "Uma3Kyakusitu1", "Uma3Kyakusitu2", "Uma3Kyakusitu3", "Uma3Kyakusitu4", "Uma3Kishu", "Uma3Chokyosi", "Uma3Souha", "Uma3DeviationValues", "Uma4Barei", "Uma4Sex", "Uma4Blinkers", "Uma4Kinryo", "Uma4Kyakusitu1", "Uma4Kyakusitu2", "Uma4Kyakusitu3", "Uma4Kyakusitu4", "Uma4Kishu", "Uma4Chokyosi", "Uma4Souha", "Uma4DeviationValues", "Uma5Barei", "Uma5Sex", "Uma5Blinkers", "Uma5Kinryo", "Uma5Kyakusitu1", "Uma5Kyakusitu2", "Uma5Kyakusitu3", "Uma5Kyakusitu4", "Uma5Kishu", "Uma5Chokyosi", "Uma5Souha", "Uma5DeviationValues", "Uma6Barei", "Uma6Sex", "Uma6Blinkers", "Uma6Kinryo", "Uma6Kyakusitu1", "Uma6Kyakusitu2", "Uma6Kyakusitu3", "Uma6Kyakusitu4", "Uma6Kishu", "Uma6Chokyosi", "Uma6Souha", "Uma6DeviationValues", "Uma7Barei", "Uma7Sex", "Uma7Blinkers", "Uma7Kinryo", "Uma7Kyakusitu1", "Uma7Kyakusitu2", "Uma7Kyakusitu3", "Uma7Kyakusitu4", "Uma7Kishu", "Uma7Chokyosi", "Uma7Souha", "Uma7DeviationValues", "Uma8Barei", "Uma8Sex", "Uma8Blinkers", "Uma8Kinryo", "Uma8Kyakusitu1", "Uma8Kyakusitu2", "Uma8Kyakusitu3", "Uma8Kyakusitu4", "Uma8Kishu", "Uma8Chokyosi", "Uma8Souha", "Uma8DeviationValues", "Uma9Barei", "Uma9Sex", "Uma9Blinkers", "Uma9Kinryo", "Uma9Kyakusitu1", "Uma9Kyakusitu2", "Uma9Kyakusitu3", "Uma9Kyakusitu4", "Uma9Kishu", "Uma9Chokyosi", "Uma9Souha", "Uma9DeviationValues", "Uma10Barei", "Uma10Sex", "Uma10Blinkers", "Uma10Kinryo", "Uma10Kyakusitu1", "Uma10Kyakusitu2", "Uma10Kyakusitu3", "Uma10Kyakusitu4", "Uma10Kishu", "Uma10Chokyosi", "Uma10Souha", "Uma10DeviationValues", "Uma11Barei", "Uma11Sex", "Uma11Blinkers", "Uma11Kinryo", "Uma11Kyakusitu1", "Uma11Kyakusitu2", "Uma11Kyakusitu3", "Uma11Kyakusitu4", "Uma11Kishu", "Uma11Chokyosi", "Uma11Souha", "Uma11DeviationValues", "Uma12Barei", "Uma12Sex", "Uma12Blinkers", "Uma12Kinryo", "Uma12Kyakusitu1", "Uma12Kyakusitu2", "Uma12Kyakusitu3", "Uma12Kyakusitu4", "Uma12Kishu", "Uma12Chokyosi", "Uma12Souha", "Uma12DeviationValues", "Uma13Barei", "Uma13Sex", "Uma13Blinkers", "Uma13Kinryo", "Uma13Kyakusitu1", "Uma13Kyakusitu2", "Uma13Kyakusitu3", "Uma13Kyakusitu4", "Uma13Kishu", "Uma13Chokyosi", "Uma13Souha", "Uma13DeviationValues", "Uma14Barei", "Uma14Sex", "Uma14Blinkers", "Uma14Kinryo", "Uma14Kyakusitu1", "Uma14Kyakusitu2", "Uma14Kyakusitu3", "Uma14Kyakusitu4", "Uma14Kishu", "Uma14Chokyosi", "Uma14Souha", "Uma14DeviationValues", "Uma15Barei", "Uma15Sex", "Uma15Blinkers", "Uma15Kinryo", "Uma15Kyakusitu1", "Uma15Kyakusitu2", "Uma15Kyakusitu3", "Uma15Kyakusitu4", "Uma15Kishu", "Uma15Chokyosi", "Uma15Souha", "Uma15DeviationValues", "Uma16Barei", "Uma16Sex", "Uma16Blinkers", "Uma16Kinryo", "Uma16Kyakusitu1", "Uma16Kyakusitu2", "Uma16Kyakusitu3", "Uma16Kyakusitu4", "Uma16Kishu", "Uma16Chokyosi", "Uma16Souha", "Uma16DeviationValues", "Uma17Barei", "Uma17Sex", "Uma17Blinkers", "Uma17Kinryo", "Uma17Kyakusitu1", "Uma17Kyakusitu2", "Uma17Kyakusitu3", "Uma17Kyakusitu4", "Uma17Kishu", "Uma17Chokyosi", "Uma17Souha", "Uma17DeviationValues", "Uma18Barei", "Uma18Sex", "Uma18Blinkers", "Uma18Kinryo", "Uma18Kyakusitu1", "Uma18Kyakusitu2", "Uma18Kyakusitu3", "Uma18Kyakusitu4", "Uma18Kishu", "Uma18Chokyosi", "Uma18Souha", "Uma18DeviationValues" ]]
出力データは以前のものと同じです。で、今回は当たり前ですが本格的に取り組みました。Copilotとまあ平日で夜勤なのでちょっと眠い感じではありますが、可能な限り作業を続け3日目となる昨日出勤2時間前程度にどうにか訓練してくれる所までこぎつけました。
# コースは小数点第1位までの実数ですが、整数に変換する必要があります。 X["Course"] = (X["Course"] * 10).astype(int) # コースデータを10倍して整数化
このコース区分はAutoMLやLightGBM用のCSVデータでもそうだったんですがコース区分を数値にしてて、"A"~"E"だけど、中には"A1"とかもあるって事で"A"は1.0、"A1"は1.1的にしてました。ML.NET系は基本実数なので特に問題なく使えてましたが、TensorFlowでファクター(特徴量)をカテゴリ変数とする場合にはint64である必要があるのでこんな感じでデータを前処理加工。
# レースのカテゴリ変数 X_train_inputs = [ X_train["JouCD"], X_train["KaisaiTuki"], X_train["TrackCD"], X_train["Course"], X_train["Tenko"], X_train["Baba"], X_train["KyosouShubetu"], X_train["KyosouJouken"], X_train["JuuryoShubetu"] ] # レースの数値データを追加 X_train_inputs.extend([ X_train["KaisaiKai"], X_train["KaisaiNichi"], X_train["Kyori"], X_train["Tousu"], X_train["StandardDeviation"] ])
こんな感じで指定しました。馬毎のファクターも同様にカテゴリ変数と数値データを指定。
# ウマごとのカテゴリ変数を追加 for i in range(18): X_train_inputs.extend([ X_train[f"Uma{i+1}Sex"], X_train[f"Uma{i+1}Blinkers"], X_train[f"Uma{i+1}Kishu"], X_train[f"Uma{i+1}Chokyosi"] ]) # ウマごとの数値データを追加 X_train_inputs.extend([ X_train[f"Uma{i+1}{feature}"] for i in range(18) for feature in ["Barei", "Kinryo", "Kyakusitu1", "Kyakusitu2", "Kyakusitu3", "Kyakusitu4", "Souha", "DeviationValues"] ])
で、TensorFlowではお決まりの層を定義していく為に
# レースのカテゴリ変数を定義 input_joucd = Input(shape=(1,), name="JouCD") # 場コード embedding_joucd = Embedding(input_dim=11, output_dim=4)(input_joucd) # 場コードの埋め込み flatten_joucd = Flatten()(embedding_joucd) input_kaisaituki = Input(shape=(1,), name="KaisaiTuki") # 開催月 embedding_kaisaituki = Embedding(input_dim=13, output_dim=4)(input_kaisaituki) # 開催月の埋め込み flatten_kaisaituki = Flatten()(embedding_kaisaituki) input_trackcd = Input(shape=(1,), name="TrackCD") # トラックコード embedding_trackcd = Embedding(input_dim=60, output_dim=4)(input_trackcd) # トラックコードの埋め込み flatten_trackcd = Flatten()(embedding_trackcd) input_course = Input(shape=(1,), name="Course") # コース embedding_course = Embedding(input_dim=100, output_dim=4)(input_course) # コースの埋め込み flatten_course = Flatten()(embedding_course) input_tenko = Input(shape=(1,), name="Tenko") # 天候 embedding_tenko = Embedding(input_dim=7, output_dim=2)(input_tenko) # 天候の埋め込み flatten_tenko = Flatten()(embedding_tenko) input_baba = Input(shape=(1,), name="Baba") # 馬場状態 embedding_baba = Embedding(input_dim=5, output_dim=2)(input_baba) # 馬場状態の埋め込み flatten_baba = Flatten()(embedding_baba) input_kyosoushubetu = Input(shape=(1,), name="KyosouShubetu") # 競走種別 embedding_kyosoushubetu = Embedding(input_dim=25, output_dim=2)(input_kyosoushubetu) # 競走種別の埋め込み flatten_kyosoushubetu = Flatten()(embedding_kyosoushubetu) input_kyosoujouken = Input(shape=(1,), name="KyosouJouken") # 競走条件 embedding_kyosoujouken = Embedding(input_dim=1000, output_dim=8)(input_kyosoujouken) # 競走条件の埋め込み flatten_kyosoujouken = Flatten()(embedding_kyosoujouken) input_juuryoushubetu = Input(shape=(1,), name="JuuryoShubetu") # 斤量種別 embedding_juuryoushubetu = Embedding(input_dim=5, output_dim=2)(input_juuryoushubetu) # 斤量種別の埋め込み flatten_juuryoushubetu = Flatten()(embedding_juuryoushubetu) # レースの数値変数を定義 input_kaisai_kai = Input(shape=(1,), name="KaisaiKai") # 開催回 input_kaisai_nichi = Input(shape=(1,), name="KaisaiNichi") # 開催日 input_kyori = Input(shape=(1,), name="Kyori") # 距離 input_tousu = Input(shape=(1,), name="Tousu") # 頭数 input_standard_deviation = Input(shape=(1,), name="StandardDeviation") # 標準偏差
てな感じでして
# レースの特徴量を結合 race_features = Concatenate()([ flatten_joucd, flatten_kaisaituki, flatten_trackcd, flatten_course, flatten_tenko, flatten_baba, flatten_kyosoushubetu, flatten_kyosoujouken, flatten_juuryoushubetu, input_kaisai_kai, input_kaisai_nichi, input_kyori, input_tousu, input_standard_deviation ]) race_dense = Dense(64, activation='relu')(race_features) # 隠れ層の学習 race_dense = Dense(32, activation='relu')(race_dense) # 更に学習層を追加
この後、当然馬毎の入力層も定義し
# 馬ごとのネットワーク merged_horses = Concatenate()(uma_networks) # レース特徴量と馬特徴量を結合 final_features = Concatenate()([race_dense, merged_horses]) # 結合後のネットワーク全体 x = Dense(128, activation='relu')(final_features) # 隠れ層 output = Dense(18, activation='linear', name="Output")(x) # 出力層
これで、層は出来たので
# モデルを構築 model_inputs = [input_joucd, input_kaisaituki, input_trackcd, input_course, input_tenko, input_baba, input_kyosoushubetu, input_kyosoujouken, input_juuryoushubetu, input_kaisai_kai, input_kaisai_nichi, input_kyori, input_tousu, input_standard_deviation] + uma_inputs model = Model(inputs=model_inputs, outputs=output)
後は入力データを↑の様に整えるのに
X_train_inputs = [ X_train["JouCD"], # JouCD X_train["KaisaiTuki"], # KaisaiTuki X_train["TrackCD"], # TrackCD X_train["Course"], # Course X_train["Tenko"], # Tenko X_train["Baba"], # Baba X_train["KyosouShubetu"], # KyosouShubetu X_train["KyosouJouken"], # KyosouJouken X_train["JuuryoShubetu"], # JuuryoShubetu X_train["KaisaiKai"], # KaisaiKai X_train["KaisaiNichi"], # KaisaiNichi X_train["Kyori"], # Kyori X_train["Tousu"], # Tousu X_train["StandardDeviation"], # StandardDeviation ] for i in range(18): X_train_inputs.extend([ X_train[f"Uma{i+1}Sex"], # Uma{i+1}Sex X_train[f"Uma{i+1}Blinkers"], # Uma{i+1}Blinkers X_train[f"Uma{i+1}Kishu"], # Uma{i+1}Kishu X_train[f"Uma{i+1}Chokyosi"], # Uma{i+1}Chokyosi X_train[f"Uma{i+1}Barei"], # Uma{i+1}Barei X_train[f"Uma{i+1}Kinryo"], # Uma{i+1}Kinryo X_train[f"Uma{i+1}Kyakusitu1"], # Uma{i+1}Kyakusitu1 X_train[f"Uma{i+1}Kyakusitu2"], # Uma{i+1}Kyakusitu2 X_train[f"Uma{i+1}Kyakusitu3"], # Uma{i+1}Kyakusitu3 X_train[f"Uma{i+1}Kyakusitu4"], # Uma{i+1}Kyakusitu4 X_train[f"Uma{i+1}Souha"], # Uma{i+1}Souha X_train[f"Uma{i+1}DeviationValues"], # Uma{i+1}DeviationValues ])
として、モデルの訓練は以前のものほぼ変わらずですが、
# モデルの訓練 from tensorflow.keras.callbacks import EarlyStopping early_stopping = EarlyStopping(monitor='val_rmse', patience=5, mode='min') history = model.fit( X_train_inputs, # 入力データをリスト形式で渡す Y_train, # 出力データ(ターゲット) epochs=2000, batch_size=32, validation_split=0.2, callbacks=[early_stopping] )
流石に複雑なのでってのと、何度もやるのは辛いと想像して最初からepochsを2,000にしてます。ただ、これ、ちょっとザックリと指定してしまいましたが、昨日スタートすると明らかに各epochがこれまでと違い時間が掛かります。特にプログラム的に時間表示させたりしてないので目測的に測ると4分とかです。たった今205回目が終わってました。4×205=820÷60=13.6時間です。もし、過学習でEarlyStoppingにならないと4×2,000=8,000÷60=133.3÷24=5.5日です😰
今晩も夜勤で出勤しますが、訓練が終わらない事には予測させるコーディングも進められないので今週末には間に合わない。まっ、GW中には形に出来れば...
追記 2025.4.19 18:30
少し前に675個目のepochが終わりました。TensorFlowってテキストベースでログが出て各epochの終わりに
いやね、そろそろ、いつEarlyStoppingになってもって思ってますが地味に進んでるのがepochs=2000って指定が良かったのかが...ここまで36時間以上なのでやり直しは簡単ではないので期待してる😉
追記 2025.4.19
↑の追記は間違いが多いかな。多分675/2000って出てるEpochですが、これ次に始まった奴だったと思うので、厳密には674個目の終わりだった。更にそろそろ36時間以上ではなく48時間以上だな。いや、一昨日の出勤2時間前にコーディング終えてスタートしたんでね😉 先程750個目がスタートした。
追記 2025.4.20
何が失敗っていきなり2,000epochsで行った事ですね😭 いや、実際問題としてはその位必要な感じで進んではいます。だからこそ中断という選択は無いんです。ただ、今回ってbatch_size=32で行ったんですが、こちらのPCには64GB積んでるんでbatch_size=64でも行けたかも? これ指定してれば半分で済んだかも? その辺りも後から分かったけど今更中断出来ないのが辛いです。開始してからこれに要する時間が5.5日程度と分かった時点で一旦止める判断しなかったのが悔やまれますが、これも自分の知識不足が原因として。先程929回目がスタートしました。まだ半分に届いてない。でもloss: 6.1598と確実に進んでるのは分かります。進まなければEarlyStoppingが効くはずなのでね。まいったなぁ、終わるのはこのまま行くと3.4日後って木曜日になるのかなぁorz
確かにこれまでの苦労がうその様に楽に動きます。C#に固執しなければ良さげですが、そうもいかないのはこれまでの蓄積したアプリの形。ここにどうにかTensorFlowのモデルを読み込んで利用出来るまでもって行きたい。
主に順位予測に対してなんですが、ここまでModel BuilderでRMSE 3.0880とか、LightGBMではRMSE 3.6735程度。これがまあ検証は出来ていませんが、RMSE 2.77とか2.78辺りが出てます。Epochsがやり始めは50だったけど、Copilotに相談しながらLightGBMでも採用している過学習させない工夫入れたり、特徴量のグループ化等取り入れて何度か500まで試してるんですが、それでもEarly Stoppingされないって事は回数足りてないので明日もう少し増やしてどこまでになるか確認します。
しかし、ここまで苦労しててもC#でモデル読み込んで予測可能にならなかったら...
ここにも何度となく色々な事にチャレンジしている事は書いてます。まあ、その主軸はディープラーニングであるTensorFlowなんですが、これ自体は本来ってかPythonで使うものなので自分自身がPythonをあまり好きになれず、ってかねぇ、60歳過ぎて手を出した訳だし自分の脳が馴染めないだけなんだけど...いや、そもそもテキストベースなのがねぇって言い訳してた。
先日何だったかやってた時にOSが開発者モード(?)じゃないとか言われて
設定にあるこれをオンにしたんですが、以前Visual StudioでPython環境整備している時にシェルスクリプトだったか許可されないからって感じで使えなかった理由がこれなんじゃと思い確認してみるとVisual Studioで無事(実際には無事にとは行かないが、毎回指定すれば)にAnacondaの仮想Python環境で行ける様になり単純なTensorFlowでの多変量多出力回帰をしてみた。CopilotとGeminiに相談しながらなんとか行けました。
CSVファイルはpandas使って
import pandas as pd # CSVファイルの読み込み data = pd.read_csv("MRaceJuni.csv") # ファイル名を適宜変更
入出力の指定して
# 入力データ(特徴量) X = data[[ "JouCD", "KaisaiTuki", "KaisaiKai", "KaisaiNichi", "TrackCD", "Course", "Kyori", "Tousu", "Tenko", "Baba", "KyosouShubetu", "KyosouJouken", "JuuryoShubetu", "Uma1Souha", "Uma2Souha", "Uma3Souha", "Uma4Souha", "Uma5Souha", "Uma6Souha", "Uma7Souha", "Uma8Souha", "Uma9Souha", "Uma10Souha", "Uma11Souha", "Uma12Souha", "Uma13Souha", "Uma14Souha", "Uma15Souha", "Uma16Souha", "Uma17Souha", "Uma18Souha" ]] # 出力データ(ターゲット) Y = data[[ "Umaban1", "Umaban2", "Umaban3", "Umaban4", "Umaban5", "Umaban6", "Umaban7", "Umaban8", "Umaban9", "Umaban10", "Umaban11", "Umaban12", "Umaban13", "Umaban14", "Umaban15", "Umaban16", "Umaban17", "Umaban18" ]]
後は今までと同じ感じでデータ準備とTensorFlow特有の層を指定して学習が
from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # データ分割 X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=42) # 標準化 scaler = StandardScaler() X_train = scaler.fit_transform(X_train) X_test = scaler.transform(X_test) import tensorflow as tf from tensorflow.keras import Model, Input from tensorflow.keras.layers import Dense # 入力層を定義 input_layer = Input(shape=(X_train.shape[1],)) # 隠れ層と出力層 x = Dense(64, activation='relu')(input_layer) x = Dense(32, activation='relu')(x) output_layer = Dense(Y_train.shape[1])(x) # モデルを構築 model = Model(inputs=input_layer, outputs=output_layer) # モデルのコンパイル model.compile(optimizer='adam', loss='mse') # モデルの訓練 history = model.fit(X_train, Y_train, epochs=50, batch_size=32, validation_split=0.2)
出来たモデルの結果を
# 予測 predictions = model.predict(X_test) # 結果表示 print(predictions)
まあ、これまでのRMSEに馴染みがあるので
from sklearn.metrics import mean_squared_error import numpy as np # 平均二乗誤差(MSE)を計算 mse = mean_squared_error(Y_test, predictions) # 平方根を取ってRMSEを計算 rmse = np.sqrt(mse) print(f"Root Mean Squared Error: {rmse}")
って感じにすれば感覚つかみ易いですね。で、出来上がったモデルをどうやって利用するかが問題なんです。H5とかで保存やonnxもあり、まあ、この辺りも以前から苦労してた記憶がありますが
# SavedModel形式で保存 model.export('my_saved_model')
としてTensorFlowのSavedModel形式で保存してTensorFlow.NETでVisual Studioのc#で利用しようかと思ってますが、また躓くかもです😓
馬券は相変わらずパッとしないですね。まあ、そろそろって期待しながら今回は独自に予想してみました。
昨日は2つ程当てましたが微負け。本日はここまで酷い結果で唯一複勝1.8倍とか拾った程度で惨敗中。