Partage de technologie

[Notes d'étude Python] Outil de réglage des paramètres Optuna Titanic Case

2024-07-12

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

[Notes d'étude Python] Outil de réglage des paramètres Optuna & Titanic Case

Tremblement de fond :(Ne le lisez pas si vous voulez économiser de l'argent)
J'ai récemment trouvé un stage en tant qu'annotateur IA, mais je faisais un travail lié au texte tout au long du processus. Essentiellement, je serrais encore des vis. Je voulais juste acquérir quelques compétences en réglage et déploiement de paramètres pour augmenter ma compétitivité, afin que mon. le curriculum vitae serait plus facile à emballer à l'avenir.
Bien sûr, le premier choix pour les tutoriels est l'Université Bilibili. Comme prévu, j'ai trouvé un outil gratuit de réglage des paramètres qui a reçu de nombreuses critiques positives.Optuna
D'ailleurs, le stage que j'ai fait étaitAnnotation de texte pour la direction de la sécurité du contenu(Dicton humain : Assurez-vous que le contenu de l'ensemble de formation estPolitiquement correct), mais en regardant d'autres vidéos pour apprendre à utiliser Yolo5 pour la reconnaissance de masques et de visages, j'ai appris qu'il existe un logiciel gratuitAnnotations d'imagesL'outil est très simple à utiliser. Je l'ai testé moi-même. Il est très facile à installer et à utiliser. Il ne comporte aucune publicité ni aucune contrainte. Il met l'accent sur la simplicité et l'efficacité.
Nom de l'outil :ÉtiquetteImg
Un article de compte public partagé par l'instructeur auparavant a donné une introduction très complète :
https://mp.weixin.qq.com/s/AE_rJwd9cKQkUGFGD6EfAg
Portail des comptes publics
Insérer la description de l'image ici
————————————————————————————————————————————

Texte : À propos d'Optuna et du processus d'apprentissage
**Lien du didacticiel vidéo : **https://www.bilibili.com/list/watchlater?oid=832000670&bvid=BV1c34y1G7E8&spm_id_from=333.1007.top_right_bar_window_view_later.content.click
Vidéos des maîtres de la Station B
Insérer la description de l'image ici
Méthode d'installation:
Insérer la description de l'image ici
Anaconda doit également être installé via conda. Je viens de l'installer via pip comme indiqué dans la vidéo pour éviter les problèmes.
————————————————————————————————————————————

Lien du cas Kaggle utilisé par les maîtres :
https://www.kaggle.com/code/yunsuxiaozi/apprendre-a-utiliser-le-notebook-optuna
portail
Insérer la description de l'image ici
Bien que copier et coller soit amusant, afin de conserver la sensation et de ressentir les détails, il est recommandé que si vous avez le temps, vous l'écriviez lentement à la main. Même si vous le tapez selon cela, c'est mieux que de copier et de coller. coller directement. Lorsque vous apprenez une compétence pour la première fois, la lenteur est rapide.
De même, si vous avez Anaconda sur votre ordinateur, il est recommandé de créer un environnement virtuel spécial pour tester Optuna afin d'éviter les conflits.
————————————————————————————————————————————

Tutoriels de construction d'environnement virtuel conda et de configuration d'environnement virtuel jupyter du maître CSDN :
https://blog.csdn.net/fanstering/article/details/123459665
Vous pouvez ignorer cette étape si vous n'avez pas Anaconda

Je connais déjà cette étape de création d'un environnement virtuel. Les packages d'environnement et Optuna ont été installés. Cependant, Jupyter signale toujours qu'il n'y a pas de bibliothèque Optuna lorsque je l'exécute, je l'ai installé selon le tutoriel de cet expert.nb_condaLe problème sera résolu plus tard.
Insérer la description de l'image ici
Insérer la description de l'image ici
————————————————————————————————————————————

Entrez ensuite dans le processus familier d'écriture de code. Tout d'abord, importez les bibliothèques Python requises et installez tout ce qui manque. Anaconda recommande l'installation de pip et l'installation de conda.

S'il signale une erreur fantomatique : TqdmWarning : IProgress non trouvé. Veuillez mettre à jour Jupyter et Ipywidgets. Voir https://ipywidgets.read
zhebuInsérer la description de l'image ici

N'ayez pas peur, il vous suffit de mettre à niveau Jupyter.
Insérer la description de l'image ici
Insérer la description de l'image ici
Après avoir terminé les trois premières étapes, j'ai actualisé et exécuté cette étape du programme et tout allait bien.
Insérer la description de l'image ici
————————————————————————————————
Insérer la description de l'image ici
Lien de téléchargement de l'ensemble de données : https://www.kaggle.com/competitions/titanic/data?select=train.csv
portail
Insérer la description de l'image ici
Insérer la description de l'image ici

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

Cette ligne de code crée une nouvelle colonne 'Embarked_is_nan', qui est utilisée pour marquer les valeurs nulles (NaN) dans la colonne 'Embarked'. Si l'élément dans la colonne « Embarqué » n'est pas lui-même (c'est-à-dire que l'élément est un NaN), la position correspondante dans la nouvelle colonne sera définie sur True.
C'est la première fois que je vois ce genre d'écriture.

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

Ce morceau de code est un peu compliqué. Il filtre d'abord quatre fonctionnalités importantes ['Pclass', 'Sex', 'SibSp', 'Parch'] et les stocke dans la liste des clés. Ces colonnes sont considérées comme potentiellement liées. la situation de survie des passagers.
Parcourez ensuite la liste une par une pour voir combien de valeurs uniques chaque fonctionnalité a dans l'ensemble d'entraînement.
Si le nombre de valeurs uniques len (valeurs) d'une colonne clé est inférieur à 10, le code analysera plus en détail la relation entre cette colonne et la situation de survie.
(Je ne comprends pas pourquoi key!= "Survived" est souligné. Il n'y a aucune valeur de "Survived" dans cette liste de clés ??)
Imprimez-le et constatez que les quatre attributs remplissent les conditions :
Insérer la description de l'image ici

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

Dans cette étape, dans l'ensemble d'entraînement train_df, le code calcule le taux de survie moyen de la colonne « Survived » correspondant à chaque valeur unique de la liste des clés.
Insérer la description de l'image ici
Comme le montre la figure, la valeur de la trame de données key_target change avec la valeur de l'attribut key à chaque cycle. Par exemple, lorsque key = Pclass est traité, les clés de key_target sont 1, 2 et 3, et la la valeur est le taux de survie moyen correspondant ; traitement Lorsque key = sex, les clés de key_target sont « Femme » et « Mâle », et les valeurs sont également les taux de survie moyens correspondants.
Les étapes suivantes sont un peu compliquées. Dessinez un tableau de mots pour le comprendre :
Il y a un total de quatre attributs dans les clés. L'un d'eux sera utilisé pour chaque cas. Enfin, les données des quatre attributs seront stockées dans total_df, résumées et renvoyées.
C'est le cas de PClass. PClass a trois valeurs : 1/2/3. Le taux de survie moyen est calculé pour chaque valeur et stocké dans key_target.
Ensuite, la clé de key_target est extraite et stockée dans la liste des clés (oui, cette liste est également appelée clés..., mais à ce stade, les valeurs qu'elle contient devraient être les trois valeurs​​1/ 2/3 de PClass), et la valeur est stockée dans la liste cible. (C'est-à-dire les trois nombres 0,629630, 0,472826, 0,242363), puis nommer artificiellement les deux colonnes de clé et de valeur. La colonne clé est également appelée PClass. , et la colonne de valeur est plus personnalisée et devrait s'appeler « PClass_target ».
Insérer la description de l'image ici
Par analogie, les key_target des trois attributs suivants se trouvent tous dans cette routine, mais la table total_df est en constante expansion.
Insérer la description de l'image ici
(le mâle ici est un mot hors limites, l'image a été coupée et un morceau séparé a été ajouté plus tard)
Jusqu'à ce que total_df devienne une grande table :
Insérer la description de l'image ici
Pour être honnête, pour un cas Optuna dont l'objectif principal est d'apprendre aux gens comment utiliser l'outil de réglage des paramètres, la logique écrite par l'auteur original à cette étape a vraiment augmenté le fardeau de compréhension pour moi...
J'ai demandé à Kimi de réécrire ce code dans une version plus claire et plus simple, afin qu'il ne soit pas facile de confondre autant de touches et de cibles qui remplissent l'écran :
Insérer la description de l'image ici
Cette partie n'est pas au centre de l'étape de réglage des paramètres. Si vous ne la comprenez vraiment pas, vous pouvez la sauter. ——————————————————————————————————————————
Utilisez la moyenne pour combler les valeurs manquantes. Marquez les étapes courantes du traitement des données que vous avez apprises.
Insérer la description de l'image ici
Supplément : lorsque j'ai suivi le cours d'analyse de données et de visualisation Tableau auparavant, l'enseignant a partagé un article présentant spécifiquement de nombreux types de données manquantes et de méthodes de traitement : https://towardsdatascience.com/all-about-missing-data-handling-b94b8b5d2184.
Ajouter une description du lien
Le message est en anglais et vous devez vous inscrire et vous connecter pour le consulter.
————————————————————————————————————————————
Après avoir obtenu l'ensemble de données total_df avec des attributs de plus en plus complets, il est à nouveau divisé en ensemble d'entraînement et en ensemble de test en fonction de la longueur précédente.
Insérer la description de l'image ici
————————————————————————————————————————————
Insérer la description de l'image ici
Il est mentionné ici que le rapport entre l'ensemble d'entraînement et l'ensemble de test est de 8 : 2, soit 4 : 1, ce qui est un rapport de division très courant.
L'auteur original considérait probablement que test et valide étaient la même chose, il n'y avait donc aucune distinction particulière dans la dénomination.
Insérer la description de l'image ici
Mais en fait, ces deux concepts ne sont pas exactement les mêmes (mais je vois que parfois la distinction n'est pas stricte). J'utilise ici une méthode d'écriture unifiée de test_X et test_y.
Insérer la description de l'image ici
Insérer la description de l'image ici
————————————————————————————————————————————
importerRégresseur LGBM , bien que l'ensemble de données du Titanic soit principalement utilisé pour des problèmes de classification (prédire si un passager survivra), l'auteur original le traite ici comme un problème de régression. J'ai considéré que pour les débutants, il serait plus facile de commencer en choisissant un didacticiel avec un ensemble de données simple et familier et une explication vidéo, donc je ne me suis pas soucié des détails des problèmes de régression ou de classification. Une fois que vous maîtrisez le processus, vous pouvez trouver en ligne des données plus complexes et standardisées pour vous entraîner.
Lien d'apprentissage supplémentaire : "Paramètre LGBMRegressor définissant le paramètre lgbmclassifier"
https://blog.51cto.com/u_12219/10333606
Ajouter une description du lien
(Au fait, n'y a-t-il pas un classificateur LGBM dans cet article ? Pourquoi l'auteur a-t-il spécifiquement mentionné le traitement des problèmes de régression dans la vidéo ?)
————————————————————————————————————————————
RMSE en tant que fonction de perte, c'est-à-dire un indice d'évaluation, est une fonction Python qui calcule l'erreur quadratique moyenne (Root Mean Square Error).Plus c'est petit, mieux c'est
Insérer la description de l'image ici
————————————————————————————————————————————
Définissez les paramètres de l'objectif de la tâche selon l'explication vidéo de l'auteur original :
Pour connaître les noms de paramètres spécifiques, leur signification et les valeurs recommandées, veuillez vous référer à l'article d'apprentissage supplémentaire « Définition des paramètres LGBMRegressor Paramètre lgbmclassifier » ci-dessus.

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

————————————————————————————————————————————
Code clé : appelez Optuna, créez une tâche d'apprentissage, spécifiez la perte minimale et définissez le nom de la tâche :

#创建的研究命名,找最小值
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

Insérer la description de l'image ici
————————————————————————————————————————————
L'idée est bonne, mais nous avons rencontré une erreur étrange : fit() a obtenu un argument de mot-clé inattendu 'early_stopping_rounds' :
Insérer la description de l'image ici
La méthode de Kimi a quand même signalé une erreur après l'avoir essayée, ce n'est donc probablement pas nous qui devrions en être responsables.Insérer la description de l'image ici
Insérer la description de l'image ici
Les maîtres de StackFlow proposent deux solutions :
https://stackoverflow.com/questions/76895269/lgbmclassifier-fit-got-an-unexpected-keyword-argument-early-stopping-rounds

portail
Insérer la description de l'image ici
Insérer la description de l'image ici
Notez qu'il est préférable d'utiliser pip install, conda install semble incapable de s'installer.
Insérer la description de l'image ici
Mais j'ai trouvé que ça ne servait à rien... J'ai toujours la même erreur, je n'ai pas reconnu early_stopping_rounds, et même après l'avoir supprimé, je n'ai pas reconnu le paramètre verbeux suivant...
Il n'est pas possible de modifier les paramètres selon le post supplémentaire précédent. Il semble que la mise à jour des informations soit en retard...
Insérer la description de l'image ici
Insérer la description de l'image ici

————————————————————————————————————————————
Au cours du processus de recherche, j'ai également trouvé un point sujet aux erreurs : le early_stopping_rounds semble n'avoir qu'une limite maximale de 100.
https://blog.csdn.net/YangTinTin/article/details/120708391
portail
Insérer la description de l'image ici
————————————————————————————————————————————
J'ai cherché manuellement sur Internet et demandé à Kimi, mais je n'ai pas encore trouvé d'alternative très efficace. Puisque nous souhaitons principalement tester l’utilisation d’Optuna, nous supprimons d’abord ces deux paramètres gênants.

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

Code objectif complet :

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

Ensuite vous pouvezGetBest_TrialA obtenu:
Insérer la description de l'image ici
————————————————————————————————————————————
De même, l'UP original utilisait égalementxgboost et catboostDes méthodes similaires sont utilisées pour trouver les paramètres optimaux.
Il n'est pas difficile de voir que la principale différence entre les trois méthodes différentes réside dans le paramètre param sélectionné et la méthode fonctionnelle spécifiée par le modèle.
Boost XGB :
Insérer la description de l'image ici
Insérer la description de l'image ici
Résultats XGBoost
Insérer la description de l'image ici
————————————————————————————————————————————
CatBoost :
Insérer la description de l'image ici
Insérer la description de l'image ici
Résultats CatBoost :
Insérer la description de l'image ici
————————————————————————————————————————————
dernière utilisationValidation croisée pliée en KObtenez les meilleurs résultats :
La validation croisée est également un terme couramment utilisé en apprentissage automatique.
Insérer la description de l'image ici

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

Insérer la description de l'image ici
Insérer la description de l'image iciInsérer la description de l'image ici

Insérer la description de l'image ici
kf est un objet KFold, qui est un outil de la bibliothèque scikit-learn pour implémenter la validation croisée K-fold. KFold divise l'ensemble de données enn_splits sous-ensembles, chaque sous-ensembleÀ tour de rôle en tant qu'ensemble de validation, et le reste sert d’ensemble de formation.
pour train_index, valid_index dans kf.split(x) : cette ligne de code parcourra l'objet KFold, renvoyant deux tableaux pour chaque itération : train_index et valid_index.train_index contient l'index du point de données utilisé pour la formation, tandis que valid_index contient l'index du point de données utilisé pour la validation . Selon l'index de l'ensemble complet X, y, vous pouvez obtenir les données de l'ensemble de formation et de l'ensemble de vérification à chaque fois. Ce processus revient à perturber toute la classe, en sélectionnant au hasard quelques élèves à chaque fois et en appelant un groupe d'élèves.
————————————————————————————————————————————
Maintenant, j'ai rencontré un autre bug courant. Même si je ne sais pas comment cela s'est produit, je ne sais pas si Python devrait à nouveau être blâmé. (Parce que les formes des ensembles de données X et Y étaient exactement les mêmes que celles de l'auteur auparavant, il n'y aura logiquement aucune autre opération sur eux plus tard...)
Insérer la description de l'image ici
Insérer la description de l'image ici
Insérer la description de l'image ici
N'ayez pas peur si vous rencontrez des problèmes, résolvez-les ! Il faut faire confiance à Kimi sur ce coup-là ! (D'ailleurs, les employés de la société d'intelligence artificielle dans laquelle je suis stagiaire utilisent aussi Kimi, donc Kimi est relativement fiable, et c'est gratuit !!)
Insérer la description de l'image ici
N'oubliez pas de désactiver les paramètres early_stopping_rounds et verbose en même temps pour éviter de provoquer une autre erreur.
Insérer la description de l'image ici
Ce morceau de code est relativement long, et il y a beaucoup de répétitions.

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

Le résultat intermédiaire entre moi et l’auteur original est quelque peu différent. Je ne sais pas ce qui cause l’écart :
Insérer la description de l'image ici
Insérer la description de l'image ici
Mais heureusement, il semble que les résultats ne soient pas trop mauvais pour l’instant :
Insérer la description de l'image ici
Insérer la description de l'image ici
————————————————————————————————————————————
Testez les performances de chaque modèle sur l'ensemble de test :

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

Insérer la description de l'image ici
Insérer la description de l'image ici
Insérer la description de l'image ici
Regardez la sortie test_pred.shape. Ne regardez pas la forme carrée du tableau. Regardez la forme comme un tableau unidimensionnel avec 418 éléments.
En Python, la forme d'un tableau unidimensionnel est généralement représentée par (N,), où N est le nombre total d'éléments dans le tableau.
————————————————————————————————————————————
Tel qu'utilisé dans la phrase test_pred=(test_pred &gt;= 0.5).astype(np.int64), il existe de nombreux exemples de création d'une nouvelle colonne et de comparaison de la taille pour attribuer une valeur Bool de True ou False. projet:
Insérer la description de l'image ici
Insérer la description de l'image ici
————————————————————————————————————————————
Enfin, enregistrez et écrivez dans le fichier 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

Insérer la description de l'image ici
————————————————————————————————————————————
J'enverrai mon package de code sur la page d'accueil du CSDN. Les amis dans le besoin sont invités à le télécharger eux-mêmes. Rendez-vous dans le prochain didacticiel.
Insérer la description de l'image ici
————————————————————————————————————————————
Autres contenus d’apprentissage connexes :
(1) **9.1 Ajustement des paramètres du modèle [Stanford 21 Fall : Practical Machine Learning Chinese Edition] : **La vidéo de l'enseignant Li Mu présente quelques théories sur l'ajustement des paramètres. Si vous ne comprenez pas l'ajustement des paramètres, vous pouvez la regarder pour apprendre. notions de base. .
https://www.bilibili.com/video/BV1vQ4y1e7LF/?spm_id_from=333.788.recommend_more_video.1&vd_source=cdfd0a0810bcc0bcdbcf373dafdf6a82
portail
(deux) Cet outil d’ajustement automatique du ginseng est tout simplement trop puissant ! Il peut pleinement répondre à l'utilisation quotidienne de l'apprentissage automatique et du réglage des paramètres d'apprentissage profond ! Un outil indispensable pour les débutants !: Le contenu de la vidéo n'est pas aussi bon que la vidéo de démonstration que j'ai suivie. Elle parle principalement brièvement d'Optuna sans aucun cas pratique.
https://www.bilibili.com/video/BV1Zs421K7Qj/?spm_id_from=333.788.recommend_more_video.6&vd_source=cdfd0a0810bcc0bcdbcf373dafdf6a82
portail
Cependant, je suis très intéressé par le livre présenté par cet UP, car pour un novice comme moi qui manque d'expérience et qui aime trouver des règles, j'espère vraiment avoir un guide qui pourra m'initier à quelques formules et directions universelles.