{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Regression Analysis" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "import statsmodels.formula.api as sm\n", "from sklearn.linear_model import LinearRegression\n", "from scipy import stats" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Get the data" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data_str = '''Region Alcohol Tobacco\n", "North 6.47 4.03\n", "Yorkshire 6.13 3.76\n", "Northeast 6.19 3.77\n", "East_Midlands 4.89 3.34\n", "West_Midlands 5.63 3.47\n", "East_Anglia 4.52 2.92\n", "Southeast 5.89 3.20\n", "Southwest 4.79 2.71\n", "Wales 5.27 3.53\n", "Scotland 6.08 4.51\n", "Northern_Ireland 4.02 4.56'''\n", "\n", "# Read in the data. Note that for Python 2.x, you have to change the \"import\" statement\n", "from io import StringIO\n", "df = pd.read_csv(StringIO(data_str), sep=r'\\s+')\n", "\n", "# Plot the data\n", "df.plot('Tobacco', 'Alcohol', style='o')\n", "plt.ylabel('Alcohol')\n", "plt.title('Sales in Several UK Regions')\n", "#plt.show()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Show Regression Analysis" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " OLS Regression Results \n", "==============================================================================\n", "Dep. Variable: Alcohol R-squared: 0.615\n", "Model: OLS Adj. R-squared: 0.567\n", "Method: Least Squares F-statistic: 12.78\n", "Date: Sun, 01 Nov 2015 Prob (F-statistic): 0.00723\n", "Time: 18:30:14 Log-Likelihood: -4.9998\n", "No. Observations: 10 AIC: 14.00\n", "Df Residuals: 8 BIC: 14.60\n", "Df Model: 1 \n", "Covariance Type: nonrobust \n", "==============================================================================\n", " coef std err t P>|t| [95.0% Conf. Int.]\n", "------------------------------------------------------------------------------\n", "Intercept 2.0412 1.001 2.038 0.076 -0.268 4.350\n", "Tobacco 1.0059 0.281 3.576 0.007 0.357 1.655\n", "==============================================================================\n", "Omnibus: 2.542 Durbin-Watson: 1.975\n", "Prob(Omnibus): 0.281 Jarque-Bera (JB): 0.904\n", "Skew: -0.014 Prob(JB): 0.636\n", "Kurtosis: 1.527 Cond. No. 27.2\n", "==============================================================================\n", "\n", "Warnings:\n", "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "C:\\WinPython-32bit-3.4.3.6\\python-3.4.3\\lib\\site-packages\\scipy\\stats\\stats.py:1285: UserWarning: kurtosistest only valid for n>=20 ... continuing anyway, n=10\n", " \"anyway, n=%i\" % int(n))\n" ] } ], "source": [ "result = sm.ols('Alcohol ~ Tobacco', df[:-1]).fit()\n", "print(result.summary())" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Model Parameters" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### F-Test" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "F-statistic: 12.785, p-value: 0.00723\n" ] } ], "source": [ "N = result.nobs\n", "k = result.df_model+1\n", "dfm, dfe = k-1, N - k\n", "F = result.mse_model / result.mse_resid\n", "p = 1.0 - stats.f.cdf(F,dfm,dfe)\n", "print('F-statistic: {:.3f}, p-value: {:.5f}'.format( F, p ))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Likelihood" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ln(L) = -4.99975869739\n" ] } ], "source": [ "N = result.nobs\n", "SSR = result.ssr\n", "s2 = SSR / N\n", "L = ( 1.0/np.sqrt(2*np.pi*s2) ) ** N * np.exp( -SSR/(s2*2.0) )\n", "print('ln(L) =', np.log( L ))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Coefficients" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Intercept 2.041223\n", "Tobacco 1.005896\n", "dtype: float64\n" ] } ], "source": [ "print(result.params)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Standard Error" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "# Standard Errors\n", "df['Eins'] = np.ones(( len(df), ))\n", "Y = df.Alcohol[:-1]\n", "X = df[['Tobacco','Eins']][:-1]" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[[ 1.00136021 nan]\n", " [ nan 0.28132158]]\n" ] } ], "source": [ "X = df.Tobacco[:-1]\n", "\n", "# add a column of ones for the constant intercept term\n", "X = np.vstack(( np.ones(X.size), X ))\n", "\n", "# convert the NumPy arrray to matrix\n", "X = np.matrix( X )\n", "\n", "# perform the matrix multiplication,\n", "# and then take the inverse\n", "C = np.linalg.inv( X * X.T )\n", "\n", "# multiply by the MSE of the residual\n", "C *= result.mse_resid\n", "\n", "# take the square root\n", "SE = np.sqrt(C)\n", "\n", "print(SE)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### T-statistic" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "t = 3.57560845424\n" ] } ], "source": [ "i = 1\n", "beta = result.params[i]\n", "se = SE[i,i]\n", "t = beta / se\n", "print('t =', t)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "p = 0.007\n" ] } ], "source": [ "N = result.nobs\n", "k = result.df_model + 1\n", "dof = N - k\n", "p_onesided = 1.0 - stats.t( dof ).cdf( t )\n", "p = p_onesided * 2.0\n", "print('p = {0:.3f}'.format(p))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Confidence Intervals" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "-0.267917709371 4.35036388305\n" ] } ], "source": [ "i = 0\n", "\n", "# the estimated coefficient, and its variance\n", "beta, c = result.params[i], SE[i,i]\n", "\n", "# critical value of the t-statistic\n", "N = result.nobs\n", "P = result.df_model\n", "dof = N - P - 1\n", "z = stats.t( dof ).ppf(0.975)\n", "\n", "# the confidence interval\n", "print(beta - z * c, beta + z * c)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Analysis of Residuals" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Skew and Kurtosis" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Skewness: -0.014, Kurtosis: 1.527\n" ] } ], "source": [ "d = Y - result.fittedvalues\n", "S = np.mean( d**3.0 ) / np.mean( d**2.0 )**(3.0/2.0)\n", "K = np.mean( d**4.0 ) / np.mean( d**2.0 )**(4.0/2.0)\n", "print('Skewness: {:.3f}, Kurtosis: {:.3f}'.format( S, K ))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Omnibus Test" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Omnibus: 2.5418981690649516\n", "Pr( Omnibus ) = 0.2805652152710648\n", "Omnibus: 2.5418981690649542, p = 0.28056521527106454\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "C:\\WinPython-32bit-3.4.3.6\\python-3.4.3\\lib\\site-packages\\scipy\\stats\\stats.py:1285: UserWarning: kurtosistest only valid for n>=20 ... continuing anyway, n=10\n", " \"anyway, n=%i\" % int(n))\n" ] } ], "source": [ "def Z1( s, n ):\n", " Y = s * np.sqrt( ( ( n + 1 )*( n + 3 ) ) / ( 6.0 * ( n - 2.0 ) ) )\n", " b = 3.0 * ( n**2.0 + 27.0*n - 70 )*( n + 1.0 )*( n + 3.0 )\n", " b /= ( n - 2.0 )*( n + 5.0 )*( n + 7.0 )*( n + 9.0 )\n", " W2 = - 1.0 + np.sqrt( 2.0 * ( b - 1.0 ) )\n", " alpha = np.sqrt( 2.0 / ( W2 - 1.0 ) )\n", " z = 1.0 / np.sqrt( np.log( np.sqrt( W2 ) ) )\n", " z *= np.log( Y / alpha + np.sqrt( ( Y / alpha )**2.0 + 1.0 ) )\n", " return z\n", "\n", "def Z2( k, n ):\n", " E = 3.0 * ( n - 1.0 ) / ( n + 1.0 )\n", " v = 24.0 * n * ( n - 2.0 )*( n - 3.0 )\n", " v /= ( n + 1.0 )**2.0*( n + 3.0 )*( n + 5.0 )\n", " X = ( k - E ) / np.sqrt( v )\n", " b = ( 6.0 * ( n**2.0 - 5.0*n + 2.0 ) ) / ( ( n + 7.0 )*( n + 9.0 ) )\n", " b *= np.sqrt( ( 6.0 * ( n + 3.0 )*( n + 5.0 ) ) / ( n * ( n - 2.0 )*( n - 3.0 ) ) )\n", " A = 6.0 + ( 8.0 / b )*( 2.0 / b + np.sqrt( 1.0 + 4.0 / b**2.0 ) )\n", " z = ( 1.0 - 2.0 / A ) / ( 1.0 + X * np.sqrt( 2.0 / ( A - 4.0 ) ) )\n", " z = ( 1.0 - 2.0 / ( 9.0 * A ) ) - z**(1.0/3.0)\n", " z /= np.sqrt( 2.0 / ( 9.0 * A ) )\n", " return z\n", "\n", "K2 = Z1( S, N )**2.0 + Z2( K, N )**2.0\n", "print('Omnibus: {}'.format( K2))\n", "\n", "p = 1.0 - stats.chi2(2).cdf( K2 )\n", "print('Pr( Omnibus ) = {}'.format( p ))\n", "\n", "(K2, p) = stats.normaltest(result.resid)\n", "print('Omnibus: {0}, p = {1}'.format(K2, p))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Durbin Watson" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Durbin-Watson: 1.97535\n" ] } ], "source": [ "DW = np.sum( np.diff( result.resid.values )**2.0 ) / result.ssr\n", "print('Durbin-Watson: {:.5f}'.format( DW ))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Jarque-Bera Test" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "JB-statistic: 0.90421, p-value: 0.63629\n" ] } ], "source": [ "JB = (N/6.0) * ( S**2.0 + (1.0/4.0)*( K - 3.0 )**2.0 )\n", "p = 1.0 - stats.chi2(2).cdf(JB)\n", "print('JB-statistic: {:.5f}, p-value: {:.5f}'.format( JB, p ))" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Condition Number" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(array([ 136.51527115, 0.18412885]), matrix([[ 0.96332746, -0.26832855],\n", " [ 0.26832855, 0.96332746]]))\n" ] } ], "source": [ "X = df.Tobacco[:-1]\n", " \n", "# add a column of ones for the constant intercept term\n", "X = np.vstack(( X, np.ones( X.size ) ))\n", " \n", "# convert the NumPy arrray to matrix\n", "X = np.matrix( X )\n", "EV = np.linalg.eig( X * X.T )\n", "print(EV)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false, "slideshow": { "slide_type": "fragment" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Condition No.: 27.22887\n" ] } ], "source": [ "CN = np.sqrt( EV[0].max() / EV[0].min() )\n", "print('Condition No.: {:.5f}'.format( CN ))" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.0" } }, "nbformat": 4, "nbformat_minor": 0 }