[PYTHON] J'ai essayé d'utiliser GLM (modèle linéaire généralisé) pour les données de prix des actions

introduction

Lorsque nous examinons la relation entre les deux données sur le cours des actions, nous commençons généralement l'analyse en supposant que les ratios de profit logarithmiques des deux ont une distribution normale. Cependant, lorsque l'on regarde le prix réel de l'action, il est difficile de voir une distribution normale propre, il est donc nécessaire de prêter une attention particulière aux valeurs statistiques de sortie lors de l'analyse de régression à l'aide d'un modèle linéaire.

Il existe GLM (= modèle linéaire généralisé) en tant que modèle qui gère les relations qui n'ont pas de distribution normale, mais pour l'appliquer, il est nécessaire d'apprendre le concept de modélisation statistique, et certaines lacunes techniques sont nécessaires. Je le sens. Cependant, comme il est supporté par python ** statsmodels **, j'ai décidé de l'utiliser en "trial" sans trop penser à la rigueur.

Premièrement, nous avons choisi les actions liées à l'automobile (3 sociétés) de la première section de la Bourse de Tokyo comme cibles d'analyse. Le diagramme de dispersion de la marge logarithmique de trois combinaisons de deux sociétés sélectionnées parmi trois sociétés est présenté dans la figure ci-dessous.

scatter01.png

Il peut être confirmé que tous les trois ont une corrélation positive pas si forte (faible). Nous avons décidé de prendre les données intermédiaires (stock2 vs stock3) de ces trois et d'effectuer une analyse de régression. À propos, stock2 est un stock avec le code stock 7203 et stock3 est un stock avec le code stock 7267.

Application d'un modèle linéaire

Tout d'abord, une analyse de régression a été effectuée à l'aide du modèle linéaire. Le code est le suivant jusqu'à la lecture des données et l'analyse de régression du modèle linéaire.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import statsmodels.api as sm

    
def my_tof(s):
	f1 = float(s.replace(',', ''))
	return f1

# pandas read_csv()
my_colmn = ['Date', 'Open', 'High', 'Low', 'Close', 'Diff', 'Volume', 'cH', 'cI', 'cJ', 'cK', 'cL', 'cM', 'cN', 'cO']

index = pd.date_range(start='2014/1/1', end='2014/12/31', freq='B')
stock_raw = pd.DataFrame(index=index)
mydf = pd.DataFrame(index=index)

stock1 = pd.read_csv('./x7201-2014.csv', index_col=0, parse_dates=True, skiprows=1, names=my_colmn, header=None)
stock_raw['stock1'] = stock1[::-1].loc[:, 'Close']
stock2 = pd.read_csv('./x7203-2014.csv', index_col=0, parse_dates=True, skiprows=1, names=my_colmn, header=None)
stock_raw['stock2'] = stock2[::-1].loc[:, 'Close']
stock3 = pd.read_csv('./x7267-2014.csv', index_col=0, parse_dates=True, skiprows=1, names=my_colmn, header=None)
stock_raw['stock3'] = stock3[::-1].loc[:, 'Close']

stock_raw.dropna(inplace=True)
stock_base_label = ['stock1', 'stock2', 'stock3']

for st in stock_base_label:
	st_price = st + '_p'
	st_return = st + '_ret'
	st_log_return = st + '_lgret'
	
	mydf[st_price] = stock_raw[st].apply(my_tof)
	mydf[st_price].fillna(method='ffill', inplace=True)
	mydf[st_return] = mydf[st_price] / mydf[st_price].shift(1)
	mydf[st_log_return] = np.log(mydf[st_return])

# scatter plotting
(Omis)

# apply OLS model 
mydf.dropna(inplace=True)

x1 = mydf['stock2_lgret'].values    # stock2 log-return
x1a = sm.add_constant(x1)
y1 = mydf['stock3_lgret'].values    # stock3 log-return

# OLS (linear model)
md0 = sm.OLS(y1, x1a)
res0 = md0.fit()
print res0.summary()

plt.figure(figsize=(5,4))
plt.scatter(mydf['stock2_lgret'], mydf['stock3_lgret'], c='b', alpha=0.6)
plt.plot(x1, res0.fittedvalues, 'r-', label='Linear Model')
plt.grid(True)

Comme ci-dessus, statsmodels.api.OLS () est utilisé. En conséquence, le graphique suivant a été obtenu.

Fig. stock2 vs. stock3 (Log Return) Linear Model scatter_md0.png

GLM (Gaussian distribution) Ensuite, une analyse de régression GLM est effectuée. Le GLM (modèle linéaire généralisé) des statsmodels prend en charge les distributions de probabilité utilisables suivantes (appelées famille). (Extrait du document)

Families for GLM(Generalized Linear Model)

Family The parent class for one-parameter exponential families. Remark
Binomial Binomial exponential family distribution. Distribution binaire
Gamma Gamma exponential family distribution. Distribution gamma
Gaussian Gaussian exponential family distribution. Distribution gaussienne
InverseGaussian InverseGaussian exponential family. Distribution gaussienne inverse
NegativeBinomial Negative Binomial exponential family. Distribution binomiale négative
Poisson Poisson exponential family. Distribution de Poisson

De plus, la fonction de lien qui peut être utilisée (devient une combinaison) est déterminée pour chaque famille. (Extrait du document) La fonction de lien peut être spécifiée en option, mais si elle n'est pas spécifiée, la fonction par défaut semble être utilisée.

ident log logit probit cloglog pow opow nbinom loglog logc
Gaussian x x x
inv Gaussian x x x
binomial x x x x x x x x x
Poission x x x
neg binomial x x x x
gamma x x x

Tout d'abord, le calcul a été effectué à l'aide de la fonction gaussienne. Le code est le suivant.


# apply GLM(Gaussian) model
md1 = sm.GLM(y1, x1a, family=sm.families.Gaussian())    # Gaussian()
res1 = md1.fit()
print res1.summary()

plt.figure(figsize=(5,4))
plt.scatter(mydf['stock2_lgret'], mydf['stock3_lgret'], c='g', alpha=0.6)
plt.plot(x1, res1.fittedvalues, 'r-', label='GLM(Gaussian)')
plt.grid(True)

Fig. stock2 vs. stock3 (GLM(gaussian dist.)) scatter_md1.png

La ligne ajustée par GLM ne semble pas du tout changer par rapport à la figure ci-dessus. Comparez le résumé des résultats du calcul ().

** Résumé OLS **

In [71]: print res0.summary()
                            OLS Regression Results
==============================================================================
Dep. Variable:                      y   R-squared:                       0.486
Model:                            OLS   Adj. R-squared:                  0.484
Method:                 Least Squares   F-statistic:                     241.1
Date:                Sun, 26 Jul 2015   Prob (F-statistic):           1.02e-38
Time:                        16:18:16   Log-Likelihood:                 803.92
No. Observations:                 257   AIC:                            -1604.
Df Residuals:                     255   BIC:                            -1597.
Df Model:                           1
Covariance Type:            nonrobust
==============================================================================
                 coef    std err          t      P>|t|      [95.0% Conf. Int.]
------------------------------------------------------------------------------
const         -0.0013      0.001     -1.930      0.055        -0.003  2.64e-05
x1             0.7523      0.048     15.526      0.000         0.657     0.848
==============================================================================
Omnibus:                       10.243   Durbin-Watson:                   1.997
Prob(Omnibus):                  0.006   Jarque-Bera (JB):               16.017
Skew:                          -0.235   Prob(JB):                     0.000333
Kurtosis:                       4.129   Cond. No.                         73.0
==============================================================================

** GLM (dist. Gaussienne) Résumé **

In [72]: print res1.summary()

                 Generalized Linear Model Regression Results
==============================================================================
Dep. Variable:                      y   No. Observations:                  257
Model:                            GLM   Df Residuals:                      255
Model Family:                Gaussian   Df Model:                            1
Link Function:               identity   Scale:                0.00011321157031
Method:                          IRLS   Log-Likelihood:                 803.92
Date:                Sun, 26 Jul 2015   Deviance:                     0.028869
Time:                        16:12:11   Pearson chi2:                   0.0289
No. Iterations:                     4
==============================================================================
                 coef    std err          z      P>|z|      [95.0% Conf. Int.]
------------------------------------------------------------------------------
const         -0.0013      0.001     -1.930      0.054        -0.003  2.02e-05
x1             0.7523      0.048     15.526      0.000         0.657     0.847
==============================================================================

On peut voir que le contenu des deux sorties est assez différent.

Dans OLS, les valeurs de R-carré, AIC et BIC sont sorties, mais dans GLM, elles ne sont pas sorties, et à la place, les statistiques de déviance (degré de déviation), Pearson chi2, etc. sont sorties. Comme pour les deux, la valeur numérique de Log-Likelihood (Log-Probabilité) est sortie.

A partir de la sortie de GLM, on peut voir que la fonction de liaison est définie sur «identité» (fonction de liaison égale). De plus, comme le coefficient de régression partielle était la même valeur (-0,0013, 0,7523) pour les MCO et les GLM, il a été confirmé que les résultats (contenu) de l'analyse de régression étaient les mêmes.

GLM (Gamma distribution)

Ensuite, j'ai essayé de calculer GLM en utilisant la distribution Gamma comme distribution. Je pensais qu'il était discutable de savoir si la distribution gamma pouvait bien exprimer le taux de profit boursier, mais je l'ai essayé dans le but d'essayer un calcul de type GLM.

Le problème avec l'exécution du calcul est que le ratio boursier logarithmique prend une valeur négative lorsque le cours de l'action baisse, mais cela se situe en dehors de la plage de distribution gamma. Par conséquent, le calcul a été effectué avec le taux de retour du cours de l'action avant de prendre le logarithme comme valeur y. (Je ne peux pas nier que je me sens un peu forcé ...)

# apply GLM(gamma) model

x2 = x1 ; x2a = x1a
y2 = mydf['stock3_ret'].values    # replaced

md2 = sm.GLM(y2, x2a, family=sm.families.Gamma())
res2 = md2.fit()

# print summary and plot fitting curve
print res2.summary()
plt.figure(figsize=(5,4))
plt.scatter(mydf['stock2_lgret'], mydf['stock3_ret'], c='c', alpha=0.6)
plt.plot(x2, res2.fittedvalues, 'r-', label='GLM(Gamma)')
plt.grid(True)

y2_fit_log = np.log(res2.fittedvalues)
plt.figure(figsize=(5,4))
plt.scatter(mydf['stock2_lgret'], mydf['stock3_lgret'], c='c', alpha=0.6)
plt.plot(x2, y2_fit_log, 'r-', label='GLM(Gamma)')

Fig. stock2 vs. stock3 (GLM(gamma dist.)) (log - ident) scatter_md2(log-ident).png ** (log --log) ** (valeur y convertie) scatter_md2(log-log).png

Sous forme de graphique, le même résultat a été obtenu. Regardons summary ().

In [73]: print res2.summary()

                 Generalized Linear Model Regression Results
==============================================================================
Dep. Variable:                      y   No. Observations:                  257
Model:                            GLM   Df Residuals:                      255
Model Family:                   Gamma   Df Model:                            1
Link Function:          inverse_power   Scale:               0.000113369003649
Method:                          IRLS   Log-Likelihood:                 803.72
Date:                Sun, 26 Jul 2015   Deviance:                     0.028956
Time:                        16:12:16   Pearson chi2:                   0.0289
No. Iterations:                     5
==============================================================================
                 coef    std err          z      P>|z|      [95.0% Conf. Int.]
------------------------------------------------------------------------------
const          1.0013      0.001   1502.765      0.000         1.000     1.003
x1            -0.7491      0.048    -15.470      0.000        -0.844    -0.654
==============================================================================

En passant de GLM (dist. Gaussienne) à GLM (dist. Gamma), la valeur de log-vraisemblance et de déviance a légèrement changé. Cependant, il est certain que le modèle n'a pas tellement changé qu'il pourrait être amélioré. Puisque la valeur y a été convertie et calculée, le coefficient de régression partielle est différent.

Avant et après, afin de confirmer la normalité des données, un histogramme du retour logarithmique de stock2 et stock3 a été dessiné. La forme était comme indiqué dans la figure ci-dessous.

histogram2.png

Conclusion pour le moment

Dans cette analyse de données, nous n'avons pas pu confirmer l'amélioration de la précision du modèle en appliquant le GLM. On considère que cela est dû au fait que le cours des actions du même secteur (la période est d'environ un an) n'était pas compliqué (non linéaire). Cependant, ce n'est pas une mauvaise chose que le nombre d'outils pouvant être utilisés pour analyser diverses données augmentera à l'avenir, je voudrais donc approfondir ma compréhension du GLM et d'autres méthodes avancées d'analyse de régression.

Cette fois (actions de la société A du constructeur automobile et actions de la société B) n'a pas montré sa puissance, mais il est possible qu'elle puisse être utilisée efficacement en combinaison avec une couleur de cheveux légèrement différente, par exemple (température maximale vs stock de la société de bière). Sont attendus.

Les références

--statsmodels documentation http://statsmodels.sourceforge.net/stable/glm.html

--Introduction aux statistiques (Département de statistique, Faculté des arts libéraux, Université de Tokyo) http://www.utp.or.jp/bd/978-4-13-042065-5.html

--Introduction à la modélisation statistique pour l'analyse des données (Kubo, Iwanami Shoten) https://www.iwanami.co.jp/cgi-bin/isearch?isbn=ISBN978-4-00-006973-1

Recommended Posts

J'ai essayé d'utiliser GLM (modèle linéaire généralisé) pour les données de prix des actions
Introduction à la modélisation statistique pour le modèle linéaire généralisé d'analyse de données (GLM)
J'ai essayé d'utiliser l'API de données YOUTUBE V3
J'ai essayé d'utiliser Firebase pour le serveur de cache de Django
Prévision du cours de l'action à l'aide du Deep Learning [acquisition de données]
J'ai essayé DBM avec Pylearn 2 en utilisant des données artificielles
■ Kaggle Practice for Beginners -House Sale Price (j'ai essayé d'utiliser PyCaret) -par Google Colaboratory
J'ai essayé d'implémenter diverses méthodes d'apprentissage automatique (modèle de prédiction) en utilisant scicit-learn
J'ai essayé d'utiliser paramétré
J'ai essayé d'utiliser argparse
J'ai essayé d'utiliser la mimesis
J'ai essayé d'utiliser anytree
J'ai essayé d'utiliser aiomysql
J'ai essayé d'utiliser Summpy
J'ai essayé d'utiliser coturn
J'ai essayé d'utiliser Pipenv
J'ai essayé d'héberger un exemple de modèle de Pytorch en utilisant TorchServe
J'ai essayé d'utiliser matplotlib
J'ai essayé d'utiliser "Anvil".
J'ai essayé d'utiliser Hubot
J'ai essayé d'utiliser ESPCN
J'ai essayé d'utiliser openpyxl
J'ai essayé de regrouper les données ECG en utilisant la méthode K-Shape
J'ai essayé d'utiliser Ipython
J'ai essayé d'utiliser PyCaret
J'ai essayé d'utiliser cron
J'ai essayé d'utiliser l'API de Sakenowa Data Project
J'ai essayé d'utiliser ngrok
J'ai essayé d'utiliser face_recognition
J'ai essayé d'utiliser Jupyter
J'ai essayé de lire les données d'un fichier en utilisant Node.js.
J'ai essayé d'utiliser doctest
J'ai essayé d'utiliser du folium
J'ai essayé d'utiliser jinja2
J'ai essayé d'utiliser du folium
J'ai essayé d'utiliser la fenêtre de temps
Le modèle linéaire généralisé (GLM) et le réseau neuronal sont les mêmes (1)
J'ai essayé de rechercher des vidéos à l'aide de l'API de données Youtube (débutant)
J'ai essayé de refactoriser le modèle CNN de TensorFlow en utilisant TF-Slim
J'ai essayé d'héberger un modèle d'apprentissage en profondeur de TensorFlow à l'aide de TensorFlow Serving
J'ai essayé d'utiliser Tensorboard, un outil de visualisation pour l'apprentissage automatique
Le modèle linéaire généralisé (GLM) et le réseau neuronal sont les mêmes (2)
Notes diverses sur l'utilisation de python pour les projets
[Python] J'ai essayé de collecter des données en utilisant l'API de wikipedia
J'ai essayé d'analyser les données scRNA-seq en utilisant l'analyse des données topologiques (TDA)
Introduction à la modélisation statistique pour l'analyse des données Sélection du modèle GLM
J'ai essayé d'obtenir rapidement des données d'AS / 400 en utilisant pypyodbc
[Pour les débutants] J'ai essayé d'utiliser l'API Tensorflow Object Detection
[J'ai essayé d'utiliser Pythonista 3] Introduction
J'ai essayé d'utiliser RandomForest
J'ai essayé d'utiliser BigQuery ML
J'ai essayé d'utiliser Amazon Glacier
J'ai essayé d'utiliser git inspector
Prévision du cours de l'action avec LSTM_1
J'ai essayé d'utiliser magenta / TensorFlow