[PYTHON] Une histoire qui avait du mal à traiter en boucle 3 millions de données d'identification

Suite de l'article d'hier

■ Objectif

Un mois de données est préparé pour chacun des 3 millions d'identifiants Le contenu des données est une variable explicative et une variable objective. En d'autres termes, le tableau comporte trois colonnes: ID, variable explicative et variable objective. Le nombre d'enregistrements est de 3 millions x 30 jours ≒ 90 millions

À ce moment, pour chacun des 3 millions d'ID, une simple régression des variables explicatives et des variables objectives pendant 30 jours a été effectuée. Je souhaite stocker le coefficient de corrélation, la pente et la valeur p pour chaque ID en sortie.

■ Politique

Effectue une régression dans une boucle for pour 3 millions d'ID et stocke les résultats sous forme de liste Enfin, combinez les listes dans un bloc de données

■ Environnement

Instance EC2 (ubuntu: r5d.4xlarge) JupyterLab 0.35.3

■ Défis

Extraction avec df.loc [] avec ID comme index + Le traitement est lent même en utilisant la trame de données dask (cela prend 2 mois)

■ Solution

Un tableau avec la forme suivante

ID x y
01 x.xx y.yy
01 x.xx y.yy
・ ・ ・ ・ ・ ・ ・ ・ ・
01 x.xx y.yy
02 x.xx y.yy
02 x.xx y.yy
・ ・ ・ ・ ・ ・ ・ ・ ・
02 x.xx y.yy

Convertir sous la forme suivante

ID monthly_x monthly_y
01 [x.xx, x.xx ,....] [y.yy, y.yy ,....]
02 [x.xx, x.xx ,....] [y.yy, y.yy ,....]
03 [x.xx, x.xx ,....] [y.yy, y.yy ,....]
04 [x.xx, x.xx ,....] [y.yy, y.yy ,....]
05 [x.xx, x.xx ,....] [y.yy, y.yy ,....]
06 [x.xx, x.xx ,....] [y.yy, y.yy ,....]

Le flux de conversion est les deux étapes suivantes

code1.py



import pandas as pd
#Un état dans lequel une colonne représentant la date est ajoutée au bloc de données d'origine (ici, "date"_Le nom de la colonne est
pivot_df = pd.pivot_table(df, index="ID",columns="date_")

Avec cela, les valeurs de x et y sont conservées horizontalement pour chaque date.

code2.py



pivot_df["x"] = [list(pivot_df.x.loc[i,:]) for i in pivot_df.index]
pivot_df["y"] = [list(pivot_df.y.loc[i,:]) for i in pivot_df.index]

Ce processus est ** environ 0,2 ms ** par ID, ** environ 10 ~ 15 min ** avec 3 millions d'ID (** notation forte **)

Essayez d'effectuer un traitement de régression sur la table convertie Cette régression utilise une régression robuste en tenant compte des valeurs aberrantes. (Pour plus d'informations sur la régression robuste, ici est facile à comprendre) (Comme j'ai l'habitude de dériver le coefficient de détermination R ^ 2 pour une régression robuste, je le résumerai quand j'aurai le temps. C'est prévu.)

code3.py


import statsmodels.api as sm

pivot_df["model"] = [sm.RLM(i, sm.add_constant(j)) for i,j in zip(pivot_df.x ,pivot_df.y)]
pivot_df["result"] = [i.fit() for i in pivot_df.model]

Avec le code ci-dessus, ** environ 8,8 ms ** par ID Si vous ne sauvegardez pas le "modèle" et que vous vous adaptez à une doublure, ** environ 7,9 ms ** par ID Jusqu'à présent, au total ** environ 9 ms ** par ID

Dans article précédent, il a fallu 1,7 seconde pour extraire 1 ID, donc Même en incluant la régression, le temps de traitement a été réduit à 1/200, et le temps de traitement a été réduit à ** 1/10000 ** par rapport au temps jusqu'au prétraitement de la régression.

■ Conclusion

** Notation d'inclusion la plus forte ** Pour être honnête, le temps de traitement de chacun des 3 millions d'identifiants était ridiculement calculé pour prendre plus d'un an, mais avec un peu d'ingéniosité, il était possible de le tourner pendant environ 8 heures.

(Je vous serais reconnaissant si vous pouviez m'apprendre d'autres bonnes méthodes)

■ Plans futurs

En ce qui concerne la régression, cet article a simplement utilisé StatsModels, mais le coefficient de détermination de la régression robuste ne peut pas être facilement dérivé d'une bibliothèque telle que StatsModels (pour autant que je sache), donc une certaine ingéniosité est nécessaire. Je suis moelleux en pensant que ce serait bien si je pouvais résumer tout en enquêtant sur cela (~~ juste en pensant ~~)

Recommended Posts

Une histoire qui avait du mal à traiter en boucle 3 millions de données d'identification
Une histoire sur la difficulté à traiter en boucle 3 millions de données d'identification
Une histoire à laquelle j'étais accro chez np.where
Une histoire à laquelle j'étais accro à appeler Lambda depuis AWS Lambda.
Une histoire à laquelle j'étais accro après la communication SFTP avec python
Une histoire que Seaborn était facile, pratique et impressionnée
Une histoire qui était terrible si SELinux était correctement désactivé
Comment rédiger un test de traitement utilisant BigQuery
Un script python qui convertit les données Oracle Database en csv
[Python] Une histoire qui semblait tomber dans un piège à contourner
L'histoire selon laquelle la version de python 3.7.7 n'était pas adaptée à Heroku
Une histoire que Qiita voulait vraiment voir dans un environnement proxy
L'histoire selon laquelle le gardien était confiné lorsque le laboratoire a été converti à l'IoT
Création d'un service qui vous permet de rechercher des données J-League
Une histoire accro aux pipelines Azure
Une histoire à laquelle j'étais accro à essayer d'obtenir une URL de vidéo avec tweepy
Une histoire qui a souffert d'une différence de système d'exploitation lors de la tentative d'implémentation d'un article