Histoire d'approximation de puissance par Python

L'histoire commence par dessiner une courbe d'approximation de puissance avec EXCEL

Il y avait une certaine décomposition des données de séries chronologiques, et quand j'ai essayé de dessiner une courbe d'approximation avec EXCEL, l'approximation de puissance était un bon sentiment, j'ai donc décidé de la reproduire avec Python au lieu d'EXCEL pour des raisons commerciales. En l'essayant, cela ne convient pas pour une raison quelconque ... Quand je me suis demandé pourquoi, je suis arrivé aux informations suivantes. Multiplier l'approximation par Python La plupart des problèmes peuvent être résolus en regardant ce site, mais j'écrirai un article pour mon mémorandum.

Différence entre l'approximation de puissance par curve_fit de scipy et l'approximation de puissance d'EXCEL

L'expression de puissance est définie comme suit.   y = bx^{a} La fonction curve_fit de scipy effectue une régression non linéaire qui renvoie $ a $ et $ b $ qui sont les plus similaires aux données de l'équation ci-dessus.

Alors qu'en est-il de EXCEL? L'équation ci-dessus peut être convertie comme suit.   y = bx^{a} $ \ Rightarrow \ ln y = \ ln (bx ^ {a}) ・ ・ ・ (prendre un logarithme) $ $ \ Flèche droite \ ln y = a \ ln x + \ ln b ・ ・ ・ (décomposer le côté droit) $ $ \ Rightarrow Y = aX + B ・ ・ ・ (résumer la partie logarithmique comme une nouvelle variable) $ En prenant le logarithme logarithmique de cette manière, une régression linéaire de $ Y = aX + B $ peut être effectuée. En d'autres termes, il semble que l'approximation de puissance d'EXCEL produit le résultat de la ** conversion logarithmique et de la régression linéaire **.

Essayez-le avec Python

Voyons ce qui se passe réellement avec Python. Pour les données, nous utiliserons les données sur l'évolution du nombre de décès infantiles et des taux de mortalité dans le «Livre blanc 2011 sur les enfants et les jeunes» sur la page du Cabinet Office. «Livre blanc 2011 sur les enfants et les jeunes» Évolution du nombre de décès infantiles et des taux de mortalité

Lisez d'abord les données

read_data.py


import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import pandas as pd

df=pd.read_csv('Mortalité infantile.csv',encoding='cp932') #Encodage avec prévention déformée='cp932'
display(df)

image.png

Moulé car il a une structure étrange

adjust_data.py


df=df.iloc[3:18,:].rename(columns={'1er-1-Figure 6 Évolution du nombre de décès infantiles et des taux de mortalité':'Annuel'\
                                 ,'Unnamed: 1':'Décès infantile (personnes)'\
                                 ,'Unnamed: 2':'Décès infantile (milliers)'\
                                 ,'Unnamed: 3':'Mortalité infantile'})
#Créer des colonnes de numéros de série pour un traitement ultérieur
rank=range(1,len(df)+1)
df['rank']=rank
#Le taux de mortalité infantile est de type flottant car toutes les colonnes sont de type objet
df['Mortalité infantile']=df['Mortalité infantile'].astype(float)
df['Décès infantile (personnes)']=df['Décès infantile (personnes)'].str.replace(',','').astype(np.int)
display(df)

image.png

Graphique de mortalité infantile

plot.py


x=df['Annuel']
y=df['Mortalité infantile']
ax=plt.subplot(1,1,1)
ax.plot(x,y)
ax.set_xlabel('Annuel')
ax.set_ylabel('Mortalité infantile')
plt.show()

image.png Le taux de mortalité infantile est bien inférieur à ce qu'il était il y a 60 ans. Les progrès des soins médicaux sont incroyables. Il est maintenant temps de trouver les paramètres approximatifs.

Régression non linéaire avec curve_fit de scipy

func.py


def exp_func(x, a, b):
    return b*(x**a)

def exp_fit(val1_quan, val2_quan):
    #maxfev: nombre maximum d'appels de fonction, check_fini: si True, ValueError se produit si NaN est inclus.
    l_popt, l_pcov = curve_fit(exp_func, val1_quan, val2_quan, maxfev=10000, check_finite=False)
    return exp_func(val1_quan, *l_popt),l_popt

Trouvez les paramètres $ a $ et $ b $ de exp_func en utilisant exp_fit.

culc_params.py


x=df['Annuel']
x2=df['rank']
y=df['Mortalité infantile']
y_fit,l_popt=exp_fit(x2,y)

ax=plt.subplot(1,1,1)
ax.plot(x,y,label='obs')
ax.plot(x,y_fit,label='model')
ax.set_xlabel('Annuel')
ax.set_ylabel('Mortalité infantile')
plt.legend()
plt.show()
print('a : {},   b : {}'.format(l_popt[0],l_popt[1]))#Paramètre obtenu a,Vérifier b

image.png

Bon sentiment.

Reproduction de l'approximation de puissance d'EXCEL (conversion logariale et régression linéaire)

func2.py


def exp_func_log(x, a, b):
    return a*np.log(x) + np.log(b)

def exp_func_log_fit(val1_quan, val2_quan):
    l_popt, l_pcov = curve_fit(exp_func_log, val1_quan, np.log(val2_quan), maxfev=10000, check_finite=False)
    return exp_func_log(val1_quan, *l_popt),l_popt

def log_to_exp(x,a,b):
    return np.exp(a*np.log(x) + np.log(b))

Trouvez les paramètres $ a $ et $ b $ de exp_func_log en utilisant exp_func_log_fit. Puisque $ Y $ approché en utilisant les paramètres obtenus $ a $ et $ b $ est $ \ ln y $, log_to_exp est utilisé pour le convertir à partir de la valeur logarithmique et le renvoyer.

culc_params2.py


x=df['Annuel']
x2=df['rank']
y=df['Mortalité infantile']
y_fit,l_popt=exp_func_log_fit(x2,y)
y_fit=log_to_exp(x2,l_popt[0],l_popt[1])

ax=plt.subplot(1,1,1)
ax.plot(x,y,label='obs')
ax.plot(x,y_fit,label='model')
ax.set_xlabel('Annuel')
ax.set_ylabel('Mortalité infantile')
plt.legend()
plt.show()
print('a : {},   b : {}'.format(l_popt[0],l_popt[1])) #Paramètre obtenu a,Vérifier b

image.png Cela fait du bien, mais je pense que la régression non linéaire directe était plus applicable.

Résumé

Je ne sais pas laquelle me convient. Cependant, si vous vous retrouvez dans une situation où "EXCEL peut le faire, mais Python ne fait pas la même chose!", Vous voudrez peut-être vous en souvenir.

Postscript (immédiatement après la rédaction du 28/02/2020)

Lorsque la valeur numérique des données est grande et floue, l'approximation par régression non linéaire est facilement tirée par la grande fluctuation de la valeur numérique. Du point de vue de la capacité de généralisation, il peut être préférable d'effectuer une transformation logarithmique et une régression linéaire.

Insérez un nombre fictif dans le nombre de décès infantiles (personnes)

dummydata.py


df=pd.read_csv('Mortalité infantile.csv',encoding='cp932')
df=df.iloc[3:18,:].rename(columns={'1er-1-Figure 6 Évolution du nombre de décès infantiles et des taux de mortalité':'Annuel'\
                                 ,'Unnamed: 1':'Décès infantile (personnes)'\
                                 ,'Unnamed: 2':'Décès infantile (milliers)'\
                                 ,'Unnamed: 3':'Mortalité infantile'})
#Créer des colonnes de numéros de série pour un traitement ultérieur
rank=range(1,len(df)+1)
df['rank']=rank
#Le taux de mortalité infantile est de type flottant car toutes les colonnes sont de type objet
df['Mortalité infantile']=df['Mortalité infantile'].astype(float)
df['Décès infantile (personnes)']=df['Décès infantile (personnes)'].str.replace(',','').astype(np.int)

#Insérer des données factices
df2=df.copy()
df2.loc[df2['Annuel']=='Heisei 2', 'Décès infantile (personnes)']=60000
df2.loc[df2['Annuel']=='13', 'Décès infantile (personnes)']=40000
df2.loc[df2['Annuel']=='15', 'Décès infantile (personnes)']=20000
df2.loc[df2['Annuel']=='18', 'Décès infantile (personnes)']=10000
display(df2)

x=df2['Annuel']
y=df2['Décès infantile (personnes)']
ax=plt.subplot(1,1,1)
ax.plot(x,y)
ax.set_xlabel('Annuel')
ax.set_ylabel('Décès infantile (personnes)')
ax.set_title('Numéros factices en 1990,13,15,Insérer dans 18')
plt.show()

image.png image.png

Tracez à nouveau une courbe approximative en utilisant la fonction utilisée dans ce volume

dummydata.py


#Régression non linéaire
x=df2['Annuel']
x2=df2['rank']
y=df2['Décès infantile (personnes)']
y_fit,l_popt=exp_fit(x2,y)

ax=plt.subplot(1,1,1)
ax.plot(x,y,label='obs')
ax.plot(x,y_fit,label='model')
ax.set_xlabel('Annuel')
ax.set_ylabel('Décès infantile (personnes)')
plt.legend()
plt.show()
print('a : {},   b : {}'.format(l_popt[0],l_popt[1]))

#Régression linéaire de transformation logistique
x=df2['Annuel']
x2=df2['rank']
y=df2['Décès infantile (personnes)']
y_fit,l_popt=exp_func_log_fit(x2,y)
y_fit=log_to_exp(x2,l_popt[0],l_popt[1])

ax=plt.subplot(1,1,1)
ax.plot(x,y,label='obs')
ax.plot(x,y_fit,label='model')
ax.set_xlabel('Annuel')
ax.set_ylabel('Décès infantile (personnes)')
plt.legend()
plt.show()
print('a : {},   b : {}'.format(l_popt[0],l_popt[1]))

Approximative avec régression non linéaire image.png Approximation avec régression linéaire de transformation logarithmique image.png

Évidemment, celle approchée par la régression non linéaire est tirée par la fluctuation de la valeur numérique saisie dans le mannequin. Il semble important de bien les distinguer et de les utiliser en fonction de la situation.

Recommended Posts

Histoire d'approximation de puissance par Python
Le pouvoir des pandas: Python
L'histoire de Python et l'histoire de NaN
Extension du dictionnaire python par argument
Comportement de python3 par le serveur de Sakura
Enquête sur l'alimentation CC contrôlable par Python
Explication du modèle d'optimisation de la production par Python
Approximation de bas rang des images par HOSVD étape par étape
Approximation de bas rang de l'image par décomposition de Tucker
[Mémo d'apprentissage] Bases de la classe par python
Branchement conditionnel de Python appris avec la chimioinfomatique
Échelle de gris par matrice-Reinventor of Python image processing-
L'histoire de la manipulation des variables globales Python
Pandas du débutant, par le débutant, pour le débutant [Python]
Analyse d'image de microtomographie à rayons X par Python
L'histoire du traitement A du blackjack (python)
Les bases de Python ①
Bases de python ①
Copie de python
Introduction de Python
Approximation de bas rang des images par décomposition de singularité
Approximation de bas rang des images par HOSVD et HOOI
Traitement d'image? L'histoire du démarrage de Python pour
L'histoire de la lecture des données HSPICE en Python
Exécutez Power Query en passant des arguments à Python
Histoire de base de l'héritage en Python (pour les débutants)
Jugement des nombres premiers par Python
[Python] Opération d'énumération
Liste des modules python
[Traitement du langage 100 coups 2020] Résumé des exemples de réponses par Python
Traitement d'image par matrice Basics & Contents-Reinventor of Python image processing-
L'histoire de Python sans opérateurs d'incrémentation et de décrémentation.
Mémo de visualisation par Python
Traitement de la communication par Python
Unification de l'environnement Python
Copie des préférences python
L'histoire de l'inadéquation de Hash Sum causée par gcrypto20
Résumé des articles sur Python du chercheur Yukiya dans une société pharmaceutique
Principes de base du grattage Python
[python] comportement d'argmax
petite histoire de python
Utilisation des locaux Python ()
le zen de Python
L'histoire de FileNotFound en Python open () mode = 'w'
Installation de Python 3.3 rc1
L'histoire de sys.path.append ()
# 4 [python] Bases des fonctions
Réponse de Beamformer par python
Connaissance de base de Python
Anecdotes sobres de python3
Résumé des arguments Python
Regrouper par éléments consécutifs d'une liste en Python
Bases de python: sortie
L'histoire de la conversion automatique du langage de TypeScript / JavaScript / Python
Installation de matplotlib (Python 3.3.2)
Application de Python 3 vars
Mémo de "Cython-Accélérer Python en fusionnant avec C"
Divers traitements de Python