<# .SYNOPSIS Analizza i CSV prodotti da capture-features.ps1. .DESCRIPTION Per ogni file riporta: - distribuzione delle etichette emesse; - media delle feature NORMALIZZATE (cio' che il classificatore vede davvero); - media dei punteggi grezzi per classe e il divario rispetto alla vincente. Serve a rispondere a "perche' sbaglia su questo genere" invece di ritoccare i pesi a caso. .PARAMETER Csv Uno o piu' file CSV. Il nome del file viene usato come etichetta. .PARAMETER SkipSeconds Righe iniziali da scartare (warm-up del folding ritmico). .EXAMPLE powershell -ExecutionPolicy Bypass -File tools\analyze-features.ps1 -Csv C:\temp\rock.csv,C:\temp\hiphop.csv #> param( [Parameter(Mandatory = $true)][string[]]$Csv, [int]$SkipSeconds = 16 ) $featureNames = @( "dembow", "fourFloor", "tempo(latin)", "lowRatio", "flatness", "highRatio", "density", "centroid", "regularity", "regMid", "dynamics" ) $classCols = @("s_latin", "s_electronic", "s_hiphop", "s_rock", "s_classical") foreach ($path in $Csv) { if (-not (Test-Path $path)) { Write-Host "manca: $path" -ForegroundColor Yellow; continue } $all = @(Import-Csv $path) $rows = @($all | Select-Object -Skip $SkipSeconds) if ($rows.Count -eq 0) { Write-Host "nessuna riga utile in $path" -ForegroundColor Yellow; continue } Write-Host "" Write-Host ("=== {0} ({1} righe utili) ===" -f (Split-Path -Leaf $path), $rows.Count) -ForegroundColor Cyan Write-Host "etichette:" $rows | Group-Object label | Sort-Object Count -Descending | ForEach-Object { Write-Host (" {0,-11} {1,3} ({2:P0})" -f $_.Name, $_.Count, ($_.Count / $rows.Count)) } Write-Host "feature normalizzate (media):" for ($i = 0; $i -lt $featureNames.Count; $i++) { $col = "f{0}_*" -f $i $name = ($rows[0].PSObject.Properties.Name | Where-Object { $_ -like $col } | Select-Object -First 1) if (-not $name) { continue } $avg = ($rows | Measure-Object -Property $name -Average).Average $bar = "#" * [int]([math]::Round($avg * 30)) Write-Host (" {0,-14} {1,5:F2} {2}" -f $featureNames[$i], $avg, $bar) } Write-Host "punteggi grezzi (media):" $scores = @{} foreach ($c in $classCols) { $scores[$c] = ($rows | Measure-Object -Property $c -Average).Average } $best = ($scores.GetEnumerator() | Sort-Object Value -Descending | Select-Object -First 1) foreach ($c in $classCols) { $v = $scores[$c] $gap = $v - $best.Value $color = if ($c -eq $best.Key) { "Green" } else { "Gray" } Write-Host (" {0,-14} {1,5:F2} ({2,6:F2})" -f $c.Substring(2), $v, $gap) -ForegroundColor $color } } Write-Host "" Write-Host "Nota: 'dynamics' alta premia classical; 'flatness' bassa penalizza rock;" Write-Host " 'tempo(latin)' e' zero fuori da 85-105 BPM."