{ "metadata": { "name": "", "signature": "sha256:80f2731e0b0fc4e8024017abe17c7495dd2b9fd81e6ab9353220b69eb9563264" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "mca - Burgundies Example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This example demonstrated capabilities of ``mca`` package by reproducing results of [Multiple Correspondence Analysis, Hedbi & Valentin, 2007](https://www.utdallas.edu/~herve/Abdi-MCA2007-pretty.pdf)." ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Imports and loading data" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import mca\n", "import pandas as pd\n", "import numpy as np\n", "\n", "np.set_printoptions(formatter={'float': '{: 0.4f}'.format})\n", "pd.set_option('display.precision', 5)\n", "pd.set_option('display.max_columns', 25)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "For input format, `mca` uses \n", "[`DataFrame`](http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.html) \n", "from \n", "[`pandas`](http://pandas.pydata.org/) package. \n", "\n", "Here we use `pandas` to load CSV file with indicator matrix $X$ of categorical data with 6 observations, 10 variables and 22 levels in total. We also set up supplementary variable $j_{sup}$ and supplementary observation $i_{sup}$." ] }, { "cell_type": "code", "collapsed": false, "input": [ "data = pd.read_table('../data/burgundies.csv',\n", " sep=',', skiprows=1, index_col=0, header=0)\n", "X = data.drop('oak_type', axis=1)\n", "j_sup = data.oak_type\n", "i_sup = np.array([0, 1, 0, 1, 0, .5, .5, 1, 0, 1, 0, 0, 1, 0, .5, .5, 1, 0, .5, .5, 0, 1])\n", "ncols = 10\n", "\n", "X.shape, j_sup.shape, i_sup.shape" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 2, "text": [ "((6, 22), (6,), (22,))" ] } ], "prompt_number": 2 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Table 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"Data for the barrel-aged red burgundy wines example. \u201cOak Type\" is an illustrative (supplementary) variable, the wine W? is an unknown wine treated as a supplementary observation.\" (Hedbi & Valentin, 2007)" ] }, { "cell_type": "code", "collapsed": false, "input": [ "src_index = (['Expert 1'] * 7 + ['Expert 2'] * 9 + ['Expert 3'] * 6)\n", "var_index = (['fruity'] * 2 + ['woody'] * 3 + ['coffee'] * 2 + ['fruity'] * 2\n", " + ['roasted'] * 2 + ['vanillin'] * 3 + ['woody'] * 2 + ['fruity'] * 2\n", " + ['butter'] * 2 + ['woody'] * 2)\n", "yn = ['y','n']; rg = ['1', '2', '3']; val_index = yn + rg + yn*3 + rg + yn*4\n", "col_index = pd.MultiIndex.from_arrays([src_index, var_index, val_index], \n", " names=['source', 'variable', 'value'])\n", "\n", "table1 = pd.DataFrame(data=X.values, index=X.index, columns=col_index)\n", "table1.loc['W?'] = i_sup\n", "table1['','Oak Type',''] = j_sup\n", "\n", "table1" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sourceExpert 1Expert 2Expert 3
variablefruitywoodycoffeefruityroastedvanillinwoodyfruitybutterwoodyOak Type
valueyn123ynynyn123ynynynyn
W1 1 0 0 0 1 0.0 1.0 1 0 0 1 0 0 1 0.0 1.0 0 1 0.0 1.0 0 1 1
W2 0 1 0 1 0 1.0 0.0 0 1 1 0 0 1 0 1.0 0.0 0 1 1.0 0.0 1 0 2
W3 0 1 1 0 0 1.0 0.0 0 1 1 0 1 0 0 1.0 0.0 0 1 1.0 0.0 1 0 2
W4 0 1 1 0 0 1.0 0.0 0 1 1 0 1 0 0 1.0 0.0 1 0 1.0 0.0 1 0 2
W5 1 0 0 0 1 0.0 1.0 1 0 0 1 0 0 1 0.0 1.0 1 0 0.0 1.0 0 1 1
W6 1 0 0 1 0 0.0 1.0 1 0 0 1 0 1 0 0.0 1.0 1 0 0.0 1.0 0 1 1
W? 0 1 0 1 0 0.5 0.5 1 0 1 0 0 1 0 0.5 0.5 1 0 0.5 0.5 0 1NaN
\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 3, "text": [ "source Expert 1 Expert 2 \\\n", "variable fruity woody coffee fruity roasted vanillin \n", "value y n 1 2 3 y n y n y n 1 \n", "W1 1 0 0 0 1 0.0 1.0 1 0 0 1 0 \n", "W2 0 1 0 1 0 1.0 0.0 0 1 1 0 0 \n", "W3 0 1 1 0 0 1.0 0.0 0 1 1 0 1 \n", "W4 0 1 1 0 0 1.0 0.0 0 1 1 0 1 \n", "W5 1 0 0 0 1 0.0 1.0 1 0 0 1 0 \n", "W6 1 0 0 1 0 0.0 1.0 1 0 0 1 0 \n", "W? 0 1 0 1 0 0.5 0.5 1 0 1 0 0 \n", "\n", "source Expert 3 \n", "variable woody fruity butter woody Oak Type \n", "value 2 3 y n y n y n y n \n", "W1 0 1 0.0 1.0 0 1 0.0 1.0 0 1 1 \n", "W2 1 0 1.0 0.0 0 1 1.0 0.0 1 0 2 \n", "W3 0 0 1.0 0.0 0 1 1.0 0.0 1 0 2 \n", "W4 0 0 1.0 0.0 1 0 1.0 0.0 1 0 2 \n", "W5 0 1 0.0 1.0 1 0 0.0 1.0 0 1 1 \n", "W6 1 0 0.0 1.0 1 0 0.0 1.0 0 1 1 \n", "W? 1 0 0.5 0.5 1 0 0.5 0.5 0 1 NaN " ] } ], "prompt_number": 3 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "MCA" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's create two `MCA` instances - one with Benz\u00e9cri correction enabled (default) and one without it. Parameter `ncols` denotes number of categorical variables." ] }, { "cell_type": "code", "collapsed": false, "input": [ "mca_ben = mca.MCA(X, ncols=ncols)\n", "mca_ind = mca.MCA(X, ncols=ncols, benzecri=False)\n", "\n", "print(mca.MCA.__doc__)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "Run MCA on selected columns of a pd DataFrame.\n", " If the column are specified, assume that they hold\n", " categorical variables that need to be replaced with\n", " dummy indicators, otherwise process the DataFrame as is.\n", "\n", " 'cols': The columns of the DataFrame to process.\n", " 'ncols': The number of columns before dummy coding. To be passed if cols isn't.\n", " 'benzecri': Perform Benz\u00e9cri correction (default: True)\n", " 'TOL': value below which to round eigenvalues to zero (default: 1e-4)\n", " \n" ] } ], "prompt_number": 4 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Table 2 (L, expl_var)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"Eigenvalues, corrected eigenvalues, proportion of explained inertia and corrected proportion of explained inertia. The eigenvalues of the Burt matrix are equal to the squared eigenvalues of the indicator matrix; The corrected eigenvalues for Benz\u00e9cri and Greenacre are the same, but the proportion of explained variance differ. Eigenvalues are denoted by\n", "\u03bb, proportions of explained inertia by \u03c4 (note that the average inertia used to compute Greenacre\u2019s correction is equal to\n", "I = .7358).\" (Hedbi & Valentin, 2007)\n", "\n", "Field `L` contains the eigenvalues, or the *principal inertias*, of the factors. Method `expl_var` returns proportion of explained inertia for each factor, whereas Greenacre corrections may be enabled with parameter `greenacre` and `N` limits number of retained factors.\n", "\n", "Note that Burt matrix values are not included in the following table, as it is not currently implemented in `mca` package." ] }, { "cell_type": "code", "collapsed": false, "input": [ "data = {'I\u03bb': pd.Series(mca_ind.L),\n", " '\u03c4I': mca_ind.expl_var(greenacre=False, N=4),\n", " 'Z\u03bb': pd.Series(mca_ben.L),\n", " '\u03c4Z': mca_ben.expl_var(greenacre=False, N=4),\n", " 'c\u03bb': pd.Series(mca_ben.L),\n", " '\u03c4c': mca_ind.expl_var(greenacre=True, N=4)}\n", "\n", "# 'Indicator Matrix', 'Benzecri Correction', 'Greenacre Correction'\n", "columns = ['I\u03bb', '\u03c4I', 'Z\u03bb', '\u03c4Z', 'c\u03bb', '\u03c4c']\n", "table2 = pd.DataFrame(data=data, columns=columns).fillna(0)\n", "table2.index += 1\n", "table2.loc['\u03a3'] = table2.sum()\n", "table2.index.name = 'Factor'\n", "\n", "table2" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
I\u03bb\u03c4IZ\u03bb\u03c4Zc\u03bb\u03c4c
Factor
1 0.8532 0.7110 0.7004 0.9823 0.7004 0.9519
2 0.2000 0.1667 0.0123 0.0173 0.0123 0.0168
3 0.1151 0.0959 0.0003 0.0004 0.0003 0.0004
4 0.0317 0.0264 0.0000 0.0000 0.0000 0.0000
\u03a3 1.2000 1.0000 0.7130 1.0000 0.7130 0.9691
\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 5, "text": [ " I\u03bb \u03c4I Z\u03bb \u03c4Z c\u03bb \u03c4c\n", "Factor \n", "1 0.8532 0.7110 0.7004 0.9823 0.7004 0.9519\n", "2 0.2000 0.1667 0.0123 0.0173 0.0123 0.0168\n", "3 0.1151 0.0959 0.0003 0.0004 0.0003 0.0004\n", "4 0.0317 0.0264 0.0000 0.0000 0.0000 0.0000\n", "\u03a3 1.2000 1.0000 0.7130 1.0000 0.7130 0.9691" ] } ], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "The inertia is simply the sum of the principle inertias:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "mca_ind.inertia, mca_ind.L.sum(), mca_ben.inertia, mca_ben.L.sum()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 6, "text": [ "(1.1999999999999997,\n", " 1.1999999999999997,\n", " 0.71302972718038071,\n", " 0.71302972718038071)" ] } ], "prompt_number": 6 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Table 3 (fs_r, cos_r, cont_r, fs_r_sup)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"Factor scores, squared cosines, and contributions for the observations (I-set). The eigenvalues and\n", "proportions of explained inertia are corrected using Benz\u00e9cri/Greenacre formula. ~~Contributions corresponding\n", "to negative scores are in italic.~~ The mystery wine (Wine ?) is a supplementary observation. Only the first two\n", "factors are reported.\" (Hedbi & Valentin, 2007)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Firstly, we once again tabulate eigenvalues and their proportions. This time only for the first two factors and as percentage." ] }, { "cell_type": "code", "collapsed": false, "input": [ "data = np.array([mca_ben.L[:2], \n", " mca_ben.expl_var(greenacre=True, N=2) * 100]).T\n", "df = pd.DataFrame(data=data, columns=['c\u03bb','%c'], index=range(1,3))\n", "df" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
c\u03bb%c
1 0.7004 95.1889
2 0.0123 1.6779
\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 7, "text": [ " c\u03bb %c\n", "1 0.7004 95.1889\n", "2 0.0123 1.6779" ] } ], "prompt_number": 7 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Factor scores, squared cosines, and contributions for the observations are computed by `fs_r`, `cos_r` and `cont_r` methods respectively, where `r` denotes *rows* (i.e. observations). Again, `N` limits the number of retained factors.\n", "\n", "Factor scores of supplementary observation $i_{sup}$ is computed by method `fs_r_sup`.\n", "\n", "Note that squared cosines do not agree with those in the reference. See [issue #1](https://github.com/esafak/mca/issues/1)." ] }, { "cell_type": "code", "collapsed": false, "input": [ "fs, cos, cont = 'Factor score','Squared cosines', 'Contributions x 1000'\n", "table3 = pd.DataFrame(columns=X.index, index=pd.MultiIndex\n", " .from_product([[fs, cos, cont], range(1, 3)]))\n", "\n", "table3.loc[fs, :] = mca_ben.fs_r(N=2).T\n", "table3.loc[cos, :] = mca_ben.cos_r(N=2).T\n", "table3.loc[cont, :] = mca_ben.cont_r(N=2).T * 1000\n", "table3.loc[fs, 'W?'] = mca_ben.fs_r_sup(pd.DataFrame([i_sup]), N=2)[0]\n", "\n", "np.round(table3.astype(float), 2)" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
WineW1W2W3W4W5W6W?
Factor score1 0.86 -0.71 -0.92 -0.86 0.92 0.71 0.03
2 0.08 -0.16 0.08 0.08 0.08 -0.16-0.63
Squared cosines1 0.99 0.95 0.99 0.99 0.99 0.95 NaN
2 0.01 0.05 0.01 0.01 0.01 0.05 NaN
Contributions x 10001 176.68 120.99 202.33 176.68 202.33 120.99 NaN
2 83.33 333.33 83.33 83.33 83.33 333.33 NaN
\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 8, "text": [ "Wine W1 W2 W3 W4 W5 W6 W?\n", "Factor score 1 0.86 -0.71 -0.92 -0.86 0.92 0.71 0.03\n", " 2 0.08 -0.16 0.08 0.08 0.08 -0.16 -0.63\n", "Squared cosines 1 0.99 0.95 0.99 0.99 0.99 0.95 NaN\n", " 2 0.01 0.05 0.01 0.01 0.01 0.05 NaN\n", "Contributions x 1000 1 176.68 120.99 202.33 176.68 202.33 120.99 NaN\n", " 2 83.33 333.33 83.33 83.33 83.33 333.33 NaN" ] } ], "prompt_number": 8 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Table 4 (fs_c, cos_c, cont_c, fs_c_sup)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"Factor scores, squared cosines, and contributions for the variables (J-set). The eigenvalues and\n", "percentages of inertia have been corrected using Benz\u00e9cri/Greenacre formula. ~~Contributions corresponding to\n", "negative scores are in italic.~~ Oak 1 and 2 are supplementary variables.\" (Hedbi & Valentin, 2007)\n", "\n", "Computations for *columns* (i.e. variables) are analogous to those of *rows*. Before the supplementary variable factor scores can be computed, $j_{sup}$ must be converted from categorical variable into dummy indicator matrix by method `mca.dummy`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "table4 = pd.DataFrame(columns=col_index, index=pd.MultiIndex\n", " .from_product([[fs, cos, cont], range(1, 3)]))\n", "table4.loc[fs, :] = mca_ben.fs_c(N=2).T\n", "table4.loc[cos, :] = mca_ben.cos_c(N=2).T\n", "table4.loc[cont,:] = mca_ben.cont_c(N=2).T * 1000\n", "\n", "fs_c_sup = mca_ben.fs_c_sup(mca.dummy(pd.DataFrame(j_sup)), N=2)\n", "table4.loc[fs, ('Oak', '', 1)] = fs_c_sup[0]\n", "table4.loc[fs, ('Oak', '', 2)] = fs_c_sup[1]\n", "\n", "np.round(table4.astype(float), 2)" ], "language": "python", "metadata": {}, "outputs": [ { "html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
sourceExpert 1Expert 2Expert 3Oak
variablefruitywoodycoffeefruityroastedvanillinwoodyfruitybutterwoody
valueyn123ynynyn123ynynynyn12
Factor score1 0.90 -0.90 -0.97 0.00 0.97 -0.90 0.90 0.90 -0.90 -0.90 0.90 -0.97 0.00 0.97 -0.90 0.90 0.28-0.28 -0.90 0.90 -0.90 0.90 0.99-0.99
2 0.00 0.00 0.18 -0.35 0.18 -0.00 0.00 0.00 -0.00 -0.00 0.00 0.18 -0.35 0.18 -0.00 0.00-0.00 0.00 -0.00 0.00 -0.00 0.00 0.00-0.00
Squared cosines1 1.00 1.00 0.97 0.00 0.97 1.00 1.00 1.00 1.00 1.00 1.00 0.97 0.00 0.97 1.00 1.00 0.97 0.97 1.00 1.00 1.00 1.00 NaN NaN
2 0.00 0.00 0.03 1.00 0.03 0.00 0.00 0.00 0.00 0.00 0.00 0.03 1.00 0.03 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 NaN NaN
Contributions x 10001 57.96 57.96 44.37 0.00 44.37 57.96 57.96 57.96 57.96 57.96 57.96 44.37 0.00 44.37 57.96 57.96 5.56 5.56 57.96 57.96 57.96 57.96 NaN NaN
2 0.00 0.00 83.33 333.33 83.33 0.00 0.00 0.00 0.00 0.00 0.00 83.33 333.33 83.33 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 NaN NaN
\n", "
" ], "metadata": {}, "output_type": "pyout", "prompt_number": 9, "text": [ "source Expert 1 \\\n", "variable fruity woody coffee \n", "value y n 1 2 3 y n \n", "Factor score 1 0.90 -0.90 -0.97 0.00 0.97 -0.90 0.90 \n", " 2 0.00 0.00 0.18 -0.35 0.18 -0.00 0.00 \n", "Squared cosines 1 1.00 1.00 0.97 0.00 0.97 1.00 1.00 \n", " 2 0.00 0.00 0.03 1.00 0.03 0.00 0.00 \n", "Contributions x 1000 1 57.96 57.96 44.37 0.00 44.37 57.96 57.96 \n", " 2 0.00 0.00 83.33 333.33 83.33 0.00 0.00 \n", "\n", "source Expert 2 \\\n", "variable fruity roasted vanillin \n", "value y n y n 1 2 3 \n", "Factor score 1 0.90 -0.90 -0.90 0.90 -0.97 0.00 0.97 \n", " 2 0.00 -0.00 -0.00 0.00 0.18 -0.35 0.18 \n", "Squared cosines 1 1.00 1.00 1.00 1.00 0.97 0.00 0.97 \n", " 2 0.00 0.00 0.00 0.00 0.03 1.00 0.03 \n", "Contributions x 1000 1 57.96 57.96 57.96 57.96 44.37 0.00 44.37 \n", " 2 0.00 0.00 0.00 0.00 83.33 333.33 83.33 \n", "\n", "source Expert 3 \\\n", "variable woody fruity butter woody \n", "value y n y n y n y \n", "Factor score 1 -0.90 0.90 0.28 -0.28 -0.90 0.90 -0.90 \n", " 2 -0.00 0.00 -0.00 0.00 -0.00 0.00 -0.00 \n", "Squared cosines 1 1.00 1.00 0.97 0.97 1.00 1.00 1.00 \n", " 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 \n", "Contributions x 1000 1 57.96 57.96 5.56 5.56 57.96 57.96 57.96 \n", " 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 \n", "\n", "source Oak \n", "variable \n", "value n 1 2 \n", "Factor score 1 0.90 0.99 -0.99 \n", " 2 0.00 0.00 -0.00 \n", "Squared cosines 1 1.00 NaN NaN \n", " 2 0.00 NaN NaN \n", "Contributions x 1000 1 57.96 NaN NaN \n", " 2 0.00 NaN NaN " ] } ], "prompt_number": 9 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Figure 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\"Multiple Correspondence Analysis. Projections on the first 2 dimensions. The eigenvalues (\u03bb) and\n", "proportion of explained inertia (\u03c4) have been corrected with Benz\u00e9cri/Greenacre formula. (a) The I set: rows\n", "(i.e., wines), wine ? is a supplementary element. (b) The J set: columns (i.e., adjectives). Oak 1 and Oak 2 are\n", "supplementary elements. (the projection points have been slightly moved to increase readability). (Projections\n", "from Tables 3 and 4).\" (Hedbi & Valentin, 2007)\n", "\n", "Following plots do not introduce anything new in terms of `mca` package, it just reuses factor scores from Tables 3 and 4. But everybody loves colourful graphs, so..." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt\n", "\n", "points = table3.loc[fs].values\n", "labels = table3.columns.values\n", "\n", "plt.figure()\n", "plt.margins(0.1)\n", "plt.axhline(0, color='gray')\n", "plt.axvline(0, color='gray')\n", "plt.xlabel('Factor 1')\n", "plt.ylabel('Factor 2')\n", "plt.scatter(*points, s=120, marker='o', c='r', alpha=.5, linewidths=0)\n", "for label, x, y in zip(labels, *points):\n", " plt.annotate(label, xy=(x, y), xytext=(x + .03, y + .03))\n", "plt.show()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "display_data", "png": "iVBORw0KGgoAAAANSUhEUgAAAYYAAAEKCAYAAAAW8vJGAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAH7BJREFUeJzt3X90VPWd//HnkICCEEKgQLKAiVVASSJBZJMJysgPf1EQ\ny0q31sVuW7799tTWg7RfqX77TdJvT9d22+N2j909/bq2YtfagnX9VbVGl7GUDFIx/BAClhLkd6Ah\nAZSC/LjfPz43P264M3NDZuZOMq/HOffk3jufzLwzuXPfcz+f+/l8QERERERERERERERERERERERE\nREREJGkCfgeQCDNmzLDeeustv8MQEelt3gJCXXf2S30ciffWW29hWdZFL1VVVT36/Uxb9H55X2bM\nmOF7DL1p0bGV2vcKmOF2Tu0TiUFERBJHiSEBli5dyo9//OP27VtuuYUlS5a0by9btoyKigrGjh1L\nWVkZkyZNYuLEiReUefTRRwE4fvw4Y8aM4Wtf+1rq/ggRSSkv540ZM2Zw9dVXM2zYMObNm+da5tFH\nHyUrK4uysjLKyspYsGBBj2NTYgBCoVCPfn/69OnU1dUBcP78eZqbm9m2bVv745FIhLlz51JeXk59\nfT3r1q2jsbGRjRs3OspUVlYC8O1vf5sZM1yv8NJCT9+vTFJYWOh3CL1KJh1bXs4bt912G6NHj+YX\nv/gFlmU5yoRCISKRCMFgkEGDBlFfX099fT3PP/98j2NTYqDnB2NFRQWRSASArVu3UlxczJAhQ2ht\nbeX06dM0NDSwePFi3n77bQDq6+u55JJLyMnJcZSZMmUKGzZs4PDhw9x88809/bOSJpM+vD1VVFTk\ndwi9SiYdW17OG3fffTd//vOfGTx4MCdOnHCUqaioaD9vJFp2wp8xAxUUFJCdnc3evXuJRCJUVFSw\nf/9+IpEIOTk5lJSUMG7cOAAmTpzIrl27WLhwIVdddVV7mdLSUrKysvjGN77B008/TW1trc9/lYgk\nk9fzRnZ2NocPH6alpYW7777bUaa0tJT+/ftz6tQprrvuOgYMGMDy5cu54447ehSbEkOCBINB6urq\nqKur44EHHmD//v3U1dUxdOhQpk+fDsCNN97IvHnzeO6556irq2P27NntZYLBID/5yU+4/fbbKSgo\naLtjQET6MC/njWAwyHvvvUdLS0t78mgr01b9vGfPHvLz82lsbGTmzJmUlJRwxRVXXHRcflcl3Qps\n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\n", "text": [ "" ] } ], "prompt_number": 10 }, { "cell_type": "code", "collapsed": false, "input": [ "noise = 0.05 * (np.random.rand(*table4.T[fs].shape) - 0.5)\n", "fs_by_source = table4.T[fs].add(noise).groupby(level=['source'])\n", "\n", "fig, ax = plt.subplots()\n", "plt.margins(0.1)\n", "plt.axhline(0, color='gray')\n", "plt.axvline(0, color='gray')\n", "plt.xlabel('Factor 1')\n", "plt.ylabel('Factor 2')\n", "ax.margins(0.1)\n", "markers = '^', 's', 'o', 'o'\n", "colors = 'r', 'g', 'b', 'y'\n", "for fscore, marker, color in zip(fs_by_source, markers, colors):\n", " label, points = fscore\n", " ax.plot(*points.T.values, marker=marker, color=color, label=label, linestyle='', alpha=.5, mew=0, ms=12)\n", "ax.legend(numpoints=1, loc=4)\n", "plt.show()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "display_data", "png": "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\nSURERERERERERERERERERERERERERERERERERCR5/X+nr0soL4i//AAAAABJRU5ErkJggg==\n", "text": [ "" ] } ], "prompt_number": 11 } ], "metadata": {} } ] }