java实现Fmeasure计算_聚类结果的评估指标及其JAVA实现

一. 前言

又GET了一项技能。在做聚类算法的时候,由于要评估所提出的聚类算法的好坏,于是需要与一些已知的算法对比,或者用一些人工标注的标签来比较,于是用到了聚类结果的评估指标。我了解了以下几项。

TP:是指被聚在一类的两个量被正确的分类了(即在标准标注里属于一类的两个对象被聚在一类)

TN:是指不应该被聚在一类的两个对象被正确地分开了(即在标准标注里不是一类的两个对象在待测结果也没聚在一类)

FP:指不应该放在一类的对象被错误的放在了一类。(即在标准标注里不是一类,但在待测结果里聚在一类)

FN:指不应该分开的对象被错误的分开了。(即在标准标注里是一类,但在待测结果里没聚在一类)

P = TP + FP

N = TN + FN

1.准确率、识别率:(rank Index)  RI

accuracy = (TP + TN)/(P + N)

2.错误率、误分类率

error rate = (FP + FN)/(P + N)

3.敏感度

sensitivity = TP / P

4.特效性

specificity = TN / N

5.精度

precision = TP  /   (TP + FP)

6.召回率

recall  =  TP  /   (TP  + FN)

7.RI  其实就是  1  的 accuracy

8.F度量

fd89309172c8722546599b47fc5893f9.png

P为precision

R为recall

9.NMI(normalized mutual information)

712f3a1a557e41ba7864785ad2f5aa44.png

10 Jaccard

J = TP  / (TP + F)

二、JAVA实现(未优化)

其中很多重复代码,还没有优化。。。

package others;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

import javax.rmi.CORBA.Util;

import org.graphstream.algorithm.measure.NormalizedMutualInformation;

/*function:常用的聚类评价指标有purity, precision, recall, RI 和 F-score,jaccard

* @param:

* @author:Wenbao Li

* @Data:2015-07-13

*/

public class ClusterEvaluation {

public static void main(String[] args){

int[] A = {1,3,3,3,3,3,3,2,1,0,2,0,2,0,2,1,1,0,1,1};

int[] B = {2,2,0,0,0,3,2,2,3,1,3,1,0,1,2,1,0,1,3,3};

double purity = Purity(A,B);

System.out.println("purity\t\t"+purity);

System.out.println("Pre\t\t"+Precision(A,B));

System.out.println("Recall\t\t"+Recall(A,B));

System.out.println("RI(Accuracy)\t\t"+RI(A,B));

System.out.println("Fvalue\t\t"+F_score(A,B));

System.out.println("NMI\t\t"+NMI(A,B));

}

/*

* 计算一个聚类结果的簇的个数,以及每一簇中的对象个数,

*/

public static Map> clusterDistri(int[] A){

Map> clusterD = new HashMap>();

int max = -1;

for(int i = 0;i< A.length;i++){

if(max < A[i]){

max = A[i];

}

}

for(int i = 0;i< A.length;i++){

int temp = A[i];

if(temp < max+1){

if(clusterD.containsKey(temp)){

Set set = clusterD.get(temp);

set.add(i+1);

clusterD.put(temp, set);

}else{

Set set = new HashSet();

set.add(i+1);

clusterD.put(temp, set);

}

}

}

return clusterD;

}

public static double ClusEvaluate(String method,int[] A,int[] B){

switch(method){

case "Purity":

return Purity(A,B);

case "Precision":

return Precision(A,B);

case "Recall":

return Recall(A,B);

case "RI":

return RI(A,B);

case "F_score":

return F_score(A,B);

case "NMI":

return NMI(A,B);

case "Jaccard":

return Jaccard(A,B);

default:

return -1.0;

}

}

public static int[] commNum(Map> A,Map> B){

int[] commonNo = new int[A.size()];

int com = 0;

Iterator>> itA = A.entrySet().iterator();

int i = 0;

while(itA.hasNext()){

Entry> entryA = itA.next();

Set setA = entryA.getValue();

Iterator>> itB = B.entrySet().iterator();

int maxComm = -1;

while(itB.hasNext()){

Entry> entryB = itB.next();

Set setB = entryB.getValue();

int lengthA = setA.size();

Set temp = new HashSet(setA);

temp.removeAll(setB);

int lengthCom = lengthA - temp.size();

if(maxComm < lengthCom){

maxComm = lengthCom;

}

}

commonNo[i] = maxComm;

com = com + maxComm;

i++;

}

return commonNo;

}

/*

* 所有簇分配正确的除以总的。其中B是对比的标准标签。

*/

public static double Purity(int[] A,int[] B){

double value;

Map> clusterA = clusterDistri(A);

Map> clusterB = clusterDistri(B);

int[] commonNo = commNum(clusterA,clusterB);

int com = 0;

for(int i = 0;i

com = com + commonNo[i];

}

value = com*1.0/A.length;

return value;

}

/*

* @param A,B

* @return 精度

*/

public static double Precision(int[] A,int[] B){

double value = 0.0;

Map> clusterA = clusterDistri(A);//得到聚类结果A的类分布

Map> clusterB = clusterDistri(B);//得到聚类B(标准)的类分布

int[] commonNo = commNum(clusterA,clusterB);//得到A中每个簇中聚类正确的数目。

int allP = 0;

int TP = 0;

int FP = 0;

int TN = 0;

int FN = 0;

Iterator>> itA = clusterA.entrySet().iterator();

int i = 0;

while(itA.hasNext()){

Entry> entryA = itA.next();

allP = allP + combination(entryA.getValue().size(),2);

TP = TP + combination(commonNo[i],2);

i++;

}

FP = allP - TP;

itA = clusterA.entrySet().iterator();

while(itA.hasNext()){

Entry> entryA = itA.next();

Iterator>> itA2 = clusterA.entrySet().iterator();

while(itA2.hasNext()){

Entry> entryA2 = itA2.next();

if(entryA != entryA2){

Set s1 = entryA.getValue();

Set s2 = entryA2.getValue();

for(Integer i1 :s1){

for(Integer i2:s2){

if(B[i1-1] != B[i2-1]){

TN++;

}else{

FN++;

}

}

}

}

}

}

double P = TP*1.0/(TP + FP);

return P;

}

/*

* @param A,B

* @return recal召回率

*/

public static double Recall(int[] A,int[] B){

double value = 0.0;

Map> clusterA = clusterDistri(A);//得到聚类结果A的类分布

Map> clusterB = clusterDistri(B);//得到聚类B(标准)的类分布

int[] commonNo = commNum(clusterA,clusterB);//得到A中每个簇中聚类正确的数目。

int allP = 0;

int TP = 0;

int FP = 0;

int TN = 0;

int FN = 0;

Iterator>> itA = clusterA.entrySet().iterator();

int i = 0;

while(itA.hasNext()){

Entry> entryA = itA.next();

allP = allP + combination(entryA.getValue().size(),2);

TP = TP + combination(commonNo[i],2);

i++;

}

FP = allP - TP;

itA = clusterA.entrySet().iterator();

while(itA.hasNext()){

Entry> entryA = itA.next();

Iterator>> itA2 = clusterA.entrySet().iterator();

while(itA2.hasNext()){

Entry> entryA2 = itA2.next();

if(entryA != entryA2){

Set s1 = entryA.getValue();

Set s2 = entryA2.getValue();

for(Integer i1 :s1){

for(Integer i2:s2){

if(B[i1-1] != B[i2-1]){

TN++;

}else{

FN++;

}

}

}

}

}

}

double R = TP * 1.0/(TP + FN);

return R;

}

/*

* @param A,B

* @return RankIndex

*/

public static double RI(int[] A,int[] B){

double value = 0.0;

Map> clusterA = clusterDistri(A);//得到聚类结果A的类分布

Map> clusterB = clusterDistri(B);//得到聚类B(标准)的类分布

int[] commonNo = commNum(clusterA,clusterB);//得到A中每个簇中聚类正确的数目。

int P = 0;

int TP = 0;

int FP = 0;

int TN = 0;

int FN = 0;

Iterator>> itA = clusterA.entrySet().iterator();

int i = 0;

while(itA.hasNext()){

Entry> entryA = itA.next();

P = P + combination(entryA.getValue().size(),2);

TP = TP + combination(commonNo[i],2);

i++;

}

FP = P - TP;

itA = clusterA.entrySet().iterator();

while(itA.hasNext()){

Entry> entryA = itA.next();

Iterator>> itA2 = clusterA.entrySet().iterator();

while(itA2.hasNext()){

Entry> entryA2 = itA2.next();

if(entryA != entryA2){

Set s1 = entryA.getValue();

Set s2 = entryA2.getValue();

for(Integer i1 :s1){

for(Integer i2:s2){

if(B[i1-1] != B[i2-1]){

TN++;

}else{

FN++;

}

}

}

}

}

}

value = (TP + TN)*1.0/(TP + FP + FN + TN);

return value;

}

/*

* F值,是对精度和召回率的平衡,

* @param A:评估对象。B:评估标准;beta:均衡参数

* @return F值

*/

public static double F_score(int[] A,int[] B){

double beta = 1.0;

double value = 0.0;

Map> clusterA = clusterDistri(A);//得到聚类结果A的类分布

Map> clusterB = clusterDistri(B);//得到聚类B(标准)的类分布

int[] commonNo = commNum(clusterA,clusterB);//得到A中每个簇中聚类正确的数目。

int allP = 0;

int TP = 0;

int FP = 0;

int TN = 0;

int FN = 0;

Iterator>> itA = clusterA.entrySet().iterator();

int i = 0;

while(itA.hasNext()){

Entry> entryA = itA.next();

allP = allP + combination(entryA.getValue().size(),2);

TP = TP + combination(commonNo[i],2);

i++;

}

FP = allP - TP;

itA = clusterA.entrySet().iterator();

while(itA.hasNext()){

Entry> entryA = itA.next();

Iterator>> itA2 = clusterA.entrySet().iterator();

while(itA2.hasNext()){

Entry> entryA2 = itA2.next();

if(entryA != entryA2){

Set s1 = entryA.getValue();

Set s2 = entryA2.getValue();

for(Integer i1 :s1){

for(Integer i2:s2){

if(B[i1-1] != B[i2-1]){

TN++;

}else{

FN++;

}

}

}

}

}

}

double P = TP*1.0/(TP + FP);

double R = TP * 1.0/(TP + FN);

value = (beta*beta + 1)*P * R/(beta*beta*P + R);

return value;

}

public static double Jaccard(int[] A,int[] B){

double value = 0.0;

Map> clusterA = clusterDistri(A);//得到聚类结果A的类分布

Map> clusterB = clusterDistri(B);//得到聚类B(标准)的类分布

int[] commonNo = commNum(clusterA,clusterB);//得到A中每个簇中聚类正确的数目。

int allP = 0;

int TP = 0;

int FP = 0;

int TN = 0;

int FN = 0;

Iterator>> itA = clusterA.entrySet().iterator();

int i = 0;

while(itA.hasNext()){

Entry> entryA = itA.next();

allP = allP + combination(entryA.getValue().size(),2);

TP = TP + combination(commonNo[i],2);

i++;

}

FP = allP - TP;

itA = clusterA.entrySet().iterator();

while(itA.hasNext()){

Entry> entryA = itA.next();

Iterator>> itA2 = clusterA.entrySet().iterator();

while(itA2.hasNext()){

Entry> entryA2 = itA2.next();

if(entryA != entryA2){

Set s1 = entryA.getValue();

Set s2 = entryA2.getValue();

for(Integer i1 :s1){

for(Integer i2:s2){

if(B[i1-1] != B[i2-1]){

TN++;

}else{

FN++;

}

}

}

}

}

}

value = TP * 1.0 / (TP + FP + FN);

return value;

}

public static double NMI(int[] A,int[] B){

Map> clusterA = clusterDistri(A);//得到聚类结果A的类分布

Map> clusterB = clusterDistri(B);//得到聚类B(标准)的类分布

Iterator>> itA = clusterA.entrySet().iterator();

Iterator>> itB = clusterB.entrySet().iterator();

Set> partitionF = new HashSet>();

Set> partitionR = new HashSet>();

int nodeCount = B.length;

while(itA.hasNext()){

Entry> entryA = itA.next();

Set setA = entryA.getValue();

partitionF.add(setA);

setA = null;

entryA = null;

}

while(itB.hasNext()){

Entry> entryB = itB.next();

Set setB = entryB.getValue();

partitionR.add(setB);

setB = null;

entryB = null;

}

return computeNMI(partitionF,partitionR,nodeCount);

}

public static double computeNMI(Set> partitionF,

Set> partitionR,int nodeCount) {

int[][] XY = new int[partitionR.size()][partitionF.size()];

int[] X = new int[partitionR.size()];

int[] Y = new int[partitionF.size()];

int i = 0;

int j = 0;

for (Set com1 : partitionR) {

j = 0;

for (Set com2 : partitionF) {

XY[i][j] = intersect(com1, com2);//待测结果第i个簇和标准结果第j个簇的共有元素个数

X[i] += XY[i][j];//待测结果第i个簇与所有标准结果簇的公共元素个数(感觉就是第i个簇的元素个数)

Y[j] += XY[i][j];//标准结果簇第j个簇的元素个数()

j++;

}

i++;

}

int N = nodeCount;

double Ixy = 0;

double Ixy2 = 0;

for (i = 0; i < partitionR.size(); i++) {

for (j = 0; j < partitionF.size(); j++) {

if (XY[i][j] > 0) {

Ixy += ((double) XY[i][j] / N)

* (Math.log((double) XY[i][j] * N / (X[i] * Y[j])) / Math

.log(2.0));

//Ixy2 = (float) (Ixy2 + -2.0D * XY[i][j]

//* Math.log(XY[i][j] * N / X[i] * Y[j]));

}

}

}

//System.out.println(Ixy2);

//double denom = 0.0F;

//for (int ii = 0; ii < X.length; ++ii)

//denom = (double) (denom + X[ii] * Math.log(X[ii] / N));

//for (int jj = 0; jj < Y.length; ++jj) {

//denom = (double) (denom + Y[jj] * Math.log(Y[jj] / N));

//}

//

//System.out.println(denom);

//double M = (Ixy / denom);

//

//return M;

double Hx = 0;

double Hy = 0;

for (i = 0; i < partitionR.size(); i++) {

if (X[i] > 0)

Hx += h((double) X[i] / N);

}

for (j = 0; j < partitionF.size(); j++) {

if (Y[j] > 0)

Hy += h((double) Y[j] / N);

}

double InormXY = Ixy / Math.sqrt(Hx * Hy);

return InormXY;

}

private static double h(double p) {

return -p * (Math.log(p) / Math.log(2.0));

}

/*

* 两个集合的公共元素个数

*/

private static int intersect(Set com1, Set com2) {

int num = 0;

for (Integer v1 : com1) {

if (com2.contains(v1))

num++;

}

return num;

}

/*

* C(m,n)=m取n

*/

public static int combination(int m,int n){

int result = 1;

if(m < n){

return -1;

}

result = factorial(m)/(factorial(n)*factorial(m-n));

return result;

}

public static int factorial(int m){

if((m == 1) || (m == 0)){

return 1;

}else if(m < 0){

return -1;

}else{

return m*factorial(m-1);

}

}

}

5655742.html

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

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

相关文章

java窗体容器坐标_Java的屏幕坐标是以像素为单位的,容器的左下角被确定为坐标的起点。...

屏单位的的左定为的起点Despite ________ difficulties, they did not find the life in London unpleasant.幕坐As soon as I was ____________, I began to have second thoughts about leaving.标被确The girl was uncertain what to do, or what tone of voice to_________…

mysql 相同字段相减_mysql datetime 类型字段相减

背景&#xff1a;今天测试一个mariadb中datatime类型的字段相减问题&#xff0c;直接用2个字段相减得到的数值并不是秒&#xff0c;很坑。后面百度了一些方法&#xff0c;说是使用 DateDiff 函数&#xff0c;这个函数文档还说有3个参数&#xff0c;但是3个参数运行是报错的。要…

Java最短路径类型_JAVA 最短路径

1.从景石出发&#xff0c;步行游览以下景点:①游客服务中心&#xff0c;②阳光草坪&#xff0c;③森林小剧场&#xff0c;④儿童科普体验区&#xff0c;⑤儿童戏水场&#xff0c;⑥湿地博物馆&#xff0c;⑦湿地商业街。建立数学模型&#xff0c;找出从景石出发&#xff0c;到达…

php 开启,PHP服务的开启详细步骤

安装完php,使用chkconfig命令来查看php-fpm服务是否开启&#xff0c;如果没有开启1. 在/etc/init.d/目录下创建脚本php-fpmvim/etc/init.d/php-fpm2. 编写脚本内容(将一下复制进去相应改动安装路径)#!/bin/sh## php-fpm - this script starts and stops the php-fpm daemin## c…

linux下安装mysql5.7.19,Linux下MySQL5.1升级到高版本MySQL5.7.19详解 | zifangsky的个人博客...

一 数据备份(1)查看当前版本&#xff1a;Shell[rootcentos ~]# mysql -V1[rootcentos~]# mysql -V(2)备份数据&#xff1a;Shell[rootcentos ~]# mysqldump -u root -h 127.0.0.1 -P 3306 -p --all-databases > databases.sql1[rootcentos~]# mysqldump -u root -h 127.0.0.…

mysql event使用,用MySQL的Event设置定时任务执行sql语句 | 老疯子

想在每天某个特定时间段定时执行一条sql语句命令&#xff0c;来进行数据库的备份或者更新删除等&#xff0c;可以直接使用MySQL自带的定时任务Event事件来执行操作。需要注意的是Event事件是在MySQL 5.1版本中新增的&#xff0c;还有一点就是确保你有MySQL数据库的root管理权限…

MATLAB设置x为0到10所有数,MATLAB教学_10数值微积分

本文学习视频地址&#xff1a;https://www.bilibili.com/video/av68228488?p10课堂PPT以及本人学习代码已上传。本文学习内容&#xff1a;多项式的微分和积分数值的微分和积分目录多项式的表示方法polyval()polyder()16分钟练习conv()polyint()Numerical Differentiation39分钟…

php header 404 nginx,ThinkPHP在nginx下怎么设置?路由统统404,疯了~

本地用MAMP跑的代码&#xff0c;运行没问题。但是部署到CENTOS 6.8 NGINX服务器上的时候&#xff0c;路由地址都404了&#xff01;[可以访问] http://something.com/API/public/index.php[404] http://something.com/API/public/index.php/consult_add折腾一晚上了。。简直了&a…

php strchr 截断,PHP strchr() 函数

w3school 教程PHP String 函数查找 "world" 在 "Hello world!" 中的第一次超并返回此字符串的其余个别&#xff1a;echo strchr("Hello world!","world");?>运行实例strchr() 函数搜他串在另一字符串中的第一次常该函数是 strstr(…

matlab aic sic,sic是什么意思_sic的翻译_音标_读音_用法_例句_爱词霸在线词典

全部In the mud -- En ange e il mondo ! [ sic ] ( 6 )污泥里 —— Efangoeilmondo! ( 六 )汉英文学 - 围城Fixed - seal & rotational - seal are made of various msterials, SIC, Carbon, Ceramic and can withstand various chemicals.固定环 及 转动环由各种不同材质…

win7卸载oracle12c,Windows7上完全卸载Oracle 12c操作步骤

Windows7上完全卸载Oracle 12c操作步骤1.关闭Oracle所有的服务,按【winR】运行【services.msc】找到所有Oracle开头的服务(OracleVssWriterORCLOracleServiceORCLOracleOraDB12Home1TNSListenerOracleOraDB12Home1MTSRecoveryServiceOracleJobSchedulerORCL),点击停止。2.使用O…

linux怎样扩容目录,Linux系统下对目录扩容的方法介绍

1、现象&#xff1a;日志服务器当初考虑不周&#xff0c;分区划分不太合理&#xff1a;2、目标&#xff1a;将/home磁盘空间缩减 并将新的磁盘分区扩充到/根目录卸载/home分区并压缩分区卸载/home时 提示目标忙&#xff0c;fuser -m /home查看谁用/home时提示没有fuser命令[ro…

linux多线程九宫格,项目实战:Qt九宫格图片资源浏览器(支持window、linux、兼容各国产系统,支持子文件夹,多选,全选,图片预览,行数与列数设置等)...

需求做嵌入式设备&#xff0c;需求九宫格图片资源浏览器&#xff1a;1.设置根目录&#xff1b;2.可拖动&#xff1b;3.可设置列数与行数&#xff1b;4.点击文件夹可以进入文件夹&#xff1b;5.点击图片可以浏览图片&#xff1b;6.支持触摸屏上下拽拖浏览&#xff1b;7.支持长安…

window连接树莓派linux桌面,远程连接Raspberry Pi(树莓派)图形用户界面(X Window)

背景&#xff1a;有的时候&#xff0c;我们希望能远程连接一台linux的图形界面用来管理机器,这里需要用到tightvncserver和xtightvncviewer两个工具我的树莓派的ip是10.141.247.134 另一台机器为作client去链接树莓派的ip为10.141.247.121. 先在树莓派的机器上安装tightvncs…

linux小红帽系统能用微信,小红帽腾讯QQ微信登录版-小红帽腾讯版v1.0.3 安卓版-腾牛安卓网...

小红帽腾讯版是一款专为广大喜爱玩童话类手游的玩家打造的欧美风游戏&#xff0c;这款游戏有着最为精致的游戏画面&#xff0c;黑色风格的童话故事&#xff0c;带领玩家领略不一样的童年世界&#xff0c;给您带来最佳的游戏体验&#xff01;小红帽腾讯版简介《小红帽》是一款改…

计算机二级c语言2021年重点内容,2021年5月计算机二级C语言试题(总)

一个考生的快乐&#xff0c;不是因为他备考的时间多&#xff0c;而是因为他的选择对。选择考无忧题库&#xff0c;做二级C语言试题&#xff0c;助你备考轻松&#xff01;二级C语言试题【1】1.若有以下数组说明&#xff0c;则i10;a[a[i]]元素数值是(C)。int a[12]{1,4,7,10,2,5,…

android 图片合成pdf文件,教你怎么把多张图片合成一个pdf文件

当你遇到需要把多张图片合并成一个pdf文件时&#xff0c;你需要怎么做?可能有些朋友会说下载一个pdf格式转换工具&#xff0c;其实不必这么麻烦&#xff0c;你只要把文件上传到在线迅捷pdf转换器&#xff0c;就可以一站式帮你搞定pdf文件的格式转换以及一些常用的功能操作(如p…

华为系统鸿蒙优势,华为鸿蒙2.0可以替代安卓吗,华为鸿蒙2.0优势在哪

在华为开发者大会上&#xff0c;华为消费业务CEO 余承东&#xff0c;正式发布鸿蒙OS2.0&#xff0c;并宣布华为鸿蒙OS将全面启用全场景生态&#xff0c;并将于2020年12月发布手机版。余承东还表示&#xff0c;明年&#xff0c;华为的智能手机将全面升级&#xff0c;以支持鸿蒙操…

网页自动关机代码HTML,win10系统打开邮件显示网页html源代码如何解决

有不少win10系统用户在打开邮件的时候&#xff0c;发现内容全是显示网页的html源代码&#xff0c;无法看到内容&#xff0c;遇到这样的问题该怎么办呢&#xff0c;通常是自带的"邮件和日历"应用暂时不支持查看HTML格式的邮件&#xff0c;下面给大家分享一下具体的解决…

retrofit 2.0 android 教程,初识Retrofit2.0

Retrofit无疑是当下最流行的Android网络请求框架了&#xff0c;是Square提供的开源产品。官方网站是这样介绍Retrofit的—-A type-safe HTTP client for Android and Java&#xff0c;为Android平台的应用提供一个类型安全的HTTP客户端。Retrofit 是一套注解形式的网络请求封装…