Les deux tâches d'apprentissage supervisé les plus courantes sont la régression linéaire et le classificateur linéaire. La régression linéaire prédit une valeur tandis que le classificateur linéaire prédit une classe. Ce didacticiel est axé sur le classificateur linéaire.
Qu'est-ce que le classificateur linéaire?
Un classificateur linéaire dans l'apprentissage automatique est une méthode permettant de trouver la classe d'un objet en fonction de ses caractéristiques pour la classification statistique. Il prend une décision de classification basée sur la valeur d'une combinaison linéaire de caractéristiques d'un objet. Le classificateur linéaire est utilisé dans des problèmes pratiques tels que la classification de documents et des problèmes ayant de nombreuses variables.
Les problèmes de classification représentent environ 80% de la tâche d'apprentissage automatique. La classification vise à prédire la probabilité de chaque classe compte tenu d'un ensemble d'entrées. L'étiquette (c'est-à-dire la variable dépendante) est une valeur discrète, appelée classe.
- Si l'étiquette n'a que deux classes, l'algorithme d'apprentissage est un classificateur binaire.
- Le classificateur multiclasse s'attaque aux étiquettes avec plus de deux classes.
Par exemple, un problème de classification binaire typique est de prédire la probabilité qu'un client effectue un deuxième achat. Prédire le type d'animal affiché sur une image est un problème de classification multiclasse puisqu'il existe plus de deux variétés d'animaux.
La partie théorique de ce didacticiel met l'accent sur la classe binaire. Vous en apprendrez plus sur la fonction de sortie multiclasse dans un prochain didacticiel.
Dans ce tutoriel, vous apprendrez
- Qu'est-ce que le classificateur linéaire?
- Comment fonctionne le classificateur binaire?
- Comment mesurer les performances du classificateur linéaire?
- Précision
- Matrice de confusion
- Précision et sensibilité
- Classificateur linéaire avec TensorFlow
- Étape 1) Importez les données
- Étape 2) Conversion de données
- Étape 3) Former le classificateur
- Étape 4) Améliorez le modèle
- Étape 5) Hyperparamètre: Lasso & Ridge
Comment fonctionne le classificateur binaire?
Vous avez appris dans le didacticiel précédent qu'une fonction est composée de deux types de variables, une variable dépendante et un ensemble de fonctionnalités (variables indépendantes). Dans la régression linéaire, une variable dépendante est un nombre réel sans plage. L'objectif principal est de prédire sa valeur en minimisant l'erreur quadratique moyenne.
Pour le classificateur binaire TensorFlow, l'étiquette peut avoir deux valeurs entières possibles. Dans la plupart des cas, il s'agit de [0,1] ou [1,2]. Par exemple, l'objectif est de prédire si un client achètera un produit ou non. L'étiquette est définie comme suit:
- Y = 1 (le client a acheté le produit)
- Y = 0 (le client n'achète pas le produit)
Le modèle utilise les fonctionnalités X pour classer chaque client dans la classe la plus probable à laquelle il appartient, à savoir, acheteur potentiel ou non.
La probabilité de succès est calculée par régression logistique . L'algorithme calculera une probabilité basée sur la caractéristique X et prédit un succès lorsque cette probabilité est supérieure à 50%. Plus formellement, la probabilité est calculée comme indiqué dans l'exemple de classification binaire TensorFlow ci-dessous:
où 0 est l'ensemble des poids, les caractéristiques et b le biais.
La fonction peut être décomposée en deux parties:
- Le modèle linéaire
- La fonction logistique
Modèle linéaire
Vous connaissez déjà la façon dont les poids sont calculés. Les poids sont calculés à l'aide d'un produit scalaire: Y est une fonction linéaire de toutes les caractéristiques x i . Si le modèle n'a pas de caractéristiques, la prédiction est égale au biais, b.
Les poids indiquent la direction de la corrélation entre les caractéristiques x i et l'étiquette y. Une corrélation positive augmente la probabilité de la classe positive tandis qu'une corrélation négative conduit la probabilité plus près de 0 (c'est-à-dire une classe négative).
Le modèle linéaire renvoie uniquement le nombre réel, ce qui est incompatible avec la mesure de probabilité de la plage [0,1]. La fonction logistique est nécessaire pour convertir la sortie du modèle linéaire en probabilité,
Fonction logistique
La fonction logistique, ou fonction sigmoïde, a une forme en S et la sortie de cette fonction est toujours comprise entre 0 et 1.
![](https://cdn.css-code.org/3011442/binary_classification_in_tensorflow_linear_classifier_example.png.webp)
Exemple de fonction logistique
Il est facile de remplacer la sortie de la régression linéaire par la fonction sigmoïde. Il en résulte un nouveau nombre avec une probabilité comprise entre 0 et 1.
Le classificateur peut transformer la probabilité en une classe
- Les valeurs comprises entre 0 et 0,49 deviennent la classe 0
- Les valeurs comprises entre 0,5 et 1 deviennent la classe 1
Comment mesurer les performances du classificateur linéaire?
Précision
La performance globale d'un classificateur est mesurée avec la métrique de précision. La précision recueille toutes les valeurs correctes divisées par le nombre total d'observations. Par exemple, une valeur de précision de 80% signifie que le modèle est correct dans 80% des cas.
![](https://cdn.css-code.org/3011442/binary_classification_in_tensorflow_linear_classifier_example_2.png.webp)
Mesurer les performances du classificateur linéaire à l'aide de la métrique de précision
Vous pouvez noter une lacune avec cette métrique, en particulier pour la classe de déséquilibre. Un jeu de données de déséquilibre se produit lorsque le nombre d'observations par groupe n'est pas égal. Disons; vous essayez de classer un événement rare avec une fonction logistique. Imaginez que le classificateur essaie d'estimer le décès d'un patient suite à une maladie. Dans les données, 5% des patients décèdent. Vous pouvez entraîner un classificateur pour prédire le nombre de décès et utiliser la métrique de précision pour évaluer les performances. Si le classificateur prédit 0 décès pour l'ensemble de données, il sera correct dans 95% des cas.
Matrice de confusion
Une meilleure façon d'évaluer les performances d'un classificateur est d'examiner la matrice de confusion.
![](https://cdn.css-code.org/3011442/binary_classification_in_tensorflow_linear_classifier_example_3.png.webp)
Mesurer les performances du classificateur linéaire à l'aide de la matrice de confusion
La matrice de confusion visualise la précision d'un classificateur en comparant les classes réelles et prévues, comme illustré dans l'exemple de classificateur linéaire ci-dessus. La matrice de confusion binaire est composée de carrés:
- TP: True Positive: les valeurs prédites correctement prédites comme positives réelles
- FP: Les valeurs prédites prédisaient incorrectement un réel positif. c.-à-d. valeurs négatives prédites comme positives
- FN: faux négatif: valeurs positives prédites comme négatives
- TN: Vrai Négatif: Les valeurs prédites correctement prédites comme négatives réelles
À partir de la matrice de confusion, il est facile de comparer la classe réelle et la classe prédite.
Précision et sensibilité
La matrice de confusion donne un bon aperçu du vrai positif et du faux positif. Dans certains cas, il est préférable d'avoir une métrique plus concise.
Précision
La métrique de précision montre la précision de la classe positive. Il mesure la probabilité que la prédiction de la classe positive soit correcte.
Le score maximum est de 1 lorsque le classificateur classe parfaitement toutes les valeurs positives. La précision seule n'est pas très utile car elle ignore la classe négative. La métrique est généralement associée à la métrique de rappel. Le rappel est également appelé sensibilité ou vrai taux positif.
Sensibilité
La sensibilité calcule le rapport des classes positives correctement détectées. Cette métrique donne à quel point le modèle est bon pour reconnaître une classe positive.
Classificateur linéaire avec TensorFlow
Pour ce didacticiel, nous utiliserons l'ensemble de données du recensement. Le but est d'utiliser les variables de l'ensemble de données du recensement pour prédire le niveau de revenu. Notez que le revenu est une variable binaire
- avec une valeur de 1 si le revenu> 50k
- 0 si revenu <50k.
Cette variable est votre étiquette
Cet ensemble de données comprend huit variables catégorielles:
- lieu de travail
- éducation
- matrimonial
- Occupation
- relation
- course
- sexe
- pays d'origine
de plus, six variables continues:
- âge
- fnlwgt
- education_num
- capital_gain
- capital_loss
- heures_semaine
Grâce à cet exemple de classification TensorFlow, vous comprendrez comment entraîner des classificateurs TensorFlow linéaires avec l'estimateur TensorFlow et comment améliorer la métrique de précision.
Nous procéderons comme suit:
- Étape 1) Importez les données
- Étape 2) Conversion de données
- Étape 3) Former le classificateur
- Étape 4) Améliorez le modèle
- Étape 5) Hyperparamètre: Lasso & Ridge
Étape 1) Importez les données
Vous importez d'abord les bibliothèques utilisées lors du tutoriel.
import tensorflow as tfimport pandas as pd
Ensuite, vous importez les données de l'archive de l'UCI et définissez les noms des colonnes. Vous utiliserez les COLONNES pour nommer les colonnes dans une trame de données pandas.
Notez que vous allez entraîner le classificateur à l'aide d'une trame de données Pandas.
## Define path dataCOLUMNS = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital','occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss','hours_week', 'native_country', 'label']PATH = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.data"PATH_test = "https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.test"
Les données stockées en ligne sont déjà réparties entre un rame et un banc d'essai.
df_train = pd.read_csv(PATH, skipinitialspace=True, names = COLUMNS, index_col=False)df_test = pd.read_csv(PATH_test,skiprows = 1, skipinitialspace=True, names = COLUMNS, index_col=False)
La rame contient 32 561 observations et l'ensemble de test 16 281
print(df_train.shape, df_test.shape)print(df_train.dtypes)(32561, 15) (16281, 15)age int64workclass objectfnlwgt int64education objecteducation_num int64marital objectoccupation objectrelationship objectrace objectsex objectcapital_gain int64capital_loss int64hours_week int64native_country objectlabel objectdtype: object
Tensorflow nécessite une valeur booléenne pour entraîner le classificateur. Vous devez convertir les valeurs de chaîne en entier. L'étiquette est stockée en tant qu'objet, cependant, vous devez la convertir en valeur numérique. Le code ci-dessous crée un dictionnaire avec les valeurs à convertir et en boucle sur l'élément de colonne. Notez que vous effectuez cette opération deux fois, une pour le test du train, une pour l'ensemble de test
label = {'<=50K': 0,'>50K': 1}df_train.label = [label[item] for item in df_train.label]label_t = {'<=50K.': 0,'>50K.': 1}df_test.label = [label_t[item] for item in df_test.label]
Dans les données du train, il y a 24 720 revenus inférieurs à 50k et 7841 au-dessus. Le rapport est presque le même pour l'ensemble de test. Veuillez consulter ce tutoriel sur les facettes pour en savoir plus.
print(df_train["label"].value_counts())### The model will be correct in atleast 70% of the caseprint(df_test["label"].value_counts())## Unbalanced labelprint(df_train.dtypes)0 247201 7841Name: label, dtype: int640 124351 3846Name: label, dtype: int64age int64workclass objectfnlwgt int64education objecteducation_num int64marital objectoccupation objectrelationship objectrace objectsex objectcapital_gain int64capital_loss int64hours_week int64native_country objectlabel int64dtype: object
Étape 2) Conversion de données
Quelques étapes sont nécessaires avant d'entraîner un classificateur linéaire avec Tensorflow. Vous devez préparer les fonctionnalités à inclure dans le modèle. Dans la régression de référence, vous utiliserez les données d'origine sans appliquer de transformation.
L'estimateur doit disposer d'une liste de fonctionnalités pour entraîner le modèle. Par conséquent, les données de la colonne doivent être converties en un tenseur.
Une bonne pratique consiste à définir deux listes d'entités en fonction de leur type, puis à les passer dans les colonnes feature_column de l'estimateur.
Vous commencerez par convertir des entités continues, puis définirez un compartiment avec les données catégorielles.
Les caractéristiques de l'ensemble de données ont deux formats:
- Entier
- Objet
Chaque fonctionnalité est répertoriée dans les deux variables suivantes selon leurs types.
## Add features to the bucket:### Define continuous listCONTI_FEATURES = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week']### Define the categorical listCATE_FEATURES = ['workclass', 'education', 'marital', 'occupation', 'relationship', 'race', 'sex', 'native_country']
La feature_column est équipée d'un objet numeric_column pour aider à la transformation des variables continues en tenseur. Dans le code ci-dessous, vous convertissez toutes les variables de CONTI_FEATURES en un tenseur avec une valeur numérique. Ceci est obligatoire pour construire le modèle. Toutes les variables indépendantes doivent être converties dans le type approprié de tenseur.
Ci-dessous, nous écrivons un code pour vous permettre de voir ce qui se passe derrière feature_column.numeric_column. Nous afficherons la valeur convertie pour l'âge. C'est à des fins explicatives, il n'est donc pas nécessaire de comprendre le code python. Vous pouvez vous référer à la documentation officielle pour comprendre les codes.
def print_transformation(feature = "age", continuous = True, size = 2):#X = fc.numeric_column(feature)## Create feature namefeature_names = [feature]## Create dict with the datad = dict(zip(feature_names, [df_train[feature]]))## Convert ageif continuous == True:c = tf.feature_column.numeric_column(feature)feature_columns = [c]else:c = tf.feature_column.categorical_column_with_hash_bucket(feature, hash_bucket_size=size)c_indicator = tf.feature_column.indicator_column(c)feature_columns = [c_indicator]## Use input_layer to print the valueinput_layer = tf.feature_column.input_layer(features=d,feature_columns=feature_columns)## Create lookup tablezero = tf.constant(0, dtype=tf.float32)where = tf.not_equal(input_layer, zero)## Return lookup tbleindices = tf.where(where)values = tf.gather_nd(input_layer, indices)## Initiate graphsess = tf.Session()## Print valueprint(sess.run(input_layer))print_transformation(feature = "age", continuous = True)[[39.][50.][38.]… [58.][22.][52.]]
Les valeurs sont exactement les mêmes que dans df_train
continuous_features = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES]
Selon la documentation de TensorFlow, il existe différentes manières de convertir des données catégorielles. Si la liste de vocabulaire d'une fonctionnalité est connue et n'a pas beaucoup de valeurs, il est possible de créer la colonne catégorielle avec categorical_column_with_vocabulary_list. Il attribuera à toute liste de vocabulaire unique un identifiant.
Par exemple, si un statut de variable a trois valeurs distinctes:
- Mari
- Épouse
- Seul
Ensuite, trois ID seront attribués. Par exemple, le mari aura l'ID 1, la femme l'ID 2 et ainsi de suite.
À des fins d'illustration, vous pouvez utiliser ce code pour convertir une variable d'objet en colonne catégorielle dans TensorFlow.
La fonction sexe ne peut avoir que deux valeurs: masculine ou féminine. Lorsque nous convertirons la fonction sexe, Tensorflow créera 2 nouvelles colonnes, une pour homme et une pour femme. Si le sexe est égal à masculin, alors la nouvelle colonne mâle sera égale à 1 et femelle à 0. Cet exemple est affiché dans le tableau ci-dessous:
Lignes |
sexe |
après transformation |
Masculin |
Femme |
1 |
Masculin |
=> |
1 |
0 |
2 |
Masculin |
=> |
1 |
0 |
3 |
Femme |
=> |
0 |
1 |
Dans tensorflow:
print_transformation(feature = "sex", continuous = False, size = 2)[[1. 0.][1. 0.][1. 0.]… [0. 1.][1. 0.][0. 1.]]relationship = tf.feature_column.categorical_column_with_vocabulary_list('relationship', ['Husband', 'Not-in-family', 'Wife', 'Own-child', 'Unmarried','Other-relative'])
Ci-dessous, nous avons ajouté du code Python pour imprimer l'encodage. Encore une fois, vous n'avez pas besoin de comprendre le code, le but est de voir la transformation
Cependant, un moyen plus rapide de transformer les données consiste à utiliser la méthode categorical_column_with_hash_bucket. La modification des variables de chaîne dans une matrice creuse sera utile. Une matrice clairsemée est une matrice avec presque zéro. La méthode s'occupe de tout. Il vous suffit de spécifier le nombre de compartiments et la colonne clé. Le nombre de compartiments correspond au nombre maximal de groupes que Tensorflow peut créer. La colonne clé est simplement le nom de la colonne à convertir.
Dans le code ci-dessous, vous créez une boucle sur toutes les fonctionnalités catégorielles.
categorical_features = [tf.feature_column.categorical_column_with_hash_bucket(k, hash_bucket_size=1000) for k in CATE_FEATURES]
Étape 3) Former le classificateur
TensorFlow fournit actuellement un estimateur pour la régression linéaire et la classification linéaire.
- Régression linéaire: LinearRegressor
- Classification linéaire: LinearClassifier
La syntaxe du classificateur linéaire est la même que dans le didacticiel sur la régression linéaire à l'exception d'un argument, n_class. Vous devez définir la colonne de caractéristiques, le répertoire du modèle et, comparer avec le régresseur linéaire; vous avez le définir le nombre de classe. Pour une régression logit, le nombre de classes est égal à 2.
Le modèle calculera les poids des colonnes contenues dans les fonctions continues_features et categorical_features.
model = tf.estimator.LinearClassifier(n_classes = 2,model_dir="ongoing/train",feature_columns=categorical_features+ continuous_features)
PRODUCTION:
INFO:tensorflow:Using default config.INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec':, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
Maintenant que le classificateur est défini, vous pouvez créer la fonction d'entrée. La méthode est la même que dans le didacticiel du régresseur linéaire. Ici, vous utilisez une taille de lot de 128 et vous mélangez les données.
FEATURES = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country']LABEL= 'label'def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):return tf.estimator.inputs.pandas_input_fn(x=pd.DataFrame({k: data_set[k].values for k in FEATURES}),y = pd.Series(data_set[LABEL].values),batch_size=n_batch,num_epochs=num_epochs,shuffle=shuffle)
Vous créez une fonction avec les arguments requis par l'estimateur linéaire, c'est-à-dire le nombre d'époques, le nombre de lots et mélangez l'ensemble de données ou la note. Étant donné que vous utilisez la méthode Pandas pour transmettre les données dans le modèle, vous devez définir les variables X comme une trame de données pandas. Notez que vous bouclez sur toutes les données stockées dans FEATURES.
Entraînons le modèle avec l'objet model.train. Vous utilisez la fonction précédemment définie pour alimenter le modèle avec les valeurs appropriées. Notez que vous définissez la taille du lot sur 128 et le nombre d'époques sur Aucun. Le modèle sera formé sur un millier d'étapes.
model.train(input_fn=get_input_fn(df_train,num_epochs=None,n_batch = 128,shuffle=False),steps=1000)
INFO:tensorflow:Calling model_fn.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Create CheckpointSaverHook.INFO:tensorflow: Graph was finalized.INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Saving checkpoints for 1 into ongoing/train/model.ckpt.INFO:tensorflow:loss = 88.722855, step = 1INFO:tensorflow:global_step/sec: 65.8282INFO:tensorflow:loss = 52583.64, step = 101 (1.528 sec)INFO:tensorflow:global_step/sec: 118.386INFO:tensorflow:loss = 25203.816, step = 201 (0.837 sec)INFO:tensorflow:global_step/sec: 110.542INFO:tensorflow:loss = 54924.312, step = 301 (0.905 sec)INFO:tensorflow:global_step/sec: 199.03INFO:tensorflow:loss = 68509.31, step = 401 (0.502 sec)INFO:tensorflow:global_step/sec: 167.488INFO:tensorflow:loss = 9151.754, step = 501 (0.599 sec)INFO:tensorflow:global_step/sec: 220.155INFO:tensorflow:loss = 34576.06, step = 601 (0.453 sec)INFO:tensorflow:global_step/sec: 199.016INFO:tensorflow:loss = 36047.117, step = 701 (0.503 sec)INFO:tensorflow:global_step/sec: 197.531INFO:tensorflow:loss = 22608.148, step = 801 (0.505 sec)INFO:tensorflow:global_step/sec: 208.479INFO:tensorflow:loss = 22201.918, step = 901 (0.479 sec)INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train/model.ckpt.INFO:tensorflow:Loss for final step: 5444.363.
Notez que la perte a diminué par la suite au cours des 100 dernières étapes, c'est-à-dire de 901 à 1000.
La perte finale après mille itérations est de 5444. Vous pouvez estimer votre modèle sur l'ensemble de test et voir les performances. Pour évaluer les performances de votre modèle, vous devez utiliser l'objet évaluer. Vous alimentez le modèle avec l'ensemble de test et définissez le nombre d'époques sur 1, c'est-à-dire que les données n'iront au modèle qu'une seule fois.
model.evaluate(input_fn=get_input_fn(df_test,num_epochs=1,n_batch = 128,shuffle=False),steps=1000)
INFO:tensorflow:Calling model_fn.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:22INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train/model.ckpt-1000INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Evaluation [100/1000]INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:23INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.7615626, accuracy_baseline = 0.76377374, auc = 0.63300294, auc_precision_recall = 0.50891197, average_loss = 47.12155, global_step = 1000, label/mean = 0.23622628, loss = 5993.6406, precision = 0.49401596, prediction/mean = 0.18454961, recall = 0.38637546{'accuracy': 0.7615626,'accuracy_baseline': 0.76377374,'auc': 0.63300294,'auc_precision_recall': 0.50891197,'average_loss': 47.12155,'global_step': 1000,'label/mean': 0.23622628,'loss': 5993.6406,'precision': 0.49401596,'prediction/mean': 0.18454961,'recall': 0.38637546}
TensorFlow renvoie toutes les métriques que vous avez apprises dans la partie théorique. Sans surprise, la précision est grande en raison de l'étiquette déséquilibrée. En fait, le modèle fonctionne légèrement mieux qu'une estimation aléatoire. Imaginez que le modèle prédise tous les ménages dont le revenu est inférieur à 50K, alors le modèle a une précision de 70%. En analysant de plus près, vous pouvez voir que la prédiction et le rappel sont assez faibles.
Étape 4) Améliorez le modèle
Maintenant que vous avez un modèle de référence, vous pouvez essayer de l'améliorer, c'est-à-dire d'augmenter la précision. Dans le didacticiel précédent, vous avez appris à améliorer la puissance de prédiction avec un terme d'interaction. Dans ce didacticiel, vous reviendrez sur cette idée en ajoutant un terme polynomial à la régression.
La régression polynomiale est instrumentale lorsqu'il y a non-linéarité dans les données. Il existe deux façons de saisir la non-linéarité dans les données.
- Ajouter un terme polynomial
- Répartir la variable continue en une variable catégorielle
Terme polynomial
À partir de l'image ci-dessous, vous pouvez voir ce qu'est une régression polynomiale. C'est une équation avec X variables de puissance différente. Une régression polynomiale du second degré a deux variables, X et X au carré. Le troisième degré a trois variables, X, X 2 et X 3
![](https://cdn.css-code.org/3011442/binary_classification_in_tensorflow_linear_classifier_example_4.png.webp)
Qu'est-ce que la régression polynomiale
Ci-dessous, nous avons construit un graphique avec deux variables, X et Y. Il est évident que la relation n'est pas linéaire. Si nous ajoutons une régression linéaire, nous pouvons voir que le modèle est incapable de capturer le motif (image de gauche).
Maintenant, regardez l'image de gauche de l'image ci-dessous, nous avons ajouté cinq termes à la régression (c'est-à-dire y = x + x 2 + x 3 + x 4 + x 5. Le modèle capture maintenant bien mieux le modèle. C'est la puissance de la régression polynomiale.
Revenons à notre exemple. L'âge n'est pas dans une relation linéaire avec le revenu. Le jeune âge peut avoir un revenu fixe proche de zéro parce que les enfants ou les jeunes ne travaillent pas. Ensuite, il augmente en âge de travailler et diminue pendant la retraite. Il s'agit généralement d'une forme en U inversé. Une façon de capturer ce modèle consiste à ajouter une puissance deux à la régression.
Voyons si cela augmente la précision.
Vous devez ajouter cette nouvelle entité au jeu de données et dans la liste des entités continues.
Vous ajoutez la nouvelle variable dans l'ensemble de données de train et de test, il est donc plus pratique d'écrire une fonction.
def square_var(df_t, df_te, var_name = 'age'):df_t['new'] = df_t[var_name].pow(2)df_te['new'] = df_te[var_name].pow(2)return df_t, df_te
La fonction a 3 arguments:
- df_t: définir l'ensemble d'apprentissage
- df_te: définir l'ensemble de test
- var_name = 'age': définit la variable à transformer
Vous pouvez utiliser l'objet pow (2) pour mettre au carré l'âge variable. Notez que la nouvelle variable est nommée 'new'
Maintenant que la fonction square_var est écrite, vous pouvez créer les nouveaux ensembles de données.
df_train_new, df_test_new = square_var(df_train, df_test, var_name = 'age')
Comme vous pouvez le voir, le nouvel ensemble de données a une autre fonctionnalité.
print(df_train_new.shape, df_test_new.shape)(32561, 16) (16281, 16)
La variable carrée est appelée nouvelle dans le jeu de données. Vous devez l'ajouter à la liste des fonctionnalités continues.
CONTI_FEATURES_NEW = ['age', 'fnlwgt','capital_gain', 'education_num', 'capital_loss', 'hours_week', 'new']continuous_features_new = [tf.feature_column.numeric_column(k) for k in CONTI_FEATURES_NEW]
Notez que vous avez changé le répertoire du graphique. Vous ne pouvez pas entraîner différents modèles dans le même répertoire. Cela signifie que vous devez changer le chemin de l'argument model_dir. Si vous ne le faites pas, TensorFlow générera une erreur.
model_1 = tf.estimator.LinearClassifier(model_dir="ongoing/train1",feature_columns=categorical_features+ continuous_features_new)
INFO:tensorflow:Using default config.INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train1', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec':, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}FEATURES_NEW = ['age','workclass', 'fnlwgt', 'education', 'education_num', 'marital', 'occupation', 'relationship', 'race', 'sex', 'capital_gain', 'capital_loss', 'hours_week', 'native_country', 'new']def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):return tf.estimator.inputs.pandas_input_fn(x=pd.DataFrame({k: data_set[k].values for k in FEATURES_NEW}),y = pd.Series(data_set[LABEL].values),batch_size=n_batch,num_epochs=num_epochs,shuffle=shuffle)
Maintenant que le classificateur est conçu avec le nouvel ensemble de données, vous pouvez entraîner et évaluer le modèle.
model_1.train(input_fn=get_input_fn(df_train,num_epochs=None,n_batch = 128,shuffle=False),steps=1000)
INFO:tensorflow:Calling model_fn.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Create CheckpointSaverHook.INFO:tensorflow:Graph was finalized.INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Saving checkpoints for 1 into ongoing/train1/model.ckpt.INFO:tensorflow:loss = 88.722855, step = 1INFO:tensorflow:global_step/sec: 81.487INFO:tensorflow:loss = 70077.66, step = 101 (1.228 sec)INFO:tensorflow:global_step/sec: 111.169INFO:tensorflow:loss = 49522.082, step = 201 (0.899 sec)INFO:tensorflow:global_step/sec: 128.91INFO:tensorflow:loss = 107120.57, step = 301 (0.776 sec)INFO:tensorflow:global_step/sec: 132.546INFO:tensorflow:loss = 12814.152, step = 401 (0.755 sec)INFO:tensorflow:global_step/sec: 162.194INFO:tensorflow:loss = 19573.898, step = 501 (0.617 sec)INFO:tensorflow:global_step/sec: 204.852INFO:tensorflow:loss = 26381.986, step = 601 (0.488 sec)INFO:tensorflow:global_step/sec: 188.923INFO:tensorflow:loss = 23417.719, step = 701 (0.529 sec)INFO:tensorflow:global_step/sec: 192.041INFO:tensorflow:loss = 23946.049, step = 801 (0.521 sec)INFO:tensorflow:global_step/sec: 197.025INFO:tensorflow:loss = 3309.5786, step = 901 (0.507 sec)INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train1/model.ckpt.INFO:tensorflow:Loss for final step: 28861.898.
model_1.evaluate(input_fn=get_input_fn(df_test_new,num_epochs=1,n_batch = 128,shuffle=False),steps=1000)
INFO:tensorflow:Calling model_fn.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:37INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train1/model.ckpt-1000INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Evaluation [100/1000]INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:39INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.7944229, accuracy_baseline = 0.76377374, auc = 0.6093755, auc_precision_recall = 0.54885805, average_loss = 111.0046, global_step = 1000, label/mean = 0.23622628, loss = 14119.265, precision = 0.6682401, prediction/mean = 0.09116262, recall = 0.2576703{'accuracy': 0.7944229,'accuracy_baseline': 0.76377374,'auc': 0.6093755,'auc_precision_recall': 0.54885805,'average_loss': 111.0046,'global_step': 1000,'label/mean': 0.23622628,'loss': 14119.265,'precision': 0.6682401,'prediction/mean': 0.09116262,'recall': 0.2576703}
La variable au carré a amélioré la précision de 0,76 à 0,79. Voyons si vous pouvez faire mieux en combinant la bucketisation et le terme d'interaction.
Bucketisation et interaction
Comme vous l'avez vu précédemment, un classificateur linéaire est incapable de capturer correctement le modèle âge-revenu. C'est parce qu'il apprend un poids unique pour chaque fonctionnalité. Pour faciliter la tâche du classificateur, une chose que vous pouvez faire est de regrouper la fonctionnalité. Le regroupement transforme une caractéristique numérique en plusieurs caractéristiques en fonction de la plage dans laquelle elle se situe, et chacune de ces nouvelles fonctionnalités indique si l'âge d'une personne se situe dans cette plage.
Grâce à ces nouvelles fonctionnalités, le modèle linéaire peut capturer la relation en apprenant différents poids pour chaque compartiment.
Dans TensorFlow, cela se fait avec bucketized_column. Vous devez ajouter la plage de valeurs dans les limites.
age = tf.feature_column.numeric_column('age')age_buckets = tf.feature_column.bucketized_column(age, boundaries=[18, 25, 30, 35, 40, 45, 50, 55, 60, 65])
Vous savez déjà que l'âge n'est pas linéaire avec le revenu. L'interaction est une autre façon d'améliorer le modèle. Dans le mot de TensorFlow, c'est le croisement de caractéristiques. Le croisement d'entités est un moyen de créer de nouvelles entités qui sont des combinaisons d'entités existantes, ce qui peut être utile pour un classificateur linéaire qui ne peut pas modéliser les interactions entre entités.
Vous pouvez décomposer l'âge avec une autre fonctionnalité comme l'éducation. Autrement dit, certains groupes sont susceptibles d'avoir un revenu élevé et d'autres faibles (Pensez à l'étudiant au doctorat).
education_x_occupation = [tf.feature_column.crossed_column(['education', 'occupation'], hash_bucket_size=1000)]age_buckets_x_education_x_occupation = [tf.feature_column.crossed_column([age_buckets, 'education', 'occupation'], hash_bucket_size=1000)]
Pour créer une colonne d'entités croisées, vous utilisez cross_column avec les variables à croiser dans un crochet. Le hash_bucket_size indique les possibilités de croisement maximales. Pour créer une interaction entre les variables (au moins une variable doit être catégorique), vous pouvez utiliser tf.feature_column.crossed_column. Pour utiliser cet objet, vous devez ajouter entre crochets la variable à interagir et un deuxième argument, la taille du compartiment. La taille du compartiment est le nombre maximum de groupe possible dans une variable. Ici, vous le définissez à 1000 car vous ne connaissez pas le nombre exact de groupes
age_buckets doit être mis au carré avant de l'ajouter aux colonnes de caractéristiques. Vous ajoutez également les nouvelles fonctionnalités aux colonnes de fonctionnalités et préparez l'estimateur
base_columns = [age_buckets,]model_imp = tf.estimator.LinearClassifier(model_dir="ongoing/train3",feature_columns=categorical_features+base_columns+education_x_occupation+age_buckets_x_education_x_occupation)
PRODUCTION
INFO:tensorflow:Using default config.INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train3', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec':, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
FEATURES_imp = ['age','workclass', 'education', 'education_num', 'marital','occupation', 'relationship', 'race', 'sex', 'native_country', 'new']def get_input_fn(data_set, num_epochs=None, n_batch = 128, shuffle=True):return tf.estimator.inputs.pandas_input_fn(x=pd.DataFrame({k: data_set[k].values for k in FEATURES_imp}),y = pd.Series(data_set[LABEL].values),batch_size=n_batch,num_epochs=num_epochs,shuffle=shuffle)
Vous êtes prêt à estimer le nouveau modèle et voir s'il améliore la précision.
model_imp.train(input_fn=get_input_fn(df_train_new,num_epochs=None,n_batch = 128,shuffle=False),steps=1000)
INFO:tensorflow:Calling model_fn.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Create CheckpointSaverHook.INFO:tensorflow:Graph was finalized.INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Saving checkpoints for 1 into ongoing/train3/model.ckpt.INFO:tensorflow:loss = 88.722855, step = 1INFO:tensorflow:global_step/sec: 94.969INFO:tensorflow:loss = 50.334488, step = 101 (1.054 sec)INFO:tensorflow:global_step/sec: 242.342INFO:tensorflow:loss = 56.153225, step = 201 (0.414 sec)INFO:tensorflow:global_step/sec: 213.686INFO:tensorflow:loss = 45.792007, step = 301 (0.470 sec)INFO:tensorflow:global_step/sec: 174.084INFO:tensorflow:loss = 37.485672, step = 401 (0.572 sec)INFO:tensorflow:global_step/sec: 191.78INFO:tensorflow:loss = 56.48449, step = 501 (0.524 sec)INFO:tensorflow:global_step/sec: 163.436INFO:tensorflow:loss = 32.528934, step = 601 (0.612 sec)INFO:tensorflow:global_step/sec: 164.347INFO:tensorflow:loss = 37.438057, step = 701 (0.607 sec)INFO:tensorflow:global_step/sec: 154.274INFO:tensorflow:loss = 61.1075, step = 801 (0.647 sec)INFO:tensorflow:global_step/sec: 189.14INFO:tensorflow:loss = 44.69645, step = 901 (0.531 sec)INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train3/model.ckpt.INFO:tensorflow:Loss for final step: 44.18133.
model_imp.evaluate(input_fn=get_input_fn(df_test_new,num_epochs=1,n_batch = 128,shuffle=False),steps=1000)
INFO:tensorflow:Calling model_fn.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Starting evaluation at 2018-06-02-08:28:52INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train3/model.ckpt-1000INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Evaluation [100/1000]INFO:tensorflow:Finished evaluation at 2018-06-02-08:28:54INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.8358209, accuracy_baseline = 0.76377374, auc = 0.88401634, auc_precision_recall = 0.69599575, average_loss = 0.35122654, global_step = 1000, label/mean = 0.23622628, loss = 44.67437, precision = 0.68986726, prediction/mean = 0.23320661, recall = 0.55408216{'accuracy': 0.8358209,'accuracy_baseline': 0.76377374,'auc': 0.88401634,'auc_precision_recall': 0.69599575,'average_loss': 0.35122654,'global_step': 1000,'label/mean': 0.23622628,'loss': 44.67437,'precision': 0.68986726,'prediction/mean': 0.23320661,'recall': 0.55408216}
Le nouveau niveau de précision est de 83,58%. Il est quatre pour cent plus élevé que le modèle précédent.
Enfin, vous pouvez ajouter un terme de régularisation pour éviter le surajustement.
Étape 5) Hyperparamètre: Lasso & Ridge
Votre modèle peut souffrir de surajustement ou underfitting .
- Surajustement: le modèle est incapable de généraliser la prédiction aux nouvelles données
- Sous-ajustement: le modèle est incapable de capturer le modèle des données. c'est-à-dire régression linéaire lorsque les données ne sont pas linéaires
Lorsqu'un modèle a beaucoup de paramètres et une quantité relativement faible de données, cela conduit à de mauvaises prédictions. Imaginez, un groupe n'a que trois observations; le modèle calculera un poids pour ce groupe. Le poids est utilisé pour faire une prédiction; si les observations de l'ensemble de test pour ce groupe particulier sont entièrement différentes de l'ensemble d'apprentissage, alors le modèle fera une mauvaise prédiction. Lors de l'évaluation avec l'ensemble d'apprentissage, la précision est bonne, mais pas bonne avec l'ensemble de test car les poids calculés ne sont pas les vrais pour généraliser le modèle. Dans ce cas, il ne fait pas de prédiction raisonnable sur des données invisibles.
Pour éviter le surajustement, la régularisation vous donne la possibilité de contrôler une telle complexité et de la rendre plus généralisable. Il existe deux techniques de régularisation:
- L1: Lasso
- L2: crête
Dans TensorFlow, vous pouvez ajouter ces deux hyperparamètres dans l'optimiseur. Par exemple, plus l'hyperparamètre L2 est élevé, plus le poids a tendance à être très faible et proche de zéro. La droite ajustée sera très plate, tandis qu'une L2 proche de zéro implique que les poids sont proches de la régression linéaire régulière.
Vous pouvez essayer par vous-même les différentes valeurs des hyperparamètres et voir si vous pouvez augmenter le niveau de précision.
Notez que si vous modifiez l'hyperparamètre, vous devez supprimer le dossier en cours / train4 sinon le modèle démarrera avec le modèle précédemment formé.
Voyons comment est la précision avec le battage médiatique
model_regu = tf.estimator.LinearClassifier(model_dir="ongoing/train4", feature_columns=categorical_features+base_columns+education_x_occupation+age_buckets_x_education_x_occupation,optimizer=tf.train.FtrlOptimizer(learning_rate=0.1,l1_regularization_strength=0.9,l2_regularization_strength=5))
SORTIE
INFO:tensorflow:Using default config.INFO:tensorflow:Using config: {'_model_dir': 'ongoing/train4', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': None, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_service': None, '_cluster_spec':, '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}
model_regu.train(input_fn=get_input_fn(df_train_new,num_epochs=None,n_batch = 128,shuffle=False),steps=1000)
SORTIE
INFO:tensorflow:Calling model_fn.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Create CheckpointSaverHook.INFO:tensorflow:Graph was finalized.INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Saving checkpoints for 1 into ongoing/train4/model.ckpt.INFO:tensorflow:loss = 88.722855, step = 1INFO:tensorflow:global_step/sec: 77.4165INFO:tensorflow:loss = 50.38778, step = 101 (1.294 sec)INFO:tensorflow:global_step/sec: 187.889INFO:tensorflow:loss = 55.38014, step = 201 (0.535 sec)INFO:tensorflow:global_step/sec: 201.895INFO:tensorflow:loss = 46.806694, step = 301 (0.491 sec)INFO:tensorflow:global_step/sec: 217.992INFO:tensorflow:loss = 38.68271, step = 401 (0.460 sec)INFO:tensorflow:global_step/sec: 193.676INFO:tensorflow:loss = 56.99398, step = 501 (0.516 sec)INFO:tensorflow:global_step/sec: 202.195INFO:tensorflow:loss = 33.263622, step = 601 (0.497 sec)INFO:tensorflow:global_step/sec: 216.756INFO:tensorflow:loss = 37.7902, step = 701 (0.459 sec)INFO:tensorflow:global_step/sec: 240.215INFO:tensorflow:loss = 61.732605, step = 801 (0.416 sec)INFO:tensorflow:global_step/sec: 220.336INFO:tensorflow:loss = 46.938225, step = 901 (0.456 sec)INFO:tensorflow:Saving checkpoints for 1000 into ongoing/train4/model.ckpt.INFO:tensorflow:Loss for final step: 43.4942.
model_regu.evaluate(input_fn=get_input_fn(df_test_new,num_epochs=1,n_batch = 128,shuffle=False),steps=1000)
PRODUCTION
INFO:tensorflow:Calling model_fn.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.WARNING:tensorflow:Trapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.INFO:tensorflow:Done calling model_fn.INFO:tensorflow:Starting evaluation at 2018-06-02-08:29:07INFO:tensorflow:Graph was finalized.INFO:tensorflow:Restoring parameters from ongoing/train4/model.ckpt-1000INFO:tensorflow:Running local_init_op.INFO:tensorflow:Done running local_init_op.INFO:tensorflow:Evaluation [100/1000]INFO:tensorflow:Finished evaluation at 2018-06-02-08:29:09INFO:tensorflow:Saving dict for global step 1000: accuracy = 0.83833915, accuracy_baseline = 0.76377374, auc = 0.8869794, auc_precision_recall = 0.7014905, average_loss = 0.34691378, global_step = 1000, label/mean = 0.23622628, loss = 44.12581, precision = 0.69720596, prediction/mean = 0.23662092, recall = 0.5579823{'accuracy': 0.83833915,'accuracy_baseline': 0.76377374,'auc': 0.8869794,'auc_precision_recall': 0.7014905,'average_loss': 0.34691378,'global_step': 1000,'label/mean': 0.23622628,'loss': 44.12581,'precision': 0.69720596,'prediction/mean': 0.23662092,'recall': 0.5579823}
Avec cet hyperparamètre, vous augmentez légèrement les métriques de précision. Dans le prochain didacticiel, vous apprendrez comment améliorer un classificateur linéaire à l'aide d'une méthode de noyau.
Résumé
Pour entraîner un modèle, vous devez:
- Définissez les fonctionnalités: Variables indépendantes: X
- Définissez le libellé: Variable dépendante: y
- Construire un train / ensemble de test
- Définir le poids initial
- Définir la fonction de perte: MSE
- Optimiser le modèle: descente de gradient
- Définir:
- Taux d'apprentissage
- Nombre d'époque
- Taille du lot
- Nombre de cours
Dans ce didacticiel, vous avez appris à utiliser l'API de haut niveau pour un classificateur de régression linéaire. Vous devez définir:
- Colonnes de fonctionnalités. Si continue: tf.feature_column.numeric_column (). Vous pouvez remplir une liste avec la compréhension de liste python
- L'estimateur: tf.estimator.LinearClassifier (feature_columns, model_dir, n_classes = 2)
- Une fonction pour importer les données, la taille du lot et l'époque: input_fn ()
Ensuite, vous êtes prêt à vous entraîner, évaluer et faire une prédiction avec train (), evaluer () et prédire ()
Pour améliorer les performances du modèle, vous pouvez:
- Utiliser la régression polynomiale
- Terme d'interaction: tf.feature_column.crossed_column
- Ajouter un paramètre de régularisation