Abstract
We analyze different money supply concepts and its relation to the GDP. The example is draw following Gujarati and Porter (2011, p.157) using Python in RStudio.This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
License: CC BY-SA 4.0
Sugestão de citação: FIGUEIREDO, Adriano Marcos Rodrigues. Econometria em Python: Tabela 5.6 PNB e demanda de moeda, Gujarati e Porter (2011, p.157). Campo Grande-MS,Brasil: RStudio/Rpubs, 2022. Disponível em http://rpubs.com/amrofi/Gujarati_tab5_6_python.
Esse post é semelhante ao que uso no video do Youtube em: https://youtu.be/lpni-E1PAbU, ECONOMETRIA 2020.2 Slides 02a Instalação R e RStudio. Mas nesse caso trabalharei o código em Python.
Os primeiros passos são criar ou abrir um diretório de trabalho. Se optar por criar um novo projeto, haverá a possibilidade de criar em uma pasta vazia. Em seguida, sugere-se que coloque os dados nesta pasta, se possível em um arquivo MS Excel e chame a planilha de ‘dados’.Neste caso, a planilha chama-se Tabela 5.6aula_gujarati 5ed p157.xlsx.
A Tabela 5.6 apresenta dados sobre o PNB e quatro definições do estoque de moeda dos Estados Unidos no período 1970-1983. Fazendo as regressões do PNB contra as várias definições de moeda, obtemos os resultados apresentados na Tabela 5.7. Os monetaristas ou adeptos da teoria quantitativa afirmam que a renda nominal (o PNB nominal) é determinada, em grande parte, pela variação na quantidade ou estoque de moeda, embora não haja consenso quanto à definição “certa” de moeda. De acordo com os resultados, responda às seguintes perguntas:
a. Que definição de moeda parece apresentar relação mais estreita com o PNB nominal?
b. Como os \(R^2\) são todos elevados, isso significa que a escolha da definição de moeda não tem importância?
c. Se o FED (Banco Central dos Estados Unidos) quer controlar a oferta de moeda, qual desses indicadores de moeda seria o melhor objetivo para esse fim? Isso pode ser dito com base nos resultados da regressão?
Exercício para os dados da tabela 5.6, conforme Gujarati (2011, p.157), PNB e estoque de moeda segundo quatro critérios, Estados Unidos, 1970-1983.
Usarei o pacote reticulate
em um primeiro chunk em R,
para depois rodar chunks em python dentro do RStudio.
# chunk em R
library(reticulate)
# py_install('openpyxl') # para instalar pacote openpyxl se acusar avisos de
# nova versao do conda, abrir o Terminal e executar como abaixo conda update -n
# base -c defaults conda
Coloco aqui a opção de download do xlsx mas coloquei os dados embeded no code para quem quiser. É só executar o chunk a seguir que conseguem carregar os dados.
# chunk em python
# atualizar o caminho do arquivo xlsx a ser lido
import pandas as pd
# precisei instalar openpyxl (para xlsx) e xlrd (para xls)
# neste caso, os dados estão na sheet 'dados'
df = pd.read_excel (r'E:\disciplinas\econometria\laboratorio_Python\demanda_moeda_gujarati_tab5-6\Tabela 5.6aula_gujarati 5ed p157.xlsx', sheet_name='dados')
# exibir dados e checar se vieram corretamente
print (df[["ANO" , "PNB" , "M1" , "M2" , "M3","L"]])
ANO PNB M1 M2 M3 L
0 1970 992.7 216.6 628.2 677.5 816.3
1 1971 1077.6 230.8 712.8 776.2 903.1
2 1972 1185.9 252.0 805.2 886.0 1023.0
3 1973 1326.4 265.9 861.0 985.0 1141.7
4 1974 1434.2 277.6 908.5 1070.5 1249.3
5 1975 1549.2 291.2 1023.3 1174.2 1367.9
6 1976 1718.0 310.4 1163.6 1311.9 1516.6
7 1977 1918.3 335.4 1286.7 1472.9 1704.7
8 1978 2163.9 363.1 1389.1 1647.1 1910.6
9 1979 2417.8 389.1 1498.5 1804.8 2117.1
10 1980 2631.7 414.9 1632.6 1990.0 2326.2
11 1981 2957.8 441.9 1796.6 2238.2 2599.8
12 1982 3069.3 480.5 1965.4 2462.5 2870.8
13 1983 3304.8 525.4 2196.3 2710.4 3183.1
Portanto, temos 14 observações para 6 variáveis dentro do DataFrame
de 14 linhas e 6 colunas. Podemos extrair a estrutura dos dados fazendo
o código semelhante ao dput
do R (link).
#data_as_dict= print(df.to_dict())
#df = pd.DataFrame.from_dict(data_as_dict)
df = pd.DataFrame.from_dict({'ANO': {0: 1970, 1: 1971, 2: 1972, 3: 1973, 4: 1974, 5: 1975, 6: 1976, 7: 1977, 8: 1978, 9: 1979, 10: 1980, 11: 1981, 12: 1982, 13: 1983}, 'PNB': {0: 992.7, 1: 1077.6, 2: 1185.9, 3: 1326.4, 4: 1434.2, 5: 1549.2, 6: 1718.0, 7: 1918.3, 8: 2163.9, 9: 2417.8, 10: 2631.7, 11: 2957.8, 12: 3069.3, 13: 3304.8}, 'M1': {0: 216.6, 1: 230.8, 2: 252.0, 3: 265.9, 4: 277.6, 5: 291.2, 6: 310.4, 7: 335.4, 8: 363.1, 9: 389.1, 10: 414.9, 11: 441.9, 12: 480.5, 13: 525.4}, 'M2': {0: 628.2, 1: 712.8, 2: 805.2, 3: 861.0, 4: 908.5, 5: 1023.3, 6: 1163.6, 7: 1286.7, 8: 1389.1, 9: 1498.5, 10: 1632.6, 11: 1796.6, 12: 1965.4, 13: 2196.3}, 'M3': {0: 677.5, 1: 776.2, 2: 886.0, 3: 985.0, 4: 1070.5, 5: 1174.2, 6: 1311.9, 7: 1472.9, 8: 1647.1, 9: 1804.8, 10: 1990.0, 11: 2238.2, 12: 2462.5, 13: 2710.4}, 'L': {0: 816.3, 1: 903.1, 2: 1023.0, 3: 1141.7, 4: 1249.3, 5: 1367.9, 6: 1516.6, 7: 1704.7, 8: 1910.6, 9: 2117.1, 10: 2326.2, 11: 2599.8, 12: 2870.8, 13: 3183.1}})
Vamos ver como está a tabela importada (usarei o knitr::kable para facilitar a exibição):
knitr::kable(py$df, caption = "Dados da tabela 5.6")
ANO | PNB | M1 | M2 | M3 | L | |
---|---|---|---|---|---|---|
0 | 1970 | 992.7 | 216.6 | 628.2 | 677.5 | 816.3 |
1 | 1971 | 1077.6 | 230.8 | 712.8 | 776.2 | 903.1 |
2 | 1972 | 1185.9 | 252.0 | 805.2 | 886.0 | 1023.0 |
3 | 1973 | 1326.4 | 265.9 | 861.0 | 985.0 | 1141.7 |
4 | 1974 | 1434.2 | 277.6 | 908.5 | 1070.5 | 1249.3 |
5 | 1975 | 1549.2 | 291.2 | 1023.3 | 1174.2 | 1367.9 |
6 | 1976 | 1718.0 | 310.4 | 1163.6 | 1311.9 | 1516.6 |
7 | 1977 | 1918.3 | 335.4 | 1286.7 | 1472.9 | 1704.7 |
8 | 1978 | 2163.9 | 363.1 | 1389.1 | 1647.1 | 1910.6 |
9 | 1979 | 2417.8 | 389.1 | 1498.5 | 1804.8 | 2117.1 |
10 | 1980 | 2631.7 | 414.9 | 1632.6 | 1990.0 | 2326.2 |
11 | 1981 | 2957.8 | 441.9 | 1796.6 | 2238.2 | 2599.8 |
12 | 1982 | 3069.3 | 480.5 | 1965.4 | 2462.5 | 2870.8 |
13 | 1983 | 3304.8 | 525.4 | 2196.3 | 2710.4 | 3183.1 |
Vamos olhar os dados em gráficos de dispersão.
import numpy as np
import pandas as pd
# import seaborn
import seaborn as sns
df = pd.read_excel (r'E:\disciplinas\econometria\laboratorio_Python\demanda_moeda_gujarati_tab5-6\Tabela 5.6aula_gujarati 5ed p157.xlsx', sheet_name='dados')
bplot= sns.scatterplot('M1','PNB',data=df)
FALSE C:\Users\amrof\AppData\Local\R-MINI~1\envs\R-RETI~1\lib\site-packages\seaborn\_decorators.py:36: FutureWarning: Pass the following variables as keyword args: x, y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.
FALSE warnings.warn(
bplot.axes.set_title("Oferta de moeda M1 vs PNB: Gráfico de dispersão",
fontsize=16)
bplot.set_ylabel("PNB",
fontsize=16)
bplot.set_xlabel("Oferta de moeda M1",
fontsize=16)
# dispersao 2
bplot2= sns.scatterplot('M2','PNB',data=df)
FALSE C:\Users\amrof\AppData\Local\R-MINI~1\envs\R-RETI~1\lib\site-packages\seaborn\_decorators.py:36: FutureWarning: Pass the following variables as keyword args: x, y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.
FALSE warnings.warn(
bplot2.axes.set_title("Oferta de moeda M2 vs PNB: Gráfico de dispersão",
fontsize=16)
bplot2.set_ylabel("PNB",
fontsize=16)
bplot2.set_xlabel("Oferta de moeda M2",
fontsize=16)
# dispersao 3
bplot3= sns.scatterplot('M3','PNB',data=df)
FALSE C:\Users\amrof\AppData\Local\R-MINI~1\envs\R-RETI~1\lib\site-packages\seaborn\_decorators.py:36: FutureWarning: Pass the following variables as keyword args: x, y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.
FALSE warnings.warn(
bplot3.axes.set_title("Oferta de moeda M3 vs PNB: Gráfico de dispersão",
fontsize=16)
bplot3.set_ylabel("PNB",
fontsize=16)
bplot3.set_xlabel("Oferta de moeda M3",
fontsize=16)
# dispersao 4
bplot4= sns.scatterplot('L','PNB',data=df)
FALSE C:\Users\amrof\AppData\Local\R-MINI~1\envs\R-RETI~1\lib\site-packages\seaborn\_decorators.py:36: FutureWarning: Pass the following variables as keyword args: x, y. From version 0.12, the only valid positional argument will be `data`, and passing other arguments without an explicit keyword will result in an error or misinterpretation.
FALSE warnings.warn(
bplot4.axes.set_title("Oferta de moeda L vs PNB: Gráfico de dispersão",
fontsize=16)
bplot4.set_ylabel("PNB",
fontsize=16)
bplot4.set_xlabel("Oferta de moeda L",
fontsize=16)
Vamos estimar o modelo linear múltipla fazendo as regressões do PNB contra as várias definições de moeda.
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
df = pd.read_excel (r'E:\disciplinas\econometria\laboratorio_Python\demanda_moeda_gujarati_tab5-6\Tabela 5.6aula_gujarati 5ed p157.xlsx', sheet_name='dados')
import statsmodels.formula.api as sm
eq1 = sm.ols(formula="PNB ~ M1", data=df).fit()
print(eq1.summary())
OLS Regression Results
==============================================================================
Dep. Variable: PNB R-squared: 0.991
Model: OLS Adj. R-squared: 0.990
Method: Least Squares F-statistic: 1354.
Date: Thu, 17 Mar 2022 Prob (F-statistic): 1.04e-13
Time: 18:54:24 Log-Likelihood: -79.468
No. Observations: 14 AIC: 162.9
Df Residuals: 12 BIC: 164.2
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept -787.4724 77.966 -10.100 0.000 -957.347 -617.598
M1 8.0863 0.220 36.801 0.000 7.608 8.565
==============================================================================
Omnibus: 3.736 Durbin-Watson: 1.097
Prob(Omnibus): 0.154 Jarque-Bera (JB): 1.275
Skew: 0.285 Prob(JB): 0.529
Kurtosis: 4.364 Cond. No. 1.36e+03
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 1.36e+03. This might indicate that there are
strong multicollinearity or other numerical problems.
C:\Users\amrof\AppData\Local\R-MINI~1\envs\R-RETI~1\lib\site-packages\scipy\stats\stats.py:1603: UserWarning: kurtosistest only valid for n>=20 ... continuing anyway, n=14
warnings.warn("kurtosistest only valid for n>=20 ... continuing "
eq2 = sm.ols(formula="PNB ~ M2", data=df).fit()
print(eq2.summary())
OLS Regression Results
==============================================================================
Dep. Variable: PNB R-squared: 0.991
Model: OLS Adj. R-squared: 0.990
Method: Least Squares F-statistic: 1254.
Date: Thu, 17 Mar 2022 Prob (F-statistic): 1.64e-13
Time: 18:54:24 Log-Likelihood: -80.003
No. Observations: 14 AIC: 164.0
Df Residuals: 12 BIC: 165.3
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept -44.0626 61.013 -0.722 0.484 -176.999 88.874
M2 1.5875 0.045 35.409 0.000 1.490 1.685
==============================================================================
Omnibus: 0.139 Durbin-Watson: 0.987
Prob(Omnibus): 0.933 Jarque-Bera (JB): 0.125
Skew: 0.136 Prob(JB): 0.939
Kurtosis: 2.625 Cond. No. 3.92e+03
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 3.92e+03. This might indicate that there are
strong multicollinearity or other numerical problems.
C:\Users\amrof\AppData\Local\R-MINI~1\envs\R-RETI~1\lib\site-packages\scipy\stats\stats.py:1603: UserWarning: kurtosistest only valid for n>=20 ... continuing anyway, n=14
warnings.warn("kurtosistest only valid for n>=20 ... continuing "
eq3 = sm.ols(formula="PNB ~ M3", data=df).fit()
print(eq3.summary())
OLS Regression Results
==============================================================================
Dep. Variable: PNB R-squared: 0.994
Model: OLS Adj. R-squared: 0.994
Method: Least Squares F-statistic: 2099.
Date: Thu, 17 Mar 2022 Prob (F-statistic): 7.63e-15
Time: 18:54:24 Log-Likelihood: -76.423
No. Observations: 14 AIC: 156.8
Df Residuals: 12 BIC: 158.1
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept 158.7875 43.041 3.689 0.003 65.010 252.565
M3 1.2036 0.026 45.817 0.000 1.146 1.261
==============================================================================
Omnibus: 0.385 Durbin-Watson: 0.833
Prob(Omnibus): 0.825 Jarque-Bera (JB): 0.108
Skew: 0.192 Prob(JB): 0.948
Kurtosis: 2.805 Cond. No. 4.30e+03
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 4.3e+03. This might indicate that there are
strong multicollinearity or other numerical problems.
C:\Users\amrof\AppData\Local\R-MINI~1\envs\R-RETI~1\lib\site-packages\scipy\stats\stats.py:1603: UserWarning: kurtosistest only valid for n>=20 ... continuing anyway, n=14
warnings.warn("kurtosistest only valid for n>=20 ... continuing "
eq4 = sm.ols(formula="PNB ~ L", data=df).fit()
print(eq4.summary())
# Predict values
OLS Regression Results
==============================================================================
Dep. Variable: PNB R-squared: 0.994
Model: OLS Adj. R-squared: 0.993
Method: Least Squares F-statistic: 1930.
Date: Thu, 17 Mar 2022 Prob (F-statistic): 1.26e-14
Time: 18:54:24 Log-Likelihood: -77.005
No. Observations: 14 AIC: 158.0
Df Residuals: 12 BIC: 159.3
Df Model: 1
Covariance Type: nonrobust
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept 164.2071 44.766 3.668 0.003 66.671 261.744
L 1.0291 0.023 43.937 0.000 0.978 1.080
==============================================================================
Omnibus: 1.395 Durbin-Watson: 0.838
Prob(Omnibus): 0.498 Jarque-Bera (JB): 0.130
Skew: -0.040 Prob(JB): 0.937
Kurtosis: 3.466 Cond. No. 5.00e+03
==============================================================================
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 5e+03. This might indicate that there are
strong multicollinearity or other numerical problems.
C:\Users\amrof\AppData\Local\R-MINI~1\envs\R-RETI~1\lib\site-packages\scipy\stats\stats.py:1603: UserWarning: kurtosistest only valid for n>=20 ... continuing anyway, n=14
warnings.warn("kurtosistest only valid for n>=20 ... continuing "
m1_pred = eq1.predict()
#Podemos visualizar nossa estimativa de yhat com o gráfico de dispersão.
import matplotlib.pyplot as plt
# Plot regression against actual data
plt.figure(figsize=(12, 6))
plt.plot(df['M1'], df['PNB'], 'o') # scatter plot showing actual data
plt.plot(df['M1'], m1_pred, 'r', linewidth=2) # regression line
plt.xlabel('Oferta de moeda M1')
plt.ylabel('PNB')
plt.title('Oferta de moeda M1 vs PNB: Gráfico de dispersão')
plt.show()
# Predict values
m2_pred = eq2.predict()
#Podemos visualizar nossa estimativa de yhat com o gráfico de dispersão.
import matplotlib.pyplot as plt
# Plot regression against actual data
plt.figure(figsize=(12, 6))
plt.plot(df['M2'], df['PNB'], 'o') # scatter plot showing actual data
plt.plot(df['M2'], m2_pred, 'r', linewidth=2) # regression line
plt.xlabel('Oferta de moeda M2')
plt.ylabel('PNB')
plt.title('Oferta de moeda M2 vs PNB: Gráfico de dispersão')
plt.show()
# Predict values
m3_pred = eq3.predict()
#Podemos visualizar nossa estimativa de yhat com o gráfico de dispersão.
import matplotlib.pyplot as plt
# Plot regression against actual data
plt.figure(figsize=(12, 6))
plt.plot(df['M3'], df['PNB'], 'o') # scatter plot showing actual data
plt.plot(df['M3'], m3_pred, 'r', linewidth=2) # regression line
plt.xlabel('Oferta de moeda M3')
plt.ylabel('PNB')
plt.title('Oferta de moeda M3 vs PNB: Gráfico de dispersão')
plt.show()
# Predict values
l_pred = eq4.predict()
#Podemos visualizar nossa estimativa de yhat com o gráfico de dispersão.
import matplotlib.pyplot as plt
# Plot regression against actual data
plt.figure(figsize=(12, 6))
plt.plot(df['L'], df['PNB'], 'o') # scatter plot showing actual data
plt.plot(df['L'], l_pred, 'r', linewidth=2) # regression line
plt.xlabel('Oferta de moeda L')
plt.ylabel('PNB')
plt.title('Oferta de moeda L vs PNB: Gráfico de dispersão')
plt.show()
Este é um exercício introdutório de regressão simples, em que as variáveis são intimamente relacionadas, visto que o conceito de M2 contém M1, o de M3 contém M2, e L contém M3. Ou seja, serve apenas para visualizar como operacionalizar em Python, e eventualmente investigar se as partes acrescentadas em cada conceito podem gerar alguma alteração na relação (o que não era nosso objetivo neste exemplo). Sugiro ao leitor que na sequência realize os testes de resíduos do MQO a fim de melhor observar suas características.