ml-finance-python

python scripts for finance machine learning

git clone https://9o.is/git/ml-finance-python.git

Measures of Dispersion.ipynb

(7763B)


      1 {
      2  "cells": [
      3   {
      4    "cell_type": "markdown",
      5    "metadata": {},
      6    "source": [
      7     "# Dispersion\n",
      8     "By Evgenia \"Jenny\" Nitishinskaya and Delaney Granizo-Mackenzie\n",
      9     "\n",
     10     "Notebook released under the Creative Commons Attribution 4.0 License.\n",
     11     "\n",
     12     "---\n",
     13     "Dispersion measures how spread out a set of data is. This corresponds to risk when our data set is returns over time. Data with low dispersion is heavily clustered around the mean, while high dispersion a indicates many very large and very small values.\n",
     14     "\n",
     15     "Let's generate an array of random integers to work with."
     16    ]
     17   },
     18   {
     19    "cell_type": "code",
     20    "execution_count": 39,
     21    "metadata": {
     22     "collapsed": false
     23    },
     24    "outputs": [
     25     {
     26      "name": "stdout",
     27      "output_type": "stream",
     28      "text": [
     29       "X: [ 3  8 34 39 46 52 52 52 54 57 60 65 66 75 83 85 88 94 95 96]\n",
     30       "Mean of X: 60.2\n"
     31      ]
     32     }
     33    ],
     34    "source": [
     35     "import numpy as np\n",
     36     "import math\n",
     37     "\n",
     38     "np.random.seed(121)\n",
     39     "X = np.sort(np.random.randint(100, size=20))\n",
     40     "print 'X:', X\n",
     41     "mu = np.mean(X)\n",
     42     "print 'Mean of X:', mu"
     43    ]
     44   },
     45   {
     46    "cell_type": "markdown",
     47    "metadata": {},
     48    "source": [
     49     "# Range\n",
     50     "\n",
     51     "Range is simply the difference between the maximum and minimum values in a dataset. Not surprisingly, it is very sensitive to outliers."
     52    ]
     53   },
     54   {
     55    "cell_type": "code",
     56    "execution_count": 22,
     57    "metadata": {
     58     "collapsed": false
     59    },
     60    "outputs": [
     61     {
     62      "name": "stdout",
     63      "output_type": "stream",
     64      "text": [
     65       "Range of X: 93\n"
     66      ]
     67     }
     68    ],
     69    "source": [
     70     "print 'Range of X:', np.ptp(X)"
     71    ]
     72   },
     73   {
     74    "cell_type": "markdown",
     75    "metadata": {},
     76    "source": [
     77     "# Mean absolute deviation\n",
     78     "\n",
     79     "The mean absolute deviation is the average of the distances of observations from the arithmetic mean. We use the absolute value of the deviation, so that 5 above the mean and 5 below the mean both contribute 5, because otherwise the deviations always sum to 0.\n",
     80     "\n",
     81     "$$ MAD = \\frac{\\sum_{i=1}^n |X_i - \\mu|}{n} $$\n",
     82     "\n",
     83     "where $n$ is the number of observations and $\\mu$ is their mean."
     84    ]
     85   },
     86   {
     87    "cell_type": "code",
     88    "execution_count": 26,
     89    "metadata": {
     90     "collapsed": false
     91    },
     92    "outputs": [
     93     {
     94      "name": "stdout",
     95      "output_type": "stream",
     96      "text": [
     97       "Mean absolute deviation of X: 20.52\n"
     98      ]
     99     }
    100    ],
    101    "source": [
    102     "abs_dispersion = [abs(mu - x) for x in X]\n",
    103     "MAD = sum(abs_dispersion)/len(abs_dispersion)\n",
    104     "print 'Mean absolute deviation of X:', MAD"
    105    ]
    106   },
    107   {
    108    "cell_type": "markdown",
    109    "metadata": {},
    110    "source": [
    111     "# Variance and standard deviation\n",
    112     "\n",
    113     "The variance $\\sigma^2$ is defined as the average of the squared deviations around the mean:\n",
    114     "$$ \\sigma^2 = \\frac{\\sum_{i=1}^n (X_i - \\mu)^2}{n} $$\n",
    115     "\n",
    116     "This is sometimes more convenient than the mean absolute deviation because absolute value is not differentiable, while squaring is smooth, and some optimization algorithms rely on differentiability.\n",
    117     "\n",
    118     "Standard deviation is defined as the square root of the variance, $\\sigma$, and it is the easier of the two to interpret because it is in the same units as the observations."
    119    ]
    120   },
    121   {
    122    "cell_type": "code",
    123    "execution_count": 25,
    124    "metadata": {
    125     "collapsed": false
    126    },
    127    "outputs": [
    128     {
    129      "name": "stdout",
    130      "output_type": "stream",
    131      "text": [
    132       "Variance of X: 670.16\n",
    133       "Standard deviation of X: 25.8874486962\n"
    134      ]
    135     }
    136    ],
    137    "source": [
    138     "print 'Variance of X:', np.var(X)\n",
    139     "print 'Standard deviation of X:', np.std(X)"
    140    ]
    141   },
    142   {
    143    "cell_type": "markdown",
    144    "metadata": {},
    145    "source": [
    146     "One way to interpret standard deviation is by referring to Chebyshev's inequality. This tells us that the proportion of samples within $k$ standard deviations (that is, within a distance of $k \\cdot$ standard deviation) of the mean is at least $1 - 1/k^2$ for all $k>1$.\n",
    147     "\n",
    148     "Let's check that this is true for our data set."
    149    ]
    150   },
    151   {
    152    "cell_type": "code",
    153    "execution_count": 54,
    154    "metadata": {
    155     "collapsed": false
    156    },
    157    "outputs": [
    158     {
    159      "name": "stdout",
    160      "output_type": "stream",
    161      "text": [
    162       "Observations within 1.25 stds of mean: [34, 39, 46, 52, 52, 52, 54, 57, 60, 65, 66, 75, 83, 85, 88]\n",
    163       "Confirming that 0.75 > 0.36\n"
    164      ]
    165     }
    166    ],
    167    "source": [
    168     "k = 1.25\n",
    169     "dist = k*np.std(X)\n",
    170     "l = [x for x in X if abs(x - mu) <= dist]\n",
    171     "print 'Observations within', k, 'stds of mean:', l\n",
    172     "print 'Confirming that', float(len(l))/len(X), '>', 1 - 1/k**2"
    173    ]
    174   },
    175   {
    176    "cell_type": "markdown",
    177    "metadata": {},
    178    "source": [
    179     "The bound given by Chebyshev's inequality seems fairly loose in this case. This bound is rarely strict, but it is useful because it holds for all data sets and distributions."
    180    ]
    181   },
    182   {
    183    "cell_type": "markdown",
    184    "metadata": {},
    185    "source": [
    186     "# Semivariance and semideviation\n",
    187     "\n",
    188     "Although variance and standard deviation tell us how volatile a quantity is, they do not differentiate between deviations upward and deviations downward. Often, such as in the case of returns on an asset, we are more worried about deviations downward. This is addressed by semivariance and semideviation, which only count the observations that fall below the mean. Semivariance is defined as\n",
    189     "$$ \\frac{\\sum_{X_i < \\mu} (X_i - \\mu)^2}{n_<} $$\n",
    190     "where $n_<$ is the number of observations which are smaller than the mean. Semideviation is the square root of the semivariance."
    191    ]
    192   },
    193   {
    194    "cell_type": "code",
    195    "execution_count": 32,
    196    "metadata": {
    197     "collapsed": false
    198    },
    199    "outputs": [
    200     {
    201      "name": "stdout",
    202      "output_type": "stream",
    203      "text": [
    204       "Semivariance of X: 689.512727273\n",
    205       "Semideviation of X: 26.2585743572\n"
    206      ]
    207     }
    208    ],
    209    "source": [
    210     "# Because there is no built-in semideviation, we'll compute it ourselves\n",
    211     "lows = [e for e in X if e <= mu]\n",
    212     "semivar = sum(map(lambda x: (x - mu)**2,lows))/len(lows)\n",
    213     "\n",
    214     "print 'Semivariance of X:', semivar\n",
    215     "print 'Semideviation of X:', math.sqrt(semivar)"
    216    ]
    217   },
    218   {
    219    "cell_type": "markdown",
    220    "metadata": {},
    221    "source": [
    222     "A related notion is target semivariance (and target semideviation), where we average the distance from a target of values which fall below that target:\n",
    223     "$$ \\frac{\\sum_{X_i < B} (X_i - B)^2}{n_{<B}} $$\n"
    224    ]
    225   },
    226   {
    227    "cell_type": "code",
    228    "execution_count": 55,
    229    "metadata": {
    230     "collapsed": false
    231    },
    232    "outputs": [
    233     {
    234      "name": "stdout",
    235      "output_type": "stream",
    236      "text": [
    237       "Target semivariance of X: 188\n",
    238       "Target semideviation of X: 13.7113092008\n"
    239      ]
    240     }
    241    ],
    242    "source": [
    243     "B = 19\n",
    244     "lows_B = [e for e in X if e <= B]\n",
    245     "semivar_B = sum(map(lambda x: (x - B)**2,lows_B))/len(lows_B)\n",
    246     "\n",
    247     "print 'Target semivariance of X:', semivar_B\n",
    248     "print 'Target semideviation of X:', math.sqrt(semivar_B)"
    249    ]
    250   }
    251  ],
    252  "metadata": {
    253   "kernelspec": {
    254    "display_name": "Python 2",
    255    "language": "python",
    256    "name": "python2"
    257   },
    258   "language_info": {
    259    "codemirror_mode": {
    260     "name": "ipython",
    261     "version": 2
    262    },
    263    "file_extension": ".py",
    264    "mimetype": "text/x-python",
    265    "name": "python",
    266    "nbconvert_exporter": "python",
    267    "pygments_lexer": "ipython2",
    268    "version": "2.7.6"
    269   }
    270  },
    271  "nbformat": 4,
    272  "nbformat_minor": 0
    273 }