6.3 Rule List 2

Rule List 2 right

R figure

Code
c <- 1 
pos <- c*50 
neg <- 50  

rocgrid <- function() {
    plot( c(0,neg), c(0,pos),
         xlim=c(0,neg),ylim=c(0,pos),
         #asp = pos/neg,
         xaxs = "i",yaxs = "i",
         xaxt = 'n', yaxt = 'n',
         type = "n",
         xlab = "Negatives", ylab = "Positives")

    grid (nx = neg/10, ny = pos/10, col = gray(0.5))
    

}

box <- function(x0,y0,x1,y1,col) {
    lines(c(x0,x0,x1,x1,x0),c(y0,y1,y1,y0,y0),col=col,lty=1)}

metric <- function(tp,fp,Pos,Neg,m) {
  if (tp+fp == 0) { return(0) }
  else {

    N = Pos+Neg
    TP = tp
    FP = fp
    FN = Pos-TP
    TN = Neg-FP
    if (m=='accuracy') return( (TP+TN)/N ) 
    if (m=='wracc') return( TP/N - (TP+FP)*(TP+FN)/N^2 ) 
    if (m=='confirmation') return( ((TP+FP)*(FP+TN)/N^2 - FP/N)/(sqrt((TP+FP)*(FP+TN)/N^2) - (TP+FP)*(FP+TN)/N^2) ) 
    if (m=='generality') return( (TP+FP)/N ) 
    if (m=='precision') return( TP/(TP+FP) ) 
    if (m=='laplace-precision') return( (TP+10)/(TP+FP+20) ) 
    if (m=='f-measure') return( 2*TP/(2*TP+FP+FN) ) 
    if (m=='g-measure') return( TP/(FP+Pos) ) 
    if (m=='precision*recall') return( TP^2/((TP+FP)*(TP+FN)) ) 
    if (m=='avg-precision-recall') return( TP/(2*(TP+FP)) + TP/(2*(TP+FN)) ) 
    if (m=='aucsplit') return( (TP*Neg+Pos*TN)/(2*Pos*Neg) ) 
    if (m=='balanced-aucsplit') return( TP/Pos - FP/Neg ) 
    if (m=='chi2') return( (TP*TN - FP*FN)^2 / ((TP+FP)*(TP+FN)*(FP+TN)*(FN+TN)) ) 
    if (m=='info-gain') return( entropy(Pos,Neg) - (TP+FP)/N*entropy(TP,FP) - (FN+TN)/N*entropy(FN,TN) )
    if (m=='gini') return( gini(Pos,Neg) - (TP+FP)/N*gini(TP,FP) - (FN+TN)/N*gini(FN,TN) )
    if (m=='dkm') return( dkm(Pos,Neg) - (TP+FP)/N*dkm(TP,FP) - (FN+TN)/N*dkm(FN,TN) )
    if (m=='entropy') return( entropy(TP,FP)/2 )
    if (m=='giniimp') return( gini(TP,FP) )
    if (m=='dkmimp') return( dkm(TP,FP) )
    if (m=='minacc') return( minacc(TP,FP) )
  }
}

entropy <- function(P,N) {
  p <- P/(P+N)
  n <- N/(P+N)
  if (P==0 || N==0) { return( 0 ) }
  else { return( -p*log2(p) -n*log2(n) ) }
}

gini <- function(P,N) {
  p <- P/(P+N)
  n <- N/(P+N)
  return( 4*p*n )   
}

dkm <- function(P,N) {
  p <- P/(P+N)
  n <- N/(P+N)
  return( 2*sqrt(p*n) ) 
}

minacc <- function(P,N) {
  p <- P/(P+N)
  n <- N/(P+N)
  return( min(p,n) )    
}


save = FALSE

if (save==FALSE) {colour1="red"; colour2="blue"} else {colour1="black"; colour2="black"}

contours <- function(m,label) {
    x <- seq(0,neg)
    y <- seq(0,pos)
    z <- matrix(nrow=neg+1,ncol=pos+1)
    for (i in x) {
      for (j in y) {
        z[i+1,j+1] = metric(j,i,pos,neg,m)
      }
    }
    contour(x,y,z,nlevels=10,add=TRUE,col=colour1,lty="solid",method=label)
}

contour1 <- function(m,col,lty,tp,fp,Pos,Neg) {
    v <- metric(tp,fp,Pos,Neg,m)
    col=rgb(min(2-2*v,1),v,0)
    points(fp,tp,col=col,type='p',lwd=3)
    if (tp==0 || fp==0) { 
        lines(c(0,fp),c(0,tp),col=col,lty=lty,lwd=4)
        return() 
    }
    Pos <- tp
    Neg <- fp
    x <- seq(0,Neg)
    y <- seq(0,Pos)
    z <- matrix(nrow=Neg+1,ncol=Pos+1)
    for (i in x) {
      for (j in y) {
        z[i+1,j+1] = metric(j,i,Pos,Neg,m)
      }
    }
    v <- metric(tp,fp,Pos,Neg,m)
    contour(x,y,z,level=v,add=TRUE,col=col,lty=lty,labels="",lwd=2)
}

pos=50; neg=10;
rocgrid()
d = 1
method = 'precision'
colour = 'black'

p = 30; n =  0
arrows(neg-d,pos-d,n+d,p+d,col='violet',length=0.1,lwd=3)

contour1(method,'green','solid',  p,  n, pos, neg)
NULL
Code
contour1(method,'green','solid',20,  0, pos, neg)
NULL
Code
contour1(method,colour,'dotted',10, 10, pos, neg)
contour1(method,colour,'dotted',50, 10, pos, neg)
contour1(method,colour,'dotted',20, 10, pos, neg)

Python figure

Code
import numpy as np
import matplotlib.pyplot as plt

# Parâmetros iniciais
pos = 50
neg = 10

# Funções de métrica
def precision(tp, fp):
    return tp / (tp + fp) if (tp + fp) > 0 else 0

# Geração do grid e cálculo da métrica
def compute_metric_grid(metric_func, pos, neg):
    x = np.arange(0, neg + 1)
    y = np.arange(0, pos + 1)
    z = np.zeros((len(y), len(x)))
    for i, tp in enumerate(y):
        for j, fp in enumerate(x):
            z[i, j] = metric_func(tp, fp)
    return x, y, z

# Função de desenho principal
def draw_plot():
    fig, ax = plt.subplots(figsize=(8, 6))
    ax.set_xlim(0, neg)
    ax.set_ylim(0, pos)
    ax.set_xlabel('Negatives')
    ax.set_ylabel('Positives')
    ax.grid(True, which='both', linestyle='--', color='gray', alpha=0.5)

    p, n = 30, 0
    ax.arrow(neg - 1, pos - 1, n - (neg - 1), p - (pos - 1), 
             color='violet', head_width=0.3, length_includes_head=True, linewidth=2)

    def draw_contour(tp, fp, color, style='solid'):
        v = precision(tp, fp)
        if tp == 0 or fp == 0:
            ax.plot([0, fp], [0, tp], color=color, linestyle=style, linewidth=1)
            return
        sub_pos = tp
        sub_neg = fp
        x, y, z = compute_metric_grid(precision, sub_pos, sub_neg)
        cs = ax.contour(x, y, z, levels=[v], colors=[color], linestyles=[style])
    
    draw_contour(30, 0, 'green')
    draw_contour(20, 0, 'green')
    draw_contour(10, 10, 'black', 'dotted')
    draw_contour(50, 10, 'black', 'dotted')
    draw_contour(20, 10, 'black', 'dotted')

    plt.title('ROC Grid with Precision Contours')
    plt.tight_layout()
    plt.show()

draw_plot()

Rule List 2 left

Code
graph TD;
    34["true<br>[5+, 1-]"]
    38["Length=3<br>[2+, 0-]"]:::green
    76["Length=4<br>[1+, 1-]"]
    95["Length=5<br>[2+, 0-]"]:::green
    62["Gills=no<br>[5+, 1-]"]
    33["Beak=yes<br>[5+, 1-]"]
    32["Teeth=many<br>[3+, 0-]"]:::green
    45["Teeth=few<br>[2+, 1-]"]

    34 --> 32
    34 --> 33
    34 --> 38
    34 --> 45
    34 --> 62
    34 --> 76
    34 --> 95

    classDef green fill:#00a000,stroke:#000,stroke-width:1px;
graph TD;
    34["true<br>[5+, 1-]"]
    38["Length=3<br>[2+, 0-]"]:::green
    76["Length=4<br>[1+, 1-]"]
    95["Length=5<br>[2+, 0-]"]:::green
    62["Gills=no<br>[5+, 1-]"]
    33["Beak=yes<br>[5+, 1-]"]
    32["Teeth=many<br>[3+, 0-]"]:::green
    45["Teeth=few<br>[2+, 1-]"]

    34 --> 32
    34 --> 33
    34 --> 38
    34 --> 45
    34 --> 62
    34 --> 76
    34 --> 95

    classDef green fill:#00a000,stroke:#000,stroke-width:1px;