Saltar al contenido

Diferencia entre cross_val_score y cross_val_predict

Tenemos la mejor solución que encontramos en todo internet. Nuestro deseo es que te resulte útil y si quieres compartir alguna mejora siéntete libre de hacerlo..

Solución:

cross_val_score devuelve la puntuación del pliegue de la prueba donde cross_val_predict devuelve los valores y predichos para el pliegue de prueba.

Para el cross_val_score(), está utilizando el promedio de la salida, que se verá afectada por el número de pliegues porque entonces puede tener algunos pliegues que pueden tener un error alto (no encajar correctamente).

Mientras que, cross_val_predict() devuelve, para cada elemento de la entrada, la predicción que se obtuvo para ese elemento cuando estaba en el conjunto de prueba. [Note that only cross-validation strategies that assign all elements to a test set exactly once can be used]. Por lo tanto, el aumento del número de pliegues solo aumenta los datos de entrenamiento para el elemento de prueba y, por lo tanto, su resultado puede no verse muy afectado.

Editar (después del comentario)

Por favor, eche un vistazo a la siguiente respuesta sobre cómo cross_val_predict obras:

¿Cómo se calcula la puntuación de precisión de scikit-learn cross_val_predict?

pienso que cross_val_predict estará sobreajustado porque a medida que aumenten los pliegues, más datos serán para entrenar y menos para pruebas. Entonces, la etiqueta resultante depende más de los datos de entrenamiento. Además, como ya se dijo anteriormente, la predicción para una muestra se realiza solo una vez, por lo que puede ser susceptible a la división de datos más. Es por eso que la mayoría de los lugares o tutoriales recomiendan usar el cross_val_score para analizar.

Entonces, esta pregunta también me molestó y, aunque la otra hizo buenos puntos, no respondieron todos los aspectos de la pregunta de OP.

El true La respuesta es: La divergencia en las puntuaciones para aumentar k se debe a la métrica elegida R2 (coeficiente de determinación). Por ejemplo, MSE, MSLE o MAE no habrá ninguna diferencia en el uso cross_val_score o cross_val_predict.

Vea la definición de R2:

R ^ 2 = 1 – (MSE (verdad fundamental, predicción) / MSE (verdad fundamental, significar (verdad fundamental)))

La parte en negrita explica por qué la puntuación comienza a diferir al aumentar k: cuantas más divisiones tenemos, menos muestras en el pliegue de prueba y mayor es la varianza en la media del pliegue de prueba. Por el contrario, para k pequeño, la media del pliegue de prueba no diferirá mucho de la media de verdad del terreno completo, ya que el tamaño de la muestra es todavía lo suficientemente grande como para tener una pequeña varianza.

Prueba:

import numpy as np
from sklearn.metrics import mean_absolute_error as mae
from sklearn.metrics import mean_squared_log_error as msle, r2_score

predictions = np.random.rand(1000)*100
groundtruth = np.random.rand(1000)*20

def scores_for_increasing_k(score_func):
    skewed_score = score_func(groundtruth, predictions)
    print(f'skewed score (from cross_val_predict): skewed_score')
    for k in (2,4,5,10,20,50,100,200,250):
        fold_preds = np.split(predictions, k)
        fold_gtruth = np.split(groundtruth, k)
        correct_score = np.mean([score_func(g, p) for g,p in zip(fold_gtruth, fold_preds)])

        print(f'correct CV for k=k: correct_score')

for name, score in [('MAE', mae), ('MSLE', msle), ('R2', r2_score)]:
    print(name)
    scores_for_increasing_k(score)
    print()

La salida será:

MAE
skewed score (from cross_val_predict): 42.25333901481263
correct CV for k=2: 42.25333901481264
correct CV for k=4: 42.25333901481264
correct CV for k=5: 42.25333901481264
correct CV for k=10: 42.25333901481264
correct CV for k=20: 42.25333901481264
correct CV for k=50: 42.25333901481264
correct CV for k=100: 42.25333901481264
correct CV for k=200: 42.25333901481264
correct CV for k=250: 42.25333901481264

MSLE
skewed score (from cross_val_predict): 3.5252449697327175
correct CV for k=2: 3.525244969732718
correct CV for k=4: 3.525244969732718
correct CV for k=5: 3.525244969732718
correct CV for k=10: 3.525244969732718
correct CV for k=20: 3.525244969732718
correct CV for k=50: 3.5252449697327175
correct CV for k=100: 3.5252449697327175
correct CV for k=200: 3.5252449697327175
correct CV for k=250: 3.5252449697327175

R2
skewed score (from cross_val_predict): -74.5910282783694
correct CV for k=2: -74.63582817089443
correct CV for k=4: -74.73848598638291
correct CV for k=5: -75.06145142821893
correct CV for k=10: -75.38967601572112
correct CV for k=20: -77.20560102267272
correct CV for k=50: -81.28604960074824
correct CV for k=100: -95.1061197684949
correct CV for k=200: -144.90258384605787
correct CV for k=250: -210.13375041871123

Por supuesto, hay otro efecto que no se muestra aquí, que fue mencionado por otros. Con el aumento de k, hay más modelos entrenados en más muestras y validados en menos muestras, lo que afectará las puntuaciones finales, pero esto no es inducido por la elección entre cross_val_score y cross_val_predict.

Creo que la diferencia se puede aclarar inspeccionando sus resultados. Considere este fragmento:

# Last column is the label
print(X.shape)  # (7040, 133)

clf = MLPClassifier()

scores = cross_val_score(clf, X[:,:-1], X[:,-1], cv=5)
print(scores.shape)  # (5,)

y_pred = cross_val_predict(clf, X[:,:-1], X[:,-1], cv=5)
print(y_pred.shape)  # (7040,)

Observe las formas: ¿por qué son así?
scores.shape tiene una longitud de 5 porque es una puntuación calculada con validación cruzada en 5 pliegues (ver argumento cv=5). Por lo tanto, se calcula un único valor real para cada pliegue. Ese valor es la puntuación del clasificador:

dado true etiquetas y etiquetas predichas, ¿cuántas respuestas acertó el predictor en un pliegue en particular?

En este caso, las etiquetas y dadas en la entrada se utilizan dos veces: para aprender de los datos y para evaluar el rendimiento del clasificador.

Por otro lado, y_pred.shape tiene una longitud de 7040, que es la forma del conjunto de datos. Esa es la longitud del conjunto de datos de entrada. Esto significa que cada valor no es una puntuación calculada en varios valores, sino un valor único: la predicción del clasificador:

dados los datos de entrada y sus etiquetas, ¿cuál es la predicción del clasificador en un ejemplo específico que estaba en un conjunto de prueba de un pliegue en particular?

Tenga en cuenta que no sabe qué pliegue se utilizó: cada resultado se calculó en los datos de prueba de un pliegue determinado, pero no puede saber cuál (de este resultado, al menos).

En este caso, las etiquetas se usan solo una vez: para entrenar al clasificador. Es su trabajo comparar estos resultados con los true salidas para calcular la puntuación. Si solo los promedia, como lo hizo, el resultado no es una puntuación, es solo la predicción promedio.

valoraciones y comentarios

Acuérdate de que te damos el privilegio añadir una tasación correcta si diste con la solución.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *