Compartir tecnología

[Notas de estudio de Python] Herramienta de ajuste de parámetros Optuna Titanic Case

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

[Notas de estudio de Python] Herramienta de ajuste de parámetros Optuna y Titanic Case

Temblor de fondo:(No lo leas si quieres ahorrar dinero)
Recientemente encontré una pasantía como anotador de IA, pero estuve haciendo trabajo relacionado con texto durante todo el proceso. Básicamente, todavía estaba apretando tornillos. Solo quería aprender algunas habilidades en el ajuste y la implementación de parámetros para aumentar mi competitividad. El currículum sería más fácil de empaquetar en el futuro.
Por supuesto, la primera opción para los tutoriales es la Universidad Bilibili. Como era de esperar, encontré una herramienta de ajuste de parámetros gratuita que ha recibido muchas críticas positivas.Optuna
Por cierto, la pasantía que hice fueAnotación de texto para la dirección de seguridad del contenido.(Dicho humano: asegúrese de que el contenido del conjunto de capacitación seacorrección política), pero cuando vi otros videos para aprender a usar Yolo5 para el reconocimiento de máscaras y rostros, descubrí que hay una versión gratuita.Anotación de imagenLa herramienta es muy fácil de usar. La he probado yo mismo. Es muy fácil de instalar y usar. No tiene publicidad ni cargas. Se centra en la simplicidad y la eficiencia.
Nombre de la herramienta:EtiquetaImg
Un artículo de cuenta pública compartido por el instructor anteriormente ofrece una introducción muy completa:
https://mp.weixin.qq.com/s/AE_rJwd9cKQkUGFGD6EfAg
Portal de cuentas públicas
Insertar descripción de la imagen aquí
————————————————————————————————————————————

Texto: Sobre Optuna y el proceso de aprendizaje
**Enlace del videotutorial: **https://www.bilibili.com/list/watchlater?oid=832000670&bvid=BV1c34y1G7E8&spm_id_from=333.1007.top_right_bar_window_view_later.content.click
Vídeos de los maestros de la Estación B
Insertar descripción de la imagen aquí
Metodo de instalacion:
Insertar descripción de la imagen aquí
Anaconda también debe instalarse a través de conda. Lo acabo de instalar mediante pip como se muestra en el video para evitar problemas.
————————————————————————————————————————————

Enlace del caso Kaggle utilizado por los maestros:
https://www.kaggle.com/code/yunsuxiaozi/aprende-a-usar-el-optuna/notebook
portal
Insertar descripción de la imagen aquí
Aunque copiar y pegar es divertido, para mantener la sensación + sentir los detalles, se recomienda que, si tiene tiempo, lo escriba lentamente a mano. Incluso si lo escribe de acuerdo con él, es mejor que copiar y. pegando directamente. Cuando aprendes una habilidad por primera vez, lo lento es rápido.
De manera similar, si tiene Anaconda en su computadora, se recomienda crear un entorno virtual especial para probar Optuna y evitar conflictos.
————————————————————————————————————————————

Tutoriales de configuración del entorno virtual jupyter y construcción del entorno virtual conda de CSDN master:
https://blog.csdn.net/fanstering/article/details/123459665
Puedes omitir este paso si no tienes Anaconda

Ya estoy familiarizado con este paso de establecer un entorno virtual. El entorno y los paquetes de Optuna están instalados. Sin embargo, Jupyter todavía informa que no hay una biblioteca de Optuna cuando lo instalé de acuerdo con el tutorial de este experto.nb_condaEl problema se solucionará más adelante.
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
————————————————————————————————————————————

Luego ingrese al proceso familiar de escribir código. Primero, importe las bibliotecas de Python necesarias e instale lo que falte. Tanto la instalación de pip como la instalación de conda son aceptables. Anaconda recomienda esta última.

Si informa un error fantasmal: TqdmWarning: No se encontró iProgress. Actualice jupyter y ipywidgets. Consulte https://ipywidgets.read
Zhebu-chanInsertar descripción de la imagen aquí

No tengas miedo, sólo necesitas actualizar Jupyter.
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Después de completar los primeros tres pasos, actualicé y ejecuté este paso del programa y todo estuvo bien.
Insertar descripción de la imagen aquí
————————————————————————————————
Insertar descripción de la imagen aquí
Enlace de descarga del conjunto de datos: https://www.kaggle.com/competitions/titanic/data?select=train.csv
portal
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí

total_df['Embarked_is_nan']=(total_df['Embarked']!=total_df['Embarked'])
  • 1

Esta línea de código crea una nueva columna 'Embarked_is_nan', que se utiliza para marcar valores nulos (NaN) en la columna 'Embarked'. Si el elemento en la columna 'Embarcado' no es él mismo (es decir, el elemento es un NaN), la posición correspondiente en la nueva columna se establecerá en Verdadero.
Esta es la primera vez que veo este tipo de escritura.

keys=['Pclass','Sex','SibSp','Parch']
for key in keys:
    values=np.unique(train_df[key].values)
    
    if len(values)<10 and key!="Survived":
        print(f"key:{key},values:{values}") 
        
        key_target=train_df['Survived'].groupby([train_df[key]]).mean()
        keys=key_target.keys().values
        target=key_target.values
        key_target=pd.DataFrame({key:keys,key+"_target":target})
        total_df=pd.merge(total_df,key_target,on=key,how="left")
total_df.head()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

Este fragmento de código es un poco complicado. Primero filtra cuatro características importantes ['Pclass', 'Sex', 'SibSp', 'Parch'] y las almacena en la lista de claves. Estas columnas se consideran potencialmente relacionadas. la situación de supervivencia de los pasajeros.
Luego, recorra la lista uno por uno para ver cuántos valores únicos tiene cada característica en el conjunto de entrenamiento.
Si el número de valores únicos len (valores) de una columna clave es inferior a 10, el código analizará más a fondo la relación entre esta columna y la situación de supervivencia.
(Estoy un poco confundido acerca de por qué se enfatiza key!= “Survived”. ¿No hay ningún valor de “Survived” en esta lista de claves?)
Imprímalo y descubra que los cuatro atributos cumplen las condiciones:
Insertar descripción de la imagen aquí

key_target=train_df['Survived'].groupby([train_df[key]]).mean()
  • 1

En este paso, en el conjunto de entrenamiento train_df, el código calcula la tasa de supervivencia promedio de la columna "Sobreviviente" correspondiente a cada valor único en la lista de claves.
Insertar descripción de la imagen aquí
Como se puede ver en la figura, el valor del marco de datos key_target cambia con el valor del atributo clave en cada ciclo. Por ejemplo, cuando se procesa key = Pclass, las claves de key_target son 1, 2 y 3, y las claves de key_target son 1, 2 y 3. el valor es la tasa de supervivencia promedio correspondiente; cuando key = sex, las claves de key_target son 'Mujer' y 'Masculino', y los valores también son las tasas de supervivencia promedio correspondientes.
Los pasos siguientes son un poco complicados. Dibuja una tabla de palabras para entenderlo:
Hay un total de cuatro atributos en las claves. Se utilizará uno de ellos para cada caso. Finalmente, los datos de los cuatro atributos se almacenarán en total_df, se resumirán y se devolverán.
Este es el caso de PClass. PClass tiene tres valores: 1/2/3. La tasa de supervivencia promedio se calcula para cada valor y se almacena en key_target.
Luego, la clave de key_target se extrae y se almacena en la lista de claves (sí, esta lista también se llama claves..., pero en este momento los valores que contiene deben ser los tres valores 1/ 2/3 de PClass), y el valor se almacena en la lista de destino (es decir, los tres números 0.629630, 0.472826, 0.242363), y luego nombra artificialmente las dos columnas de clave y valor. La columna de clave también se llama PClass. y la columna de valor es más personalizada y debería llamarse 'PClass_target'.
Insertar descripción de la imagen aquí
Por analogía, el key_target de los siguientes tres atributos está en esta rutina, pero la tabla total_df se expande constantemente.
Insertar descripción de la imagen aquí
(aquí la palabra masculina está fuera de límites, la imagen fue cortada y se agregó una pieza separada más tarde)
Hasta que finalmente total_df se convierte en una tabla grande:
Insertar descripción de la imagen aquí
Para ser honesto, para un caso de Optuna cuyo objetivo principal es enseñar a las personas cómo usar la herramienta de ajuste de parámetros, la lógica escrita por el autor original en este paso realmente aumentó la carga de comprensión para mí...
Le pedí a Kimi que reescribiera este código en una versión más clara y simple, para que no sea fácil confundir tantas claves y objetivos que llenan la pantalla:
Insertar descripción de la imagen aquí
Esta parte no es el foco del paso de ajuste de parámetros. Si realmente no la comprende, puede omitirla. ——————————————————————————————————————————
Utilice el promedio para completar los valores faltantes. Marque los pasos comunes en el procesamiento de datos que aprendió.
Insertar descripción de la imagen aquí
Suplemento: cuando tomé el curso de análisis de datos y visualización de Tableau antes, el profesor compartió una publicación que presentaba específicamente muchos tipos de datos faltantes y métodos de procesamiento: https://towardsdatascience.com/all-about-missing-data-handling-b94b8b5d2184
Agregar descripción del enlace
La publicación está en inglés y debes registrarte e iniciar sesión para verla.
————————————————————————————————————————————
Después de tener el conjunto de datos total_df con atributos cada vez más completos, se vuelve a dividir en el conjunto de entrenamiento y el conjunto de prueba de acuerdo con la longitud anterior.
Insertar descripción de la imagen aquí
————————————————————————————————————————————
Insertar descripción de la imagen aquí
Aquí se menciona que la proporción entre el conjunto de entrenamiento y el conjunto de prueba es 8:2, es decir, 4:1, que es una proporción de división muy común.
El autor original probablemente consideró prueba y validez como la misma cosa, por lo que no hubo distinción especial en la denominación.
Insertar descripción de la imagen aquí
Pero, de hecho, estos dos conceptos no son exactamente iguales (pero veo que a veces la distinción no es estricta). Aquí utilizo un método de escritura unificado de test_X y test_y.
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
————————————————————————————————————————————
importarregresor LGBM Aunque el conjunto de datos del Titanic se utiliza principalmente para problemas de clasificación (predecir si un pasajero sobrevivirá), el autor original lo trata aquí como un problema de regresión. Consideré que para los principiantes sería más fácil comenzar eligiendo un tutorial con un conjunto de datos simple y familiar y una explicación en video, por lo que no me preocupé por los detalles de los problemas de regresión o clasificación. Una vez que domine el proceso, podrá encontrar datos más complejos y estandarizados en línea para practicar.
Enlace de aprendizaje complementario: "Parámetro LGBMRegressor configuración parámetro lgbmclassifier"
https://blog.51cto.com/u_12219/10333606
Agregar descripción del enlace
(Por cierto, ¿no hay un clasificador LGBM en esta publicación? ¿Por qué el autor mencionó específicamente que se trata de problemas de regresión en el video?)
————————————————————————————————————————————
RMSE como función de pérdida, es decir, índice de evaluación, es una función de Python que calcula el error cuadrático medio (Root Mean Square Error).Cuanto más pequeño mejor
Insertar descripción de la imagen aquí
————————————————————————————————————————————
Establezca los parámetros del objetivo de la tarea de acuerdo con la explicación en video del autor original:
Para obtener nombres de parámetros específicos, significados y valores recomendados, consulte la publicación de aprendizaje complementaria "Configuración de parámetros LGBMRegressor Parámetro lgbmclassifier" más arriba.

def objective(trial):
    param = {
        'metric':'rmse',
        'random_state':trial.suggest_int('random_state', 2023, 2023),  #随机种子固定,所以设置为2023-2023
        'n_estimators':trial.suggest_int('n_estimators', 50, 300),  #迭代器数量 50-300 的整数
        'reg_alpha':trial.suggest_loguniform('reg_alpha', 1e-3, 10.0),
        'reg_lambda':trial.suggest_loguniform('reg_lambda', 1e-3, 10.0),  #对数正态分布的建议值
        'colsample_bytree':trial.suggest_float('colsample_bytree', 0.5, 1), #浮点数
        'subsample':trial.suggest_float('subsample', 0.5, 1),
        'learning_rate':trial.suggest_float('learning_rate', 1e-4, 0.1, log = True),
        'num_leaves':trial.suggest_int('num_leaves', 8, 64),  #整数
        'min_child_samples':trial.suggest_int('min_child_smaples', 1, 100),        
    }
    model = LGBMRegressor(**param)  #调用模型
    model.fit(train_X, train_y, eval_set = [(test_X, test_y)], early_stopping_rounds = 100, verbose = False)  #拟合
    preds = model.predict(test_X)  #计算测试集的损失
    rmse = RMSE(test_y, preds)
    return rmse
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

————————————————————————————————————————————
Código clave: llame a Optuna, cree una tarea de aprendizaje, especifique la pérdida mínima y establezca el nombre de la tarea:

#创建的研究命名,找最小值
study = optuna.create_study(direction = 'minimize', study_name = 'Optimize boosting hpyerparameters')  #创建了一个Optuna研究对象,用于优化超参数。
#关键代码:调用Optuna,创建一个学习任务,指定让损失最小,设置任务名称。
#目标函数,尝试的次数
study.optimize(objective, n_trials = 100) #将设定好参数的object任务传进来,尝试一百次
#输出最佳的参数
print('Best Trial: ',study.best_trial.params) #找到最佳参数  tudy.best_trial 表示在所有尝试中损失最小的那次试验,params 是一个字典,包含了那次试验中使用的超参数。
lgbm_params = study.best_trial.params #这行代码将最佳参数赋值给 lgbm_params 变量。这样可以将这些参数用于LightGBM模型或其他需要这些超参数的模型。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Insertar descripción de la imagen aquí
————————————————————————————————————————————
La idea está bien, pero encontramos un error extraño: fit() obtuvo un argumento de palabra clave inesperado 'early_stopping_rounds':
Insertar descripción de la imagen aquí
El método de Kimi aún reportó un error después de probarlo, por lo que probablemente no seamos nosotros quienes debamos asumir la culpa.Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Los maestros de StackFlow ofrecen dos soluciones:
https://stackoverflow.com/questions/76895269/lgbmclassifier-fit-obtuvo-un-argumento-de-palabra-clave-inesperado-rondas-detenidas-tempranamente

portal
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Tenga en cuenta que es mejor utilizar pip install; parece que conda install no se puede instalar.
Insertar descripción de la imagen aquí
Pero descubrí que no servía de nada... Todavía recibí el mismo error, no reconocí early_stopping_rounds, e incluso después de eliminarlo, no reconocí el siguiente parámetro detallado...
No es posible cambiar los parámetros según la publicación complementaria anterior. Parece que la actualización de la información se está quedando atrás...
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí

————————————————————————————————————————————
Durante el proceso de búsqueda, también encontré un punto propenso a errores: early_stopping_rounds parece tener solo un límite máximo de 100.
https://blog.csdn.net/YangTinTin/article/details/120708391
portal
Insertar descripción de la imagen aquí
————————————————————————————————————————————
Busqué manualmente en Internet y le pregunté a Kimi, pero todavía no encontré una alternativa muy efectiva. Como principalmente queremos probar el uso de Optuna, primero eliminamos estos dos parámetros problemáticos.

model.fit(train_X, train_y, eval_set=[(test_X, test_y)])  #拟合
  • 1

Código objetivo completo:

def objective(trial):
    param = {
        'metric':'rmse',
        'random_state':trial.suggest_int('random_state', 2023, 2023),  #随机种子固定,所以设置为2023-2023
        'n_estimators':trial.suggest_int('n_estimators', 50, 300),  #迭代器数量 50-300 的整数
        'reg_alpha':trial.suggest_loguniform('reg_alpha', 1e-3, 10.0),
        'reg_lambda':trial.suggest_loguniform('reg_lambda', 1e-3, 10.0),  #对数正态分布的建议值
        'colsample_bytree':trial.suggest_float('colsample_bytree', 0.5, 1), #浮点数
        'subsample':trial.suggest_float('subsample', 0.5, 1),
        'learning_rate':trial.suggest_float('learning_rate', 1e-4, 0.1, log = True),
        'num_leaves':trial.suggest_int('num_leaves', 8, 64),  #整数
        'min_child_samples':trial.suggest_int('min_child_smaples', 1, 100),        
    }
    model = LGBMRegressor(**param)  #调用模型
    model.fit(train_X, train_y, eval_set=[(test_X, test_y)])  #拟合
    preds = model.predict(test_X)  #计算测试集的损失
    rmse = RMSE(test_y, preds)
    return rmse
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Entonces tú puedesObtenerBest_TrialConsiguió:
Insertar descripción de la imagen aquí
————————————————————————————————————————————
De manera similar, la UP original también usabaxgboost y catboostSe utilizan métodos similares para encontrar los parámetros óptimos.
No es difícil ver que la principal diferencia entre los tres métodos diferentes es el parámetro seleccionado y el método de función especificado por el modelo.
XGBoost:
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Resultados de XGBoost
Insertar descripción de la imagen aquí
————————————————————————————————————————————
Refuerzo de gato:
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Resultados de CatBoost:
Insertar descripción de la imagen aquí
————————————————————————————————————————————
utilizado por última vezValidación cruzada K-foldObtenga los mejores resultados:
La validación cruzada también es un término comúnmente utilizado en el aprendizaje automático.
Insertar descripción de la imagen aquí

def accuracy(y_true, y_pred):
    return np.sum(y_true == y_pred)/len(y_true)
  • 1
  • 2

Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquíInsertar descripción de la imagen aquí

Insertar descripción de la imagen aquí
kf es un objeto KFold, que es una herramienta en la biblioteca scikit-learn para implementar la validación cruzada K-fold. KFold divide el conjunto de datos enn_splits subconjuntos, cada subconjuntoTúrnense como conjunto de validación, y el resto sirve como conjunto de entrenamiento.
para train_index, valid_index en kf.split(x): esta línea de código iterará sobre el objeto KFold y devolverá dos matrices para cada iteración: train_index y valid_index.train_index contiene el índice del punto de datos utilizado para el entrenamiento, mientras que valid_index contiene el índice del punto de datos utilizado para la validación. . De acuerdo con el índice del conjunto completo X, y, puede obtener los datos del conjunto de entrenamiento y del conjunto de verificación para cada vez. Este proceso es como interrumpir a toda la clase, seleccionar aleatoriamente algunos estudiantes cada vez y llamar a un grupo de estudiantes.
————————————————————————————————————————————
Ahora me he encontrado con otro error común. Aunque no sé cómo sucedió, no sé si Python debería asumir la culpa nuevamente. (Debido a que las formas de los conjuntos de datos X e Y eran exactamente las mismas que las del autor antes, lógicamente no habrá otras operaciones con ellos más adelante...)
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
¡No tengas miedo si encuentras problemas, solucionalos! ¡Tienes que confiar en Kimi en este caso! (Por cierto, los empleados de la empresa de inteligencia artificial donde hago prácticas también usan Kimi, por lo que Kimi es relativamente confiable y ¡¡es gratis!!)
Insertar descripción de la imagen aquí
No olvide deshabilitar los parámetros early_stopping_rounds y detallados al mismo tiempo para evitar causar otro error.
Insertar descripción de la imagen aquí
Este fragmento de código es relativamente largo y hay muchas repeticiones. Tenga cuidado de no cometer errores.

from sklearn.model_selection import KFold  #在机器学习库中导入k折交叉验证的函数
from xgboost import XGBRegressor
from lightgbm import  LGBMRegressor
from catboost import CatBoostRegressor  

def accuracy(y_true,y_pred):
    return np.sum(y_true==y_pred)/len(y_true)
print("start fit.")
folds = 10  #将数据分成10份
y=train_df['Survived']
X=train_df.drop(['Survived'],axis=1)

train_accuracy=[]
valid_accuracy=[]
# 存储已学习模型的列表
models = []

#将数据集随机打乱,并分成folds份
kf = KFold(n_splits=folds, shuffle=True, random_state=2023) 

#从x_train中按照9:1的比例分成训练集和验证集,并取出下标
for train_index, valid_index in kf.split(X):
    
    #根据下标取出训练集和验证集的数据
    x_train_cv = X.iloc[train_index]
    y_train_cv = y.iloc[train_index]
    x_valid_cv =X.iloc[valid_index]
    y_valid_cv = y.iloc[valid_index]
    
    model = LGBMRegressor(**lgbm_params)
    
    #模型用x_train_cv去训练,用x_train_cv和x_valid_cv一起去评估
    model.fit(
        x_train_cv, 
        y_train_cv, 
        eval_set = [(x_train_cv, y_train_cv), (x_valid_cv, y_valid_cv)], 
        #early_stopping_rounds=100,
        #verbose = 100, #迭代100次输出一个结果
    )
    
    #对训练集进行预测
    y_pred_train = model.predict(x_train_cv)        
    #对验证集进行预测
    y_pred_valid = model.predict(x_valid_cv) 
    
    y_pred_train=(y_pred_train>=0.5)
    y_pred_valid=(y_pred_valid>=0.5)
    
    train_acc=accuracy(y_pred_train,y_train_cv)
    valid_acc=accuracy(y_pred_valid,y_valid_cv)
    
    train_accuracy.append(train_acc)
    valid_accuracy.append(valid_acc)
    
    #将model保存进列表中
    models.append(model)
    
    model = XGBRegressor(**xgb_params)
    
    #模型用x_train_cv去训练,用x_train_cv和x_valid_cv一起去评估
    model.fit(
        x_train_cv, 
        y_train_cv, 
        eval_set = [(x_train_cv, y_train_cv), (x_valid_cv, y_valid_cv)], 
        #early_stopping_rounds=100,
        #verbose = 100, #迭代100次输出一个结果
    )
    
    #对训练集进行预测
    y_pred_train = model.predict(x_train_cv)        
    #对验证集进行预测
    y_pred_valid = model.predict(x_valid_cv) 
    
    y_pred_train=(y_pred_train>=0.5)
    y_pred_valid=(y_pred_valid>=0.5)
    
    train_acc=accuracy(y_pred_train,y_train_cv)
    valid_acc=accuracy(y_pred_valid,y_valid_cv)
    
    train_accuracy.append(train_acc)
    valid_accuracy.append(valid_acc)
    
    #将model保存进列表中
    models.append(model) 
    
    model = CatBoostRegressor(**cat_params)
    
    #模型用x_train_cv去训练,用x_train_cv和x_valid_cv一起去评估
    model.fit(
        x_train_cv, 
        y_train_cv, 
        eval_set = [(x_train_cv, y_train_cv), (x_valid_cv, y_valid_cv)], 
        #early_stopping_rounds=100,
        #verbose = 100, #迭代100次输出一个结果
    )
    
    #对训练集进行预测
    y_pred_train = model.predict(x_train_cv)        
    #对验证集进行预测
    y_pred_valid = model.predict(x_valid_cv) 
    
    y_pred_train=(y_pred_train>=0.5)
    y_pred_valid=(y_pred_valid>=0.5)
    
    train_acc=accuracy(y_pred_train,y_train_cv)
    valid_acc=accuracy(y_pred_valid,y_valid_cv)
    
    train_accuracy.append(train_acc)
    valid_accuracy.append(valid_acc)
    
    #将model保存进列表中
    models.append(model) 
    
    print(f"train_accuracy:{train_accuracy}, valid_accuracy:{valid_accuracy}")

train_accuracy=np.array(train_accuracy)
valid_accuracy=np.array(valid_accuracy)

print(f"mean_train_accuracy: {np.mean(train_accuracy)}")
print(f"mean_valid_accuracy: {np.mean(valid_accuracy)}")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120

El resultado intermedio entre el autor original y yo es algo diferente, no sé qué causa la brecha:
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Pero afortunadamente, parece que los resultados no son tan malos hasta el momento:
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
————————————————————————————————————————————
Pruebe el rendimiento de cada modelo en el conjunto de prueba:

test_X = test_df.drop(['Survived'], axis = 1).values

preds_test = []

#用每个保存的模型都对x_test预测一次,然后取平均值
for model in models:
    pred = model.predict(test_X)
    preds_test.append(pred)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
#将预测结果转换为np.array
preds_test_np = np.array(preds_test)

#按行对每个模型的预测结果取平均值
test_pred= preds_test_np.mean(axis = 0 )
test_pred=(test_pred >= 0.5).astype(np.int64) 
#平均预测值与 0.5 进行比较,根据比较结果(大于等于 0.5 为 True,否则为 False)将每个值转换为二进制形式(即 1 或 0),然后使用 astype(np.int64) 将布尔值转换为 64 位整数类型。
test_pred
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
Mire la salida test_pred.shape. No mire la forma cuadrada de la matriz. Mire la forma como una matriz unidimensional con 418 elementos.
En Python, la forma de una matriz unidimensional generalmente se representa como (N,), donde N es el número total de elementos de la matriz.
————————————————————————————————————————————
Como se usa en la oración test_pred=(test_pred &gt;= 0.5).astype(np.int64), hay muchos ejemplos de cómo crear una nueva columna y comparar el tamaño para asignar un valor Bool de Verdadero o Falso. Hay muchos ejemplos en esto. proyecto:
Insertar descripción de la imagen aquí
Insertar descripción de la imagen aquí
————————————————————————————————————————————
Finalmente guarde y escriba en un archivo CSV:

submission=pd.read_csv("D:/StudyFiles/Optuna_Titanic/data/gender_submission.csv")  #读取CSV文件,并将其存储在变量submission中
submission['Survived']=test_pred  #更新了submission DataFrame中的'Survived'列,使其包含模型预测的生存概率或分类结果。
submission.to_csv("submission.csv",index=None) #将更新后的submission DataFrame保存为一个新的CSV文件"submission.csv"。参数index=None表示在保存CSV文件时不包括行索引。
submission.head()
  • 1
  • 2
  • 3
  • 4

Insertar descripción de la imagen aquí
————————————————————————————————————————————
Enviaré mi paquete de códigos a la página de inicio de CSDN. Los amigos que lo necesiten pueden descargarlo ellos mismos. Nos vemos en el próximo tutorial.
Insertar descripción de la imagen aquí
————————————————————————————————————————————
Otros contenidos de aprendizaje relacionados:
(1) **9.1 Ajuste de parámetros del modelo [Stanford 21 Fall: Edición china de aprendizaje automático práctico]: **El video del maestro Li Mu presenta algunas teorías sobre el ajuste de parámetros. Si no comprende el ajuste de parámetros, puede verlo para aprender. conocimiento básico. .
https://www.bilibili.com/video/BV1vQ4y1e7LF/?spm_id_from=333.788.recomiende_más_video.1&vd_source=cdfd0a0810bcc0bcdbcf373dafdf6a82
portal
(dos) ¡Esta herramienta de ajuste automático de ginseng es simplemente demasiado poderosa! ¡Puede satisfacer plenamente el uso diario del aprendizaje automático y el ajuste de parámetros de aprendizaje profundo! ¡Una herramienta imprescindible para principiantes!: El contenido del video no es tan bueno como el video de demostración que seguí. Habla principalmente brevemente sobre Optuna sin ningún caso práctico.
https://www.bilibili.com/video/BV1Zs421K7Qj/?spm_id_from=333.788.recomiende_más_video.6&vd_source=cdfd0a0810bcc0bcdbcf373dafdf6a82
portal
Sin embargo, estoy muy interesado en el libro presentado por esta UP, porque para un novato como yo, que carece de experiencia y le gusta encontrar reglas, realmente espero tener una guía que pueda presentarme algunas fórmulas e instrucciones universales.