double auc(const dvec_t& dec_values, const ivec_t& ty){ double roc = 0; size_t size = dec_values.size(); size_t i; std::vector<size_t> indices(size); for(i = 0; i < size; ++i) indices[i] = i; std::sort(indices.begin(), indices.end(), Comp(&dec_values[0])); int tp = 0,fp = 0; for(i = 0; i < size; i++) { if(ty[indices[i]] == 1) tp++; else if(ty[indices[i]] == -1) { roc += tp; fp++; } } if(tp == 0 || fp == 0) { fprintf(stderr, "warning: Too few postive true labels or negative true labels\n"); roc = 0; } else roc = roc / tp / fp; printf("AUC = %g\n", roc); return roc; }
double bac(const dvec_t& dec_values, const ivec_t& ty){ size_t size = dec_values.size(); size_t i; int tp, fp, fn, tn; double specificity, recall; double bac; tp = fp = fn = tn = 0; for(i = 0; i < size; ++i) if(dec_values[i] >= 0 && ty[i] == 1) ++tp; else if(dec_values[i] >= 0 && ty[i] == -1) ++fp; else if(dec_values[i] < 0 && ty[i] == 1) ++fn; else ++tn; if(tn + fp == 0){ fprintf(stderr, "warning: No negative true label.\n"); specificity = 0; }else specificity = tn / (double)(tn + fp); if(tp + fn == 0){ fprintf(stderr, "warning: No positive true label.\n"); recall = 0; }else recall = tp / (double)(tp + fn); bac = (specificity + recall) / 2; printf("BAC = %g\n", bac); return bac; }
double gmean(const dvec_t& dec_values, const ivec_t& ty){ size_t size = dec_values.size(); size_t i; int tp, fp, fn, tn; double specificity, recall; double gmean; tp = fp = fn = tn = 0; for(i = 0; i < size; ++i) if(dec_values[i] >= 0 && ty[i] == 1) ++tp; else if(dec_values[i] >= 0 && ty[i] == -1) ++fp; else if(dec_values[i] < 0 && ty[i] == 1) ++fn; else ++tn; if(tn + fp == 0){ fprintf(stderr, "warning: No negative true label.\n"); specificity = 0; }else specificity = tn / (double)(tn + fp); if(tp + fn == 0){ fprintf(stderr, "warning: No positive true label.\n"); recall = 0; }else recall = tp / (double)(tp + fn); gmean = sqrt(specificity * recall); printf("sensitivity = %g, specificity = %g, g-mean = %g\n", recall, specificity, gmean); return gmean; }
double bac(const dvec_t& dec_values, const ivec_t& ty){ size_t size = dec_values.size(); size_t i; int tp, fp, fn, tn; double specificity, recall; double bac; tp = fp = fn = tn = 0; for(i = 0; i < size; ++i) if(dec_values[i] >= 0 && ty[i] == 1) ++tp; else if(dec_values[i] >= 0 && ty[i] == -1) ++fp; else if(dec_values[i] < 0 && ty[i] == 1) ++fn; else ++tn; if(tn + fp == 0){ fprintf(stderr, "warning: No negative true label.\n"); specificity = 0; }else specificity = tn / (double)(tn + fp); if(tp + fn == 0){ fprintf(stderr, "warning: No positive true label.\n"); recall = 0; }else recall = tp / (double)(tp + fn); bac = (specificity + recall) / 2; // Precision and recall double pos_prec = ((double)tp/(double)(tp + fp)); double pos_rec = ((double)tp/(double)(tp + fn)); double pos_f1 = (2 * pos_prec * pos_rec) / (pos_prec + pos_rec); double neg_prec = ((double)tn/(double)(tn + fn)); double neg_rec = ((double)tn/(double)(tn + fp)); double neg_f1 = (2 * neg_prec * neg_rec) / (neg_prec + neg_rec); printf("Positive Male (+1) class:\n"); printf(" TP = %d\n", tp ); printf(" FN = %d\n", fn ); printf(" FP = %d\n", fp ); printf(" TN = %d\n", tn ); printf(" precision = %g\n", pos_prec ); printf(" recall = %g\n", pos_rec ); printf(" F1 value = %g\n\n", pos_f1 ); printf("Negative Female (-1) class:\n"); printf(" TP = %d\n", tn ); printf(" FN = %d\n", fp ); printf(" FP = %d\n", fn ); printf(" TN = %d\n", tp ); printf(" precision = %g\n", neg_prec ); printf(" recall = %g\n", neg_rec ); printf(" F1 value = %g\n\n", neg_f1 ); // printf("BAC = %g\n", bac); return bac; }
double precision(const dvec_t& dec_values, const ivec_t& ty){ size_t size = dec_values.size(); size_t i; int tp, fp; double precision; tp = fp = 0; for(i = 0; i < size; ++i) if(dec_values[i] >= 0){ if(ty[i] == 1) ++tp; else ++fp; } if(tp + fp == 0){ fprintf(stderr, "warning: No postive predict label.\n"); precision = 0; }else precision = tp / (double) (tp + fp); printf("Precision = %g%% (%d/%d)\n", 100.0 * precision, tp, tp + fp); return precision; }
double recall(const dvec_t& dec_values, const ivec_t& ty){ size_t size = dec_values.size(); size_t i; int tp, fn; // true_positive and false_negative double recall; tp = fn = 0; for(i = 0; i < size; ++i) if(ty[i] == 1){ // true label is 1 if(dec_values[i] >= 0) ++tp; // predict label is 1 else ++fn; // predict label is -1 } if(tp + fn == 0){ fprintf(stderr, "warning: No postive true label.\n"); recall = 0; }else recall = tp / (double) (tp + fn); // print result in case of invocation in prediction printf("Recall = %g%% (%d/%d)\n", 100.0 * recall, tp, tp + fn); return recall; // return the evaluation value }
double fscore(const dvec_t& dec_values, const ivec_t& ty){ size_t size = dec_values.size(); size_t i; int tp, fp, fn; double precision, recall; double fscore; tp = fp = fn = 0; for(i = 0; i < size; ++i) if(dec_values[i] >= 0 && ty[i] == 1) ++tp; else if(dec_values[i] >= 0 && ty[i] == -1) ++fp; else if(dec_values[i] < 0 && ty[i] == 1) ++fn; if(tp + fp == 0){ fprintf(stderr, "warning: No postive predict label.\n"); precision = 0; }else precision = tp / (double) (tp + fp); if(tp + fn == 0){ fprintf(stderr, "warning: No postive true label.\n"); recall = 0; }else recall = tp / (double) (tp + fn); if(precision + recall == 0){ fprintf(stderr, "warning: precision + recall = 0.\n"); fscore = 0; }else fscore = 2 * precision * recall / (precision + recall); printf("F-score = %g\n", fscore); return fscore; }