python - scikit.predict() umbral predeterminado
.predict python (5)
Estoy trabajando en un problema de clasificación con clases desbalanceadas (5% de 1). Quiero predecir la clase, no la probabilidad.
En un problema de clasificación binaria, ¿scikit''s classifier.predict()
usa 0.5
de forma predeterminada? Si no es así, ¿cuál es el método predeterminado? Si lo hace, ¿cómo lo cambio?
En scikit algunos clasificadores tienen la class_weight=''auto''
, pero no todos lo hacen. Con class_weight=''auto''
, ¿ .predict()
usaría la proporción de población real como un umbral?
¿Cuál sería la forma de hacerlo en un clasificador como MultinomialNB
que no es compatible con class_weight
? Aparte de usar predict_proba()
y luego calcular las clases yo mismo.
¿es scikit''s
classifier.predict()
usando 0.5 por defecto?
En clasificadores probabilísticos, sí. Es el único umbral sensible desde un punto de vista matemático, como otros han explicado.
¿Cuál sería la forma de hacerlo en un clasificador como MultinomialNB que no es compatible con
class_weight
?
Puede establecer class_prior
, que es la probabilidad previa P ( y ) por clase y . Eso efectivamente cambia el límite de decisión. P.ej
# minimal dataset
>>> X = [[1, 0], [1, 0], [0, 1]]
>>> y = [0, 0, 1]
# use empirical prior, learned from y
>>> MultinomialNB().fit(X,y).predict([1,1])
array([0])
# use custom prior to make 1 more likely
>>> MultinomialNB(class_prior=[.1, .9]).fit(X,y).predict([1,1])
array([1])
0.5 no está relacionado con la proporción de la población de ninguna manera. Es una salida de probabilidad. No hay un "umbral", si una clase tiene una probabilidad de 0.51, entonces parece ser la clase más probable. 0.5 si siempre es el que se debe usar *, y ningún paquete utiliza un "umbral" diferente. Si sus puntajes de probabilidad son * exactos y verdaderamente representativos *, entonces siempre debe elegir la clase más probable . Hacer lo contrario solo puede reducir su precisión. Dado que estamos utilizando varios algoritmos que hacen suposiciones, no sabemos que la probabilidad sea cierta, pero iría en contra de las suposiciones hechas por su modelo.
Estás confundido sobre lo que class_weight hace. Cambiar el peso de clase aumenta los pesos para los puntos de datos en las clases menos representadas (/ decreciente para la clase sobre representada) para que el "peso" de cada clase sea igual, como si tuvieran la misma cantidad de ejemplos positivos y negativos. Este es un truco común para tratar de evitar un clasificador que siempre vota por la clase más común. Debido a esto, ambas clases son igualmente comunes desde la vista del algoritmo de aprendizaje.
- NOTA: si tiene miedo a los falsos positivos / falsos negativos, puede elegir aceptar solo una clase si su probabilidad cumple con un cierto valor mínimo. Pero eso no cambia cómo se hace el aprendizaje, y esa dosis no cambia el significado detrás de una probabilidad.
El umbral en scikit learn es 0.5 para la clasificación binaria y la clase que tenga la mayor probabilidad de clasificación multiclase. En muchos problemas, se puede obtener un resultado mucho mejor ajustando el umbral. Sin embargo, esto debe hacerse con cuidado y NO en los datos de la prueba retenida, sino mediante validación cruzada de los datos de entrenamiento. Si realiza algún ajuste del umbral en sus datos de prueba, simplemente está sobreajustando los datos de prueba.
La mayoría de los métodos de ajuste del umbral se basan en las características de funcionamiento del receptor (ROC) y la estadística J de Youden, pero también se puede hacer mediante otros métodos, como una búsqueda con un algoritmo genético.
Aquí hay un artículo de una revista de revisión por pares que describe cómo hacer esto en medicina:
http://www.ncbi.nlm.nih.gov/pmc/articles/PMC2515362/
Hasta donde sé, no hay paquete para hacerlo en Python, pero es relativamente simple (pero ineficiente) encontrarlo con una búsqueda de fuerza bruta en Python.
Este es un código R que lo hace.
## load data
DD73OP <- read.table("/my_probabilites.txt", header=T, quote="/"")
library("pROC")
# No smoothing
roc_OP <- roc(DD73OP$tc, DD73OP$prob)
auc_OP <- auc(roc_OP)
auc_OP
Area under the curve: 0.8909
plot(roc_OP)
# Best threshold
# Method: Youden
#Youden''s J statistic (Youden, 1950) is employed. The optimal cut-off is the threshold that maximizes the distance to the identity (diagonal) line. Can be shortened to "y".
#The optimality criterion is:
#max(sensitivities + specificities)
coords(roc_OP, "best", ret=c("threshold", "specificity", "sensitivity"), best.method="youden")
#threshold specificity sensitivity
#0.7276835 0.9092466 0.7559022
En caso de que alguien visite este hilo esperando la función lista para usar (Python 2.7). En este ejemplo, el punto de corte está diseñado para reflejar la relación de eventos a no eventos en el conjunto de datos original df , mientras que y_prob podría ser el resultado del método .predict_proba (suponiendo un tren estratificado / división de prueba).
def predict_with_cutoff(colname, y_prob, df):
n_events = df[colname].values
event_rate = sum(n_events) / float(df.shape[0]) * 100
threshold = np.percentile(y_prob[:, 1], 100 - event_rate)
print "Cutoff/threshold at: " + str(threshold)
y_pred = [1 if x >= threshold else 0 for x in y_prob[:, 1]]
return y_pred
Siéntase libre de criticar / modificar. Espero que ayude en casos raros cuando el equilibrio de clases está fuera de discusión y el conjunto de datos en sí es altamente desequilibrado.
Parece que estás confundiendo conceptos aquí. El umbral no es un concepto para un "clasificador genérico": los enfoques más básicos se basan en un umbral ajustable, pero la mayoría de los métodos existentes crean reglas complejas para la clasificación que no pueden (o al menos no deberían) ser vistas como un umbral.
Entonces, primero, uno no puede responder su pregunta sobre el umbral predeterminado del clasificador de scikit porque no existe tal cosa.
La ponderación de segunda clase no se trata del umbral, se trata de la capacidad del clasificador para tratar clases desbalanceadas, y es algo dependiente de un clasificador particular. Por ejemplo, en el caso de SVM, es la forma de ponderar las variables de holgura en el problema de optimización, o si lo prefiere, los límites superiores para los valores de los multiplicadores de lagrange conectados con clases particulares. Establecer esto en ''auto'' significa usar alguna heurística por defecto, pero una vez más, no se puede traducir simplemente a un umbral.
Naive Bayes, por otro lado, estima directamente la probabilidad de las clases del conjunto de entrenamiento. Se llama "clase previa" y puede establecerlo en el constructor con la variable "class_prior".
De la documentation :
Probabilidades previas de las clases. Si se especifica, los priores no se ajustan según los datos.