<jupyter_start><jupyter_text>Train a ClassifierIn this notebook we train a Gradient Boosting Decision Tree (GBDT) classifier using the implementation of the package [LightGBM](https://lightgbm.readthedocs.io/en/latest/). Index1. [Import Packages](imports)2. [Load Features](loadFeatures)3. [Generate Classifier](generateClassifier)    1. [Untrained Classifier](createClassifier)    2. [Train Classifier](trainClassifier)    3. [Save the Classifier Instance](saveClassifier) 1. Import Packages<jupyter_code>import os
import pickle
import sys
import time
import lightgbm as lgb
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy.stats
from snmachine import snclassifier
from utils.plasticc_pipeline import get_directories, load_dataset
import warnings
warnings.simplefilter('always', DeprecationWarning)
%config Completer.use_jedi = False  # enable autocomplete<jupyter_output><empty_output><jupyter_text>2. Load FeaturesFirst, **write** the path to the folder that contains the features and the labels of the events (`path_saved_features`). These quantities were calculated and saved in [5_feature_extraction](5_feature_extraction.ipynb). 2.1. Features Path**A)** Obtain path from folder structure.If you created a folder structure, you can obtain the path from there. **Write** the name of the folder in `analysis_name`.<jupyter_code>analysis_name = 'example_dataset_aug' 
folder_path = '../snmachine/example_data'

directories = get_directories(folder_path, analysis_name) 
path_saved_features = directories['features_directory']<jupyter_output><empty_output><jupyter_text>**B)** Directly **write** where you saved the files. ```pythonfolder_path = '../snmachine/example_data'path_saved_features = folder_path```  2.2. LoadThen, load the features and labels.<jupyter_code>X = pd.read_pickle(os.path.join(path_saved_features, 'features.pckl'))  # features
y = pd.read_pickle(os.path.join(path_saved_features, 'data_labels.pckl'))  # class label of each event<jupyter_output><empty_output><jupyter_text>**A)** If the dataset is not augmented, skip **B)**.**B)** If the dataset is augmented, load the augmented dataset.In order to avoid information leaks during the classifier optimization, all synthetic events generated by the training set augmentation which derived from the same original event must be placed in the same cross-validation fold. First, **write** in `data_file_name` the name of the file where your dataset is saved.In this notebook we use the dataset saved in [4_augment_data](4_augment_data.ipynb).<jupyter_code>data_file_name = 'example_dataset_aug.pckl'<jupyter_output><empty_output><jupyter_text>Then, load the augmented dataset.<jupyter_code>data_path = os.path.join(folder_path, data_file_name)
dataset = load_dataset(data_path)
metadata = dataset.metadata<jupyter_output><empty_output><jupyter_text>3. Generate Classifier 3.1. Untrained ClassifierStart by creating a classifier. For that **choose**: - classifier type: `snmachine` contains the following classifiers    * [LightGBM](https://lightgbm.readthedocs.io/en/latest/pythonapi/lightgbm.LGBMClassifier.html?highlight=classifier) classifier - `snclassifier.LightGBMClassifier`    * Boosted decision trees - `snclassifier.BoostDTClassifier`    * Boosted random forests - `snclassifier.BoostRFClassifier`    * K-nearest neighbors vote - `snclassifier.KNNClassifier`    * Support vector machine - `snclassifier.SVMClassifier`    * Multi-layer Perceptron classifier of a Neural Network - `snclassifier.NNClassifier`    * Random forest - `snclassifier.RFClassifier`    * Decision tree - `snclassifier.DTClassifier`    * Gaussian Naive Bayes - `snclassifier.NBClassifier`- `random_seed`: this allows reproducible results (**optional**).- `classifier_name`: name under which the classifier is saved (**optional**).- `**kwargs`: optional keywords to pass arguments into the underlying classifier; see the docstring in each classifier for more information (**optional**).Here we chose a LightGBM classifier.<jupyter_code>classifier_instance = snclassifier.LightGBMClassifier(classifier_name='our_classifier', random_seed=42)<jupyter_output>Created classifier of type: LGBMClassifier(random_state=42).<jupyter_text>3.2. Train ClassifierWe can now train and use the classifier generated above or optimise it beforehand. In general, it is important to optimise the classifier hyperparameters.If you do not want to optimise the classifier, **run** **A)**.**A)** Train unoptimised classifier. ```pythonclassifier.fit(X, y)``` If you want to optimise the classifier, run **B)**.**B)** Optimise and train classifier.For that, **choose**:- `param_grid`: parameter grid containing the hyperparameters names and lists of their possible settings as values. If none is provided, the code uses a default parameter grid. (**optional**)- `scoring`: metric used to evaluate the predictions on the validation sets and write it in `scoring`.     * `snmachine` contains the `'auc'` and the PLAsTiCC `'logloss'` costum metrics. For more details about these, see `snclassifier.logloss_score` and `snclassifier.auc_score`, respectively.    * Additionally, you can choose a different metric from the list in [Scikit-learn](https://scikit-learn.org/stable/modules/model_evaluation.htmlscoring-parameter) or create your own (see [`sklearn.model_selection._search.GridSearchCV`](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.GridSearchCV.html) for details).- `number_cv_folds`: number of folds for cross-validation. By default it is 5. (**optional**)- `metadata`: metadata of the events with which to train the classifier. This ensures all synthetic events generated by the training set augmentation that were derived from the same original event are placed in the same cross-validation fold. (**optional**)<jupyter_code>param_grid={'learning_rate': [.1, .25, .5]}

classifier_instance.optimise(X, y, param_grid=param_grid, scoring='logloss', 
                             number_cv_folds=5, metadata=metadata)<jupyter_output>Cross-validation for an augmented dataset.
The optimisation takes 0.892s.<jupyter_text>The classifier is optimised and its optimised hyperparameters are:<jupyter_code>classifier_instance.classifier
classifier_instance.grid_search.best_params_
classifier_instance.classifier_name<jupyter_output><empty_output><jupyter_text>3.3. Save the Classifier Instance**Write** in `path_saved_classifier` the path to the folder where to save the trained classifier instance.<jupyter_code>path_saved_classifier = directories['classifications_directory']<jupyter_output><empty_output><jupyter_text>Save the classifier instance (which includes the grid search used to optimise the classifier).<jupyter_code>classifier_instance.save_classifier(path_saved_classifier)<jupyter_output>Classifier saved in ../snmachine/example_data/example_dataset_aug/classifications/our_classifier.pck .
{'fraction_non_alphanumeric': 0.09394027254276602, 'fraction_numerical': 0.005363873586546825, 'mean_word_length': 6.5398907103825135, 'pattern_counts': {'":': 0, '<': 38, '<?xml version=': 0, '>': 38, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '10', 'dir': 'jupyter-structured-clean-dedup', 'id': '606803', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 2013, 'n_tokens_neox': 1941, 'n_words': 612, 'path': 'examples/6_train_classifier.ipynb', 'repo_name': 'heather999/snmachine', 'size': '6898'}