{"cells": [{"cell_type": "markdown", "metadata": {}, "source": ["# Faster Polynomial Features"]}, {"cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [{"data": {"text/html": ["
run previous cell, wait for 2 seconds
\n", ""], "text/plain": [""]}, "execution_count": 2, "metadata": {}, "output_type": "execute_result"}], "source": ["from jyquickhelper import add_notebook_menu\n", "add_notebook_menu()"]}, {"cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": ["%matplotlib inline"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Polynomial Features\n", "\n", "The current implementation of [PolynomialFeatures](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PolynomialFeatures.html) (0.20.2) implements a term by term product for each pair $X_i, X_j$ of features where $i \\leqslant j$ which is not the most efficient way to do it."]}, {"cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": ["import numpy.random\n", "X = numpy.random.random((100, 5))"]}, {"cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [{"data": {"text/plain": ["['1',\n", " 'x0',\n", " 'x1',\n", " 'x2',\n", " 'x3',\n", " 'x4',\n", " 'x0^2',\n", " 'x0 x1',\n", " 'x0 x2',\n", " 'x0 x3',\n", " 'x0 x4',\n", " 'x1^2',\n", " 'x1 x2',\n", " 'x1 x3',\n", " 'x1 x4',\n", " 'x2^2',\n", " 'x2 x3',\n", " 'x2 x4',\n", " 'x3^2',\n", " 'x3 x4',\n", " 'x4^2']"]}, "execution_count": 5, "metadata": {}, "output_type": "execute_result"}], "source": ["from sklearn.preprocessing import PolynomialFeatures\n", "poly = PolynomialFeatures(degree=2)\n", "Xpoly = poly.fit_transform(X)\n", "poly.get_feature_names()"]}, {"cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["114 \u00b5s \u00b1 12.4 \u00b5s per loop (mean \u00b1 std. dev. of 7 runs, 10000 loops each)\n"]}], "source": ["%timeit poly.transform(X)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The class [ExtendedFeatures](http://www.xavierdupre.fr/app/mlinsights/helpsphinx/mlinsights/mlmodel/extended_features.html) implements a different way to compute the polynomial features as it tries to reduce the number of calls to numpy by using broacasted vector multplications."]}, {"cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [{"data": {"text/plain": ["['1',\n", " 'x0',\n", " 'x1',\n", " 'x2',\n", " 'x3',\n", " 'x4',\n", " 'x0^2',\n", " 'x0 x1',\n", " 'x0 x2',\n", " 'x0 x3',\n", " 'x0 x4',\n", " 'x1^2',\n", " 'x1 x2',\n", " 'x1 x3',\n", " 'x1 x4',\n", " 'x2^2',\n", " 'x2 x3',\n", " 'x2 x4',\n", " 'x3^2',\n", " 'x3 x4',\n", " 'x4^2']"]}, "execution_count": 7, "metadata": {}, "output_type": "execute_result"}], "source": ["from mlinsights.mlmodel import ExtendedFeatures\n", "ext = ExtendedFeatures(poly_degree=2)\n", "Xpoly = ext.fit_transform(X)\n", "ext.get_feature_names()"]}, {"cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["68.7 \u00b5s \u00b1 10.6 \u00b5s per loop (mean \u00b1 std. dev. of 7 runs, 10000 loops each)\n"]}], "source": ["%timeit ext.transform(X)"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Comparison with 5 features"]}, {"cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": ["from cpyquickhelper.numbers import measure_time"]}, {"cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [{"data": {"text/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", "
averagedeviationmin_execmax_execrepeatnumbercontext_sizenamesize
630.0378300.0055770.0312480.044832510240ext+fit100000
640.0726710.0053600.0675590.082539510240poly200000
650.0757120.0182710.0604760.100143510240ext200000
660.1067550.0198610.0798800.139184510240poly+fit200000
670.0740900.0091420.0639250.085899510240ext+fit200000
\n", "
"], "text/plain": [" average deviation min_exec max_exec repeat number context_size \\\n", "63 0.037830 0.005577 0.031248 0.044832 5 10 240 \n", "64 0.072671 0.005360 0.067559 0.082539 5 10 240 \n", "65 0.075712 0.018271 0.060476 0.100143 5 10 240 \n", "66 0.106755 0.019861 0.079880 0.139184 5 10 240 \n", "67 0.074090 0.009142 0.063925 0.085899 5 10 240 \n", "\n", " name size \n", "63 ext+fit 100000 \n", "64 poly 200000 \n", "65 ext 200000 \n", "66 poly+fit 200000 \n", "67 ext+fit 200000 "]}, "execution_count": 10, "metadata": {}, "output_type": "execute_result"}], "source": ["res = []\n", "for n in [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, \n", " 5000, 10000, 20000, 50000, 100000, 200000]:\n", " X = numpy.random.random((n, 5))\n", " poly.fit(X)\n", " ext.fit(X)\n", " r1 = measure_time(\"poly.transform(X)\", context=dict(X=X, poly=poly), repeat=5, number=10, div_by_number=True)\n", " r2 = measure_time(\"ext.transform(X)\", context=dict(X=X, ext=ext), repeat=5, number=10, div_by_number=True)\n", " r3 = measure_time(\"poly.fit_transform(X)\", context=dict(X=X, poly=poly), repeat=5, number=10, div_by_number=True)\n", " r4 = measure_time(\"ext.fit_transform(X)\", context=dict(X=X, ext=ext), repeat=5, number=10, div_by_number=True)\n", " r1[\"name\"] = \"poly\"\n", " r2[\"name\"] = \"ext\"\n", " r3[\"name\"] = \"poly+fit\"\n", " r4[\"name\"] = \"ext+fit\"\n", " r1[\"size\"] = n\n", " r2[\"size\"] = n\n", " r3[\"size\"] = n\n", " r4[\"size\"] = n\n", " res.append(r1)\n", " res.append(r2)\n", " res.append(r3)\n", " res.append(r4)\n", " \n", "import pandas\n", "df = pandas.DataFrame(res)\n", "df.tail()"]}, {"cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [{"data": {"text/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", "
nameextext+fitpolypoly+fit
size
10.0000680.0004020.0002380.000275
20.0000660.0001560.0001660.000213
50.0000310.0004270.0001650.000196
100.0000480.0002370.0001340.000306
200.0000700.0001880.0001090.000153
\n", "
"], "text/plain": ["name ext ext+fit poly poly+fit\n", "size \n", "1 0.000068 0.000402 0.000238 0.000275\n", "2 0.000066 0.000156 0.000166 0.000213\n", "5 0.000031 0.000427 0.000165 0.000196\n", "10 0.000048 0.000237 0.000134 0.000306\n", "20 0.000070 0.000188 0.000109 0.000153"]}, "execution_count": 11, "metadata": {}, "output_type": "execute_result"}], "source": ["piv = df.pivot(\"size\", \"name\", \"average\")\n", "piv[:5]"]}, {"cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [{"data": {"image/png": "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\n", "text/plain": ["
"]}, "metadata": {"needs_background": "light"}, "output_type": "display_data"}], "source": ["ax = piv.plot(logy=True, logx=True)\n", "ax.set_title(\"Polynomial Features for 5 features\\ndegree=2\")\n", "ax.set_ylabel(\"seconds\")\n", "ax.set_xlabel(\"number of observations\");"]}, {"cell_type": "markdown", "metadata": {}, "source": ["The gain is mostly visible for small dimensions."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Comparison with 1000 observations\n", "\n", "In this experiment, the number of observations is fixed to 1000 but the number of features varies."]}, {"cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [{"data": {"text/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", "
averagedeviationmin_execmax_execrepeatnumbercontext_sizenamenfeatnumf
370.0093310.0016030.0082800.012519530240ext40861
380.0226190.0028680.0187930.026324530240extslow40861
390.0131880.0003700.0128280.013888530240poly501326
400.0128170.0001020.0127000.012951530240ext501326
410.0303840.0007170.0299550.031813530240extslow501326
\n", "
"], "text/plain": [" average deviation min_exec max_exec repeat number context_size \\\n", "37 0.009331 0.001603 0.008280 0.012519 5 30 240 \n", "38 0.022619 0.002868 0.018793 0.026324 5 30 240 \n", "39 0.013188 0.000370 0.012828 0.013888 5 30 240 \n", "40 0.012817 0.000102 0.012700 0.012951 5 30 240 \n", "41 0.030384 0.000717 0.029955 0.031813 5 30 240 \n", "\n", " name nfeat numf \n", "37 ext 40 861 \n", "38 extslow 40 861 \n", "39 poly 50 1326 \n", "40 ext 50 1326 \n", "41 extslow 50 1326 "]}, "execution_count": 13, "metadata": {}, "output_type": "execute_result"}], "source": ["poly = PolynomialFeatures(degree=2)\n", "ext = ExtendedFeatures(poly_degree=2)\n", "# implementation of PolynomialFeatures in 0.20.2\n", "extslow = ExtendedFeatures(poly_degree=2, kind=\"poly-slow\") \n", "\n", "\n", "res = []\n", "for n in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 40, 50]:\n", " X = numpy.random.random((1000, n))\n", " poly.fit(X)\n", " ext.fit(X)\n", " extslow.fit(X)\n", " r1 = measure_time(\"poly.transform(X)\", context=dict(X=X, poly=poly), repeat=5, number=30, div_by_number=True)\n", " r2 = measure_time(\"ext.transform(X)\", context=dict(X=X, ext=ext), repeat=5, number=30, div_by_number=True)\n", " r3 = measure_time(\"extslow.transform(X)\", context=dict(X=X, extslow=extslow), repeat=5, number=30, div_by_number=True)\n", " r1[\"name\"] = \"poly\"\n", " r2[\"name\"] = \"ext\"\n", " r3[\"name\"] = \"extslow\"\n", " r1[\"nfeat\"] = n\n", " r2[\"nfeat\"] = n\n", " r3[\"nfeat\"] = n\n", " x1 = poly.transform(X)\n", " x2 = ext.transform(X)\n", " x3 = extslow.transform(X)\n", " r1[\"numf\"] = x1.shape[1]\n", " r2[\"numf\"] = x2.shape[1]\n", " r3[\"numf\"] = x3.shape[1]\n", " res.append(r1)\n", " res.append(r2)\n", " res.append(r3)\n", " \n", "import pandas\n", "df = pandas.DataFrame(res)\n", "df.tail()"]}, {"cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [{"data": {"text/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", "
nameextextslowpoly
nfeat
10.0000260.0000590.000152
20.0000550.0001000.000113
30.0001610.0003810.000237
40.0001480.0002210.000219
50.0001850.0003400.000236
\n", "
"], "text/plain": ["name ext extslow poly\n", "nfeat \n", "1 0.000026 0.000059 0.000152\n", "2 0.000055 0.000100 0.000113\n", "3 0.000161 0.000381 0.000237\n", "4 0.000148 0.000221 0.000219\n", "5 0.000185 0.000340 0.000236"]}, "execution_count": 14, "metadata": {}, "output_type": "execute_result"}], "source": ["piv = df.pivot(\"nfeat\", \"name\", \"average\")\n", "piv[:5]"]}, {"cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [{"data": {"image/png": "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\n", "text/plain": ["
"]}, "metadata": {"needs_background": "light"}, "output_type": "display_data"}], "source": ["ax = piv.plot(logy=True, logx=True)\n", "ax.set_title(\"Polynomial Features for 1000 observations\\ndegree=2\")\n", "ax.set_ylabel(\"seconds\")\n", "ax.set_xlabel(\"number of features\");"]}, {"cell_type": "markdown", "metadata": {}, "source": ["It is twice faster."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Comparison for different degrees\n", "\n", "In this experiment, the number of observations and features is fixed, the degree increases."]}, {"cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [{"data": {"text/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", "
averagedeviationmin_execmax_execrepeatnumbercontext_sizenamedegreenumf
90.0019600.0000670.0019150.002094530240ext6210
100.0031310.0001180.0030090.003327530240poly7330
110.0030760.0002330.0028450.003393530240ext7330
120.0042990.0000460.0042430.004367530240poly8495
130.0041570.0000350.0041140.004217530240ext8495
\n", "
"], "text/plain": [" average deviation min_exec max_exec repeat number context_size \\\n", "9 0.001960 0.000067 0.001915 0.002094 5 30 240 \n", "10 0.003131 0.000118 0.003009 0.003327 5 30 240 \n", "11 0.003076 0.000233 0.002845 0.003393 5 30 240 \n", "12 0.004299 0.000046 0.004243 0.004367 5 30 240 \n", "13 0.004157 0.000035 0.004114 0.004217 5 30 240 \n", "\n", " name degree numf \n", "9 ext 6 210 \n", "10 poly 7 330 \n", "11 ext 7 330 \n", "12 poly 8 495 \n", "13 ext 8 495 "]}, "execution_count": 16, "metadata": {}, "output_type": "execute_result"}], "source": ["res = []\n", "for n in [2, 3, 4, 5, 6, 7, 8]:\n", " X = numpy.random.random((1000, 4))\n", " poly = PolynomialFeatures(degree=n)\n", " ext = ExtendedFeatures(poly_degree=n)\n", " poly.fit(X)\n", " ext.fit(X)\n", " r1 = measure_time(\"poly.transform(X)\", context=dict(X=X, poly=poly), repeat=5, number=30, div_by_number=True)\n", " r2 = measure_time(\"ext.transform(X)\", context=dict(X=X, ext=ext), repeat=5, number=30, div_by_number=True)\n", " r1[\"name\"] = \"poly\"\n", " r2[\"name\"] = \"ext\"\n", " r1[\"degree\"] = n\n", " r2[\"degree\"] = n\n", " x1 = poly.transform(X)\n", " x2 = ext.transform(X)\n", " r1[\"numf\"] = x1.shape[1]\n", " r2[\"numf\"] = x2.shape[1]\n", " res.append(r1)\n", " res.append(r2)\n", " \n", "import pandas\n", "df = pandas.DataFrame(res)\n", "df.tail()"]}, {"cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [{"data": {"text/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", "
nameextpoly
degree
20.0001400.000312
30.0003040.000363
40.0005060.000579
50.0007150.000789
60.0019600.002032
\n", "
"], "text/plain": ["name ext poly\n", "degree \n", "2 0.000140 0.000312\n", "3 0.000304 0.000363\n", "4 0.000506 0.000579\n", "5 0.000715 0.000789\n", "6 0.001960 0.002032"]}, "execution_count": 17, "metadata": {}, "output_type": "execute_result"}], "source": ["piv = df.pivot(\"degree\", \"name\", \"average\")\n", "piv[:5]"]}, {"cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [{"data": {"image/png": "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\n", "text/plain": ["
"]}, "metadata": {"needs_background": "light"}, "output_type": "display_data"}], "source": ["ax = piv.plot(logy=True, logx=True)\n", "ax.set_title(\"Polynomial Features for 1000 observations\\nnumber of features is 4\")\n", "ax.set_ylabel(\"seconds\")\n", "ax.set_xlabel(\"degree\");"]}, {"cell_type": "markdown", "metadata": {}, "source": ["It is worth transposing."]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Same experiment with interaction_only=True"]}, {"cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [{"data": {"text/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", "
averagedeviationmin_execmax_execrepeatnumbercontext_sizenamesize
290.0106910.0000730.0106180.010764230240ext50000
300.0266120.0007940.0258170.027406230240poly100000
310.0250520.0015830.0234690.026635230240ext100000
320.0587720.0013450.0574270.060118230240poly200000
330.0547710.0045550.0502160.059327230240ext200000
\n", "
"], "text/plain": [" average deviation min_exec max_exec repeat number context_size \\\n", "29 0.010691 0.000073 0.010618 0.010764 2 30 240 \n", "30 0.026612 0.000794 0.025817 0.027406 2 30 240 \n", "31 0.025052 0.001583 0.023469 0.026635 2 30 240 \n", "32 0.058772 0.001345 0.057427 0.060118 2 30 240 \n", "33 0.054771 0.004555 0.050216 0.059327 2 30 240 \n", "\n", " name size \n", "29 ext 50000 \n", "30 poly 100000 \n", "31 ext 100000 \n", "32 poly 200000 \n", "33 ext 200000 "]}, "execution_count": 19, "metadata": {}, "output_type": "execute_result"}], "source": ["res = []\n", "for n in [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, \n", " 5000, 10000, 20000, 50000, 100000, 200000]:\n", " poly = PolynomialFeatures(degree=2, interaction_only=True)\n", " ext = ExtendedFeatures(poly_degree=2, poly_interaction_only=True)\n", " X = numpy.random.random((n, 5))\n", " poly.fit(X)\n", " ext.fit(X)\n", " r1 = measure_time(\"poly.transform(X)\", context=dict(X=X, poly=poly), repeat=2, number=30, div_by_number=True)\n", " r2 = measure_time(\"ext.transform(X)\", context=dict(X=X, ext=ext), repeat=2, number=30, div_by_number=True)\n", " r1[\"name\"] = \"poly\"\n", " r2[\"name\"] = \"ext\"\n", " r1[\"size\"] = n\n", " r2[\"size\"] = n\n", " res.append(r1)\n", " res.append(r2)\n", " \n", "import pandas\n", "df = pandas.DataFrame(res)\n", "df.tail()"]}, {"cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [{"data": {"text/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", "
nameextpoly
size
10.0000420.000086
20.0000340.000104
50.0000680.000089
100.0000320.000092
200.0000400.000103
\n", "
"], "text/plain": ["name ext poly\n", "size \n", "1 0.000042 0.000086\n", "2 0.000034 0.000104\n", "5 0.000068 0.000089\n", "10 0.000032 0.000092\n", "20 0.000040 0.000103"]}, "execution_count": 20, "metadata": {}, "output_type": "execute_result"}], "source": ["piv = df.pivot(\"size\", \"name\", \"average\")\n", "piv[:5]"]}, {"cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [{"data": {"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYoAAAEpCAYAAACN9mVQAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOzdd3hUZfbA8e9JBxISSuidUEIvoYkoSrFRFAVBEZAmuroWxL5rXXVdddWfuggiiHSxgaKoKGChCygQektogUAaISHl/f1xb2AIKRPIzCST83meeZK5bc47k9wz733vPVeMMSillFL58fF0AEoppUo2TRRKKaUKpIlCKaVUgTRRKKWUKpAmCqWUUgXSRKGUUqpAmijUOSLynIjM8nQcjkTkThH53sllS1z87iQi5URksYgkisinHnj9ZiKyUUSSReTv7n595TqaKLyQiOwXkTMikiIix0RkuogEezquS2GMmW2M6Xu52xGRniKSbb8nOY/FxbDdGSLy0uVup5jcBlQHqhhjBl/uxkSkgYiYXO/ZPwpY5TFguTEmxBjzzmW+9nIRGXs521DFx8/TASiX6W+M+VFEagNLgWeAJzwck6cdNsbU8XQQjkTEzxiTWUybqw/svJTtFRJHmJPbrA/MK+pru0Ixv69lnvYovJwx5hDwLdAKQERqicgiETkpIrtFZFxe64nINyLyQK5pf4rIzfbvRkQmiMguETklIu+JiNjzfETkGRE5ICJxIjJTRELteTnfUu8WkRh73Qki0snefoKIvOvwmqNE5FeH52/b6yWJyAYR6XG575Ed7xMiskdE4kVkgYhUdpj/qYgctQ/prBSRlvb08cCdwGOOPRS7fREO65/rddg9m1gReVxEjgLT7en9RGST3f7fRaSNw/qPi8gh+5DODhHplUcbngf+CdxuxzLGyc9hjIgcBH66zPfwJ+Aa4F379ZuKSKCIvC4iB+2e7WQRKWcvX0lEvhaR4/bfwNciUsee9y+gh8O23nWI18/hNc/1Ouy/k99E5L8ichJ4zp4+WkSi7ddYKiL17eliLxtnf65/ikiry3kPvJoxRh9e9gD2A73t3+sCW4EX7ecrgPeBIKAdcBzoZc97Dphl/z4EWOOwzbZAPBBgPzfA10AYUM/ezvX2vNHAbqAREAx8Dnxiz2tgrzvZjqEvkAZ8CVQDagNxwNX28qOAXx3iGA5UweoNTwSOAkG548/jPekJxOYz7yFgNVAHCAQ+AOY6zB8NhNjz3gI2OcybAbyUa3sGiMhrGTuOTODf9vbKAR3sNncBfIGR9mcYCDQDYoBaDu9f43zacUH7nfwcZgIVgHJ5bC9nmUNALFZSq1rA391yYKzD87eARUBl+/1bDLxiz6sC3AqUt+d9CnxZwLZyYvHLaxn77yQTeMD+2ygH3Gy3P9Ke9gzwu738dcAGrL9fsZep6en/3ZL68HgA+nDBh2rtZFKABOAAVmIoh5U0soAQh2VfAWbYv5/b0dg7qZNAE/v568D7DusZ4EqH5wuAJ+zflwH3OcxrBmTY/6w5//C1HebHA7c7PP8MeMj+fRQOiSKPtp4C2uaOP4/legLZ9nuS8xhiz4vGTpb285o58eaxnTA7/lD7+QyKnijOYic3e9r/sBO5w7QdwNVABFYS6Q34F/K5X9B+Jz+HRgVsLxiIspevDiwElhaw/HLO77gFOI1DUgO6AfvyWbcdcCqvbdnPc+ItKFEczLXNb4ExDs99gFSsQ2TXAjuBroCPp/9nS/pDDz15r5uNMWHGmPrGmPuMMWeAWsBJY0yyw3IHsL7FX8AYk4618x8uIj7AMOCTXIsddfg9FWvHgv06B3K9Rs7OJscxh9/P5PE8z8F3EZloH0pIFJEEIBSomteyeThsvyc5jwX29PrAF/ZhnwSsxJEFVBcRXxF51T4slYSVhCnCa+bluDEmzeF5fWBizuvbMdTF6kXsxurxPAfEicg8Eanl5Os48znE5LeyMSbFGLPeGJNpjDkG3A/0FZGKTrx2OFZvYYNDm76zpyMi5UXkA/uwWBKwEggTEV8n25aX3G2pD7zt8PonsRJYbWPMT8C7wHvAMRGZ4mS7yiRNFGXLYaCyiIQ4TKuHdWghLx9jHYPvBaQaY1YV4XXq53qNTC5MBkVmj0c8jnVYrJIxJgxIxPrnvxwxwA25kkiQscZ37gAGYn2jD8X6ZovDa+ZVfjkVayeZo0au+bnXiQH+lev1yxtj5gIYY+YYY67Eek8N1mErZzjzORSlfHTOss683yewEn5LhzaFGmNyvgBMxOrhdDHGVASuyrXt3HGdtn8W9X29J9f7Ws4Y8zuAMeYdY0xHoCXQFJjkRLvKJE0UZYgxJgb4HXhFRILsAdMxwOx8ll+FdbjmDS7uTRRkLvCwiDQU67Tcl4H55vLPQgnB2tEdB/xE5J9AcXwLnAz8y2GgM1xEBjq8ZjrW4bHyWG1xdAxrDMDRJuAOuzdyPdYhpIJMBSaISBd7kLWCiNwkIiFiXZtwrYgEYo3lnMHq7Tjjsj4HO55m9qB4FeAdrNNfEwtb1xiTbbfrvyJSzd5ebRG5zl4kxG5LglgnDjybaxMXvK/GmONYX2iG2+/raKBxIWFMBp6U8ycfhIrIYPv3Tnb7/LGSUBrOv69ljiaKsmcY1rfiw8AXwLPGmB8KWH4m0BooyoVsH2EllpXAPqx/wgcKXMM5S7GOO+/EOoySRgGHTorgbaxB1+9FJBlrYLuLPW+m/VqHgG32PEfTgBb24Y0v7WkPAv2xxkHuxBqoz5cxZj0wDutQyCmsAdhR9uxA4FWsb+hHsQb8n3KyXZf7OTTCOlyUDGzBSpjDirD+41htWW0fXvoRqxcB1kB3Oax2rbZfx9HbwG322Uo512SMw/rWH4/VC/i9oBc3xnyB1fuaZ7/+FuAGe3ZFrER2Cuvzjccah1N5EHuQR6k8icgIYLx96EMpVQZpj0LlS0TKA/cBUzwdi1LKczRRqDzZx5KPYx0rnuPhcJRSHqSHnpRSShVIexRKKaUKpInCy0jJqmaaL7vuT0GVSD2mJMdWGBH5VkRGejqOvJSWv011Ma0eqzzCGDOhqOvY5+O/jXVdQgWs0x0fMcas8VRsIjIDq4bUM8UZg5Ov/RxWqZDhOdOMMTfkv4b3sC++/DbnKdY1LqcdFmlhjDno9sC8lPYolFMcq3Z6UDCwDuiIVWjuY+AbceJeG3b10f2uDa/oSsj7WuoYY34xxgTbV3q3tCeH5UzLnSTsiwZ1f3eJ9I0r5USkvYj8IVYJ6vlYFVkd5xdUvrqDnL8j2aciMl8urxx2LRH5TKzS0fukgLucyYWlt6uKVWY6Qazy57/k9U9tjNlrjHnTGHPEGJNljJkCBHD+Iq5iIXmXBZ8oVknqIyJytz0vvzLj+b4PYt2Fb6GIzLIvAhslIp1FZJXd/iNildUOcFinpYj8YL83x0TkKbGu+H6K82XFN9vLOpbedqbM+EixyoCfEJGnnXhvAkXkLRE5bD/eEuuq8QLfqzy2s0VE+js897djaFekD6vgWH8VkRdFZBVWb6OeHV9Ph2VesnuFOc+7i8hq+7PYJCJXXbzlskcTRSlm70y+xLr6tjJWqeZbHeZ3wLo69x6sss4fAIvsf/YArCuzZ9jrzgVuyfUSNex59YHxhWzPB6uM9GasIoO9gIfkfMmGgkzEKmMdjlWw7imcqEFk71QCsK7+daUaWHWeamOVPHlPRCrZiWo28Jr9Lba/k+/DQKxKrGH2+lnAw1iFBrvZ69xntzEE64rm77CK/EUAy4wx33G+JEewMaZtHnGPsh/XcL7U+Lu5lrkSK9H2Av4pIpGFvBdPY1VcbYdVer4zVvnuAt+rPLYzE6tkfI4bgSPGmE12uxMKeBTlBlx3YZVbr4j1N5YvEamLdYX+s1h/908An4tVvqRM00RRunUF/IG3jDEZxpiFWIdmcowDPjDGrLG/gX+MVYahq/3wA96x1/0cWJtr+9lYJT7S7eqzBW2vExBujHnBGHPWGLMXq0TCUCfakYFV2ru+HcsvppDztsWq9PkJ8LwztYcuUwbwgh3bEqwS7vn1Ypx5H1YZY740xmQbY84YYzYYY1bbVVr3YyXgnPpQ/YCjxpg3jDFpxpjkIozJ3Am8affEUoAngaFy4eGu5+0YNmMlt7wSTu5tvmCMibPrLz2PtTPO4ex7NQu4Uc5XbL0Lh3piuQr55X686mT7AT4yxkTb8RRW42oEsMgYs9T+bL7Dek+uL8LreSU9Plq61QIO5dqpOpaVrg+MlAvvVBdgr2fyWDd33aS8ymHnt70soJZY5Zxz+AK/ONGO/2CV0f5erJvkTSloZyDWXdIWA6uNMa8UsNwdWPfiAOtLUXCu+No4OeAZn2sn41hSPbf6FP4+XPA+i0hT4E2sez+Ux/q/3GDPrgvscSLGvDhTZjy/UvFF2aZj2XOn3itjzGER+Q24VUS+wKrB9GAhr30pilILrD4wTEQce9b+XFyHqszRHkXpdgSoLfbe1VbP4feCylfntW7dXNsvSjnsGKyb0jjOCzHG3FhYI+xvyRONMY2wiuk9Innc7hOsY+RYh9sOYR0CK2i7c3JiAdpg3djGMb7iOCsmr/eosPch9zr/A7Zj3SSqItahN3HYXn5VUgs7POeKcu95bfPwJW7rY6zDT4Oxelnnyt3b4y75PZwtigh5lyvPr1R5DDA912dXwRjznyK2y+tooijdVmH94/9dRPxEZBDWMeMc+ZavttfNAu631x2Ya928FLS9tUCSWIPf5cQqBd1KRDoV1gixBsgj7KSVZMd1UclnsUpCL8QqTz3CWKWsPS13mfFLeR9CsNqdIiLNgXsd5n0N1BCRh+yxoBARyalsewxoIPmfzeOKcu9zgWfEKsVeFes+3UWpLOzoS6zbwD6INWZxjsPZS3k9cpd6L4pN2IffRKQzMMhh3ifALSLSx/7cgkTkGnH+RlFeSxNFKWaMOYv1hz4Kq1zy7Vj3Rc6Zn2/5aod1x2CVwx6OtVNKL+D1CtpeFlZvoB1WSesTwIdYA5uFaYI1YJuClcDeN8Ysz2O5K7CO2ffFuo9BzjfMHk68hqtcUGb8Et+HR7FukJSMlYzn58ww1t0I+9jbPArswhqcBuvkBYB4Efkjj+26otz7S8B64E/gL+APe1qR2eNenwENcfi7dbGngeZYf/P/wKGOmT0+dIs9/ThwEOtEizK/n9RaT+ocEVkDTDbGTPd0LKpsEOvmU02Nw0WDquQp85myLBORq0Wkht0NH4l1HL/MD9wp9xDrznZj0DL2JZ4mirKtGdbpf4lYXezbjDFHPBuS8jSx6kVd7iByYa8xDmvw+FtjzMri2q5yDT30pJRSqkDao1BKKVUgTRRKKaUK5JVXZletWtU0aNDA02EopVSpsmHDhhPGmPDc070qUYhVjbJ/REQE69ev93Q4SilVqojIgbyme9WhJ2PMYmPM+NBQZ67xUkop5QyvShRKKaWKnyYKpZRSBfLaMYrcMjIyiI2NJS0t7eIVvUBQUBB16tTB39/f06EopbyMV15wFxUVZXIPZu/bt4+QkBCqVKnChZW1Sz9jDPHx8SQnJ9OwYUNPh6OUKqVEZIMxJir39DJz6CktLc0rkwSAiFClShWv7S0ppTyrzCQKwCuTRA5vbptSyg225F/p3asShYj0F5EpiYmuvoWyUkp5kU1zYeHd+c72qkSh11EopVQR7VyK+epvxIblfxNGr0oUrrJ//34iIyMZN24cLVu2pG/fvpw5c4apU6fSqVMn2rZty6233kpqaioAo0aN4t577+Waa66hUaNGrFixgtGjRxMZGcmoUaPObff777+nW7dudOjQgcGDB5OSkuKhFiqlyqSDa2DBSOLKN+W6oxPyXUwThZN27drF3/72N7Zu3UpYWBifffYZgwYNYt26dWzevJnIyEimTZt2bvlTp07x008/8d///pf+/fvz8MMPs3XrVv766y82bdrEiRMneOmll/jxxx/5448/iIqK4s033/RgC5VSZUpcNMwZQmJAODfG/50bOzbJd1Gvuo7ClRo2bEi7du0A6NixI/v372fLli0888wzJCQkkJKSwnXXXXdu+f79+yMitG7dmurVq9O6dWsAWrZsyf79+4mNjWXbtm10794dgLNnz9KtWzf3N0wpVfYkxMAng0gzftx06hE6tmjKK4Na83o+i3tVoijogrvLFRgYeO53X19fzpw5w6hRo/jyyy9p27YtM2bMYPny5Rct7+Pjc8G6Pj4+ZGZm4uvrS58+fZg7d26xx6qUUvk6HQ+f3EJGWjK3pj5NnYbNeWdYe/x88z/A5FWHntw9mJ2cnEzNmjXJyMhg9uzZRVq3a9eu/Pbbb+zevRuA1NRUdu7c6YowlVLKkp4Cs28jO+EgI888gk+N1kwdEUWQv2+Bq3lVonC3F198kS5dutCnTx+aN29epHXDw8OZMWMGw4YNo02bNnTt2pXt27e7KFKlVJmXeRYW3IU5spkHsx7kaFgHZtzdiZCgwsv+lJkSHtHR0URGRnooIvcoC21USl2C7Gz4fBxsWcgLPvfxrX9vFt57BbXDyl2wWH4lPLxqjEIppVQuxsDSJ2HLQib7D+eLrGv4dEzni5JEQTRRKKWUN/vlDVgzmc8CBvJOWj/mjutMRLWQIm3Cq8YotISHUko52DADfnqRFUHX8tTp25k6ohNt64YVeTNelSi0hIdSStmiF2O+fpjNQZ0YlziKt4d1oHtE1UvalFclCqWUUsD+XzELx7A/sDlDE+7lhVvac32rmpe8OU0USinlTY78iZk7jON+Nbkl4UEevKEdQzvXu6xNaqIogRISEnj//fc9HYZSqrQ5uQ9m3UqKCWJg4kRuv6otE65ufNmb1URRAmmiUEoVWUocfHILaWfTuTl5Ej2i2vLEDUW7EDg/mijcaNasWXTu3Jl27dpxzz33cODAAZo0acKJEyfIzs6mR48efP/99zzxxBPs2bOHdu3aMWnSJE+HrZQq6dKSYNatZCYdZVjKI0S06MDLt7QutjtfetV1FM4WBXx+8Va2HU4q1tduUasiz/Zvme/86Oho5s+fz2+//Ya/vz/33XcfK1as4PHHH2fChAl06dKFFi1a0LdvX5o2bcqWLVvYtGlTscaolPJCGWkw7w6yj21j3NmJBDXsyttDCy7yV1RelSiMMYuBxVFRUeM8HUtuy5YtY8OGDXTqZN1F6syZM1SrVo3nnnuOTz/9lMmTJ2tiUEoVTXYWfD4W9v/CY1n3c6LGVcwZ0bHQIn9F5VWJwlkFffN3FWMMI0eO5JVXXrlgempqKrGxsQCkpKQQElK0KyaVUmWUMfDNRIhezL8ZyR9hffjUySJ/RaVjFG7Sq1cvFi5cSFxcHAAnT57kwIEDPP7449x555288MILjBtndYRCQkJITk72ZLhKqZLMGFj6FGyYznS5hS8DB/LJmC5UCQ4sfN1LoInCTVq0aMFLL71E3759adOmDX369GH//v2sW7fuXLIICAhg+vTpVKlShe7du9OqVSsdzFZKXcgY+OEfsPp9Fvj14x2G8cmYLkUq8ldUWmbci5SFNipVphkDy56HX//Lt+Vu4uGU4cwbfwXtLqF+U17yKzOuPQqllCotfn4Zfv0vv4b2575Tw3jr9vbFliQKoolCKaVKg+X/hpWvsaXaAO46djuPXd/isuo3FYUmCqWUKulWvg7LX+Zg3Zvpf3AIg6PqMeHqRm57eU0USilVkv32Nvz0IvGNBtJ37xC6NKrKSzcX31XXztBEoZRSJdWq9+CHf3K6yUCu338HNStVYPLwjgT4uXfX7VWJQu9wp5TyGms+gKVPkdFsADcfGclZ48NHozoRVj7A7aF4VaLwtjvc9ezZk9yn+SqlyoB1H8K3j5Hd7CbGpkxg/6l0PrirIw2rVvBIOF6VKJRSqtTbMAO+mYhpej3PBjzKij0JvHxLa7o2quKxkDRRuNH+/ftp3rw5I0eOpE2bNtx2222kpqaybNky2rdvT+vWrRk9ejTp6ekXrDdt2jQefvjhc8+nTp3KI4884u7wlVKutnEWLH4QIvowvfbzfLLuCPf2bMzgqLoeDatMFgXk2yfg6F/Fu80areGGVwtdbMeOHUybNo3u3bszevRo3nzzTT744AOWLVtG06ZNGTFiBP/73/946KGHzq0zdOhQ2rRpw2uvvYa/vz/Tp0/ngw8+KN74lVKetXkefHU/NLqGZW3f5MU5f3FDqxpM6tvM05Fpj8Ld6tatS/fu3QEYPnw4y5Yto2HDhjRt2hSAkSNHsnLlygvWqVChAtdeey1ff/0127dvJyMjg9atW7s9dqWUi/z5KXx5LzTswbaeH/DAp9toXTuUN4e0w8fHfafB5qds9iic+ObvKpd67vPYsWN5+eWXad68OXfffXcxR6WU8pgtn8MX46HeFRzr9zGjP9hIaDl/PhwRRbmA4r2vxKXSHoWbHTx4kFWrVgEwd+5cevfuzf79+9m9ezcAn3zyCVdfffVF63Xp0oWYmBjmzJnDsGHD3BqzUspFtn0Fn42Ful1IHTybsXO2kZyWwbSRnahWMcjT0Z2jicLNIiMj+fjjj2nTpg0nT57k4YcfZvr06QwePJjWrVvj4+PDhAkT8lx3yJAhdO/enUqVKrk5aqVUsdv+DSwcDbU7kj1sAY98sYethxN5Z1h7WtSq6OnoLlA2Dz15kI+PD5MnT75gWq9evdi4ceNFyy5fvvyC57/++usFZz8ppUqpHd/BgpFQsy0MX8hrPx/mu61H+Ue/FvSKrO7p6C6iPYpSICEhgaZNm1KuXDl69erl6XCUUpdj14+w4C6o3hKGf878vxKZvGIPd3apx+juDTwdXZ60R+FGDRo0YMuWLUVeLywsjJ07d7ogIqWUWx1cA/PvhPBmcNcX/H44k6e/2EKPJlV5bkBLtxb6KwrtUSillDvE74G5Q6FiLbjrS/aeDuDeWX/QoGoF3r2jA/6+JXd3XHIjcwFvvO1rDm9um1KlXupJmD3Y+v3OhZyiIqNnrMPXR/hoZCdCy/l7Nr5ClJlEERQURHx8vFfuUI0xxMfHExRUck6nU0rZMtJg3h2QGAND53A2tCETZm3gcGIaU0d0pF6V8p6OsFClYoxCRG4GbgKqAe8ZY74v6jbq1KlDbGwsx48fL/b4SoKgoCDq1Knj6TCUUo6ys+Gr++DgKrh1GqZeV55a+Cdr9p3k7aHt6Fi/sqcjdIrLE4WIfAT0A+KMMa0cpl8PvA34Ah8aY/K9XNoY8yXwpYhUAl4Hipwo/P39adiwYVFXU0qpS/fzS7DlM+j1LKbVrbz4dTQLN8TyYK8mDGxX29PROc0dPYoZwLvAzJwJIuILvAf0AWKBdSKyCCtpvJJr/dHGmDj792fs9ZRSqmT7Yyb88gZ0GIHp/hD//m4HH/22j7u7N+Ch3k08HV2RuDxRGGNWikiDXJM7A7uNMXsBRGQeMNAY8wpW7+MCYp0z9irwrTHmj7xeR0TGA+MB6tWrV2zxK6VUke1eBosfgsbXwk1v8tay3eeulfhnvxYl9jTY/HhqMLs2EOPwPNaelp8HgN7AbSKSZ30LY8wUY0yUMSYqPDy8+CJVSqmiOLbVuuo6vDkM/pj3Vh7g7WW7GNyxDi8ObFXqkgR4bjA7r3cq39ORjDHvAO+4LhyllCoGSUdg9hAIqAB3LuDDdSf4z9Id3NyuFq/e2qZElAy/FJ7qUcQCjrdsqgMcvtyNikh/EZmSmJh4uZtSSqmiSU+BOUPgzCm4cwEfb83kpW+iual1TV4f3BbfUpokwHOJYh3QREQaikgAMBRYdLkbNcYsNsaMDw0NvewAlVLKaVmZViXYY1tg8AzmxlTi2UVb6dOiOm8NbYdfCb7q2hkuj15E5gKrgGYiEisiY4wxmcD9wFIgGlhgjNnq6liUUqrYGQPfPQ67lsINr7EwuQVPffEXPZuF8+4d7Ut0aQ5nueOspzzvsmOMWQIsKc7XEpH+QP+IiIji3KxSSuVv1Xuw7kPodj+LAm/isXkb6d64KpOHdyTQr2Tcoe5ylf5U50APPSml3GrbIvj+GYgcwLc17+Ph+ZuIalCZqSOiCPL3jiQBXpYolFLKbWLXw+fjoE4UP0W+xAPzNtO2TigfjepUYu51XVy8KlHoWU9KKbc4uQ/m3A7B1fm987tMmL+NFrUqMmN0Z4IDS0UJvSLxqkShh56UUi6XUzI8O5ONPaZy94J9RFQLZubozlQMKtnlwi+V96U+pZRylcx0mH8XnNpPdJ+Z3PHlKepXKc+ssV0IKx/g6ehcRhOFUko5wxhY9AAc+JV9V7/Fbd/6UDMsiNlju1K5gvcmCdBEoZRSzln+Cvw5n2MdJzJgRS2qhgQwZ2xXwkMCPR2Zy3nVGIUOZiulXGLTHFjxbxKaDua6P7pQMcifOeO6UiO0bNxV0qsShQ5mK6WK3d7lsOgBUmtfSd/dgygX4MfccV2pHVbO05G5jVclCqWUKlZx22H+CM6GNuKmY+MxvgHMHtulVNznujjpGIVSSuUl+RjMHkyWbyBDUh4hyZRn3rguNAoP9nRkbudVPQodo1BKFYuzp2Hu7WSfPs74zEnsz6rCrLFdaFI9xNOReYRXJQodo1BKXbbsLPhsHObwJp72eZi1Z+sza0wXImtW9HRkHuNViUIppS7b0qdhxze8GzCWRWltmTm6M61ql+0vnzpGoZRSOVZPhjX/4/OA/rx/pjczx3Smfb1Kno7K47RHoZRSAH8txHz3BL/7d+Xp1GFMGxlFpwaVPR1ViaCJQimltnyO+XwcW/1acm/qBCaP6MwVEVU9HVWJ4VWJQs96UkoV2bavMJ+NJdovkjtSJ/LGnVdwddNwT0dVonhVotCznpRSRRL9NWbhaHb5N+X2lEd4dVg3ereo7umoShyvShRKKeW0Hd9iPh3FXr8Ibk2eyPODu3Jj65qejqpE0kShlCp7dn6PWTCCA/6NuCVpIk/e3IVBHep4OqoSSxOFUqps2f0jZv5wYv0aMCBxIg/268QdXep5OqoSTROFUqrs2PMzZt6dHPGvR7/ER7nnuo6MubKhp6Mq8TRRKKXKhr0rMHOHEedXm5sSJjL8mrb87ZoIT5yoV1wAACAASURBVEdVKmiiUEp5v/2/wtyhnPCvyQ0Jk7ile1se7dvM01GVGl6VKPQ6CqXURQ6sgtlDOOlfnRtOTeK6zq34R79IRMTTkZUaXpUo9DoKpdQFYtbC7NtI8A/nupOTuKp9C/51cytNEkXkVKIQkQoi4mP/3lREBoiIv2tDU0qpyxC7Hj4ZRJJfFfqenESn1s157bY2+PhokigqZ3sUK4EgEakNLAPuBma4KiillLosh/6ATwaR4hdG35OP0qp5M966vT1+vl51EMVtnH3XxBiTCgwC/s8YcwvQwnVhKaXUJTq8CT65mVTfEK479RgREc14/84OBPhpkrhUTicKEekG3Al8Y0/Te1kopUqWI3/CzIGc8Qnm+oTHqFU/gikjOhLk7+vpyEo1ZxPFQ8CTwBfGmK0i0gj42XVhKaVUER3bCjMHkuZTjn6Jj1GpVmM+GtWJ8gH6nfZyOfUOGmNWACscnu8F/u6qoJRSqkjiouHjAZyVAPonP45/eCM+Ht2ZkCA956Y4FJgoRGQxYPKbb4wZUOwRKaVUURzfAR/3JwMfbj79JNlhDZg7tgth5QM8HZnXKKxH8br9cxBQA5hlPx8G7HdRTEop5ZzEQ/BxfzKz4dYzT5FSoT4LxnalanCgpyPzKgUmCvuQEyLyojHmKodZi0VkpUsjuwQi0h/oHxGh9VuU8nrGwJJHyU5LZFj2KxwPrMeCsV2oERrk6ci8jrOD2eH2ADYAItIQKHH3CtQrs5UqQ6IXwY4lvGcGs8+nHrPHdqFu5fKejsorOXs6wMPAchHZaz9vANzjkoiUUqowZxJgySRiApvw/unr+fxvnWkUHuzpqLyWs2c9fSciTYDm9qTtxph014WllFIF+PFZzOnj3Jv2AOOubUpkzYqejsirFeUE445YPQk/oK2IYIyZ6ZKolFIqP/t/gw0z+DTgZhKCWnJfz8aejsjrOZUoROQToDGwCciyJxtAE4VSyn0y02HxgyQF1eLZhAH834iWetW1Gzjbo4gCWhhj8r2mQimlXO6XNyB+FxOzn6R7ZD16t6ju6YjKBGcTxRas6yiOuDAWpZTKX1w0/PIma0N6s/JUW37s39LTEZUZziaKqsA2EVkLnBvE1iuzlVJukZ0Nix8kw68CE47fxt/6ROipsG7kbKJ4zpVBKKVUgTZ8BDFreCPwQUKq1GD8VY0KX0cVG6eLAopIdaCTPWmtMSbOdWEppZQt6TD88BwxYV2YfLQzM+7WAWx3c/ZWqEOAtcBgYAiwRkRuc2VgSikFwJJJmKwMRscP47qWNejZrJqnIypznD309DTQKacXISLhwI/AQlcFppRSRC+G7V/zReWxxByvwfR+emNNT3C21pNPrkNN8UVYVymlii4tEb55lOSw5jx2+CoeuLYJdSrpALYnONuj+E5ElgJz7ee3A9+6JiSllAJ+fB5zOo6JgY9Sr2ooY3s09HREZZazg9mTRGQQcCUgwBRjzBcujcwmIpHAg1in6C4zxvzPHa+rlPKgg6th/TQ21b6D7/fU4pMxLQn00wFsT3G2hEdDYIkx5nP7eTkRaWCM2V/Ieh8B/YA4Y0wrh+nXA28DvsCHxphX89uGMSYamCAiPsBUZ+JVSpVimemw6O9khtRh9IG+3NS6Jj2alLi7GpQpzo4zfApkOzzPsqcVZgZwveMEEfEF3gNuAFoAw0SkhYi0FpGvcz2q2esMAH4FljkZr1KqtPr1v3BiB++Wv490n3I80y/S0xGVec6OUfgZY87mPDHGnBWRQm9Ia4xZKSINck3uDOw2xuwFEJF5wEBjzCtYvY+8trMIWCQi3wBznIxZKVXaHN8Bv7zB0Xr9eGtnA568oQk1Q8t5Oqoyz9lEcVxEBtg7bERkIHDiEl+zNhDj8DwW6JLfwiLSE+ue3YHAkgKWGw+MB6hXr94lhqaU8hi7TIfxL8+447cSUS2Yu7vrAHZJ4GyimADMFpH3sMqLxwIjLvE1JY9p+ValNcYsB5YXtlFjzBRgCkBUVJRWuVWqtPljBhxcxfcR/+CvLYHMGdeSAD89C78kcPaspz1AVxEJBsQYk3wZrxkL1HV4Xgc4fBnbO0dE+gP9IyIiimNzSil3SToCPzzLmTpX8sD2FgxoW5MrGlf1dFTK5mwJj+oiMg341BiTbA8+j7nE11wHNBGRhvY4x1Bg0SVu6wLGmMXGmPGhoaHFsTmllLt8+xgm6yzPZo8lwNeXp2/SAeySxNl+3QxgKVDLfr4TeKiwlURkLrAKaCYisSIyxhiTCdxvby8aWGCM2VrUwJVSXmL7NxC9iJ3N/8aCvQE81LsJ1SsGeToq5cDp+1EYYxaIyJMAxphMEckqbCVjzLB8pi+hgIFppVQZkZYE3zxKdrWWjNvVleY1ghh1RQNPR6VycbZHcVpEqmAPOotIVyDRZVFdIhHpLyJTEhNLXGhKqbwsewGSjzC72kQOJmbwwsBW+PnqAHZJ4+wn8gjWOEJjEfkNmAk84LKoLpGOUShVisSshXUfktBmNC9sLMeg9rXp3LCyp6NSeXA2UTTGupL6CqyxhV04f9hKKaUulHkWFv0dE1qbR+MHEOTny5M36gB2SeVsoviHMSYJqAT0xrpeocQV59NDT0qVEr+9DcejWd/iGX7cc5qJfZsSHhLo6ahUPpxNFDkD1zcBk40xXwGFlvBwNz30pFQpsHsZrHyNzMhbeGBDNVrUrMjwrvU9HZUqgLOJ4pCIfIB1G9QlIhJYhHWVUgqMgV/egFm3QpUmvBc0jqNJabx4sw5gl3TOfjpDsMYmrjfGJACVgUkui0op5V3Sk2HBXdZZTq1uZfeAL/i/NYkMiapDx/qVPB2dKoSzJTxSgc8dnh8BjrgqqEulJTyUKoFO7IJ5d0L8brjuZUyXe/nHh2spH+DL49c393R0ygle1d/TMQqlSpjtS2DqtZB6AkZ8SWbne3nmq62s2hvPpOubUyVYB7BLAz3FVSlV/LKzYcWrsOLfUKs9DPmE1PI1+fusDfwYHceEqxtzZ2e9HUBpoYlCKVW8ziTA5+Ng1/fQbjjc9AYn0oUxU9fwV2wCLw5syV3dGng6SlUEmiiUUsXn2DaYfyckxMBNb0DUGPbHpzJy+lqOJaUxeXhH+ras4ekoVRF5VaLQwWylPGjL5/DV/RAYDKO+gXpd2HjwFGM+Xo8xhjnjutKhnp7hVBrpYLZS6vJkZcL3/4CFd0ONVnDPSqjXhR+2HWPY1NUEB/rx2b1XaJIoxbyqR6GUcrPT8VaC2LcCosbA9a+CXwCzVh/gn19toXXtUKaN6kRVPbupVNNEoZS6NIc3wfy7IOUYDHwP2g/HGMN/vtvO+8v30Kt5Nf7vjvaUD9DdTGmnn6BSqug2zYWvH4LyVWH0d1C7A2czs3n8sz/5YuMhhnWux4sDW2ppDi+hiUIp5bysDFj6FKydAg16wG3TITicpLQM7p21gd92xzPpumbc17MxIuLpaFUx8apEoWc9KeVCycfg01Fw8Hfodj/0fh58/TiamMao6WvZHZfCG4PbcmvHOp6OVBUzr+oX6llPSrlIzDqYcjUc3gi3ToPr/gW+fuw4mswt7/9G7KkzTL+7kyYJL+VVPQqllAusnw5LJkHFWjD2B6jRGoBVe+IZ/8l6yvn7Mv+errSspV/QvJUmCqVU3jLS4NtJ8MdMaNwLbv0Qylv3tF60+TCPLthM/SrlmTG6M7XDynk4WOVKmiiUUhdLPGTdP+LQBugxEa55Gnx8McYw9Ze9vLxkO50bVmbqXVGElvf3dLTKxTRRKKUutP9Xa9A64wzcPgsi+wOQlW148ettzPh9P/3a1OSNIW0J9PP1bKzKLTRRKKUsGWdg5evw63+hciOrXlN4MwDSMrJ4cN5Glm49xrgeDXnyhkh8fPT017LCqxKFnh6r1CXa+T0seRQSDkCboXDjaxBkDU6fPH2WsR+vY2NMAv/s14LRVzb0cLDK3bwqURhjFgOLo6Kixnk6FqVKhcRD8N3jEL0YqjaFkV9Dwx7nZh+MT2XU9LXEJpzh/Ts6cEPrmh4MVnmKVyUKpZSTsjJhzWT4+WUwWdDrn9DtAfALOLfIn7EJjJ6xjsxsw5yxXYhqUNmDAStP0kShVFlzcA188wgc2wJNrrMOM1VqcMEiP2+P429z/qByhQBm3N2ZiGrBnolVlQiaKJQqK1JPwo/PWtdFVKxtndHUvB/kqsk0b+1Bnv5yC5E1Q/hoVCeqhQR5KGBVUmiiUMrbGQObZsMP/7TuZ33FA3D1E9ad6Bykns3k5SXRzFp9kKubhvP+nR2oEKi7CKWJQinvdmybdZjp4Cqo2wVuetO6C10uGw6c5JEFmzl4MpXxVzVi0nXN8NcS4cqmiUIpb3T2NKz4N6x6DwJDYMD/Qbvh4HPhzj89M4u3ftzFByv2ULtSOeaN60qXRlU8FLQqqTRRKOVttn8DSx6DpFhoPxx6vwAVLt75Rx9J4uH5m9h+NJlhnevy9E0tCNZDTSoP+lehlLc4dQC+fRx2fgvVWsCt30H9bhctlpVtmLJyL2/+sIPQcgFMGxlFr8jqHghYlRaaKJQq7TLSYPX7sOI16wymPi9A1/vA9+JifQfiT/PIgs1sOHCKG1vX4KWbW1O5QkAeG1XqPK9KFFrCQ5Upp0/Aug9h7VRIPWGd6nr9qxBW96JFjTHMXnOQl5dE4+cjvD20HQPa1tLblSqneFWi0BIeqkw4vsPqQWyeB5lp0KSvdcprw6vyXPxYUhqPLfyTFTuP06NJVV67rQ01Q/X+Ecp5XpUolPJaxsC+lbDqXdj1PfgFQduh1iEmu8JrXhZtPsw/vtxCemYWLw5syfCu9bUXoYpME4VSJVnmWdj6uZUgjv4FFcKh51PQaQxUqJrvagmpZ3nmyy18/ecR2tUN480hbWkUrmU41KXRRKFUSZR6EjbMgLVTIPkIhDe3roVoPQT8Cy6p8fOOOB5f+CcnT5/l0b5NmXB1Y/z04jl1GTRRKFWSnNwLq/8HG2dBRio0ugYGvAsRvS6qyZTb6fRM/rUkmjlrDtK0ejAfjepEq9qhbgpceTNNFEp5mjEQswZ+/z/rYjkfP2g9GLr9Lc9yG3lZv98qwRFzyirB8UifpgT5621KVfHQRKGUp2RlQvQia/zh0AYoVwl6TITO4yCkhlObMMbw/vI9vP79DupoCQ7lIpoolHIXY+DUfohZC7FrYedSSIyByo3hpjeg7TAIqOD05tIysnhs4Z8s2nyY/m1r8cqg1lqCQ7mE/lUp5SoZZ+DwRisx5CSH08eteQEhUK8L3PAaNL3+omJ9hTmamMb4T9bzZ2wik65rxn09G+tpr8plNFEoVVwSY62xhph11s+jf0J2pjWvcmOI6A11O0OdzlAtEnwubQxhU0wC42eu53R6JlPu6kjfls4dplLqUmmiUOpSZJ61EkHMmvM9huTD1jy/clC7o3W1dN0uUKdTgdc8FMVXmw4xaeGfVAsJZOaYK2heo2KxbFepgmiiUMoZycesQ0c5PYbDGyEr3ZoXWg/qX2H1Fup2huqt8izIdzmysw3/+X4H/1u+h84NK/O/OztQJTiwWF9DqfxoolAqt6xMOLYFYted7zEkHLDm+QZAzXbWmUk5h5Eq1nRpOCnpmTw0byM/RscxrHM9nh/QkgA/vYBOuY8mCqWys6zyGPt/gX2/WLcNTU+y5gXXsBJC5/HWz5ptwc993+QPxqcyduY69hw/zfMDWjKim9ZqUu5XKhKFiFQAVgLPGmO+9nQ8qpTLzoa4rVZS2P8LHPgN0hKteVUioNUgqH+ldVZSaN1Cr4h2lVV74rlv9gayDXx8d2eubFI84xxKFZVLE4WIfAT0A+KMMa0cpl8PvA34Ah8aY14tZFOPAwtcFmhuGWesb5V7V4DJtu4WVq05VG0GAeXdFoZHGGOdwnlip3VDnNA61iOwFBeUy86G49vtHsNKKzGcOWXNq9QQIgdYJbobXAkVa3k2VtvsNQd49qut1K9Sng9HdqJhVeevr1CquLm6RzEDeBeYmTNBRHyB94A+QCywTkQWYSWNV3KtPxpoA2wDCq6EdjmMgWNbYc9P1uPgKqvOv4+/9W0y62xO9FC5IYRHWqc35jyqNAG/UnaXsKwM6+KvEzvtx67zv+d8u3ZUrpKdNOpZP8PqXvi8QniRrwVwGWOsduxbaSWH/b9Carw1L6weNLsRGvSwEkMeN/nxpIysbF78ehszVx2gZ7Nw3hnWnopBxTswrlRRuTRRGGNWikiDXJM7A7uNMXsBRGQeMNAY8wpW7+MCInINUAFoAZwRkSXGmOw8lhsPjAeoV69e4cElH4U9P8Pen62fp+Os6eHNoePd0Pha60wWvyCrUNvxaIiLhrhtELcddn4HJstax8fPOk++WuT53ke1Fta3VV8PH907k3BhEsj5/dS+8+f4g3UsvmoTaHUbVG1q/e5f3ro2IDHm/M9T+6wd8NnkC1/HNxBCa1uHakLrOiSSuud7JcV1bD8rA9KT4WwKpKfYP5OtAed9dmLI+Twr1oaIPtCwh5UcKtUvnhhcICH1LPfN/oPf98Qz/qpGPH59c3x9dDxCeZ4n9mK1gRiH57FAl/wWNsY8DSAio4ATeSUJe7kpwBSAqKgoc9ECZ1PhwO92YvjJ2uEDlK8KjXpaiaFRT2tnl1t4U+vRYuD5aZnp1k73+PbzyePIZtj2FWC/vG+gtdOtFnk+eVSLtL6FX8637+wsa8fo+Dhr/0w6cmFCyNlhgtVDqtLYiiWyv50QmkLVCAgqQpVRY6xeR04CSYi5MJnsWWYlYnJ9DMHVL0weYfWsnkrOjt5xp39BEkix22c/z0zLP7aQmtbn2OBKKzlUauixMYai2B2XzJiP13MkIY3XB7flto51PB2SUud4IlHk9V978Y499wLGzCjSq2RnWxdE5SSGg6utQ0i+gVCvK/R+HhpfA9VbX9pO2y/QquyZu7rn2VQ4sePC3seB3+EvhyEW/wrWXclyeh/lq1g7wfQkh51m8vlp55KBPS8jteDYgsKs7Tft65AMmkJY/eLp4YhAuTDrUaN13stkpkPS4byTybEtVo/soh2+QECwNR7i+DOsbq7pFXMtE2L9DK5WahKDo5+3x/HA3I0E+fsyd3xXOtav5OmQlLqAJxJFLOB4YLgOcLg4Niwi/YH+retWhNcjzh+XrtbSOr2x8TVQ7wrXDkgHlIda7a2Ho7RE617HOckjbhvs/gE2zbpwOR8/e0cYcv4RXA0qN3KYZu8oHZcJcFi2fBXP7yz9Aq3xnMoN855vDJw+Yb0vARWs2P3Ll5xxDjcwxjD1l7288u12WtSsyNQRUdQK03tZq5JHjCn0y/zlvYA1RvF1zllPIuIH7AR6AYeAdcAdxpitxfWaUXWCzPp3RlqJoVFPp0s2e8TpeEhLsA79BARbO1hP7+SVyyWlZfDcoq18/schbmpdk/8MbkP5gFJxtrryYiKywRgTlXu6q0+PnQv0BKqKSCzWdRDTROR+YCnWmU4fFWeSAKzDQYM+KNZNukyFKtZDeT1jDGv2nWTBuhiWbDlCWkY2D/duyt97RehFdKpEc/VZT8Pymb4EWFLcr5dz6CkiIqK4N63UJTuWlMbCDbF8uj6G/fGphAT6MahDHYZ1qkfrOnqrUlXyufzQkydERUWZ9evXezoMVYZlZGXz0/Y4FqyLYfnO42RlGzo3rMztUXW5sXVNygXobUpVyeORQ09KlTV7jqewYF0Mn/1xiBMp6VQLCWT8VY0YElVXr65WpZYmCg87lHCGjMxsGuhOpNQ6nZ7JN38dYcG6GNYfOIWvj3Bt82rcHlWXns3C8fMtO2dyKe/kVYmiNI1RGGOYvy6G5xdvw0dg5pguev58KWKMYWNMAgvWxbB482FOn82iUdUKPHFDcwZ1qE21ENdVnFHK3XSMwgNOnT7LE5//ydKtx7iicRUOJ5wh/vRZ5o7rSqvaOrhZksWnpPPFxkMsWB/DzmMplPP35aY2Nbm9U12i6lfSs5dUqaZjFCXEr7tOMPHTTZw8fZanb4xkzJUNOZKUxpDJqxg+bQ3zxnfV21uWMFnZhpW7jrNgXQw/Rh8jI8vQrm4YrwxqTb82NQnRon3Ky2mPwk3SM7N4fekOpv6yj4hqwbw9tB0ta53vPRyMT2XIB6vIzM5m3vhuRFQrxWW9vUTMyVQWrI9h4YZYjiSmUblCALe0r82QqLo0qxHi6fCUKnb59Si8KlE4jFGM27Vrl6fDOWfXsWT+Pm8T0UeSuKtrfZ66MTLP0yP3Hk9hyAer8fWBBfd0o34VHeB2p/iUdKKPJLPtSCIrdh7nt93xiECPJuEM7VSX3pHV9RakyquViUSRo6T0KIwxzFp9gJe+iSY40I/XbmtDr8jqBa6z42gyQ6esonyAH/Pv6UqdSl5+oyQPyM42HDiZyrbDSWw7ksi2w0lEH0nmaNL5IoX1q5RnUPs63BZVh9paf0mVEZoo3OxESjqPLfyTn7bH0bNZOP+5rS3hIc7dj2HLoUTumLqaShUCmD++GzVC9QyaS5WWkcWOo8lsO5JkJ4Ykoo8kkXrWupeIr4/QpFowLWpWpEWtirSoWZHImhWpVKGU3YhKqWKgicKNft4Rx6RPN5OUlsnTN0Yyolv9Ip8Ns/HgKe6atpbqFQOZf083qgYX001/vNiJlPRzySDn597jKWTbf+IhgX5E2skgJzFEVAsmyF+vklYKNFG4RVpGFq8siebjVQdoXiOEt4e2v6xBz7X7TjLyo7XUr1KeueO66rdcB1nZhu1Hk9hw4BTr959iw4FTHEo4c25+7bByRDr0ElrWqkidSuX09FWlClAmEoUnB7O3HU7iwXkb2RWXwpgrGzLpumbF8k31t90nuHvGOppWD2b22K6Eliubp2KmpGey8eD5pLDx4ClO24ePqoUEEtWgEh3qVTqXGMLKa1JVqqjKRKLI4c4eRXa24aPf9vHadzsILe/P64PbcnXT8GJ9jZ93xDF+5npa1Q7lkzFdCA707stfjDEcSjhzrrew/sApdhxNIttYt+poXqMiUfUr0dF+aE9BqeKhicIFjiWl8einm/ll1wn6tKjOq4NaU8VFYwnfbTnK3+b8Qcf6lfj47s5eVX00Iyub6CNJ53oL6w+c5FhSOgAVAnxpX+98UmhfL0wvcFPKRcpUoqgV0dLMXPQT3RpXoYKLvn0v3XqUJz77kzMZWfyzX0uGda7r8m+1izYf5qF5G+keUZWpI6JK3CCsMYb0zGyS0zJJSc/kdHrmhb/bP1PsaSnpmcSeSmVzTCJnMqzDSLXDytGxfqVzh5Ka1wjRonpKuUmZShRBtZqYGiPewt9X6Fi/Ej2ahHN103Ba1KyIj8/l7cxTz2by4tfRzF17kFa1K/LW7e3dehX1wg2xPPrpZq5tXo3Jwzu65AIwYww7jiWz81gKKWnnd/I5v6c4PtIufJ6VXfjfk49AhUA/QgL9CA8JpH09KzF0rF+JmqF6zYJSnlImEkXOYHbjxhHjPv5uFSt3HmflrhNEH0kCoEqFAK5sUpWrmoTTo2nVIlf4/Cs2kQfnbWRf/Gnuuaoxj/Rp6pErdWetPsAzX27hhlY1+L9h7YvlG3daRhar98azLDqOn7bHXXAGUY7gQD8qBPoSHOhHcJA/wfbvOTv94KBcvwdYP4MD7Yf9ezl/Xx1TUKoEKhOJIkfuMYq4pDR+2XWCX3Yd55ddJ4g/fRaA5jVCuLppOFc1Dadj/Ur5HsrJyjZMWbmXN77fQdXgQN68vS1XNK7qlrbkZ9qv+3jx620MbFeLN4e0w/cSekpxyWn8vD2OZdFx/Lr7BKlnsyjn78uVTarSO7Ia7etVomKQPxUCfakQ4HfZvTGlVMlWphOFo+xsw7YjSazcdZyVO4+z4cApMrIMQf4+dG1UhauahHNV06o0Dg9GRDiccIZHFmxi9d6T3Ni6Bi/f0rrEnHr5/vLdvPbdDoZE1eHVQW0K3ZEbY9h6OImftsexLPoYm2MTAagVGkSvyOpcG1mNbo2qlLixD6WUe2iiyMfp9ExW741n5U6rt7H3xGnA2nl2bVyFH7cdIyvb8NyAltzWsU6JO2Ty5g87eWfZLu7qWp8XBra8KL60jCx+33OCH6Pj+Ck6jqNJaYhA2zph9I6sRq/I6jSvEVLi2qWUcj+9H0U+KgT60Suy+rlifTEnU8/1Nn7Ydoxm1UN4fXDbEnur0od7NyE9I4sPVu4l0M+Hp2+K5FhSOj9tj+On7cf4dfcJ0jKyqRDgS48m4VwbWY1rmlVzuu6UUkqV+R5FQYwxpeKbtjGG5xdvY8bv+2lQpTz741MB61TTnF5Dl0aVCfTTQ0pKqfxpj+ISlIYkAVac/+zXAl8f4c/YBIZ0qkuv5tVpWj241LRBKVVyaaLwEj4+wj/6tfB0GEopL+RVl7yKSH8RmZKYmOjpUJRSymt4VaIwxiw2xowPDQ0tfGGllFJO8apEoZRSqvhpolBKKVUgTRRKKaUKpIlCKaVUgTRRKKWUKpAmCqWUUgXyyhIeIpIM7CimzYUCzl6YUdiy+c3Pa3ruaQU9d/y9KnDCyXgLo20vnmUvp+25p5W0the2fFHnOftZ537ujZ+9J/7umxhjLr6+wBjjdQ9gfTFua0pxLZvf/Lym555W0PNcv2vbvajthbTX420vbPmiznP2sy4p7S8rf/d66Klwi4tx2fzm5zU997SCnhclxqLQthfPspfT9tzTSlrbC1u+qPOK8lmXhPaXib97bz30tN7kUQGxLNC2a9vLorLcfne03Vt7FFM8HYAHadvLprLcdijb7Xd5272yR6GUUqr4eGuPQimlVDHRRKGUUqpAmiiUUkoVyOsThYhUEJGPRWSqiNzp6XjcTUQaicg0EVno6VjcTURutj/3r0Skr6fjcScRiRSRySKyUETu9XQ87mb/328QkX6ejsWdRKSniPxif/Y9i2u7pTJR1irnJwAABBpJREFUiMhHIhInIltyTb9eRHaIyG4RecKePAhYaIwZBwxwe7AuUJT2G2P2GmPGeCbS4lfEtn9pf+6jgNs9EG6xKmLbo40xE4AhQKk/bbSI//MAjwML3BulaxSx7QZIAYKA2GILoriu6HPnA7gK6ABscZjmC+wBGgEBwGagBfAk0M5eZo6nY3d3+x3mL/R03B5s+xtAB0/H7u62Y30x+h24w9Oxu7PtQG9gKNYXhH6ejt3Nbfex51cHZhdXDKWyR2GMWQmczDW5M7DbWN+gzwLzgIFYWbWOvUypbG9uRWy/VylK28Xyb+BbY8wf7o61uBX1czfGLDLGXAGU+kOuRWz7NUBX4A5gnIiU6v/7orTdGJNtzz8FBBZXDH7FtaESoDYQ4/A8FugCvAO8KyI34brL3kuCPNsvIlWAfwHtReRJY8wrHonOtfL77B/A+nYZKiIRxpjJngjOxfL73HtiHXYNBJZ4IC53yLPtxpj7AURkFHDCYefpTfL73AcB1wFhwLvF9WLelCgkj2nGGHMauNvdwXhAfu2PBya4Oxg3y6/t72B9UfBm+bV9ObDcvaG4XZ5tP/eLMTPcF4rb5fe5fw58XtwvVqq7ZLnEAnUdntcBDnsoFk8oy+3Xtp+nbS8b3Np2b0oU64AmItJQRAKwBrMWeTgmdyrL7de2a9u17S5se6lMFCIyF1gFNBORWBEZY4zJBO4HlgLRwAJjzFZPxukqZbn92nZtu7bd/W3XooBKKaUKVCp7FEoppdxHE4VSSqkCaaJQSilVIE0USimlCqSJQimlVIE0USillCqQJgqlLpGIGBF5w+H5oyLyXBHWf05EHnVJcEoVI00USl26dGCQiFT1dCBKuZImCqUuXSYwBXi4oIVEpLKIfCkif4rIahFp4zC7rYj8JCK75P/bu0PWqqMwjuPfHyKIBoPJ4t6B+AJUxDfgwGTZgqyurSvDIggWk6gw29IMC5YNFl3YGHsLLogYxvAGw2P4nzDG3Rl4d7kg3099nnBO+nFOeJ5kqfXfTrKTZD/JYZIHU7yDdKH/aXqsNAvvgIMkrzs9L4G9qppP8hhYA+612l2G3Qk3gL0km8Az4GtVvUpyBbg+veNLFzMopAlU1XGSNWAZGJ3Tdh942vq3ktxKcrPVvlTVCBgl2WZYSLMLfExyFdioqv3p3kLq8+tJmtxb4DnDq2Cc3t6Es8PWqm00ewh8Bz4nWbiUU0r/yKCQJlRVv4B1hrAYZ4e2jrRtnvtZVcet9iTJtbaJ8BGwm2QO+FFV74EPDPuSpZnx60m6HG8Yxj6P8wL4lOQA+A0snqp9AzaBO8BqVR0lWQRWkvwBTgBfFJopx4xLkrr8epIkdRkUkqQug0KS1GVQSJK6DApJUpdBIUnqMigkSV0GhSSp6y/9XHDMJ3hixwAAAABJRU5ErkJggg==\n", "text/plain": ["
"]}, "metadata": {"needs_background": "light"}, "output_type": "display_data"}], "source": ["ax = piv.plot(logy=True, logx=True)\n", "ax.set_title(\"Polynomial Features for 5 features\\ndegree is 2 + interaction_only=True\")\n", "ax.set_ylabel(\"seconds\")\n", "ax.set_xlabel(\"N obs\");"]}, {"cell_type": "markdown", "metadata": {}, "source": ["## Memory profiler"]}, {"cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [{"data": {"text/plain": ["258.02734375"]}, "execution_count": 22, "metadata": {}, "output_type": "execute_result"}], "source": ["from memory_profiler import memory_usage\n", "poly = PolynomialFeatures(degree=2, interaction_only=True)\n", "poly.fit(X)\n", "memory_usage((poly.transform, (X,)), interval=0.1, max_usage=True)"]}, {"cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [{"name": "stdout", "output_type": "stream", "text": ["10000\n", "50000\n", "100000\n", "200000\n"]}, {"data": {"text/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", "
memorynamesize
3699.679688ext50000
41243.664062poly100000
51205.515625ext100000
61952.316406poly200000
72029.765625ext200000
\n", "
"], "text/plain": [" memory name size\n", "3 699.679688 ext 50000\n", "4 1243.664062 poly 100000\n", "5 1205.515625 ext 100000\n", "6 1952.316406 poly 200000\n", "7 2029.765625 ext 200000"]}, "execution_count": 23, "metadata": {}, "output_type": "execute_result"}], "source": ["def pick_value(v):\n", " try:\n", " return v[0]\n", " except TypeError:\n", " return v\n", "\n", "res = []\n", "for n in [10000, 50000, 100000, 200000]:\n", " X = numpy.random.random((n, 50))\n", " print(n)\n", " poly = PolynomialFeatures(degree=2, interaction_only=True)\n", " ext = ExtendedFeatures(poly_degree=2, poly_interaction_only=True)\n", " poly.fit(X)\n", " ext.fit(X)\n", " r1 = memory_usage((poly.transform, (X,)), interval=0.1, max_usage=True)\n", " r2 = memory_usage((ext.transform, (X,)), interval=0.1, max_usage=True)\n", " r1 = {\"memory\": pick_value(r1)}\n", " r2 = {\"memory\": pick_value(r2)}\n", " r1[\"name\"] = \"poly\"\n", " r2[\"name\"] = \"ext\"\n", " r1[\"size\"] = n\n", " r2[\"size\"] = n\n", " res.append(r1)\n", " res.append(r2)\n", " \n", "import pandas\n", "df = pandas.DataFrame(res)\n", "df.tail()"]}, {"cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [{"data": {"text/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", "
nameextpoly
size
10000392.445312396.347656
50000699.679688718.839844
1000001205.5156251243.664062
2000002029.7656251952.316406
\n", "
"], "text/plain": ["name ext poly\n", "size \n", "10000 392.445312 396.347656\n", "50000 699.679688 718.839844\n", "100000 1205.515625 1243.664062\n", "200000 2029.765625 1952.316406"]}, "execution_count": 24, "metadata": {}, "output_type": "execute_result"}], "source": ["piv = df.pivot(\"size\", \"name\", \"memory\")\n", "piv[:5]"]}, {"cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [{"data": {"image/png": "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\n", "text/plain": ["
"]}, "metadata": {"needs_background": "light"}, "output_type": "display_data"}], "source": ["ax = piv.plot(logy=True, logx=True)\n", "ax.set_title(\"Polynomial Features for 50 features\\ndegree is 2 - memory\")\n", "ax.set_ylabel(\"Mb\")\n", "ax.set_xlabel(\"N obs\");"]}, {"cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": []}, {"cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": []}], "metadata": {"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.7.2"}}, "nbformat": 4, "nbformat_minor": 2}