Estrategías One-Vs-One y One-Vs-Rest#

  • Algunas técnicas, como la regresión logística, permiten resolver problemas de clasificación dicotómica, pero en la práctica, muchos de los problemas reales son multiclase.

  • La teoría está basada en el supuesto de que únicamente existen dos clases dicotómicas C_1 y C_2. En la realidad pueden existir más de dos clases, por lo que existen diversas estrategias comúnmente utilizadas para convertir un problema de varias clases en un problema dicotómico.

  • One-Vs-Rest: Esta estrategia consiste en construir un clasificador por clase. Para un problema con tres clases, se construye un clasificador que decide si el patrón presentado pertenece a la clase C_1 o al resto (C_2 o C_3), otro si pertenece a C_2 o al resto, y finalmente otro para diferenciar entre C_3 y el resto. En esta estructura existen puntos del espacio de entrada que no pertencen a ninguna clase. Supongamos que hay tres clases A, B y C, y un patrón x que pertenece a C, entonces:

    • x \in A?, No (pertence a B o a C).

    • x \in B?, No, entonces x \in C.

  • One-Vs-One: Se construye un clasificador por cada par de clases y la clasificación se realiza seleccionando la clase que recibe más votos. Si se tienen tres clases, se constuirian clasificadores para diferenciar entre las siguientes parejas de clases (C_1, C_2), (C_1, C_3) y (C_2, C_3). Supongamos que hay tres clases A, B y C, y un patrón x que pertenece a C, entonces:

    • x \in A o x \in B?, supongamos que se concluye que x \in B.

    • x \in A o x \in C?, se concluye que x \in C.

    • x \in B o x \in C?, se concluye que x \in C.

    • B recibe un punto y C recibe dos puntos, por tanto, x \in C.

[1]:
%%writefile data.csv
x1,x2,y
1,1,A
1,2,A
1,3,A
1,4,A
2,1,A
2,2,B
2,3,B
2,4,B
3,1,B
3,2,B
3,3,C
3,4,C
4,1,B
4,2,B
4,3,C
4,4,C
Overwriting data.csv
[2]:
import pandas as pd

df = pd.read_csv(
    "data.csv",
    sep=",",
    thousands=None,
    decimal=".",
)
[3]:
from sklearn.linear_model import LogisticRegression
from sklearn.multiclass import OneVsOneClassifier, OneVsRestClassifier

X = df[["x1", "x2"]].values
y = df.y

y_one_vs_the_rest = (
    OneVsRestClassifier(LogisticRegression(solver="lbfgs", multi_class="ovr"))
    .fit(X, y)
    .predict(X)
)

y_one_vs_one = (
    OneVsOneClassifier(LogisticRegression(solver="lbfgs", multi_class="ovr"))
    .fit(X, y)
    .predict(X)
)

pd.DataFrame(
    {"real": df.y, "one-vs-rest": y_one_vs_the_rest, "one-vs-one": y_one_vs_one}
)
[3]:
real one-vs-rest one-vs-one
0 A A A
1 A A A
2 A A A
3 A A A
4 A B A
5 B B B
6 B B B
7 B C B
8 B B B
9 B B B
10 C B B
11 C C C
12 B B B
13 B B B
14 C C C
15 C C C