Scheda Apprendimento: cosa sa il modello, cosa ha deciso, e la valutazione dall'app
Una scheda nuova nella barra laterale, fra Esporta e Impostazioni, che legge direttamente dal servizio e si aggiorna da sola ogni cinque secondi mentre e' visibile: nessun altro pezzo dell'applicazione sa che esiste. Mostra: lo stato (aste apprese, esempi visti, aste nel profilo, fattore di calibrazione, soglia per decidere, se lo studio dei dossier e' in corso); i pesi dal piu' forte con il verso dell'effetto, perche' le variabili sono a fasce e il modello e' lineare proprio per poterli leggere; le ultime decisioni date al motore, con probabilita', valore atteso ed esito (fermata, passa, o solo parere se il modello non aveva ancora appreso abbastanza); il profilo per prodotto e fascia oraria; e l'ultima valutazione. La valutazione si lancia dalla scheda, in sottofondo e annullabile. La logica e' uscita dal test ed e' entrata in LearningEvaluator, condivisa fra il target da riga di comando e la scheda: i numeri che vede l'utente sono gli stessi che vede chi sviluppa. "Ricomincia da capo" butta modello, profilo ed elenco dei dossier letti e ristudia tutto l'archivio, con una conferma prima. Le decisioni si tengono in una coda corta; lo stesso giro di un'asta ne produrrebbe molte uguali di fila, quindi si registra solo il cambiamento. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
<UserControl x:Class="AutoBidder.Controls.LearningControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ctl="clr-namespace:AutoBidder.Controls"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="800" d:DesignWidth="1200"
|
||||
Background="{DynamicResource Brush.Bg}">
|
||||
|
||||
<UserControl.Resources>
|
||||
<Style x:Key="Glyph" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="Segoe MDL2 Assets"/>
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
<Style x:Key="Stat" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource Brush.Text}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource Font.Size.Lg}"/>
|
||||
<Setter Property="FontWeight" Value="SemiBold"/>
|
||||
</Style>
|
||||
<Style x:Key="StatLabel" TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource Brush.TextMuted}"/>
|
||||
<Setter Property="FontSize" Value="{StaticResource Font.Size.Sm}"/>
|
||||
<Setter Property="Margin" Value="0,2,0,0"/>
|
||||
</Style>
|
||||
</UserControl.Resources>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- ═══ Barra strumenti ═══ -->
|
||||
<Border Grid.Row="0" Background="{DynamicResource Brush.Surface}" Padding="10,7"
|
||||
BorderBrush="{DynamicResource Brush.Border}" BorderThickness="0,0,0,1">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Button x:Name="RefreshButton" Style="{StaticResource IconButton}"
|
||||
ToolTip="Aggiorna i numeri" Click="RefreshButton_Click">
|
||||
<TextBlock Style="{StaticResource Glyph}" Text=""/>
|
||||
</Button>
|
||||
<TextBlock Text="Apprendimento" FontWeight="SemiBold" Margin="8,0,0,0"
|
||||
FontSize="{StaticResource Font.Size.Lg}"
|
||||
Foreground="{DynamicResource Brush.Text}" VerticalAlignment="Center"/>
|
||||
<Border Width="1" Background="{DynamicResource Brush.Border}" Margin="10,4"/>
|
||||
|
||||
<Border Style="{StaticResource Pill}" ToolTip="Aste da cui il modello ha imparato">
|
||||
<TextBlock x:Name="PillAuctions" Text="—" FontSize="{StaticResource Font.Size.Sm}"
|
||||
Foreground="{DynamicResource Brush.Text}"/>
|
||||
</Border>
|
||||
<Border Style="{StaticResource Pill}" ToolTip="Esempi (puntate) che hanno aggiornato i pesi">
|
||||
<TextBlock x:Name="PillUpdates" Text="—" FontSize="{StaticResource Font.Size.Sm}"
|
||||
Foreground="{DynamicResource Brush.TextMuted}"/>
|
||||
</Border>
|
||||
<Border Style="{StaticResource Pill}" ToolTip="Fattore di calibrazione: osservato/previsto sugli ultimi esempi. 1 = scala giusta">
|
||||
<TextBlock x:Name="PillCalibration" Text="—" FontSize="{StaticResource Font.Size.Sm}"
|
||||
Foreground="{DynamicResource Brush.TextMuted}"/>
|
||||
</Border>
|
||||
<Border x:Name="PillReadyBorder" Style="{StaticResource Pill}"
|
||||
ToolTip="Pronto = ha appreso abbastanza aste per fermare una puntata. Prima parla soltanto.">
|
||||
<TextBlock x:Name="PillReady" Text="—" FontSize="{StaticResource Font.Size.Sm}"
|
||||
Foreground="{DynamicResource Brush.Warning}"/>
|
||||
</Border>
|
||||
</StackPanel>
|
||||
|
||||
<StackPanel Grid.Column="2" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<Button x:Name="EvaluateButton" Style="{StaticResource SmallRoundedButton}"
|
||||
Background="{DynamicResource Brush.Accent}"
|
||||
Foreground="{DynamicResource Brush.TextOnAccent}"
|
||||
Content="Valuta ora" Margin="0,0,8,0"
|
||||
ToolTip="Addestra sui dossier più vecchi di questa macchina e giudica sui più recenti, mai visti. Poi la prova prequenziale: ogni asta prima prevista e poi appresa, come fa il motore. Qualche minuto in sottofondo."
|
||||
Click="EvaluateButton_Click"/>
|
||||
<Button x:Name="OpenFolderButton" Style="{StaticResource SmallRoundedButton}"
|
||||
Background="{DynamicResource Brush.SurfaceAlt}"
|
||||
Foreground="{DynamicResource Brush.Text}"
|
||||
Content="Apri cartella" Margin="0,0,8,0"
|
||||
ToolTip="La cartella con modello, profilo, elenco dei dossier letti e ultima valutazione"
|
||||
Click="OpenFolderButton_Click"/>
|
||||
<Button x:Name="RetrainButton" Style="{StaticResource SmallRoundedButton}"
|
||||
Background="{DynamicResource Brush.SurfaceAlt}"
|
||||
Foreground="{DynamicResource Brush.Danger}"
|
||||
Content="Ricomincia da capo"
|
||||
ToolTip="Butta modello e profilo e ristudia tutti i dossier. Non tocca i dossier né lo storico."
|
||||
Click="RetrainButton_Click"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!-- ═══ Corpo ═══ -->
|
||||
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto">
|
||||
<Grid Margin="12">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="12"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Stato -->
|
||||
<Border Grid.Row="0" Grid.Column="0" Style="{StaticResource CardBlock}">
|
||||
<StackPanel>
|
||||
<ctl:HelpHeader Title="Stato" Margin="0,0,0,10"
|
||||
Help="Il modello impara da ogni asta che chiude: per ogni puntata, è rimasta senza risposta? È l'unica etichetta abbondante — milioni di esempi — mentre le vittorie proprie sono poche decine. Il comportamento avversario non dipende da chi ha puntato, e questo rende utilizzabili le puntate altrui. Decide col valore atteso: probabilità appresa × margine residuo − costo della puntata. Sotto zero non punta, e lo scrive nel registro con i numeri. Decide solo dopo la soglia di aste apprese: prima parla soltanto."/>
|
||||
<UniformGrid Columns="3" Rows="2">
|
||||
<StackPanel Margin="0,0,8,10">
|
||||
<TextBlock x:Name="StatAuctions" Style="{StaticResource Stat}" Text="—"/>
|
||||
<TextBlock Style="{StaticResource StatLabel}" Text="aste apprese"/>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,0,8,10">
|
||||
<TextBlock x:Name="StatUpdates" Style="{StaticResource Stat}" Text="—"/>
|
||||
<TextBlock Style="{StaticResource StatLabel}" Text="esempi visti"/>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,0,8,10">
|
||||
<TextBlock x:Name="StatProfile" Style="{StaticResource Stat}" Text="—"/>
|
||||
<TextBlock Style="{StaticResource StatLabel}" Text="aste nel profilo"/>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,0,8,0">
|
||||
<TextBlock x:Name="StatCalibration" Style="{StaticResource Stat}" Text="—"/>
|
||||
<TextBlock Style="{StaticResource StatLabel}" Text="calibrazione (1 = giusta)"/>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,0,8,0">
|
||||
<TextBlock x:Name="StatThreshold" Style="{StaticResource Stat}" Text="—"/>
|
||||
<TextBlock Style="{StaticResource StatLabel}" Text="soglia per decidere"/>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="0,0,8,0">
|
||||
<TextBlock x:Name="StatBootstrap" Style="{StaticResource Stat}" Text="—"/>
|
||||
<TextBlock Style="{StaticResource StatLabel}" Text="studio dei dossier"/>
|
||||
</StackPanel>
|
||||
</UniformGrid>
|
||||
<TextBlock x:Name="StatDecisions" Style="{StaticResource Hint}" Margin="0,10,0,0" Text=""/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Cosa ha imparato -->
|
||||
<Border Grid.Row="0" Grid.Column="2" Style="{StaticResource CardBlock}">
|
||||
<StackPanel>
|
||||
<ctl:HelpHeader Title="Cosa ha imparato" Margin="0,0,0,10"
|
||||
Help="I pesi del modello, dal più forte. Positivo = quella condizione rende più probabile che una puntata resti senza risposta; negativo = meno probabile. Le variabili sono a fasce e il modello è lineare proprio per poterli leggere così. Il prodotto è ridotto a 32 cassetti con una funzione di hash: due prodotti possono condividere un cassetto, ed è accettato."/>
|
||||
<DataGrid x:Name="WeightsGrid" MaxHeight="260" IsReadOnly="True" HeadersVisibility="Column"
|
||||
AutoGenerateColumns="False" CanUserAddRows="False">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Condizione" Binding="{Binding Nome}" Width="*"/>
|
||||
<DataGridTextColumn Header="Peso" Binding="{Binding PesoDisplay}" Width="Auto" MinWidth="70"/>
|
||||
<DataGridTextColumn Header="Effetto" Binding="{Binding Effetto}" Width="Auto" MinWidth="110"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Ultime decisioni -->
|
||||
<Border Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Style="{StaticResource CardBlock}">
|
||||
<StackPanel>
|
||||
<ctl:HelpHeader Title="Ultime decisioni" Margin="0,0,0,10"
|
||||
Help="Ogni volta che il motore era pronto a puntare ha chiesto al modello. P è la probabilità che la puntata resti senza risposta; il valore atteso è P × margine residuo − costo. «Fermata» = il cancello ha detto no. «Parere» = il modello non aveva ancora appreso abbastanza per decidere, e si è limitato a dirlo."/>
|
||||
<DataGrid x:Name="DecisionsGrid" MaxHeight="280" IsReadOnly="True" HeadersVisibility="Column"
|
||||
AutoGenerateColumns="False" CanUserAddRows="False">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Ora" Binding="{Binding Ora}" Width="Auto" MinWidth="80"/>
|
||||
<DataGridTextColumn Header="Asta" Binding="{Binding Asta}" Width="*"/>
|
||||
<DataGridTextColumn Header="Prezzo" Binding="{Binding Prezzo}" Width="Auto" MinWidth="70"/>
|
||||
<DataGridTextColumn Header="P senza risposta" Binding="{Binding Prob}" Width="Auto" MinWidth="110"/>
|
||||
<DataGridTextColumn Header="Valore atteso" Binding="{Binding Ev}" Width="Auto" MinWidth="100"/>
|
||||
<DataGridTextColumn Header="Esito" Binding="{Binding Esito}" Width="Auto" MinWidth="90"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Profilo per prodotto -->
|
||||
<Border Grid.Row="2" Grid.Column="0" Style="{StaticResource CardBlock}">
|
||||
<StackPanel>
|
||||
<ctl:HelpHeader Title="Profilo per prodotto e fascia oraria" Margin="0,0,0,10"
|
||||
Help="Cosa aspettarsi prima che un'asta cominci: puntate del vincitore e prezzo di chiusura in percentuale del valore, per prodotto, fascia oraria e tipo di giorno. Solo le combinazioni con aste osservate; quando i dati sono pochi il motore restringe verso il prodotto e poi verso la media generale. Fasce: 0-8 notte e ore sospese · 9 · 10-12 · 13-17 · 18-20 · 21-23."/>
|
||||
<DataGrid x:Name="ProfileGrid" MaxHeight="320" IsReadOnly="True" HeadersVisibility="Column"
|
||||
AutoGenerateColumns="False" CanUserAddRows="False">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="Prodotto" Binding="{Binding Prodotto}" Width="*"/>
|
||||
<DataGridTextColumn Header="Fascia" Binding="{Binding Fascia}" Width="Auto" MinWidth="60"/>
|
||||
<DataGridTextColumn Header="Giorno" Binding="{Binding Giorno}" Width="Auto" MinWidth="60"/>
|
||||
<DataGridTextColumn Header="Aste" Binding="{Binding Aste}" Width="Auto" MinWidth="50"/>
|
||||
<DataGridTextColumn Header="Punt. vincitore" Binding="{Binding Puntate}" Width="Auto" MinWidth="100"/>
|
||||
<DataGridTextColumn Header="Chiusura" Binding="{Binding Chiusura}" Width="Auto" MinWidth="80"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
|
||||
<!-- Valutazione -->
|
||||
<Border Grid.Row="2" Grid.Column="2" Style="{StaticResource CardBlock}">
|
||||
<StackPanel>
|
||||
<ctl:HelpHeader Title="Ultima valutazione" Margin="0,0,0,10"
|
||||
Help="Il rapporto dell'ultima valutazione sui dossier di questa macchina. Le misure che contano: il sollevamento (quanto più spesso le puntate a probabilità alta erano davvero finali, rispetto al caso), la calibrazione per fasce (la probabilità prevista deve somigliare a quella osservata), e cosa il cancello avrebbe fatto sulle tue puntate vere."/>
|
||||
<TextBox x:Name="EvaluationBox" IsReadOnly="True" TextWrapping="NoWrap"
|
||||
MinHeight="200" MaxHeight="320"
|
||||
FontFamily="Consolas" FontSize="11.5"
|
||||
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
|
||||
Background="{DynamicResource Brush.SurfaceAlt}"
|
||||
Foreground="{DynamicResource Brush.Text}"
|
||||
BorderBrush="{DynamicResource Brush.Border}"
|
||||
Text="Nessuna valutazione ancora. Premi «Valuta ora»."/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
Reference in New Issue
Block a user