基于WPF开发动态可交互混淆矩阵

news/2025/4/1 23:48:39/文章来源:https://www.cnblogs.com/hsiang/p/18227765

最近在项目中,为了算法结果的可视化,需要用到混淆矩阵(Confusion Matrix),而网上资源大多是基于Python绘制的混淆矩阵,并且是输出图片格式,并不能响应用户点击,今天以一个简单的小例子,简述如何通过WPF绘制混淆矩阵,并可响应用户点击事件,仅供学习分享使用,如有不足之处,还请指正。

 


什么是混淆矩阵?

 

在机器学习中, 混淆矩阵是一个误差矩阵, 常用来可视化地评估监督学习算法的性能. 混淆矩阵大小为 (n_classes, n_classes) 的方阵, 其中 n_classes 表示类的数量. 这个矩阵的每一行表示真实类中的实例, 而每一列表示预测类中的实例 (Tensorflow 和 scikit-learn 采用的实现方式). 也可以是, 每一行表示预测类中的实例, 而每一列表示真实类中的实例 (Confusion matrix From Wikipedia 中的定义). 通过混淆矩阵, 可以很容易看出系统是否会弄混两个类, 这也是混淆矩阵名字的由来.

混淆矩阵是一种特殊类型的列联表(contingency table)或交叉制表(cross tabulation or crosstab). 其有两维 (真实值 "actual" 和 预测值 "predicted" ), 这两维都具有相同的类("classes")的集合. 在列联表中, 每个维度和类的组合是一个变量. 列联表以表的形式, 可视化地表示多个变量的频率分布. 

对于应用程序开发人员而言,混淆矩阵就是一个二维数组,分别表示预测值和真实值,里面的值表示对应值的占比。

 

开发步骤

 

创建WPF应用程序项目

 

在了解了混淆矩阵的用途和原理后,就可以着手去开发,首先创建一个WPF应用程序项目,然后创建模型MatrixM,主要包括标题,x轴,y轴的标签和刻度说明,数据,颜色设置。如下所示:

public class MatrixM:ObservableObject
{private string title;public string Title { get { return title; } set { SetProperty(ref title, value); } }private string xLabel;public string XLabel { get { return xLabel; } set { SetProperty(ref xLabel, value); } }private string yLabel;public string YLabel { get { return yLabel; } set { SetProperty(ref yLabel,value); } }private string[] yaxis;public string[] Yaxis { get { return yaxis; } set { SetProperty(ref yaxis, value); } }private string[] xaxis;public string[] Xaxis { get { return xaxis; } set { SetProperty(ref xaxis, value); } }public double[,] Data { get; set; }private Color minBrush;public Color MinBrush { get { return minBrush; } set { SetProperty(ref minBrush, value); } }private Color maxBrush;public Color MaxBrush { get { return maxBrush; } set { SetProperty(ref maxBrush, value); } }
}

注意:在本示例中,矩阵的数据采用二维数组进行存储。

 

构造数据

 

构造示例数据,在实际开发中,数据来源于算法的真实分析,本例主要用于演示前端开发,所以构造一些测试数据,如下所示:

private MatrixM dataM;
public MatrixM DataM { get { return dataM; } set { SetProperty(ref dataM,value); } }private UniformGrid matrix;public MainWindowViewModel()
{this.DataM = new MatrixM();this.DataM.Title = "Confusion  Matrix on Fer2024";this.DataM.XLabel = "Predict Label";this.DataM.YLabel = "Truth Label";this.DataM.Xaxis = new string[] { "Angry","Disgust","Fear","Happy","Sad","Surprise","Neutral"};this.DataM.Yaxis = new string[] { "Angry", "Disgust", "Fear", "Happy", "Sad", "Surprise", "Neutral" };this.DataM.MinBrush = Colors.White;this.DataM.MaxBrush= Colors.DarkSlateBlue;this.DataM.Data = new double[,] {{0.66,0.01,0.09,0.04,0.11,0.01,0.09 },{0.23,0.64,0.0,0.04,0.09,0.0,0.0},{0.08,0.0,0.58,0.02,0.15,0.08,0.1},{0.01,0.0,0.01,0.89,0.01,0.02,0.06 },{0.09,0.0,0.11,0.03,0.6,0.01,0.15},{0.02,0.0,0.05,0.04,0.02,0.85,0.02 },{0.05,0.0,0.04,0.07,0.11,0.01,0.72 }};
}

 

页面布局

 

在WPF中,为了弹性呈现数据及自动缩放,主要用Grid,UniformGrid进行页面布局,交互主要用Button来实现,都是基础知识。如下所示:

<Grid><Grid.ColumnDefinitions><ColumnDefinition Width="Auto"></ColumnDefinition><ColumnDefinition Width="*"></ColumnDefinition><ColumnDefinition Width="Auto"></ColumnDefinition></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition Height="Auto"></RowDefinition><RowDefinition></RowDefinition><RowDefinition Height="Auto"></RowDefinition></Grid.RowDefinitions><TextBlock Text="{Binding DataM.Title}" FontSize="20" FontWeight="Bold" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5"></TextBlock><TextBlock Text="{Binding DataM.YLabel}" Grid.Row="1" Grid.Column="0" FontWeight="Bold" FontSize="14" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5"><TextBlock.LayoutTransform><RotateTransform Angle="270"></RotateTransform></TextBlock.LayoutTransform></TextBlock><Grid Grid.Row="1" Grid.Column="1"><Grid.RowDefinitions><RowDefinition Height="*"></RowDefinition><RowDefinition Height="Auto"></RowDefinition></Grid.RowDefinitions><Grid.ColumnDefinitions><ColumnDefinition Width="Auto"></ColumnDefinition><ColumnDefinition Width="*"></ColumnDefinition><ColumnDefinition Width="Auto"></ColumnDefinition></Grid.ColumnDefinitions><ItemsControl Grid.Row="0" Grid.Column="0" Grid.RowSpan="1" ItemsSource="{Binding DataM.Yaxis}"><ItemsControl.ItemsPanel><ItemsPanelTemplate><UniformGrid Columns="1"></UniformGrid></ItemsPanelTemplate></ItemsControl.ItemsPanel><ItemsControl.ItemTemplate><DataTemplate><StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right"><TextBlock Text="{Binding}"></TextBlock><Border Width="10" Height="1" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Right" Margin="10 0 0 0"></Border></StackPanel></DataTemplate></ItemsControl.ItemTemplate></ItemsControl><Border BorderBrush="Black" BorderThickness="1" Grid.Row="0" Grid.Column="1" ><UniformGrid x:Name="matrix" ><UniformGrid.Resources><Style TargetType="Button"><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Opacity" Value="0.5"></Setter><Setter Property="FontWeight" Value="Bold"></Setter><Setter Property="FontSize" Value="16"></Setter><Setter Property="Cursor" Value="Hand"></Setter></Trigger></Style.Triggers></Style></UniformGrid.Resources></UniformGrid></Border><ItemsControl Grid.Row="1" Grid.Column="1" ItemsSource="{Binding DataM.Xaxis}"><ItemsControl.ItemsPanel><ItemsPanelTemplate><UniformGrid Rows="1"></UniformGrid></ItemsPanelTemplate></ItemsControl.ItemsPanel><ItemsControl.ItemTemplate><DataTemplate><StackPanel Orientation="Vertical" VerticalAlignment="Top" HorizontalAlignment="Center"><Border Width="10" Height="1" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Center" Margin="0 0 0 0"><Border.RenderTransformOrigin><Point X="0.5" Y="0.5"></Point></Border.RenderTransformOrigin><Border.LayoutTransform><TransformGroup><RotateTransform Angle="90"></RotateTransform></TransformGroup></Border.LayoutTransform></Border><TextBlock Text="{Binding}"><TextBlock.RenderTransformOrigin><Point X="0.5" Y="0.5"></Point></TextBlock.RenderTransformOrigin><TextBlock.LayoutTransform><TransformGroup><RotateTransform Angle="-45"></RotateTransform><TranslateTransform Y="20"></TranslateTransform></TransformGroup></TextBlock.LayoutTransform></TextBlock></StackPanel></DataTemplate></ItemsControl.ItemTemplate></ItemsControl><Rectangle  Grid.Row="0" Grid.Column="2" Width="20" Margin="10 0"><Rectangle.Fill><LinearGradientBrush StartPoint="0 0" EndPoint="1 1"><GradientStop Offset="0" Color="{Binding DataM.MaxBrush}"></GradientStop><GradientStop Offset="1" Color="{Binding DataM.MinBrush}"></GradientStop></LinearGradientBrush></Rectangle.Fill></Rectangle></Grid><TextBlock Text="{Binding DataM.XLabel}" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" FontWeight="Bold" FontSize="14" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="5"></TextBlock></Grid>

 

注意:标题,刻度,轴说明 ,都是固定布局,可以进行数据绑定,而矩阵内容需要动态创建,所以分开处理。

 

构造矩阵

 

在本示例中,混淆矩阵以UniformGrid为容器,动态根据数据创建,并填充到容器中,如下所示:

private IRelayCommand<object> loadedCommand;public IRelayCommand<object> LoadedCommand =>loadedCommand??=new RelayCommand<object>(Loaded);private void Loaded(object obj)
{if (obj != null){var win = obj as MainWindow;if (win != null){this.matrix = win.matrix;InitMatrix();}}
}private void InitMatrix()
{if(this.matrix == null){return;}this.matrix.Children.Clear();this.matrix.Rows = this.DataM.Data.GetLength(0);this.matrix.Columns = this.DataM.Data.GetLength(1);var color = this.DataM.MaxBrush;for(int row = 0; row < this.DataM.Data.GetLength(0); row++){for(int col = 0; col < this.DataM.Data.GetLength(1); col++){Border border = new Border();border.Background = new SolidColorBrush(Color.FromArgb((byte)(this.DataM.Data[row, col] * color.A), color.R, color.G, color.B));var button = new Button();button.Content = this.DataM.Data[row, col].ToString("0.00");button.FontSize = 12;button.HorizontalContentAlignment= System.Windows.HorizontalAlignment.Center;button.VerticalContentAlignment= System.Windows.VerticalAlignment.Center;button.Background = Brushes.Transparent;button.BorderThickness = new System.Windows.Thickness(0);border.Child= button;this.matrix.Children.Add(border);}}
}

注意,在Grid,UniformGrid此类容器中,控件不需要设置宽和高,会自动根据容器大小进行自适应。且不能设置对齐属性,否则控件大小则不会自适应调整大小。

 

示例效果

 

运行VS,实例效果如下所示:

以上就是【基于WPF开发动态可交互混淆矩阵】的全部内容。希望可以一起学习,共同进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/719499.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OOP课程第二次Blog

一、 前言 本次博客是对于题目集4~6的总结和反思。 知识点 本阶段题目集的主要考察的知识点是继承和多态,继承包括对super、extend关键字的使用,方法的重写等,多态包括向上转型、向下转型等。此外还考察了抽象类和接口及之前的封装性,需要我们有抽象类的能力。在设计上考察…

task6

// P286例8.17 // 对教材上的程序作了微调整,把输出学生信息单独编写成一个函数模块 // 打印不及格学生信息和所有学生信息程分别调用 #include <stdio.h> #include <string.h> #define N 3 // 运行程序输入测试时,可以把这个数组改小一些输入测试 typedef str…

Git操作指南:多人协作提交代码的规范

操作指南 以TortoiseGit以例,多人或多台电脑之间同步协作少用git pull,而是要通过以下方法右键 点击 git sync,选择 Fetch & Rebase 等待Fetch完之后,在弹出来的选项中选择Rebase 在Rebase窗口,点击Start RebaseFetch这步可以换成pull吗?因为rebase的时候,也是要mer…

LitCTF2024——ezrc4

0x01 关于rc4 rc4简介 rc4的维基 具体实现 step1 rc4_init() void rc4_init(unsigned char* s_box,unsigned char* key) {int i=0,j=0;char k[256];int len=strlen(key);for(i=0;i<256;i++){//以256填充s盒s[i]=i;//使用key循环填充kk[i]=key[i%len];}//打乱s盒for(i=0;i<…

不存在的图片

流程 查看图片特征 --> 查看图片表面信息 --> 利用010查看二进制信息 --> 利用format检测 --> 利用Stegdetect检测 --> 解密图片16进制文件倒置脚本 整体字符反向输出 with open("n.png","rb") as f:t = f.read()for i in t[::-1]:a = hex(…

static和final关键字

一. static关键字1.被static修饰的变量/方法属于类变量/方法,可以通过类名.变量/方法直接调用,不用new一个类出来原因:静态方法是与类相关联的,而不是与类的实例相关联的。静态方法被加载到内存中的类区域,并且在类加载的过程中就会被初始化,不需要等到创建类的实例时才初…

hive搭建+问题解决

hive-3.1.2分布式搭建文档谷歌浏览器下载网址:Google Chrome – Download the fast, secure browser from Google 华为云镜像站:https://mirrors.huaweicloud.com/home1、上传解压配置环境变量 # 1、解压 tar -zxvf apache-hive-3.1.2-bin.tar.gz -C /usr/local/soft/# 2、重…

e语言 获取重定向的location地址

demo本文来自博客园,作者:__username,转载请注明原文链接:https://www.cnblogs.com/code3/p/18229890

osg使用整理(11):延迟渲染

osg使用整理(11):延迟渲染 一、基础概念前向渲染流程:顶点着色器->图元装配成点线三角形->几何着色器->裁剪剔除->光栅化(片元着色器)->透明度测试、深度测试。延迟渲染流程:顶点着色器->图元装配成点线三角形->几何着色器->裁剪剔除->光栅化…

龙哥量化:期货软件中红红绿绿的多开,空开,空平,多平,多换,空换,双开,双平,换手是什么意思?(转载的)

期货投资者在看盘时,会看到红红绿绿的"多开,空开,空平,多平,多换,空换,双开,双平,换手",以快期专业版为例,如下图1所示:图1.红绿开平数据(快期专业版) 这些数据里面的红色和绿色是什么意思呢?红色表示主动买,绿色表示主动卖吗?多开,空开,多平,双…

6.3深圳安服面试

公司概况、企业文化、自己应聘职位的特点、工作内容 业务产品、研究领域,国家专精特新小巨人 安全咨询、培训、运营三位一体的网络安全综合服务,总部广州;业务: 等保,密评,风险评估,监测、巡检、渗透、应急、培训; 提供解决方案; 安全评估:包括主机漏扫、基线检查、渗…

CTFshow-Crypto(17-25)

17EZ_avbv(easy) 18贝斯多少呢 base62穷举分段 给了段编码,hint为base62 8nCDq36gzGn8hf4M2HJUsn4aYcYRBSJwj4aE0hbgpzHb4aHcH1zzC9C3IL随波逐流和Cyberchef都没梭哈出来 看了师傅们的wp大概意思是: 分组长度固定,但是不一定是被整除为整数,只要找到从头开始截取一个长度解…