[PYTHON] Gestion des modèles d'apprentissage automatique pour éviter de se quereller avec le côté commercial

introduction

Voici Miyano (@estie_mynfire) de Estie CTO. Le premier jour, j'ai écrit un petit contenu de niche (j'ai essayé Pandas 'Sql Upsert), mais cette fois je le fais à l'estie ** "Office" À propos de "Prévisions de loyers équitables" **.

En ce qui concerne la location de bureaux, contrairement au logement, le loyer proposé n'est pas si public (seulement un tiers ou moins des propriétés sont ouvertes au public dans les 5 quartiers centraux), et le loyer contractuel n'est fondamentalement pas disponible ** Il est difficile de collecter des données de réponse correctes **. Dans de telles circonstances, lors de l'estimation du loyer immobilier, nous vérifions conjointement l'exactitude du modèle tout en intégrant le regard professionnel de l'immobilier de bureaux du côté des entreprises.

Comme il existe de nombreuses interactions avec les sites commerciaux, j'écrirai sur ce à quoi je porte une attention particulière et ce que j'ai imaginé.

Tâche

Comme mentionné ci-dessus, puisque nous travaillons avec les membres du côté commercial, les problèmes suivants sont plus susceptibles de se produire que lors du développement uniquement avec des ingénieurs ML.

Défi 1. Gérer les anciens modèles

Avec les commentaires des ingénieurs d'affaires et l'expansion des données sources Nous apportons fréquemment des modifications logiques telles que la suppression des propriétés hors de valeur, l'ajout de quantités de caractéristiques et la modification des données d'apprentissage, et nous apportons des améliorations chaque jour pour créer des modèles plus précis. Cependant, comme mentionné ci-dessus, la précision de ces modèles ne peut pas toujours être évaluée en utilisant uniquement des indicateurs numériques (des yeux professionnels sont également nécessaires). J'avais l'intention de faire un meilleur modèle que par le passé

** "Oh, si c'était un modèle il y a deux mois, ça aurait été une bonne valeur ici, mais c'est une valeur étrange!" **

Ce qui arrive souvent. ~~ La plupart du temps, je remarque que lorsque je suis pressé, je suis ** picotement **. ~~

Dans un tel cas, si vous pouvez immédiatement revenir à l'état du modèle précédent, vous pouvez immédiatement rechercher la cause et la refléter dans les données de production à grande vitesse.

Défi 2. Explication des estimations du modèle

Lors de la vérification conjointe de l'exactitude, on nous demande souvent d'expliquer la cause, par exemple "La valeur estimée ici, pourquoi est-ce une telle valeur?". Dans un tel cas, si vous pouvez expliquer, "Je suis fortement influencé par cette quantité de fonctionnalités", vous pouvez poursuivre une discussion plus significative.

Défi 3. Visualisation de la sortie pour la vérification de l'exactitude

Comme mentionné ci-dessus, nous créons plusieurs nouveaux modèles chaque jour, produisons la sortie du modèle et demandons au côté commercial de vérifier la précision à grande vitesse. À ce moment-là, si la sortie est au format tabulaire, l'analyse intuitive est difficile, et la communication pour afficher uniquement les valeurs dans cette zone peut se produire sur plusieurs allers-retours.

Que fais tu

Les mesures suivantes sont prises pour résoudre ce qui précède.

Gestion de la version du modèle Correspondence 1

Gestion du code

La logique (y compris les paramètres élevés) et les tickets de modification des données d'entraînement sont gérés par des problèmes github, et la branche est coupée pour chaque problème. Si la prochaine version à sortir est la v1.1.0 et que les numéros de problème correspondants sont 4 et 6, le nom de la branche sera quelque chose comme dev / v1.1.0 / issue4_6. Au moment de la publication, il est une fois fusionné dans la branche v1.1.0 et la gestion des balises est également effectuée.

Gestion des versions des fichiers générés intermédiaires

Tous les fichiers utilisés pour l'apprentissage et l'estimation sont gérés par s3. Un compartiment pour l'apprentissage automatique est préparé dans s3, et les fichiers intermédiaires sont stockés sous la même structure de répertoires (dev / v1.1.0 / issue4_6) que le nom de la branche.

Correspondance 2 Explication de la cause à l'aide de SHAP

Lorsqu'on lui a demandé «Pourquoi cette valeur estimée est-elle ici?», Il est possible de comprendre la cause en utilisant SHAP, alors ajoutez la colonne shap_value lors de l'estimation. Il est. Il existe différents articles sur SHAP, veuillez donc vous y référer.

Explication de l'interprétation du modèle d'apprentissage automatique à l'aide de Shap

En termes simples, il nous indique "combien chaque fonctionnalité a contribué à la valeur estimée".

import shap
def calc_shap(df_, feature_list, model, rank_th=5) -> pd.core.frame.DataFrame:
    '''shap_Ajouter une colonne de valeur
    Args:
        df_ (pd.core.frame.DataFrame):Données pour lesquelles vous souhaitez calculer le loyer estimé après avoir ajouté le montant de la fonctionnalité
        feature_list ([str]):Liste des noms de fonctionnalités
        model :Modèle d'apprentissage
        rank_th (int): shap_Combien de fonctionnalités avec une valeur élevée doivent être affichées. par défaut 5.
    Returns:
        pd.core.frame.DataFrame.
    '''
    df = df_.copy()
    explainer = shap.TreeExplainer(model)
    shap_values = explainer.shap_values(df[feature_list])
    shap_df = pd.DataFrame(shap_values, columns=feature_list) # df[feature_values]Trame de données dans laquelle toutes les valeurs de
    shap_rank = shap_df.applymap(lambda x: abs(x)).rank(axis=1, ascending=False, method='min') #Pour chaque enregistrement,Ceux avec une grande valeur absolue(⇔ Haute contribution)Classement de
    main_contri_col = {i: [col for col in r.keys() if r[col] <= rank_th] for i, r in shap_rank.iterrows()} #Classement de contribution pour chaque enregistrement_Obtenir la liste des colonnes jusqu'au th
    main_contri_val = [shap_df.loc[i, main_contri_col[i]].to_dict() for i in main_contri_col.keys()] #Classement de contribution pour chaque enregistrement_Obtenez des colonnes jusqu'à th et leur contribution
    df['shap_value'] = main_contri_val
    return df

La valeur de cette colonne shap_value est une chaîne json {'Zone': 22627, 'Âge': 717, 'hoge1': -5409, 'hoge2': 2968, 'hoge3': 3791} Ça ressemble à ça. Ceci est utile car vous pouvez découvrir que "la zone contribue de manière insensée", et lorsque vous la recherchez, vous pouvez découvrir que l'ordre des zones de l'enregistrement estimé était incorrect.

Réponse 3 Visualisation sur une carte pour la vérification de l'exactitude

Afin que les membres commerciaux puissent vérifier la précision indépendamment à grande vitesse Non seulement la précision simple et la différence entre le résultat et la logique précédente, mais également les données d'apprentissage et la valeur estimée pour diverses propriétés sont visualisées. Les images suivantes sont des échantillons antérieurs, mais les propriétés avec des estimations élevées sont représentées en orange, et les propriétés avec des estimations faibles sont représentées en bleu clair. (Habituellement, les données d'entraînement sont également tracées avec des cercles noirs)

image.png

Le code de visualisation est ci-dessous.

'''Visualisation du loyer estimé par folium
Required:
    pandas
    folium
    matplotlib
'''

import subprocess
import pandas as pd
import folium
import matplotlib.colors as cl

def calc_RGB_value(norm_rent: float) -> str:
    '''0-Renvoie un nombre compressé à l'échelle 1 en notation hexadécimale RVB
La propriété la moins chère est bleu clair,Rendre les propriétés chères orange
    Args:
        norm_rent (float): 0-Valeur numérique compressée à 1 échelle
    Returns:
        str
        ex: #54b0c5
    '''
    R_val = 41 + (255 - 41) * norm_rent
    G_val = 182 + (150 - 182) * norm_rent
    B_val = 246 + (0 - 246) * norm_rent
    return cl.to_hex((R_val / 255, G_val / 255, B_val / 255, 1))

def add_color_col(df_: pd.core.frame.DataFrame) -> pd.core.frame.DataFrame:
    '''Ajouter une colonne de couleur
    Args:
        df_ (pd.core.frame.DataFrame): estimated_Trame de données contenant la colonne de loyer
    Returns:
        pd.core.frame.DataFrame
        'color'Ajouter une colonne et retourner
    '''
    df = df_.copy()
    norm = cl.Normalize(vmin=df['estimated_rent'].min(), vmax=df['estimated_rent'].max())
    norm_rent_ = [norm(v) for v in df['estimated_rent']]  #Loyer estimé 0,Faites-en une échelle
    color_ = [calc_RGB_value(norm_rent) for norm_rent in norm_rent_]
    df["color"] = color_
    return df

class Drawer:
    def __init__(self, ld_path, ed_path):
        self.read_ld(ld_path)
        self.read_ed(ed_path)
        self.add_color_col()
        self.init_map()
    def read_ld(self, ld_path):
        '''Lecture des données d'entraînement
        '''
        self.ld = pd.read_csv(ld_path)
        assert 'answer_rent' in self.ld.columns
    def read_ed(self, ed_path):
        '''Lecture des données après calcul du loyer estimé
        '''
        self.ed = pd.read_csv(ed_path)
        assert 'estimated_rent' in self.ld.columns
    def add_color_col(self):
        self.ed = add_color_col(self.ed)
        self.ld['color'] = '#262626' #noir
    def init_map(self):
        '''Initialiser la carte
        '''
        self.map = folium.Map(
            location=[self.ed.latitude.mean(),self.ed.longitude.mean()],
            zoom_start=6, tiles='cartodbpositron')
    def add_ld_plot(self, size=15):
        '''Graphique des données d'entraînement
        size (int):La taille du cercle de l'intrigue. par défaut 15.
        '''
        for i, row in self.ld.iterrows():
            folium.Circle(
                radius=size, location=[row['latitude'], row['longitude']],
                popup='Nom de la propriété: %s' % (row['Nom de la propriété'] if 'Nom de la propriété' in row.keys() else '' +
                '<br/>Loyer correct: {:,.0f}Cercle/Tsubo'.format(row['ans_rent']),
                color=row['color'], fill_color=row['color']).add_to(self.map)
    def add_ed_plot(self, size=5):
        '''Terrain de loyer estimé
        size (int):La taille du cercle de l'intrigue. par défaut 5.
        '''
        for i, row in self.ld.iterrows():
            folium.Circle(
                radius=size, location=[row['latitude'], row['longitude']],
                popup='Nom de la propriété: %s' % (row['Nom de la propriété'] if 'Nom de la propriété' in row.keys() else '' +
                '<br/>Loyer estimé: {:,.0f}Cercle/Tsubo'.format(row['estimated_rent']),
                color=row['color'], fill_color=row['color']).add_to(self.map)
if __name__ == '__main__':
    drawer = Drawer(
        ld_path='s3://hogehoge/dev/v1.1.0/issue4_6/ld.csv',
        ed_path='s3://hogehoge/dev/v1.1.0/issue4_6/ed.csv')
    drawer.add_ld_plot()
    drawer.add_ed_plot()
    drawer.map.save('map.html')
    subprocess.call(
        ['aws', 's3', 'mv', 'map.html', 's3://hogehoge/dev/v1.1.0/issue4_6/map.html'])

en conclusion

à partir de maintenant

Bien que la méthode soit encore primitive, la gestion de la synchronisation de la version du code de données est effectuée par la méthode ci-dessus. Dans le futur, je pense introduire MLflow pour le rendre plus facile à gérer, mais j'écrirai une suite dès son introduction.

À propos d'Estie

Chez estie, nous sommes toujours à la recherche d'ingénieurs passionnés par les nouvelles technologies et d'ingénieurs full-stack! https://www.wantedly.com/companies/company_6314859/projects

estie -> https://www.estie.jp estiepro -> https://pro.estie.jp Site de la société-> https://www.estie.co.jp

Recommended Posts

Gestion des modèles d'apprentissage automatique pour éviter de se quereller avec le côté commercial
J'ai essayé de visualiser le modèle avec la bibliothèque d'apprentissage automatique low-code "PyCaret"
Essayez d'évaluer les performances du modèle d'apprentissage automatique / de régression
Essayez d'évaluer les performances du modèle d'apprentissage automatique / de classification
Validez le modèle d'entraînement avec Pylearn2
Enregistrez les étapes pour comprendre l'apprentissage automatique
[Introduction à l'apprentissage automatique] Jusqu'à ce que vous exécutiez l'exemple de code avec chainer
[Python] Introduction facile à l'apprentissage automatique avec python (SVM)
Un débutant en apprentissage automatique a essayé de créer un modèle de prédiction de courses de chevaux avec python
J'ai essayé de déplacer l'apprentissage automatique (détection d'objet) avec TouchDesigner
La première étape de l'apprentissage automatique ~ Pour ceux qui veulent essayer l'implémentation avec python ~
Essayez de prédire le taux de change (FX) avec un apprentissage automatique non approfondi
Prédire le sexe des utilisateurs de Twitter grâce à l'apprentissage automatique
Apprentissage automatique avec des images de catégorie Caffe -1 à l'aide du modèle de référence
Résumé du site pour apprendre l'apprentissage automatique avec une vidéo en anglais
Tentative d'inclusion du modèle d'apprentissage automatique dans le package python
Bilan du premier défi du machine learning avec Keras
Introduction à l'apprentissage automatique
J'ai essayé de compresser l'image en utilisant l'apprentissage automatique
Oncle SE avec un cerveau endurci a essayé d'étudier l'apprentissage automatique
Introduction à l'apprentissage automatique avec scikit-learn - De l'acquisition de données à l'optimisation des paramètres
Pour ceux qui souhaitent démarrer l'apprentissage automatique avec TensorFlow2
Comment augmenter le nombre d'images de jeux de données d'apprentissage automatique
Apprentissage automatique pour apprendre avec Nogisaka 46 et Keyakizaka 46 Partie 1 Introduction
J'ai capturé le projet Toho avec Deep Learning ... je le voulais.
J'ai essayé d'écrire dans un modèle de langage profondément appris
Modèle d'apprentissage automatique prenant en compte la maintenabilité
L'apprentissage automatique appris avec Pokemon
Une introduction à l'apprentissage automatique
Apprentissage automatique avec Python! Préparation
Démineur d'apprentissage automatique avec PyTorch
Calibrer le modèle avec PyCaret
Commencer avec l'apprentissage automatique Python
Super introduction à l'apprentissage automatique
Essayez le machine learning à la légère avec Kaggle
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Introduction ~
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Implémentation ~
Une histoire coincée avec l'installation de la bibliothèque de machine learning JAX
[Apprentissage automatique] Vérifiez les performances du classificateur à l'aide de données de caractères manuscrites
[Apprentissage automatique] Comprenez à partir des mathématiques pourquoi le coefficient de corrélation varie de -1 à 1.
Avant l'introduction à l'apprentissage automatique. ~ Technologie requise pour l'apprentissage automatique autre que l'apprentissage automatique ~
Apprentissage automatique avec python sans perdre aux variables catégorielles (conversion de variable factice)
[Apprentissage automatique] Regroupez les articles Yahoo News avec le modèle de sujet MLlib (LDA).
Comment utiliser l'apprentissage automatique pour le travail? 01_ Comprendre l'objectif de l'apprentissage automatique
kintone x Gestion simple des cartes de visite réalisée par machine learning @kintone Café
[Introduction au style GAN] Apprentissage unique de l'animation avec votre propre machine ♬
Les gens mémorisent les connaissances acquises dans le cerveau, comment mémoriser les connaissances acquises dans l'apprentissage automatique
Comment créer une API de machine learning sans serveur avec AWS Lambda
À propos de l'itinéraire le plus court pour créer un modèle de reconnaissance d'image par apprentissage automatique et mettre en œuvre une application Android
(Apprentissage automatique) J'ai essayé de comprendre attentivement l'algorithme EM dans la distribution gaussienne mixte avec l'implémentation.
Introduction au Deep Learning pour la première fois (Chainer) Reconnaissance de caractères japonais Chapitre 2 [Génération de modèles par apprentissage automatique]
"Introduction à l'apprentissage automatique par inférence bayésienne" Inférence approximative du modèle mixte de Poisson implémenté uniquement avec Python numpy
J'ai essayé de créer Othello AI avec tensorflow sans comprendre la théorie de l'apprentissage automatique ~ Battle Edition ~
Introduction à la rédaction de notes d'apprentissage automatique
J'ai essayé l'apprentissage automatique avec liblinear
Apprentissage automatique par python (1) Classification générale
Explorez le labyrinthe avec l'apprentissage augmenté
SVM essayant l'apprentissage automatique avec scikit-learn
Analyse inverse du modèle d'apprentissage automatique