java计算混淆矩阵(分类指标:查准率P,查全率R,P和R的调和均值F1,正确率A)

【0】README

本文使用 java 计算混淆矩阵,并利用 混淆矩阵值计算 分类指标;通用分类指标有: 查准率,查全率,查准率和查全率的调和均值F1值,正确率, AOC, AUC等;本文计算前4个指标;(附源代码和结果截图)


【1】什么是混淆矩阵(借用自己PPT截图)


【2】查准率和查全率的区别

查准率:查准率表示选出的样本中有多少比例样本是正例(期望样本);

查全率:查全率表示有多少比例的正样本(期望样本)被选出来了;


【3】如何计算多分类混淆矩阵的评价指标(摘自周志华老师的机器学习,极力推荐大家买一本



【4】源码如下

// 计算混淆矩阵,并根据混淆矩阵计算 10次交叉验证下的 评估指标均值(精确度, 召回率, F值, 准确率 这4个指标) 
public class SingleConfusionMatrix {
//	C:\Users\pacoson\Desktop\confusion_matrixprivate static String dir = "C:" + File.separator + "Users" + File.separator + "pacoson" + File.separator + "Desktop" + File.separator + "confusion_matrix";private static double[][][] averages = new double[10][3][4]; // 10次交叉验证, 3个unknown(12, 24, 48),4个度量指标(查全率,查准率,F1,准确率)private static int fold = 0;private static int counter = 6;public static void main(String[] args) {File file = new File(dir);showFiles();}// show files. public static void showFiles() {File[] files = new File(dir).listFiles();  for(File file: files) {  // 遍历 dir 目录下的所有文件String filename = file.getName(); String prefix = filename.split("_")[0]; if(prefix.length() > 1) continue;fold = Integer.valueOf(prefix); // 10次交叉验证的编号System.out.println("\n====== fold=" + fold + "======"); double[][] array = new double[100][6]; // item 数组DataRead reader = new DataRead(file.getAbsolutePath());	reader.readDataToArray(1, 1, array); // 数据读取完毕 computeConfusion(0, array); // 预测长度12
//			computeConfusion(1, array); // 预测长度24
//			computeConfusion(2, array); // 预测长度48break;}
//		computeAverage();}// column = 1(12), 2(24), 3(48)static void computeConfusion(int column, double[][] array) { // 1.计算confusion12/24/48: TP FN FP TNint[][] confusions = new int[6][4];counter = 6;for (int id = 0; id < 6; id++) {for (int i = 0; i < array.length; i++) {if(array[i][column] == id) {if(array[i][column+3] == id) // column = 1(12), 2(24), 3(48)confusions[id][0]++; // TPelseconfusions[id][1]++; // FN} else if(array[i][column] != id) {if(array[i][column+3] == id)confusions[id][2]++; // FPelseconfusions[id][3]++; // TN}}}// 2.计算 统计指标: // 精确度P=TP/(TP+FP), 查准率// 召回率R= TP/(TP+FN), 查全率// f1值=2*P*R/(P+R)// 准确率=(TP+TN)/(TP+FN+FP+TN)double[][] metrices = new double[6][4]; // 精确度, 召回率, F1值, 分类准确率for (int i = 0; i < confusions.length; i++) { double[] metric = metrices[i];int[] confusion = confusions[i];System.out.print("confusion matrix: TP, FN, FP, TN: ");for (int j = 0; j < confusion.length; j++) { // 打印每个混淆矩阵System.out.print(confusion[j] + ", ");}System.out.println();if(confusion[0] + confusion[2] != 0) // 分母不能为零.metric[0] =  (double)confusion[0] / (confusion[0] + confusion[2]); // 精确度if(confusion[0] + confusion[1] != 0) // 分母不能为零.metric[1] =  (double)confusion[0] / (confusion[0] + confusion[1]); // 召回率if(metric[0] + metric[1] != 0) // 分母不能为零.metric[2] =  (double)2*metric[0]*metric[1]/(metric[0] + metric[1]); // f值metric[3] =  (double)(confusion[0]+confusion[3]) / (confusion[0] + confusion[1]+ confusion[2]+ confusion[3]); // 准确率if(confusion[3] == 100) { // 如果 TN == 100, 表明没有这个类成员(TN表示真实类别不是该类别且预测类别也不是该类别,那如果总数为100,则没有模型没有选出该类别)。metric[3] = 0;counter--;}}// 3.求均值(宏精确度, 宏召回率, 宏F1值, 宏准确率)
//		double[] average = new double[4];
//		private static double[][][] averages = new double[10][3][4]; // 10次交叉验证, 3个unknown(12, 24, 48),4个度量指标(查全率,查准率,F1,准确率)
//		double[][] metrices = new double[6][4]; // 精确度, 召回率, F1值, 分类准确率double[] average = averages[fold][column];System.out.println("counter = " + counter);for (int j = 0; j < metrices[0].length; j++) {double sum = 0;for (int i = 0; i < metrices.length; i++) {sum += metrices[i][j];}average[j] = sum/counter;System.out.print(average[j] + " ");}System.out.println();}public static void computeAverage() {System.out.println("\n ===  计算10折交叉验证的统计指标均值  === \n");// 预测长度为 12(j==0), 24(j==1), 48(j==2)for (int j = 0; j < 3; j++) { 			for (int k = 0; k < averages[0][0].length; k++) { // 4 个 itemsdouble sum = 0;for (int i = 0; i < averages.length; i++) { // 行(10折) sum += averages[i][j][k];}System.out.print(sum/10 + " ");}System.out.println();}}
} 




Tips: 10次交叉验证实验,只需要调用其中的 computeAverage() 方法 就可以计算 其10次的均值了。(这里只求出了某次交叉实验的均值)


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

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

相关文章

什么是CPU密集型、IO密集型?

转载自 什么是CPU密集型、IO密集型&#xff1f;CPU密集型&#xff08;CPU-bound&#xff09; CPU密集型也叫计算密集型&#xff0c;指的是系统的硬盘、内存性能相对CPU要好很多&#xff0c;此时&#xff0c;系统运作大部分的状况是CPU Loading 100%&#xff0c;CPU要读/写I/O(硬…

Properties类与IO流

1.概念 Properties是Map的子类&#xff0c;是一个双列集合&#xff0c;键和值都是字符串类型。Map集合的方法它都能使用&#xff1b; 但是推荐是Properties自己特有的方法&#xff0c;对集合进行操作。 2.特有方法 //properties属于Map集合【该集合一般添加字符串键值对】 /…

什么是无监督学习(监督学习,半监督学习,无监督聚类)?

作者&#xff1a;王丰 链接&#xff1a;https://www.zhihu.com/question/23194489/answer/25028661 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 这个问题可以回答得很简单&#xff1a;是否有监督&#xff08;sup…

Java中的6颗语法糖

转载自 Java中的6颗语法糖语法糖&#xff08;Syntactic Sugar&#xff09;&#xff0c;也称糖衣语法&#xff0c;指在计算机语言中添加的某种语法&#xff0c;这种语法对语言本身功能来说没有什么影响&#xff0c;只是为了方便程序员的开发&#xff0c;提高开发效率。说白了&am…

其他流总述

1.转换流 InputStreamReader: 把InputStream转换为Reader&#xff0c;可以指定编码表 OutputStreamWriter: 把OutputStream转换为Writer&#xff0c;可以指定编码表 //转换流[用于指定编码表读入或写出] public class Demo1 {public static void main(String[] args) throws …

如何查阅相关工作所用到的文献资料

以百度学术为例。 step1&#xff1a;百度学术里输入 最关键的paper 名称&#xff0c;并点击 被引量链接&#xff1b; step2&#xff1a;通过最近年份 或 其他条件 筛选paper &#xff08;注意看发表期刊或会议的级别&#xff09; step3&#xff1a;主要看paper的摘要或 intro&…

递归算法介绍及Java应用实战

转载自 递归算法介绍及Java应用实战 什么是递归算法 递归算法是把问题转化为规模缩小了的同类问题的子问题&#xff0c;然后递归调用函数&#xff08;或过程&#xff09;来表示问题的解。一个过程(或函数)直接或间接调用自己本身&#xff0c;这种过程(或函数)叫递归过程(或函数…

K最近邻分类器

转自&#xff1a; http://www.cnblogs.com/qwertWZ/p/4582096.html 本章介绍了《机器学习实战》这本书中的第一个机器学习算法&#xff1a;k-近邻算法&#xff0c;它非常有效而且易于掌握。首先&#xff0c;我们将探讨k-近邻算法的基本理论&#xff0c;以及如何使用距离测量的方…

多线程安全问题1

1.问题的产生 原因&#xff1a;多个线程操作同一个共享数据。 原理&#xff1a;多个线程在访问共享数据时&#xff0c;由于CPU的随机性&#xff0c;一个线程还没有执行完&#xff0c;执行权被其他线程抢走了&#xff0c;这个时候就有可能出现线程安全问题。 解决方式&#xff…

Java父类强制转换子类原则

转载自 Java父类强制转换子类原则最近&#xff0c;微信群友在讨论子类父类的转换问题&#xff0c;其实不难&#xff0c;给大家用实例来说明一下就很明了了。 我们知道Java中子类转换成父类是没有任何问题的&#xff0c;那父类可以转换成子类吗&#xff1f; 来看下面这段程序&am…

生产者和消费者案例

1.案例描述 这里以吃饭为例&#xff0c;假设有一个桌子&#xff0c;用来存汉堡包&#xff0c;然后有厨师和消费者&#xff0c;厨师往桌子上放汉堡包&#xff0c;消费者从桌子上取走汉堡包。当两者在一个时间段同时进行多次自己的操作时&#xff0c;很明显这就是多线程编程的生…

用Python开始机器学习(4:KNN分类算法)

转自&#xff1a; http://blog.csdn.net/lsldd/article/details/41357931 1、KNN分类算法 KNN分类算法&#xff08;K-Nearest-Neighbors Classification&#xff09;&#xff0c;又叫K近邻算法&#xff0c;是一个概念极其简单&#xff0c;而分类效果又很优秀的分类算法。 他的…

Mybatis传递多个参数的4种方式

转载自 Mybatis传递多个参数的4种方式&#xff08;干货&#xff09;现在大多项目都是使用Mybatis了&#xff0c;但也有些公司使用Hibernate。使用Mybatis最大的特性就是sql需要自己写&#xff0c;而写sql就需要传递多个参数。面对各种复杂的业务场景&#xff0c;传递参数也是一…

多线程安全问题2

1.volatile关键字 <1>作用&#xff1a;强制线程每次在使用的时候,都会看一下共享区域最新的值[用于提供线程安全] <2>与synchronized的区别和联系&#xff1a; 把代码块声明为 synchronized&#xff0c;有两个重要后果&#xff0c;通常是指该代码具有 原子性&…

Maven Optional Exclusions使用区别

转载自 Maven Optional & Exclusions使用区别 Optional和Exclusions都是用来排除jar包依赖使用的&#xff0c;两者在使用上却是相反。 Optional定义后&#xff0c;该依赖只能在本项目中传递&#xff0c;不会传递到引用该项目的父项目中&#xff0c;父项目需要主动引用该依赖…

为什么jdk的CLASSPATH环境变量需要设置rt.jar 和 tools.jar

How Classes are Found 中有说明&#xff1a;&#xff08;java启动类文件在 rt.jar中&#xff0c; 而 工具类文件在 tools.jar 中&#xff09; How the Java Launcher Finds Classes The Java launcher, java, initiates the Java virtual machine. The virtual machine searc…

线程池的实现

1.创建线程池 API提供了一个工具类叫Executors&#xff0c;可以用它的方法生成不同特点的线程池&#xff0c;返回一个ExecutorService对象。 <1>Executors.newCachedThreadPool() 【池子中默认是空的&#xff0c;最多可以容纳int类型的最大值】 <3>Executors.new…

JSON Web Token (JWT),服务端信息传输安全解决方案

转载自 JSON Web Token (JWT)&#xff0c;服务端信息传输安全解决方案JWT介绍 JSON Web Token(JWT)是一种开放标准(RFC 7519)&#xff0c;它定义了一种紧凑独立的基于JSON对象在各方之间安全地传输信息的方式。这些信息可以被验证和信任&#xff0c;因为它是数字签名的。JWTs可…

thinking-in-java(18) java io

【0】README&#xff1a;本篇文章是以 thinking in java 为基础梳理的&#xff1b; 【18.1.1 目录列表器】 // 传入正则表达式以过滤文件名如 (.*src)* public class DirList {public static void main(String[] args) {File path new File(".");String[] list; i…

并发工具类【线程安全相关的类】

1.Hashtable和ConcurrentHashMap Hashtable&#xff1a;哈希表结构&#xff08;数组链表&#xff09;&#xff0c;线程安全的(同步代码块&#xff0c;效率低) ConcurrentHashMap&#xff1a; jdk7:采用Segment数组[不会扩容] HashEntry[二次哈希计算存入的位置,可扩容]&#…