From f429fb5d45d217d2652d579efa74148318a09f75 Mon Sep 17 00:00:00 2001 From: tpsatish95 Date: Thu, 6 Dec 2018 16:52:29 -0500 Subject: [PATCH 1/3] Update mgcpy bechmarks to compare fast mgc --- mgcpy/benchmarks/mgc_python_performance.ipynb | 172 +++++++++++++++++- 1 file changed, 167 insertions(+), 5 deletions(-) diff --git a/mgcpy/benchmarks/mgc_python_performance.ipynb b/mgcpy/benchmarks/mgc_python_performance.ipynb index 9bb705f..45e4b2e 100644 --- a/mgcpy/benchmarks/mgc_python_performance.ipynb +++ b/mgcpy/benchmarks/mgc_python_performance.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -28,14 +28,14 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ - "def mgc(X, Y):\n", + "def mgc(X, Y, is_fast=False):\n", " mgc = MGC()\n", "# mgc_statistic, independence_test_metadata = mgc.test_statistic(X, Y)\n", - " p_value, metadata = mgc.p_value(X, Y) # p-value call has mgc.test_statistic(X, Y) call\n", + " p_value, metadata = mgc.p_value(X, Y, is_fast=is_fast) # p-value call has mgc.test_statistic(X, Y) call\n", "# print(\"MGC stats from Python:\")\n", "# print(\"MGC test statistic:\", metadata[\"test_statistic\"])\n", "# print(\"P Value:\", p_value)\n", @@ -425,6 +425,168 @@ "plt.legend()" ] }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Linear data (varying num_samples) - Fast MGC\n", + "\n", + "num_samples time_taken(in secs)\n", + "10 [0.009937260998412967, 0.006971208960749209, 0.00851285899989307, 0.007001145975664258, 0.007364065037108958]\n", + "20 [0.013805667986162007, 0.012984061962924898, 0.012354757986031473, 0.013664765981957316, 0.010665838024578989]\n", + "30 [0.01729093200992793, 0.012268604943528771, 0.012671170989051461, 0.011940094991587102, 0.011755009065382183]\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/scipy/stats/_distn_infrastructure.py:1735: RuntimeWarning: divide by zero encountered in double_scalars\n", + " x = np.asarray((x - loc)/scale, dtype=dtyp)\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/scipy/stats/_distn_infrastructure.py:1735: RuntimeWarning: divide by zero encountered in double_scalars\n", + " x = np.asarray((x - loc)/scale, dtype=dtyp)\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/scipy/stats/_distn_infrastructure.py:1735: RuntimeWarning: divide by zero encountered in double_scalars\n", + " x = np.asarray((x - loc)/scale, dtype=dtyp)\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/scipy/stats/_distn_infrastructure.py:1735: RuntimeWarning: divide by zero encountered in double_scalars\n", + " x = np.asarray((x - loc)/scale, dtype=dtyp)\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/mgcpy-0.0.4-py3.6-macosx-10.13-x86_64.egg/mgcpy/independence_tests/mgc/threshold_smooth.py:54: RuntimeWarning: invalid value encountered in greater\n", + " significant_connected_region = local_correlation_matrix > threshold\n", + "/usr/local/var/pyenv/versions/py3/envs/ML/lib/python3.6/site-packages/scipy/stats/_distn_infrastructure.py:1735: RuntimeWarning: divide by zero encountered in double_scalars\n", + " x = np.asarray((x - loc)/scale, dtype=dtyp)\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "40 [0.020842907018959522, 0.018102316069416702, 0.022479727980680764, 0.02483542903792113, 0.019535422092303634]\n", + "50 [0.03613659495022148, 0.026224412955343723, 0.025395689997822046, 0.024829013971611857, 0.02520094090141356]\n", + "60 [0.034173641935922205, 0.03446560900192708, 0.03535817901138216, 0.039391946978867054, 0.034553198027424514]\n", + "70 [0.04626641294453293, 0.04520784202031791, 0.04255034390371293, 0.04290726501494646, 0.04613724094815552]\n", + "80 [0.06585719098802656, 0.057089149951934814, 0.05837591795716435, 0.058390229009091854, 0.06029797799419612]\n", + "90 [0.06505067890975624, 0.06504994304850698, 0.06521781696937978, 0.07156319194473326, 0.06859320495277643]\n", + "100 [0.08849724300671369, 0.0775414330419153, 0.07958152203354985, 0.07980452594347298, 0.0788903699722141]\n", + "110 [0.09184161003213376, 0.08922904101200402, 0.09646733594127, 0.09718551696278155, 0.10458254802506417]\n", + "120 [0.1191785610280931, 0.11659046495333314, 0.10537252889480442, 0.1160321970237419, 0.11862371896859258]\n", + "130 [0.13264634809456766, 0.13590998807922006, 0.15327011398039758, 0.14836418896447867, 0.137127390014939]\n", + "140 [0.15582118893507868, 0.1476625050418079, 0.1529817070113495, 0.15209201897960156, 0.14758490701206028]\n", + "150 [0.16182203008793294, 0.17047211597673595, 0.16169877001084387, 0.15995072096120566, 0.16114080895204097]\n", + "\n", + "[(10, [0.009937260998412967, 0.006971208960749209, 0.00851285899989307, 0.007001145975664258, 0.007364065037108958]), (20, [0.013805667986162007, 0.012984061962924898, 0.012354757986031473, 0.013664765981957316, 0.010665838024578989]), (30, [0.01729093200992793, 0.012268604943528771, 0.012671170989051461, 0.011940094991587102, 0.011755009065382183]), (40, [0.020842907018959522, 0.018102316069416702, 0.022479727980680764, 0.02483542903792113, 0.019535422092303634]), (50, [0.03613659495022148, 0.026224412955343723, 0.025395689997822046, 0.024829013971611857, 0.02520094090141356]), (60, [0.034173641935922205, 0.03446560900192708, 0.03535817901138216, 0.039391946978867054, 0.034553198027424514]), (70, [0.04626641294453293, 0.04520784202031791, 0.04255034390371293, 0.04290726501494646, 0.04613724094815552]), (80, [0.06585719098802656, 0.057089149951934814, 0.05837591795716435, 0.058390229009091854, 0.06029797799419612]), (90, [0.06505067890975624, 0.06504994304850698, 0.06521781696937978, 0.07156319194473326, 0.06859320495277643]), (100, [0.08849724300671369, 0.0775414330419153, 0.07958152203354985, 0.07980452594347298, 0.0788903699722141]), (110, [0.09184161003213376, 0.08922904101200402, 0.09646733594127, 0.09718551696278155, 0.10458254802506417]), (120, [0.1191785610280931, 0.11659046495333314, 0.10537252889480442, 0.1160321970237419, 0.11862371896859258]), (130, [0.13264634809456766, 0.13590998807922006, 0.15327011398039758, 0.14836418896447867, 0.137127390014939]), (140, [0.15582118893507868, 0.1476625050418079, 0.1529817070113495, 0.15209201897960156, 0.14758490701206028]), (150, [0.16182203008793294, 0.17047211597673595, 0.16169877001084387, 0.15995072096120566, 0.16114080895204097])]\n" + ] + } + ], + "source": [ + "print(\"Linear data (varying num_samples) - Fast MGC\\n\")\n", + "print(\"num_samples\", \"time_taken(in secs)\")\n", + "num_samples_range = range(10, 151, 10)\n", + "linear_data_fast_mgc = list()\n", + "for num_samples in num_samples_range:\n", + " X, Y = sims.linear_sim(num_samp=num_samples, num_dim=1, noise=0.1)\n", + "\n", + "# start = time.time()\n", + "# mgc(X, Y)\n", + "# end = time.time()\n", + "# time_taken = end - start\n", + " mgc_w = wrapper(mgc, X, Y, True)\n", + " time_taken = timeit.repeat(mgc_w, repeat=5, number=1) # 5 executions\n", + "\n", + " print(num_samples, time_taken)\n", + " linear_data_fast_mgc.append((num_samples, time_taken))\n", + "print()\n", + "print(linear_data_fast_mgc)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt; plt.style.use('classic')\n", + "plt.rcParams[\"legend.loc\"] = \"best\"\n", + "plt.rcParams['figure.facecolor'] = 'white'\n", + "\n", + "num_samples = range(10, 151, 10)\n", + "r_perf_times = {10: [1.179895, 1.435764, 1.392574, 1.364731, 1.244356], 20: [3.626441, 3.38207, 3.435028, 3.312011, 3.472121], 30: [6.725924, 7.19072, 6.850648, 7.024207, 6.970873], 40: [11.60234, 11.26915, 11.36571, 12.27015, 12.33833], 50: [19.56418, 17.98312, 17.36909, 17.16499, 18.17077], 60: [25.21052, 24.80274, 24.37495, 24.47379, 25.59039], 70: [33.09666, 33.38766, 32.52008, 32.90658, 33.6318], 80: [41.91707, 42.18968, 42.25746, 43.52817, 42.34682], 90: [54.26672, 60.08258, 52.39857, 51.12012, 52.91298], 100: [66.36207, 70.70109, 64.84415, 65.04437, 63.17586], 110: [76.69378, 77.56344, 79.68007, 79.66596, 82.81884], 120: [97.89148, 96.41177, 99.12007, 100.0838, 100.4973], 130: [119.39, 117.1136, 118.6135, 117.5654, 116.0784], 140: [139.2461, 136.9656, 137.8895, 136.6488, 139.2114], 150: [158.5903, 156.5999, 161.6194, 160.23, 161.1935]}\n", + "linear_data_copy = [(10, [1.3570548910065554, 1.317704908986343, 1.250599796010647, 1.2129867470066529, 1.2188538330083247]), (20, [2.809477289003553, 2.662971756013576, 2.668166168994503, 2.810354543995345, 2.8085849939961918]), (30, [5.089567081973655, 4.908904140000232, 4.963905091979541, 4.862470469990512, 4.872956630017143]), (40, [7.7755367509962525, 7.639183080988005, 7.636393271997804, 7.643885943980422, 7.673354588012444]), (50, [11.33807383000385, 11.284572928998386, 11.579023433005204, 11.935501523985295, 11.589415601018118]), (60, [15.944066369003849, 15.691345383005682, 15.252294573001564, 15.21922270700452, 15.21380895600305]), (70, [20.097495351015823, 20.11479070200585, 20.14134455099702, 20.623360280005727, 20.394629952003015]), (80, [25.643525285995565, 25.59139153698925, 25.659372112015262, 25.80397002500831, 25.668325702979928]), (90, [32.741740912984824, 31.854122709017247, 31.89940690298681, 31.885286441014614, 32.73692899401067]), (100, [41.03519103198778, 40.1257850920083, 40.30881031299941, 39.976445167005295, 39.989109216985526]), (110, [46.49892311100848, 48.002260846988065, 48.743909012991935, 47.894316210004035, 46.35784816299565]), (120, [57.73439836999751, 59.01353847500286, 56.690341667999746, 56.15975032598362, 57.02876815799391]), (130, [67.02439867099747, 68.27157784899464, 66.59815313798026, 65.15316394198453, 66.08920010898146]), (140, [79.0230416849954, 77.24781862000236, 79.41891040399787, 77.30308651400264, 79.06514339800924]), (150, [90.88946284601116, 86.56499147901195, 86.16265920398291, 86.45272049200139, 87.83721533801872])]\n", + "python_perf_times = [j for i, j in linear_data_copy]\n", + "python_perf_times_fast_mgc = [j for i, j in linear_data_fast_mgc]\n", + "\n", + "plt.plot(num_samples, [np.mean(v) for k, v in r_perf_times.items()], marker='o', markerfacecolor='darkgreen', markersize=6, color='green', linewidth=2, label=\"R\")\n", + "plt.plot(num_samples, [np.mean(i) for i in python_perf_times], marker='X', markerfacecolor='red', markersize=8, color='orange', linewidth=2, label=\"Python\")\n", + "plt.plot(num_samples, [np.mean(i) for i in python_perf_times_fast_mgc], marker='X', markerfacecolor='darkblue', markersize=8, color='blue', linewidth=2, label=\"Python (FastMGC)\")\n", + "\n", + "plt.ylim(-10, 160)\n", + "plt.xlabel('# of Samples (Data Points)', fontsize=18)\n", + "plt.ylabel('Execution Time (Seconds)', fontsize=18)\n", + "plt.legend()" + ] + }, { "cell_type": "code", "execution_count": 33, From d8f2d5601ffe33f8ba414295c7f9e8227f2c4803 Mon Sep 17 00:00:00 2001 From: tpsatish95 Date: Sat, 8 Dec 2018 18:11:54 -0500 Subject: [PATCH 2/3] Make Docker build's branch specific --- Dockerfile | 3 ++- mgcpy/independence_tests/unit_tests/mgc/__init__.py | 0 2 files changed, 2 insertions(+), 1 deletion(-) mode change 100644 => 100755 mgcpy/independence_tests/unit_tests/mgc/__init__.py diff --git a/Dockerfile b/Dockerfile index fd65d2b..c5a1760 100644 --- a/Dockerfile +++ b/Dockerfile @@ -82,7 +82,8 @@ RUN mkdir /root/code/ WORKDIR /root/code/ # clone the mgcpy code into the container -RUN git clone https://github.com/NeuroDataDesign/mgcpy.git . +ARG SOURCE_BRANCH=master +RUN git clone -b ${SOURCE_BRANCH} https://github.com/NeuroDataDesign/mgcpy.git . # install python requirements RUN pip install -r requirements.txt diff --git a/mgcpy/independence_tests/unit_tests/mgc/__init__.py b/mgcpy/independence_tests/unit_tests/mgc/__init__.py old mode 100644 new mode 100755 From c63d0108a596987d4da6fca31af45470f9a56bd8 Mon Sep 17 00:00:00 2001 From: tpsatish95 Date: Sat, 8 Dec 2018 18:22:04 -0500 Subject: [PATCH 3/3] Remove pytest call from Dockerfile, Travis CI does that Replace with simple import check --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index c5a1760..056b5cb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -100,9 +100,9 @@ RUN python setup.py build_ext --inplace # add mgcpy to PYTHONPATH for dev purposes RUN echo "export PYTHONPATH='${PYTHONPATH}:/root/code'" >> ~/.bashrc -# test if mgcpy is correctly installed +# clean dir and test if mgcpy is correctly installed RUN py3clean . -RUN pytest +RUN python -c "import mgcpy" # launch terminal CMD ["/bin/bash"]