scikit-learn - export_graphviz - randomforestclassifier
¿Qué hace `sample_weight` en la forma en que funciona` DecisionTreeClassifier` en sklearn? (1)
Así que dediqué un poco de tiempo a mirar la fuente de sklearn porque en realidad he querido tratar de resolver esto por un tiempo ahora también. Me disculpo por la duración, pero no sé cómo explicarlo más brevemente.
Algunos preliminares rápidos:
Digamos que tenemos un problema de clasificación con las clases K. En una región de espacio característico representada por el nodo de un árbol de decisión, recuerde que la "impureza" de la región se mide al cuantificar la falta de homogeneidad, utilizando la probabilidad de la clase en esa región. Normalmente, estimamos:
Pr(Class=k) = #(examples of class k in region) / #(total examples in region)
La medida de impureza toma como entrada, la matriz de probabilidades de clase:
[Pr(Class=1), Pr(Class=2), ..., Pr(Class=K)]
y escupe un número que le dice cuán "impura" o cuán heterogénea es la región del espacio característico. Por ejemplo, la medida de gini para un problema de dos clases es 2*p*(1-p)
, donde p = Pr(Class=1)
y 1-p=Pr(Class=2)
.
Ahora, básicamente, la respuesta corta a tu pregunta es:
sample_weight
aumenta las estimaciones de probabilidad en la matriz de probabilidad ... lo que aumenta la medida de impureza ... que aumenta la forma en que se dividen los nodos ... lo que aumenta la forma en que se construye el árbol ... lo que aumenta el espacio de funciones para la clasificación.
Creo que esto se ilustra mejor con el ejemplo.
Primero considere el siguiente problema de clase 2 donde las entradas son de 1 dimensión:
from sklearn.tree import DecisionTreeClassifier as DTC
X = [[0],[1],[2]] # 3 simple training examples
Y = [ 1, 2, 1 ] # class labels
dtc = DTC(max_depth=1)
Entonces, buscaremos árboles con solo un nodo raíz y dos hijos. Tenga en cuenta que la impureza predeterminada mide la medida de gini.
Caso 1: sin sample_weight
dtc.fit(X,Y)
print dtc.tree_.threshold
# [0.5, -2, -2]
print dtc.tree_.impurity
# [0.44444444, 0, 0.5]
El primer valor en el conjunto de threshold
nos dice que el primer ejemplo de entrenamiento se envía al nodo secundario izquierdo, y los ejemplos de entrenamiento segundo y tercero se envían al nodo secundario derecho. Los dos últimos valores en el threshold
son marcadores de posición y deben ignorarse. El conjunto de impurity
nos dice los valores de impureza calculados en los nodos padre, izquierdo y derecho, respectivamente.
En el nodo padre, p = Pr(Class=1) = 2. / 3.
, de modo que gini = 2*(2.0/3.0)*(1.0/3.0) = 0.444....
También puede confirmar las impurezas del nodo hijo.
Caso 2: con sample_weight
Ahora, intentemos:
dtc.fit(X,Y,sample_weight=[1,2,3])
print dtc.tree_.threshold
# [1.5, -2, -2]
print dtc.tree_.impurity
# [0.44444444, 0.44444444, 0.]
Puedes ver que el umbral de la función es diferente. sample_weight
también afecta la medida de impureza en cada nodo. Específicamente, en las estimaciones de probabilidad, el primer ejemplo de entrenamiento se cuenta del mismo modo, el segundo se cuenta como el doble y el tercero se cuenta como el triple, debido a los pesos de muestra que hemos proporcionado.
La impureza en la región del nodo padre es la misma. Esto es solo una coincidencia Podemos calcularlo directamente:
p = Pr(Class=1) = (1+3) / (1+2+3) = 2.0/3.0
La medida de gini de 4/9
sigue.
Ahora, puede ver desde el umbral elegido que el primer y el segundo ejemplo de entrenamiento se envían al nodo secundario izquierdo, mientras que el tercero se envía a la derecha. Vemos que se calcula que la impureza es 4/9
también en el nodo secundario izquierdo porque:
p = Pr(Class=1) = 1 / (1+2) = 1/3.
La impureza de cero en el niño correcto se debe a un solo ejemplo de entrenamiento que se encuentra en esa región.
Puede ampliar esto con valores de muestra no enteros de forma similar. Recomiendo probar algo como sample_weight = [1,2,2.5]
y confirmar las impurezas calculadas.
¡Espero que esto ayude!
He leído de esta documentación que:
"El equilibrio de clases se puede hacer muestreando un número igual de muestras de cada clase, o preferiblemente normalizando la suma de los pesos de muestra (sample_weight) para cada clase con el mismo valor".
Pero, todavía no está claro cómo funciona esto. Si configuro sample_weight
con una matriz de solo dos valores posibles, 1
y 2
, ¿esto significa que las muestras con 2
muestras se muestrearán dos veces más que las muestras con 1
cuando se realiza el embolsado? No puedo pensar en un ejemplo práctico para esto.