You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

run_pathkernel_acyclic.ipynb 110 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. {
  2. "cells": [
  3. {
  4. "cell_type": "code",
  5. "execution_count": 1,
  6. "metadata": {},
  7. "outputs": [
  8. {
  9. "name": "stdout",
  10. "output_type": "stream",
  11. "text": [
  12. "\n",
  13. "--- This is a regression problem ---\n",
  14. "\n",
  15. "1. Loading dataset from file...\n",
  16. "\n",
  17. "2. Calculating gram matrices. This could take a while...\n",
  18. "\n",
  19. " --- mean average path kernel matrix of size 183 built in 21.83512854576111 seconds ---\n",
  20. "\n",
  21. "gram matrix with parameters {} is: \n",
  22. "[[0.55555556 0.22222222 0. ... 0. 0. 0. ]\n",
  23. " [0.22222222 0.27777778 0. ... 0. 0. 0. ]\n",
  24. " [0. 0. 0.55555556 ... 0.03030303 0.03030303 0.03030303]\n",
  25. " ...\n",
  26. " [0. 0. 0.03030303 ... 0.08297521 0.05553719 0.05256198]\n",
  27. " [0. 0. 0.03030303 ... 0.05553719 0.07239669 0.0538843 ]\n",
  28. " [0. 0. 0.03030303 ... 0.05256198 0.0538843 0.07438017]]\n"
  29. ]
  30. },
  31. {
  32. "data": {
  33. "image/png": "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\n",
  34. "text/plain": [
  35. "<matplotlib.figure.Figure at 0x7f845a03af60>"
  36. ]
  37. },
  38. "metadata": {},
  39. "output_type": "display_data"
  40. },
  41. {
  42. "name": "stdout",
  43. "output_type": "stream",
  44. "text": [
  45. "\n",
  46. "3. Fitting and predicting using nested cross validation. This could really take a while...\n",
  47. "calculate performance: 0%| | 1/1200 [00:00<02:00, 9.98it/s]"
  48. ]
  49. },
  50. {
  51. "name": "stderr",
  52. "output_type": "stream",
  53. "text": [
  54. "/home/ljia/.local/lib/python3.5/site-packages/sklearn/linear_model/ridge.py:154: UserWarning: Singular matrix in solving dual problem. Using least-squares solution instead.\n",
  55. " warnings.warn(\"Singular matrix in solving dual problem. Using \"\n"
  56. ]
  57. },
  58. {
  59. "name": "stdout",
  60. "output_type": "stream",
  61. "text": [
  62. " \n",
  63. "4. Getting final performances...\n",
  64. "\n",
  65. "best_params_out: [{}]\n",
  66. "best_params_in: [{'alpha': 0.0025719138090593446}]\n",
  67. "best_val_perf: 23.66357723619167\n",
  68. "best_val_std: 1.7375991881363788\n",
  69. "final_performance: 25.04174263900284\n",
  70. "final_confidence: 9.596718064653482\n",
  71. "train_performance: 11.194641025303468\n",
  72. "train_std: 0.7327157793544619\n",
  73. "time to calculate gram matrix: 21.83512854576111 s\n",
  74. "\n",
  75. "params train_perf valid_perf test_perf gram_matrix_time\n",
  76. "--------------------- ------------ ------------- -------------- ------------------\n",
  77. "{'alpha': '1.00e-04'} 19.23±17.16 144.93±259.55 78.37±110.59 21.84\n",
  78. "{'alpha': '1.34e-04'} 24.29±41.62 124.75±185.82 264.04±1154.46 21.84\n",
  79. "{'alpha': '1.80e-04'} 17.57±13.69 90.89±97.20 65.45±85.08 21.84\n",
  80. "{'alpha': '2.42e-04'} 16.45±11.32 70.08±62.49 54.85±55.03 21.84\n",
  81. "{'alpha': '3.26e-04'} 15.95±15.23 64.78±82.79 53.05±61.25 21.84\n",
  82. "{'alpha': '4.38e-04'} 12.86±9.14 46.45±42.05 51.47±109.06 21.84\n",
  83. "{'alpha': '5.88e-04'} 10.92±3.07 34.99±14.10 32.71±25.29 21.84\n",
  84. "{'alpha': '7.90e-04'} 10.37±2.21 30.13±10.14 28.80±13.94 21.84\n",
  85. "{'alpha': '1.06e-03'} 10.00±1.35 26.14±4.82 26.12±10.87 21.84\n",
  86. "{'alpha': '1.43e-03'} 10.15±1.07 24.60±3.25 25.30±10.06 21.84\n",
  87. "{'alpha': '1.91e-03'} 10.55±0.87 23.87±2.29 24.99±9.73 21.84\n",
  88. "{'alpha': '2.57e-03'} 11.19±0.73 23.66±1.74 25.04±9.60 21.84\n",
  89. "{'alpha': '3.46e-03'} 12.11±0.64 23.84±1.51 25.40±9.52 21.84\n",
  90. "{'alpha': '4.64e-03'} 13.30±0.57 24.35±1.46 26.04±9.45 21.84\n",
  91. "{'alpha': '6.24e-03'} 14.80±0.53 25.19±1.46 26.97±9.33 21.84\n",
  92. "{'alpha': '8.38e-03'} 16.59±0.50 26.35±1.43 28.15±9.18 21.84\n",
  93. "{'alpha': '1.13e-02'} 18.66±0.49 27.77±1.39 29.59±9.00 21.84\n",
  94. "{'alpha': '1.51e-02'} 20.96±0.50 29.44±1.34 31.24±8.82 21.84\n",
  95. "{'alpha': '2.03e-02'} 23.46±0.51 31.31±1.28 33.07±8.68 21.84\n",
  96. "{'alpha': '2.73e-02'} 26.09±0.53 33.35±1.22 35.05±8.56 21.84\n",
  97. "{'alpha': '3.67e-02'} 28.81±0.56 35.52±1.16 37.13±8.48 21.84\n",
  98. "{'alpha': '4.92e-02'} 31.57±0.58 37.76±1.12 39.26±8.43 21.84\n",
  99. "{'alpha': '6.61e-02'} 34.32±0.61 40.02±1.09 41.41±8.38 21.84\n",
  100. "{'alpha': '8.89e-02'} 37.01±0.64 42.24±1.07 43.51±8.34 21.84\n",
  101. "{'alpha': '1.19e-01'} 39.61±0.67 44.37±1.06 45.54±8.32 21.84\n",
  102. "{'alpha': '1.60e-01'} 42.07±0.70 46.36±1.05 47.43±8.29 21.84\n",
  103. "{'alpha': '2.15e-01'} 44.38±0.73 48.19±1.05 49.19±8.28 21.84\n",
  104. "{'alpha': '2.89e-01'} 46.52±0.75 49.86±1.04 50.80±8.27 21.84\n",
  105. "{'alpha': '3.89e-01'} 56.79±18.72 58.55±15.28 59.93±19.91 21.84\n",
  106. "{'alpha': '5.22e-01'} 60.92±21.98 61.86±19.27 63.58±23.19 21.84\n",
  107. "{'alpha': '7.02e-01'} 53.55±1.68 55.34±2.01 55.70±8.15 21.84\n",
  108. "{'alpha': '9.43e-01'} 54.87±0.84 56.38±1.12 56.86±8.51 21.84\n",
  109. "{'alpha': '1.27e+00'} 57.20±0.84 58.38±1.04 58.95±8.80 21.84\n",
  110. "{'alpha': '1.70e+00'} 60.12±0.84 60.97±1.01 61.62±9.11 21.84\n",
  111. "{'alpha': '2.29e+00'} 63.75±0.85 64.32±0.98 65.05±9.44 21.84\n",
  112. "{'alpha': '3.07e+00'} 68.24±0.85 68.56±0.96 69.39±9.72 21.84\n",
  113. "{'alpha': '4.12e+00'} 73.66±0.86 73.79±0.96 74.73±9.92 21.84\n",
  114. "{'alpha': '5.54e+00'} 79.94±0.88 79.92±0.95 80.98±10.00 21.84\n",
  115. "{'alpha': '7.44e+00'} 86.87±0.90 86.76±0.96 87.91±9.99 21.84\n",
  116. "{'alpha': '1.00e+01'} 94.13±0.92 93.96±0.97 95.18±9.90 21.84\n",
  117. "calculate performance: 100%|██████████| 1200/1200 [01:20<00:00, 19.66it/s]"
  118. ]
  119. }
  120. ],
  121. "source": [
  122. "%load_ext line_profiler\n",
  123. "%matplotlib inline\n",
  124. "import numpy as np\n",
  125. "import sys\n",
  126. "sys.path.insert(0, \"../\")\n",
  127. "from pygraph.utils.model_selection_precomputed import model_selection_for_precomputed_kernel\n",
  128. "from pygraph.kernels.pathKernel import pathkernel\n",
  129. "\n",
  130. "datafile = '../../../../datasets/acyclic/Acyclic/dataset_bps.ds'\n",
  131. "estimator = pathkernel\n",
  132. "param_grid_precomputed = {}\n",
  133. "param_grid = {'alpha': np.logspace(-4, 1, num = 40, base = 10)}\n",
  134. "\n",
  135. "model_selection_for_precomputed_kernel(datafile, estimator, param_grid_precomputed, param_grid, \n",
  136. " 'regression', NUM_TRIALS=30)"
  137. ]
  138. },
  139. {
  140. "cell_type": "code",
  141. "execution_count": 2,
  142. "metadata": {},
  143. "outputs": [
  144. {
  145. "name": "stdout",
  146. "output_type": "stream",
  147. "text": [
  148. "The line_profiler extension is already loaded. To reload it, use:\n",
  149. " %reload_ext line_profiler\n",
  150. "\n",
  151. " --- This is a regression problem ---\n",
  152. "\n",
  153. "\n",
  154. " Loading dataset from file...\n",
  155. "\n",
  156. " Calculating kernel matrix, this could take a while...\n",
  157. "\n",
  158. " --- mean average path kernel matrix of size 185 built in 29.430902242660522 seconds ---\n",
  159. "[[ 0.55555556 0.22222222 0. ..., 0. 0. 0. ]\n",
  160. " [ 0.22222222 0.27777778 0. ..., 0. 0. 0. ]\n",
  161. " [ 0. 0. 0.55555556 ..., 0.03030303 0.03030303\n",
  162. " 0.03030303]\n",
  163. " ..., \n",
  164. " [ 0. 0. 0.03030303 ..., 0.08297521 0.05553719\n",
  165. " 0.05256198]\n",
  166. " [ 0. 0. 0.03030303 ..., 0.05553719 0.07239669\n",
  167. " 0.0538843 ]\n",
  168. " [ 0. 0. 0.03030303 ..., 0.05256198 0.0538843\n",
  169. " 0.07438017]]\n",
  170. "\n",
  171. " Saving kernel matrix to file...\n",
  172. "\n",
  173. " Mean performance on train set: 3.619948\n",
  174. "With standard deviation: 0.512351\n",
  175. "\n",
  176. " Mean performance on test set: 18.418852\n",
  177. "With standard deviation: 10.781119\n",
  178. "\n",
  179. "\n",
  180. " rmse_test std_test rmse_train std_train k_time\n",
  181. "----------- ---------- ------------ ----------- --------\n",
  182. " 18.4189 10.7811 3.61995 0.512351 29.4309\n"
  183. ]
  184. }
  185. ],
  186. "source": [
  187. "%load_ext line_profiler\n",
  188. "\n",
  189. "import sys\n",
  190. "sys.path.insert(0, \"../\")\n",
  191. "from pygraph.utils.utils import kernel_train_test\n",
  192. "from pygraph.kernels.pathKernel import pathkernel, _pathkernel_do\n",
  193. "\n",
  194. "datafile = '../../../../datasets/acyclic/Acyclic/dataset_bps.ds'\n",
  195. "kernel_file_path = 'kernelmatrices_path_acyclic/'\n",
  196. "\n",
  197. "kernel_para = dict(node_label = 'atom', edge_label = 'bond_type')\n",
  198. "\n",
  199. "kernel_train_test(datafile, kernel_file_path, pathkernel, kernel_para, normalize = False)\n",
  200. "\n",
  201. "# %lprun -f _pathkernel_do \\\n",
  202. "# kernel_train_test(datafile, kernel_file_path, pathkernel, kernel_para, normalize = False)"
  203. ]
  204. },
  205. {
  206. "cell_type": "code",
  207. "execution_count": null,
  208. "metadata": {},
  209. "outputs": [],
  210. "source": [
  211. "# results\n",
  212. "\n",
  213. "# with y normalization\n",
  214. " RMSE_test std_test RMSE_train std_train k_time\n",
  215. "----------- ---------- ------------ ----------- --------\n",
  216. " 14.0015 6.93602 3.76191 0.702594 37.5759\n",
  217. "\n",
  218. "# without y normalization\n",
  219. " RMSE_test std_test RMSE_train std_train k_time\n",
  220. "----------- ---------- ------------ ----------- --------\n",
  221. " 18.4189 10.7811 3.61995 0.512351 29.4309"
  222. ]
  223. },
  224. {
  225. "cell_type": "code",
  226. "execution_count": 1,
  227. "metadata": {
  228. "scrolled": true
  229. },
  230. "outputs": [
  231. {
  232. "name": "stdout",
  233. "output_type": "stream",
  234. "text": [
  235. "\n",
  236. "- This script take as input a kernel matrix\n",
  237. "and returns the classification or regression performance\n",
  238. "- The kernel matrix can be calculated using any of the graph kernels approaches\n",
  239. "- The criteria used for prediction are SVM for classification and kernel Ridge regression for regression\n",
  240. "- For predition we divide the data in training, validation and test. For each split, we first train on the train data, \n",
  241. "then evaluate the performance on the validation. We choose the optimal parameters for the validation set and finally\n",
  242. "provide the corresponding performance on the test set. If more than one split is performed, the final results \n",
  243. "correspond to the average of the performances on the test sets. \n",
  244. "\n",
  245. "@references\n",
  246. " https://github.com/eghisu/GraphKernels/blob/master/GraphKernelsCollection/python_scripts/compute_perf_gk.py\n",
  247. "\n"
  248. ]
  249. },
  250. {
  251. "ename": "IndentationError",
  252. "evalue": "unindent does not match any outer indentation level (utils.py, line 106)",
  253. "output_type": "error",
  254. "traceback": [
  255. "Traceback \u001b[0;36m(most recent call last)\u001b[0m:\n",
  256. " File \u001b[1;32m\"/usr/local/lib/python3.5/dist-packages/IPython/core/interactiveshell.py\"\u001b[0m, line \u001b[1;32m2910\u001b[0m, in \u001b[1;35mrun_code\u001b[0m\n exec(code_obj, self.user_global_ns, self.user_ns)\n",
  257. "\u001b[0;36m File \u001b[0;32m\"<ipython-input-1-0b5b9ebb5cc4>\"\u001b[0;36m, line \u001b[0;32m31\u001b[0;36m, in \u001b[0;35m<module>\u001b[0;36m\u001b[0m\n\u001b[0;31m from pygraph.utils.utils import split_train_test\u001b[0m\n",
  258. "\u001b[0;36m File \u001b[0;32m\"../pygraph/utils/utils.py\"\u001b[0;36m, line \u001b[0;32m106\u001b[0m\n\u001b[0;31m train_means_list = []\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m unindent does not match any outer indentation level\n"
  259. ]
  260. }
  261. ],
  262. "source": [
  263. "# Author: Elisabetta Ghisu\n",
  264. "\n",
  265. "\"\"\"\n",
  266. "- This script take as input a kernel matrix\n",
  267. "and returns the classification or regression performance\n",
  268. "- The kernel matrix can be calculated using any of the graph kernels approaches\n",
  269. "- The criteria used for prediction are SVM for classification and kernel Ridge regression for regression\n",
  270. "- For predition we divide the data in training, validation and test. For each split, we first train on the train data, \n",
  271. "then evaluate the performance on the validation. We choose the optimal parameters for the validation set and finally\n",
  272. "provide the corresponding performance on the test set. If more than one split is performed, the final results \n",
  273. "correspond to the average of the performances on the test sets. \n",
  274. "\n",
  275. "@references\n",
  276. " https://github.com/eghisu/GraphKernels/blob/master/GraphKernelsCollection/python_scripts/compute_perf_gk.py\n",
  277. "\"\"\"\n",
  278. "\n",
  279. "print(__doc__)\n",
  280. "\n",
  281. "import sys\n",
  282. "import os\n",
  283. "import pathlib\n",
  284. "from collections import OrderedDict\n",
  285. "sys.path.insert(0, \"../\")\n",
  286. "from tabulate import tabulate\n",
  287. "\n",
  288. "import numpy as np\n",
  289. "import matplotlib.pyplot as plt\n",
  290. "\n",
  291. "from pygraph.kernels.pathKernel import pathkernel\n",
  292. "from pygraph.utils.graphfiles import loadDataset\n",
  293. "from pygraph.utils.utils import split_train_test\n",
  294. "\n",
  295. "train_means_list = []\n",
  296. "train_stds_list = []\n",
  297. "test_means_list = []\n",
  298. "test_stds_list = []\n",
  299. "kernel_time_list = []\n",
  300. "\n",
  301. "print('\\n Loading dataset from file...')\n",
  302. "dataset, y = loadDataset(\"../../../../datasets/acyclic/Acyclic/dataset_bps.ds\")\n",
  303. "y = np.array(y)\n",
  304. "print(y)\n",
  305. "\n",
  306. "# setup the parameters\n",
  307. "model_type = 'regression' # Regression or classification problem\n",
  308. "print('\\n --- This is a %s problem ---' % model_type)\n",
  309. "\n",
  310. "trials = 100 # Trials for hyperparameters random search\n",
  311. "splits = 10 # Number of splits of the data\n",
  312. "alpha_grid = np.logspace(-10, 10, num = trials, base = 10) # corresponds to (2*C)^-1 in other linear models such as LogisticRegression\n",
  313. "C_grid = np.logspace(-10, 10, num = trials, base = 10)\n",
  314. "\n",
  315. "# set the output path\n",
  316. "kernel_file_path = 'kernelmatrices_path_acyclic/'\n",
  317. "if not os.path.exists(kernel_file_path):\n",
  318. " os.makedirs(kernel_file_path)\n",
  319. "\n",
  320. "\"\"\"\n",
  321. "- Here starts the main program\n",
  322. "- First we permute the data, then for each split we evaluate corresponding performances\n",
  323. "- In the end, the performances are averaged over the test sets\n",
  324. "\"\"\"\n",
  325. "\n",
  326. "# save kernel matrices to files / read kernel matrices from files\n",
  327. "kernel_file = kernel_file_path + 'km.ds'\n",
  328. "path = pathlib.Path(kernel_file)\n",
  329. "# get train set kernel matrix\n",
  330. "if path.is_file():\n",
  331. " print('\\n Loading the kernel matrix from file...')\n",
  332. " Kmatrix = np.loadtxt(kernel_file)\n",
  333. " print(Kmatrix)\n",
  334. "else:\n",
  335. " print('\\n Calculating kernel matrix, this could take a while...')\n",
  336. " Kmatrix, run_time = pathkernel(dataset, node_label = 'atom', edge_label = 'bond_type')\n",
  337. " kernel_time_list.append(run_time)\n",
  338. " print(Kmatrix)\n",
  339. " print('\\n Saving kernel matrix to file...')\n",
  340. "# np.savetxt(kernel_file, Kmatrix)\n",
  341. " \n",
  342. "train_mean, train_std, test_mean, test_std = \\\n",
  343. " split_train_test(Kmatrix, y, alpha_grid, C_grid, splits, trials, model_type, normalize = True)\n",
  344. " \n",
  345. "train_means_list.append(train_mean)\n",
  346. "train_stds_list.append(train_std)\n",
  347. "test_means_list.append(test_mean)\n",
  348. "test_stds_list.append(test_std)\n",
  349. " \n",
  350. "print('\\n') \n",
  351. "table_dict = {'RMSE_test': test_means_list, 'std_test': test_stds_list, \\\n",
  352. " 'RMSE_train': train_means_list, 'std_train': train_stds_list, 'k_time': kernel_time_list}\n",
  353. "keyorder = ['RMSE_test', 'std_test', 'RMSE_train', 'std_train', 'k_time']\n",
  354. "print(tabulate(OrderedDict(sorted(table_dict.items(), key = lambda i:keyorder.index(i[0]))), headers='keys'))"
  355. ]
  356. },
  357. {
  358. "cell_type": "code",
  359. "execution_count": 1,
  360. "metadata": {},
  361. "outputs": [
  362. {
  363. "ename": "ImportError",
  364. "evalue": "cannot import name 'deltaKernel'",
  365. "output_type": "error",
  366. "traceback": [
  367. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  368. "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)",
  369. "\u001b[0;32m<ipython-input-1-51fa7de99690>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0msys\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minsert\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"../\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0mpygraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mutils\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgraphfiles\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mloadDataset\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0;32mfrom\u001b[0m \u001b[0mpygraph\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mkernels\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdeltaKernel\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mdeltaKernel\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mdataset\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mloadDataset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"../../../../datasets/acyclic/Acyclic/dataset_bps.ds\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
  370. "\u001b[0;31mImportError\u001b[0m: cannot import name 'deltaKernel'"
  371. ]
  372. }
  373. ],
  374. "source": [
  375. "import sys\n",
  376. "import networkx as nx\n",
  377. "sys.path.insert(0, \"../\")\n",
  378. "from pygraph.utils.graphfiles import loadDataset\n",
  379. "from pygraph.kernels.deltaKernel import deltaKernel\n",
  380. "\n",
  381. "dataset, y = loadDataset(\"../../../../datasets/acyclic/Acyclic/dataset_bps.ds\")\n",
  382. "G1 = dataset[12]\n",
  383. "G2 = dataset[55]\n",
  384. "sp1 = []\n",
  385. "num_nodes = G1.number_of_nodes()\n",
  386. "for node1 in range(num_nodes):\n",
  387. " for node2 in range(node1 + 1, num_nodes):\n",
  388. " sp1.append(nx.shortest_path(G1, node1, node2, weight = 'cost'))\n",
  389. "print(sp1)\n",
  390. "print(len(sp1))\n",
  391. "sp2 = []\n",
  392. "num_nodes = G2.number_of_nodes()\n",
  393. "for node1 in range(num_nodes):\n",
  394. " for node2 in range(node1 + 1, num_nodes):\n",
  395. " sp2.append(nx.shortest_path(G2, node1, node2, weight = 'cost'))\n",
  396. "print(sp2)\n",
  397. "print(len(sp2))\n",
  398. "\n",
  399. "kernel = 0\n",
  400. "for path1 in sp1:\n",
  401. " for path2 in sp2:\n",
  402. " if len(path1) == len(path2):\n",
  403. " kernel_path = deltaKernel(G1.node[path1[0]]['label'] == G2.node[path2[0]]['label'])\n",
  404. " print(kernel_path)\n",
  405. " if kernel_path:\n",
  406. " print('yes')\n",
  407. " for i in range(1, len(path1)):\n",
  408. " kernel_path *= deltaKernel(G1[path1[i - 1]][path1[i]]['label'] == G2[path2[i - 1]][path2[i]]['label']) * deltaKernel(G1.node[path1[i]]['label'] == G2.node[path2[i]]['label'])\n",
  409. " kernel += kernel_path\n",
  410. " \n",
  411. "kernel = kernel / (len(sp1) * len(sp2))\n",
  412. "\n",
  413. "print(kernel)"
  414. ]
  415. },
  416. {
  417. "cell_type": "code",
  418. "execution_count": 30,
  419. "metadata": {
  420. "scrolled": false
  421. },
  422. "outputs": [
  423. {
  424. "name": "stdout",
  425. "output_type": "stream",
  426. "text": [
  427. "\n",
  428. "- This script take as input a kernel matrix\n",
  429. "and returns the classification or regression performance\n",
  430. "- The kernel matrix can be calculated using any of the graph kernels approaches\n",
  431. "- The criteria used for prediction are SVM for classification and kernel Ridge regression for regression\n",
  432. "- For predition we divide the data in training, validation and test. For each split, we first train on the train data, \n",
  433. "then evaluate the performance on the validation. We choose the optimal parameters for the validation set and finally\n",
  434. "provide the corresponding performance on the test set. If more than one split is performed, the final results \n",
  435. "correspond to the average of the performances on the test sets. \n",
  436. "\n",
  437. "@references\n",
  438. " https://github.com/eghisu/GraphKernels/blob/master/GraphKernelsCollection/python_scripts/compute_perf_gk.py\n",
  439. "\n",
  440. "\n",
  441. " --- This is a regression problem ---\n",
  442. "\n",
  443. " Normalizing output y...\n",
  444. "\n",
  445. " Loading the train set kernel matrix from file...\n",
  446. "[[ 0.15254237 0.08333333 0.0625 ..., 0.11363636 0.11363636\n",
  447. " 0.11363636]\n",
  448. " [ 0.08333333 0.18518519 0.15591398 ..., 0.16617791 0.16617791\n",
  449. " 0.16890214]\n",
  450. " [ 0.0625 0.15591398 0.15254237 ..., 0.12987013 0.12987013\n",
  451. " 0.13163636]\n",
  452. " ..., \n",
  453. " [ 0.11363636 0.16617791 0.12987013 ..., 0.26383753 0.2639004\n",
  454. " 0.26156557]\n",
  455. " [ 0.11363636 0.16617791 0.12987013 ..., 0.2639004 0.26396688\n",
  456. " 0.26162729]\n",
  457. " [ 0.11363636 0.16890214 0.13163636 ..., 0.26156557 0.26162729\n",
  458. " 0.25964592]]\n",
  459. "\n",
  460. " Loading the test set kernel matrix from file...\n",
  461. "[[ 0.18518519 0.1715847 0.11111111 0.16588603 0.11904762 0.16450216\n",
  462. " 0.17281421 0.14285714 0.125 0.16477273 0.16880154 0.14583333\n",
  463. " 0.1660693 0.16906445 0.13333333 0.16612903 0.16420966 0.16441006\n",
  464. " 0.15151515]\n",
  465. " [ 0.1715847 0.19988118 0.15173333 0.18435596 0.16465263 0.21184723\n",
  466. " 0.18985964 0.19960191 0.16819723 0.21540115 0.19575264 0.2041482\n",
  467. " 0.21842419 0.20001664 0.18754969 0.2205599 0.20506165 0.22256445\n",
  468. " 0.2141792 ]\n",
  469. " [ 0.11111111 0.15173333 0.16303156 0.13416478 0.16903494 0.16960573\n",
  470. " 0.13862936 0.18511129 0.16989276 0.17395417 0.14762351 0.18709221\n",
  471. " 0.17706477 0.15293506 0.17970939 0.17975775 0.16082785 0.18295252\n",
  472. " 0.19186573]\n",
  473. " [ 0.16588603 0.18435596 0.13416478 0.17413923 0.14529511 0.19230449\n",
  474. " 0.17775828 0.17598858 0.14892223 0.19462663 0.18166555 0.17986029\n",
  475. " 0.1964604 0.18450695 0.16510376 0.19788853 0.1876399 0.19921541\n",
  476. " 0.18843419]\n",
  477. " [ 0.11904762 0.16465263 0.16903494 0.14529511 0.17703225 0.18464872\n",
  478. " 0.15002895 0.19785455 0.17779663 0.18950917 0.16010081 0.2005743\n",
  479. " 0.19306131 0.16599977 0.19113529 0.1960531 0.175064 0.19963794\n",
  480. " 0.20696464]\n",
  481. " [ 0.16450216 0.21184723 0.16960573 0.19230449 0.18464872 0.23269314\n",
  482. " 0.19681552 0.22450276 0.1871932 0.23765844 0.20733248 0.22967925\n",
  483. " 0.241199 0.21337314 0.21125341 0.24426963 0.22285333 0.24802555\n",
  484. " 0.24156669]\n",
  485. " [ 0.17281421 0.18985964 0.13862936 0.17775828 0.15002895 0.19681552\n",
  486. " 0.18309269 0.18152273 0.15411585 0.19935309 0.18641218 0.18556038\n",
  487. " 0.20169527 0.18946029 0.17030032 0.20320694 0.19192382 0.2042596\n",
  488. " 0.19428999]\n",
  489. " [ 0.14285714 0.19960191 0.18511129 0.17598858 0.19785455 0.22450276\n",
  490. " 0.18152273 0.23269314 0.20168735 0.23049584 0.19407926 0.23694176\n",
  491. " 0.23486084 0.20134404 0.22042984 0.23854906 0.21275711 0.24302959\n",
  492. " 0.24678197]\n",
  493. " [ 0.125 0.16819723 0.16989276 0.14892223 0.17779663 0.1871932\n",
  494. " 0.15411585 0.20168735 0.18391356 0.19188588 0.16365606 0.20428161\n",
  495. " 0.1952436 0.16940489 0.1919249 0.19815511 0.17760881 0.20152837\n",
  496. " 0.20988805]\n",
  497. " [ 0.16477273 0.21540115 0.17395417 0.19462663 0.18950917 0.23765844\n",
  498. " 0.19935309 0.23049584 0.19188588 0.24296859 0.21058278 0.23586086\n",
  499. " 0.24679036 0.21702635 0.21699483 0.25006701 0.22724646 0.25407837\n",
  500. " 0.24818625]\n",
  501. " [ 0.16880154 0.19575264 0.14762351 0.18166555 0.16010081 0.20733248\n",
  502. " 0.18641218 0.19407926 0.16365606 0.21058278 0.19214629 0.19842989\n",
  503. " 0.21317298 0.19609213 0.18225175 0.2151567 0.20088139 0.2171273\n",
  504. " 0.20810339]\n",
  505. " [ 0.14583333 0.2041482 0.18709221 0.17986029 0.2005743 0.22967925\n",
  506. " 0.18556038 0.23694176 0.20428161 0.23586086 0.19842989 0.24154885\n",
  507. " 0.24042054 0.20590264 0.22439219 0.24421452 0.21769149 0.24880304\n",
  508. " 0.25200246]\n",
  509. " [ 0.1660693 0.21842419 0.17706477 0.1964604 0.19306131 0.241199\n",
  510. " 0.20169527 0.23486084 0.1952436 0.24679036 0.21317298 0.24042054\n",
  511. " 0.25107069 0.21988195 0.22126548 0.25446921 0.23058896 0.25855949\n",
  512. " 0.25312182]\n",
  513. " [ 0.16906445 0.20001664 0.15293506 0.18450695 0.16599977 0.21337314\n",
  514. " 0.18946029 0.20134404 0.16940489 0.21702635 0.19609213 0.20590264\n",
  515. " 0.21988195 0.20052959 0.18917551 0.22212027 0.2061696 0.22441239\n",
  516. " 0.21607563]\n",
  517. " [ 0.13333333 0.18754969 0.17970939 0.16510376 0.19113529 0.21125341\n",
  518. " 0.17030032 0.22042984 0.1919249 0.21699483 0.18225175 0.22439219\n",
  519. " 0.22126548 0.18917551 0.2112185 0.224781 0.20021961 0.22904467\n",
  520. " 0.23356012]\n",
  521. " [ 0.16612903 0.2205599 0.17975775 0.19788853 0.1960531 0.24426963\n",
  522. " 0.20320694 0.23854906 0.19815511 0.25006701 0.2151567 0.24421452\n",
  523. " 0.25446921 0.22212027 0.224781 0.25800115 0.23326559 0.26226067\n",
  524. " 0.25717144]\n",
  525. " [ 0.16420966 0.20506165 0.16082785 0.1876399 0.175064 0.22285333\n",
  526. " 0.19192382 0.21275711 0.17760881 0.22724646 0.20088139 0.21769149\n",
  527. " 0.23058896 0.2061696 0.20021961 0.23326559 0.21442192 0.2364528\n",
  528. " 0.22891788]\n",
  529. " [ 0.16441006 0.22256445 0.18295252 0.19921541 0.19963794 0.24802555\n",
  530. " 0.2042596 0.24302959 0.20152837 0.25407837 0.2171273 0.24880304\n",
  531. " 0.25855949 0.22441239 0.22904467 0.26226067 0.2364528 0.26687384\n",
  532. " 0.26210305]\n",
  533. " [ 0.15151515 0.2141792 0.19186573 0.18843419 0.20696464 0.24156669\n",
  534. " 0.19428999 0.24678197 0.20988805 0.24818625 0.20810339 0.25200246\n",
  535. " 0.25312182 0.21607563 0.23356012 0.25717144 0.22891788 0.26210305\n",
  536. " 0.26386999]]\n"
  537. ]
  538. },
  539. {
  540. "ename": "ValueError",
  541. "evalue": "Precomputed metric requires shape (n_queries, n_indexed). Got (19, 19) for 164 indexed.",
  542. "output_type": "error",
  543. "traceback": [
  544. "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
  545. "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
  546. "\u001b[0;32m<ipython-input-30-d4c5f46d5abf>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 133\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 134\u001b[0m \u001b[0;31m# predict on the test set\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 135\u001b[0;31m \u001b[0my_pred_test\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mKR\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpredict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mKmatrix_test\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 136\u001b[0m \u001b[0;31m# print(y_pred)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 137\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
  547. "\u001b[0;32m/usr/local/lib/python3.5/dist-packages/sklearn/kernel_ridge.py\u001b[0m in \u001b[0;36mpredict\u001b[0;34m(self, X)\u001b[0m\n\u001b[1;32m 182\u001b[0m \"\"\"\n\u001b[1;32m 183\u001b[0m \u001b[0mcheck_is_fitted\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m\"X_fit_\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"dual_coef_\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 184\u001b[0;31m \u001b[0mK\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_kernel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mX_fit_\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 185\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mK\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdual_coef_\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
  548. "\u001b[0;32m/usr/local/lib/python3.5/dist-packages/sklearn/kernel_ridge.py\u001b[0m in \u001b[0;36m_get_kernel\u001b[0;34m(self, X, Y)\u001b[0m\n\u001b[1;32m 119\u001b[0m \"coef0\": self.coef0}\n\u001b[1;32m 120\u001b[0m return pairwise_kernels(X, Y, metric=self.kernel,\n\u001b[0;32m--> 121\u001b[0;31m filter_params=True, **params)\n\u001b[0m\u001b[1;32m 122\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mproperty\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
  549. "\u001b[0;32m/usr/local/lib/python3.5/dist-packages/sklearn/metrics/pairwise.py\u001b[0m in \u001b[0;36mpairwise_kernels\u001b[0;34m(X, Y, metric, filter_params, n_jobs, **kwds)\u001b[0m\n\u001b[1;32m 1389\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1390\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmetric\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"precomputed\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1391\u001b[0;31m \u001b[0mX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcheck_pairwise_arrays\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mY\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprecomputed\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1392\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mX\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1393\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmetric\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mGPKernel\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
  550. "\u001b[0;32m/usr/local/lib/python3.5/dist-packages/sklearn/metrics/pairwise.py\u001b[0m in \u001b[0;36mcheck_pairwise_arrays\u001b[0;34m(X, Y, precomputed, dtype)\u001b[0m\n\u001b[1;32m 117\u001b[0m \u001b[0;34m\"(n_queries, n_indexed). Got (%d, %d) \"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 118\u001b[0m \u001b[0;34m\"for %d indexed.\"\u001b[0m \u001b[0;34m%\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 119\u001b[0;31m (X.shape[0], X.shape[1], Y.shape[0]))\n\u001b[0m\u001b[1;32m 120\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mX\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mY\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 121\u001b[0m raise ValueError(\"Incompatible dimension for X and Y matrices: \"\n",
  551. "\u001b[0;31mValueError\u001b[0m: Precomputed metric requires shape (n_queries, n_indexed). Got (19, 19) for 164 indexed."
  552. ]
  553. }
  554. ],
  555. "source": [
  556. "# Author: Elisabetta Ghisu\n",
  557. "\n",
  558. "\"\"\"\n",
  559. "- This script take as input a kernel matrix\n",
  560. "and returns the classification or regression performance\n",
  561. "- The kernel matrix can be calculated using any of the graph kernels approaches\n",
  562. "- The criteria used for prediction are SVM for classification and kernel Ridge regression for regression\n",
  563. "- For predition we divide the data in training, validation and test. For each split, we first train on the train data, \n",
  564. "then evaluate the performance on the validation. We choose the optimal parameters for the validation set and finally\n",
  565. "provide the corresponding performance on the test set. If more than one split is performed, the final results \n",
  566. "correspond to the average of the performances on the test sets. \n",
  567. "\n",
  568. "@references\n",
  569. " https://github.com/eghisu/GraphKernels/blob/master/GraphKernelsCollection/python_scripts/compute_perf_gk.py\n",
  570. "\"\"\"\n",
  571. "\n",
  572. "print(__doc__)\n",
  573. "\n",
  574. "import sys\n",
  575. "import pathlib\n",
  576. "import os\n",
  577. "sys.path.insert(0, \"../\")\n",
  578. "from tabulate import tabulate\n",
  579. "\n",
  580. "import random\n",
  581. "import numpy as np\n",
  582. "import matplotlib.pyplot as plt\n",
  583. "\n",
  584. "from sklearn.kernel_ridge import KernelRidge # 0.17\n",
  585. "from sklearn.metrics import accuracy_score, mean_squared_error\n",
  586. "from sklearn import svm\n",
  587. "\n",
  588. "from pygraph.kernels.pathKernel import pathKernel\n",
  589. "from pygraph.utils.graphfiles import loadDataset\n",
  590. "\n",
  591. "# print('\\n Loading dataset from file...')\n",
  592. "# dataset, y = loadDataset(\"/home/ljia/Documents/research-repo/datasets/acyclic/Acyclic/dataset_bps.ds\")\n",
  593. "# y = np.array(y)\n",
  594. "# print(y)\n",
  595. "\n",
  596. "# kernel_file_path = 'marginalizedkernelmatrix.ds'\n",
  597. "# path = pathlib.Path(kernel_file_path)\n",
  598. "# if path.is_file():\n",
  599. "# print('\\n Loading the matrix from file...')\n",
  600. "# Kmatrix = np.loadtxt(kernel_file_path)\n",
  601. "# print(Kmatrix)\n",
  602. "# else:\n",
  603. "# print('\\n Calculating kernel matrix, this could take a while...')\n",
  604. "# Kmatrix = marginalizeKernel(dataset)\n",
  605. "# print(Kmatrix)\n",
  606. "# print('Saving kernel matrix to file...')\n",
  607. "# np.savetxt(kernel_file_path, Kmatrix)\n",
  608. "\n",
  609. "# setup the parameters\n",
  610. "model_type = 'regression' # Regression or classification problem\n",
  611. "print('\\n --- This is a %s problem ---' % model_type)\n",
  612. "\n",
  613. "# datasize = len(dataset)\n",
  614. "trials = 100 # Trials for hyperparameters random search\n",
  615. "splits = 100 # Number of splits of the data\n",
  616. "alpha_grid = np.linspace(0.01, 100, num = trials) # corresponds to (2*C)^-1 in other linear models such as LogisticRegression\n",
  617. "# C_grid = np.linspace(0.0001, 10, num = trials)\n",
  618. "random.seed(20) # Set the seed for uniform parameter distribution\n",
  619. "data_dir = '/home/ljia/Documents/research-repo/datasets/acyclic/Acyclic/'\n",
  620. "\n",
  621. "# set the output path\n",
  622. "kernel_file_path = 'kernelmatrices_marginalized_acyclic/'\n",
  623. "if not os.path.exists(kernel_file_path):\n",
  624. " os.makedirs(kernel_file_path)\n",
  625. "\n",
  626. "\n",
  627. "\"\"\"\n",
  628. "- Here starts the main program\n",
  629. "- First we permute the data, then for each split we evaluate corresponding performances\n",
  630. "- In the end, the performances are averaged over the test sets\n",
  631. "\"\"\"\n",
  632. "\n",
  633. "# Initialize the performance of the best parameter trial on validation with the corresponding performance on test\n",
  634. "val_split = []\n",
  635. "test_split = []\n",
  636. "\n",
  637. "p_quit = 0.5\n",
  638. "\n",
  639. "# for each split of the data\n",
  640. "for j in range(10):\n",
  641. " dataset_train, y_train = loadDataset(data_dir + 'trainset_' + str(j) + '.ds')\n",
  642. " dataset_test, y_test = loadDataset(data_dir + 'testset_' + str(j) + '.ds')\n",
  643. " \n",
  644. " # Normalization step (for real valued targets only)\n",
  645. " if model_type == 'regression':\n",
  646. " print('\\n Normalizing output y...')\n",
  647. " y_train_mean = np.mean(y_train)\n",
  648. " y_train_std = np.std(y_train)\n",
  649. " y_train = (y_train - y_train_mean) / float(y_train_std)\n",
  650. "# print(y)\n",
  651. " \n",
  652. " # save kernel matrices to files / read kernel matrices from files\n",
  653. " kernel_file_train = kernel_file_path + 'train' + str(j) + '_pquit_' + str(p_quit)\n",
  654. " kernel_file_test = kernel_file_path + 'test' + str(j) + '_pquit_' + str(p_quit)\n",
  655. " path_train = pathlib.Path(kernel_file_train)\n",
  656. " path_test = pathlib.Path(kernel_file_test)\n",
  657. " # get train set kernel matrix\n",
  658. " if path_train.is_file():\n",
  659. " print('\\n Loading the train set kernel matrix from file...')\n",
  660. " Kmatrix_train = np.loadtxt(kernel_file_train)\n",
  661. " print(Kmatrix_train)\n",
  662. " else:\n",
  663. " print('\\n Calculating train set kernel matrix, this could take a while...')\n",
  664. " Kmatrix_train = marginalizedkernel(dataset_train, p_quit, 20)\n",
  665. " print(Kmatrix_train)\n",
  666. " print('\\n Saving train set kernel matrix to file...')\n",
  667. " np.savetxt(kernel_file_train, Kmatrix_train)\n",
  668. " # get test set kernel matrix\n",
  669. " if path_test.is_file():\n",
  670. " print('\\n Loading the test set kernel matrix from file...')\n",
  671. " Kmatrix_test = np.loadtxt(kernel_file_test)\n",
  672. " print(Kmatrix_test)\n",
  673. " else:\n",
  674. " print('\\n Calculating test set kernel matrix, this could take a while...')\n",
  675. " Kmatrix_test = marginalizedkernel(dataset_test, p_quit, 20)\n",
  676. " print(Kmatrix_test)\n",
  677. " print('\\n Saving test set kernel matrix to file...')\n",
  678. " np.savetxt(kernel_file_test, Kmatrix_test)\n",
  679. "\n",
  680. " # For each parameter trial\n",
  681. " for i in range(trials):\n",
  682. " # For regression use the Kernel Ridge method\n",
  683. " if model_type == 'regression':\n",
  684. " # print('\\n Starting experiment for trial %d and parameter alpha = %3f\\n ' % (i, alpha_grid[i]))\n",
  685. "\n",
  686. " # Fit the kernel ridge model\n",
  687. " KR = KernelRidge(kernel = 'precomputed', alpha = alpha_grid[i])\n",
  688. " KR.fit(Kmatrix_train, y_train)\n",
  689. "\n",
  690. " # predict on the test set\n",
  691. " y_pred_test = KR.predict(Kmatrix_test)\n",
  692. " # print(y_pred)\n",
  693. "\n",
  694. " # adjust prediction: needed because the training targets have been normalized\n",
  695. " y_pred_test = y_pred_test * float(y_train_std) + y_train_mean\n",
  696. " # print(y_pred_test)\n",
  697. "\n",
  698. " # root mean squared error in test \n",
  699. " rmse_test = np.sqrt(mean_squared_error(y_test, y_pred_test))\n",
  700. " perf_all_test.append(rmse_test)\n",
  701. "\n",
  702. " # print('The performance on the validation set is: %3f' % rmse)\n",
  703. " # print('The performance on the test set is: %3f' % rmse_test)\n",
  704. "\n",
  705. " # --- FIND THE OPTIMAL PARAMETERS --- #\n",
  706. " # For regression: minimise the mean squared error\n",
  707. " if model_type == 'regression':\n",
  708. "\n",
  709. " # get optimal parameter on test (argmin mean squared error)\n",
  710. " min_idx = np.argmin(perf_all_test)\n",
  711. " alpha_opt = alpha_grid[min_idx]\n",
  712. "\n",
  713. " # corresponding performance on test for the same parameter\n",
  714. " perf_test_opt = perf_all_test[min_idx]\n",
  715. "\n",
  716. " print('The best performance is for trial %d with parameter alpha = %3f' % (min_idx, alpha_opt))\n",
  717. " print('The corresponding performance on test set is: %3f' % perf_test_opt)\n",
  718. " \n",
  719. " \n",
  720. " \n",
  721. "\n",
  722. "# For each split of the data\n",
  723. "for j in range(10, 10 + splits):\n",
  724. " print('Starting split %d...' % j)\n",
  725. "\n",
  726. " # Set the random set for data permutation\n",
  727. " random_state = int(j)\n",
  728. " np.random.seed(random_state)\n",
  729. " idx_perm = np.random.permutation(datasize)\n",
  730. "# print(idx_perm)\n",
  731. " \n",
  732. " # Permute the data\n",
  733. " y_perm = y[idx_perm] # targets permutation\n",
  734. "# print(y_perm)\n",
  735. " Kmatrix_perm = Kmatrix[:, idx_perm] # inputs permutation\n",
  736. "# print(Kmatrix_perm)\n",
  737. " Kmatrix_perm = Kmatrix_perm[idx_perm, :] # inputs permutation\n",
  738. " \n",
  739. " # Set the training, validation and test\n",
  740. " # Note: the percentage can be set up by the user\n",
  741. " num_train_val = int((datasize * 90) / 100) # 90% (of entire dataset) for training and validation\n",
  742. " num_test = datasize - num_train_val # 10% (of entire dataset) for test\n",
  743. " num_train = int((num_train_val * 90) / 100) # 90% (of train + val) for training\n",
  744. " num_val = num_train_val - num_train # 10% (of train + val) for validation\n",
  745. " \n",
  746. " # Split the kernel matrix\n",
  747. " Kmatrix_train = Kmatrix_perm[0:num_train, 0:num_train]\n",
  748. " Kmatrix_val = Kmatrix_perm[num_train:(num_train + num_val), 0:num_train]\n",
  749. " Kmatrix_test = Kmatrix_perm[(num_train + num_val):datasize, 0:num_train]\n",
  750. "\n",
  751. " # Split the targets\n",
  752. " y_train = y_perm[0:num_train]\n",
  753. "\n",
  754. " # Normalization step (for real valued targets only)\n",
  755. " print('\\n Normalizing output y...')\n",
  756. " if model_type == 'regression':\n",
  757. " y_train_mean = np.mean(y_train)\n",
  758. " y_train_std = np.std(y_train)\n",
  759. " y_train = (y_train - y_train_mean) / float(y_train_std)\n",
  760. "# print(y)\n",
  761. " \n",
  762. " y_val = y_perm[num_train:(num_train + num_val)]\n",
  763. " y_test = y_perm[(num_train + num_val):datasize]\n",
  764. " \n",
  765. " # Record the performance for each parameter trial respectively on validation and test set\n",
  766. " perf_all_val = []\n",
  767. " perf_all_test = []\n",
  768. " \n",
  769. " "
  770. ]
  771. },
  772. {
  773. "cell_type": "code",
  774. "execution_count": null,
  775. "metadata": {},
  776. "outputs": [],
  777. "source": []
  778. }
  779. ],
  780. "metadata": {
  781. "kernelspec": {
  782. "display_name": "Python 3",
  783. "language": "python",
  784. "name": "python3"
  785. },
  786. "language_info": {
  787. "codemirror_mode": {
  788. "name": "ipython",
  789. "version": 3
  790. },
  791. "file_extension": ".py",
  792. "mimetype": "text/x-python",
  793. "name": "python",
  794. "nbconvert_exporter": "python",
  795. "pygments_lexer": "ipython3",
  796. "version": "3.5.2"
  797. }
  798. },
  799. "nbformat": 4,
  800. "nbformat_minor": 2
  801. }

A Python package for graph kernels, graph edit distances and graph pre-image problem.