From 0c277eacd130554510405eba6e74e925556e3d6e Mon Sep 17 00:00:00 2001 From: Dave Bechberger Date: Fri, 19 Jan 2024 14:05:38 -0900 Subject: [PATCH 1/3] Added Vector Similarity Notebook and updated the other algorithm notebooks to point to it as a Next Step. Added a PDF of supported algorithms and updated the Getting Started notebook to not use %status in favor of %opencypher_status --- ...tting-Started-With-Neptune-Analytics.ipynb | 8 +- ...on-Neptune-Analytics-Algorithm-Support.pdf | Bin 0 -> 78313 bytes .../02-Path-Finding-Algorithms.ipynb | 4 +- .../03-Centrality-Algorithms.ipynb | 4 +- .../04-Community-Detection-Algorithms.ipynb | 4 +- .../06-Vector-Similarity-Algorithms.ipynb | 388 ++++++++++++++++++ .../unit/notebooks/test_validate_notebooks.py | 1 + 7 files changed, 402 insertions(+), 7 deletions(-) create mode 100644 src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/00-Amazon-Neptune-Analytics-Algorithm-Support.pdf create mode 100644 src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/06-Vector-Similarity-Algorithms.ipynb diff --git a/src/graph_notebook/notebooks/02-Neptune-Analytics/01-Getting-Started/01-Getting-Started-With-Neptune-Analytics.ipynb b/src/graph_notebook/notebooks/02-Neptune-Analytics/01-Getting-Started/01-Getting-Started-With-Neptune-Analytics.ipynb index d2341a3e..6363f64b 100644 --- a/src/graph_notebook/notebooks/02-Neptune-Analytics/01-Getting-Started/01-Getting-Started-With-Neptune-Analytics.ipynb +++ b/src/graph_notebook/notebooks/02-Neptune-Analytics/01-Getting-Started/01-Getting-Started-With-Neptune-Analytics.ipynb @@ -77,7 +77,7 @@ }, "outputs": [], "source": [ - "%status" + "%opencypher_status" ] }, { @@ -85,13 +85,13 @@ "id": "8f3b5040-15be-474e-9b55-01b60945085d", "metadata": {}, "source": [ - "Examining the response we should see that the graph status is currently `healthy` as well as some metadata such as versions and the start time for the cluster.\n", + "Examining the response we should see that the graph returns an object that contains some information on currently running openCypher queries.\n", "\n", "## Getting Help\n", "You can get help at any time using the `--help` option.\n", "\n", "```\n", - "%status --help\n", + "%opencypher_status --help\n", "```\n", "\n", "**Note:** If you are using a cell magic the cell body needs at least one character in it for `--help` to work.\n", @@ -429,4 +429,4 @@ }, "nbformat": 4, "nbformat_minor": 5 -} \ No newline at end of file +} diff --git a/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/00-Amazon-Neptune-Analytics-Algorithm-Support.pdf b/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/00-Amazon-Neptune-Analytics-Algorithm-Support.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bb04b6e879b3d25f1d8c31c682a555f6b5ad739c GIT binary patch literal 78313 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%0D9&64%S7))TaBfE0d3G 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 literal 0 HcmV?d00001 diff --git a/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/02-Path-Finding-Algorithms.ipynb b/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/02-Path-Finding-Algorithms.ipynb index a83fc0ef..ec91fd64 100644 --- a/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/02-Path-Finding-Algorithms.ipynb +++ b/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/02-Path-Finding-Algorithms.ipynb @@ -544,7 +544,9 @@ "\n", "* [Community detection/clustering algorithms](./04-Community-Detection-Algorithms.ipynb)\n", "\n", - "* [Similarity algorithms](./05-Similarity-Algorithms.ipynb)" + "* [Similarity algorithms](./05-Similarity-Algorithms.ipynb)\n", + "\n", + "* [Vector Similarity algorithms](./06-Vector-Similarity-Algorithms.ipynb)" ] } ], diff --git a/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/03-Centrality-Algorithms.ipynb b/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/03-Centrality-Algorithms.ipynb index 6819e8fc..ce941c96 100644 --- a/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/03-Centrality-Algorithms.ipynb +++ b/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/03-Centrality-Algorithms.ipynb @@ -400,7 +400,9 @@ "\n", "* [Community detection/clustering algorithms](./04-Community-Detection-Algorithms.ipynb)\n", "\n", - "* [Similarity algorithms](./05-Similarity-Algorithms.ipynb)" + "* [Similarity algorithms](./05-Similarity-Algorithms.ipynb)\n", + "\n", + "* [Vector Similarity algorithms](./06-Vector-Similarity-Algorithms.ipynb)" ] } ], diff --git a/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/04-Community-Detection-Algorithms.ipynb b/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/04-Community-Detection-Algorithms.ipynb index 3f307c7d..be43d8b0 100644 --- a/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/04-Community-Detection-Algorithms.ipynb +++ b/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/04-Community-Detection-Algorithms.ipynb @@ -371,7 +371,9 @@ "\n", "* [Centrality algorithms](./03-Centrality-Algorithms.ipynb)\n", "\n", - "* [Similarity algorithms](./05-Similarity-Algorithms.ipynb)" + "* [Similarity algorithms](./05-Similarity-Algorithms.ipynb)\n", + "\n", + "* [Vector Similarity algorithms](./06-Vector-Similarity-Algorithms.ipynb)" ] } ], diff --git a/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/06-Vector-Similarity-Algorithms.ipynb b/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/06-Vector-Similarity-Algorithms.ipynb new file mode 100644 index 00000000..b1acea1d --- /dev/null +++ b/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/06-Vector-Similarity-Algorithms.ipynb @@ -0,0 +1,388 @@ +{ + "cells": [ + { + "attachments": { + "02e14c92-e464-46c9-9dfd-0ebb4a676358.png": { + "image/png": "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zTJwXU4EREAEREAEJL76DYiACIiACIhAlglIfLMMXJcTAREQAREQgWpCIAIiIAIiIAL5QIClCH7//Xf37bffuu+++86tXr3aVa1a1W233XauXr16bquttnIbbZQfNqXENx9+cWqjCIiACBQxgV9//dV9/fXXbtKkSW727Nlu8eLF7scff3S//fabie2WW27p6tSp43beeWfXtm1bt8suu7hNN93UValSJbTUJL6hvTVqmAiIgAiIwIoVK9wXX3zhxo4d69566y03efJk98svv7g///yzBJzq1au7Zs2auS5durhDDjnE7bnnnmYRV6sWTpmroiUFS9w/fREBERABEQgBAe9iRnQfeeQRN2LECLN0y2oaItykSRN3/fXXmxDvsMMOoXRF54dzvCza2i8CIiACIlBQBBjbnTp1qrv33nvdqFGj3Nq1a1PqH8d99dVX7vLLLzdLGfd0GIvEN4x3RW0SAREQgSImgNX7008/uQceeMDGeQmsYluiEj+uy3EIMOPCTz/9tBs3blyp5yaqL1vbwukMz1bvdR0REAEREIHQEVi1apWbNm2ae++99yyq2QsvQssYbvv27S2oascdd7Sx3wULFriPP/7YffPNN1EL+Y8//nATJ050u+22mx3foEGDUPVT4huq26HGiIAIiIAIfP/99+6DDz5wy5Yts6lFnsjGG2/sdt11V3fCCSe4gw46yMZ2EVmE+vnnn3evv/66+/LLL/3h7ocffrBgLQK2JL5RLPogAiIgAiIQdgJYnWvWrDHXLeLHK9MF0Rw/fnzUiuV6WL01atRwF1xwgevRo4erXbt2tBlENteqVcutW7fOzZs3r8R5WMWI82GHHRY9PgwfNOYbhrugNoiACIhACAkgvIy3MsWHaOOZM2c6LM1MF6YSLVy40MTUX2uTTTZxdevWdV27dnXbb7+93xx9r1+/vs3xZa5vbEHIScoRtiK3c9juiNojAiIgAjkmwBxaLEhcv2PGjHHTp0839y/i17FjR9etWze3xx57ZCyRBQLvrW2PAvGtWbOm23zzzS2rld/u3xkL3nrrrc069tt4J2qaZBxhKxLfsN0RtUcEREAEckDARwnPmTPHffbZZ+7TTz+1d8ZLf/75ZwtsYjx11qxZbsaMGW733Xe3V+vWrR2BT/FRx5XpAikj4zNUIchY4UQy83AQn0aS9hOoRZR0bMFN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AiKQhMBLL71kaRL32msvWxpvyJAhtpJQklMKcheLIZBmkmxZfnWk2EUc8qHTcjvnw11SG0VABIqWACvuYN3y+vLLL20Zv08++cQWIShWKLjbWbCBVY5I4oEVzNq/jP/mS5H45sudUjtFQASKigALyHvRJakEa+fyqlWrVlFxSNTZadOmWb5oVk7C5UzaSVYukvgmoqVtIiACIiACZRJ48803TXRZjIDxzAceeMD169evzPOK6YAff/zRLN/PP//cBLdz587mhs4nBhrzzae7pbaKgAgULIHHHnvMderUyaJ4caWyKP0HH3wg4S3QO15Q4vvOO+9k7TY98cQTtrZk1i6oC4mACBQcgcWLF7vrrrvO1a1b17HqD2vWzpo1yz3//PM2l7XgOqwORQnktfgitrzIdsLkat4TlZUrVyba7Pjh476oSPn9998dr2SF/aw9uXbt2mSHaZ8IiECRERg/frw744wzHPNVX375ZXfNNde4pUuXujvuuCOvUiQW2W1La3fzUny94CK2119/vQFhojmh5oSeszAzy07NmzfPlqAi+0mPHj2iCzBPmTLFtWnTxubJ7bfffpaa7IcffrB6cPWwaDNPnpT33nvP6jjxxBPtO//wH+XOO+90V199tTv88MPt9Z///Ce6nw/9+/e3CLx//etfFoV30003ldivLyIgAsVHAKHt3r27Y4ySh//Bgwe7qVOnuosuusiRt1ileAjkVbQz7pl3333XrF0mVyO4vMcWIt/4QR999NHuhBNOcAMHDrQk3DxVMo6COPft29eNGDEi+oT53HPPufPOO8+98MILttjzP//5T/fzzz9btbiBmFMXK7633nqrCWrjxo0tyXfs9fnM3DsmwWP1MhmcOWksGM1/PNpFP3ipiIAIFD6B1atXR6OWZ86c6c466yw3ceJEt8ceexR+59XDUgnkheWLUOFWRnixVLFwEwlvbC8RvVdffdWEl+1YwhTmx3Xr1i0qvGw79thjHVFzTNpOR0F8WSQa6/i2226z9y233NLaQ/1Y6/RHApwO2qpDBMJJAKFlHJe/PXjCMAaWLFliQizhDec9y2arqmXzYuW9Fu5lhIr3a6+9ttxihQDGlz///HODlS8QQqzidGVIQWhbt25trqXY6/v2cB2El77xqkjfYuvVZxEQgfAQeOutt0xg8XThNbvvvvvcqaeeGp4GqiWhIBBay5fxXB9A5cUqHcR44nzjjTfc119/Ha1u+PDhZgn7MZftttuuxH7c0fGFydzffvttdDOi7l3VWNLDhg2zZN9cjxdjzD/99FP0eMSXfiG8CDDfVURABPKXwOOPP24P3IzpssYs8SMffvihhDd/b2lGW14to7VXoHKsXESXsdyyXMuJqufHjotn3LhxFnjFf4KGDRu6e++91w7HKn3mmWfMfb377rtb0APjxE8//XS0Op5WEUQEmnRuLVq0MMHGndy7d287jkCrXr16uQkTJth3ohcJwCLTCq5xgr1Id9azZ0/bTyaWyy+/fIOUcF50vRVckT5HG64PIiACWSXAA7jPQsWsinPOOcc99dRTJYa1stogXSxvCIRKfBGiyrphyQjDK1nBEmUuHQKJ8DLHLrYg2GSZmT17tu3bYostouLtj+M8nmwJqtp4443tONzXvuBmYoxn7ty5Nv674447+l0bvNNv/+LBQ27oDRBpgwiEigAP3YguiTEYYuLBm9SP3nsWqsZWsDF45tasWWPTMfHsUVjEgIcMvvN3MheFa9MG2kLhO1NGaSttjv07nIv2pXrN0IhvOoQ31U5zHAFZTZs2TXpKs2bNku5nZ6NGjUo9hnUmW7ZsWer++B0woPAAQvHf7Yv+EQERyDkBUj4iujycs54sMyu8NyznjUtTAxAwFixYtGiRzdogcGzdunVWO7NGiNTGq8ffvjp16tg6upkWPNqE2OJpwOChDbSFQttoI95OcivstNNObocddgi9CIdCfLH2cDfL5bpecCXA9v9K/4hAzgkwPdG7llnsoFCnCjElEoEjdoW/xzxYMMPk+++/j94DhI8hOoSO2JbDDjvMhJjhvOrVq0ePS+cHZqGwshOrGL322ms2JXTBggVm6XId9jPciDeTIT/yPHQNhi233nprezDA0Apjybn4Sng3/Fl4i1cCvCEbbRGBbBEg3sOLLjMV/KpCftpittqRjevguiXGhWBUEgwx5EbioUTTL9mGEN59992Wu+CAAw4wwdt3331t1kg624tVi7DyIDBmzBhrIw9DPCjEF9r7+uuvm7WO1/K4446z5EpYwrlykce3MfZ7TsUXkZHFG3s71n+WAK9noU8ikE0Co0ePNtFl4XqCLwnWJIajEAsiRo4D/g4jcrhvcTeXJnAwwAWMKGIhI8K8T5482bVt29YddNBBFvHN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edSoUbZkGeO5//73vyW8ZcHTfhEQgawQyIj4+pZr3NeTyOw747qrV69OehFc0kxHytfCilll/Z4IOCPanteqVavca6+95j799FNbR7dKlSr52nW1WwREoAAJZER8GfPldf311xcgsvB1iQhnxjWTFY5h3c58LAiv/y3xu4otTBW69dZbzZ1++umnu1133dUW3B46dKg79NBDYw/VZxEQAREIDYGMiC+9w/Wskj0CfnpRaVcsa39p5+V6e6zwxrbFTxWqXbu2e/TRR925555rU4Xuvfde17Zt29hD9VkEREAEQkcgY+JLT3ETluUqDB0RNSg0BPjteIvXNyp2qtD06dPdoEGD3Jw5c9xVV13lttlmG3+Y3kVABEQg1AQyJr5yPYf6vudF4xIFWDFVCJEdN26cGzt2rDv++OPzoi9qpAiIgAjEEsjYVCMugus50R/Q2AboswgkIpDod7PZZptZBDNju/vss0+i07RNBERABPKCQMYsX3rvg2Pkes6L30JoGsk47+eff75Be3799VeHqxlh1m9qAzzaIAIikEcEMiq+cMD6jR+3yyM+amqWCfgAqx9//DF6ZdzM/uU3IsAcqyICIiAC+Uggo25ngGD9Ir5YKt4SzkdQanN2CPAbif+dxFu5Pnsa7/pdZee+6CoiIALpJZAV8eWPKQIc/0c1vV1RbYVAINFvJNG2Quir+iACIlC8BDLudgatTzcpN2Hx/tDUcxEQAREQgfUEsiK+WC4a+10PXZ9EQAREQASKm0BWxBfEWL2IcKIpJMV9C9R7ERABERCBYiOQNfEFrHc/xwfQFBt09VcEREAERKC4CWRVfL37WdZvcf/o1HsREAERKHYCWRVfYMv9XOw/OfVfBERABEQg6+ILcu9+RohVREAEREAERKDYCOREfL37mbm/EuBi+8mpvyIgAiIgAhlPslEaYi+6PvWk/17a8dqemAD5jlevXu3Wrl2b+ID/2+qP++2331z16tWTHqudIiACIiACmSWQM/GlW15wJcDlv8l//vmnW7NmjZs1a5abO3eui82FnKi27777zn355ZduwYIFrkGDBm7TTTdNdJi2iYAIiIAIZIFA1UAAr8vCdUq9BC5oihdg/9026p9SCaxYscK9/vrr9gDz3nvvuZUrV7pIJFLq8Qj11KlT3bx589x2223nmjZtWuqx2iECIiACIpBZAjkXX7rnBVcCXPbNRkQ/+eQT9/DDD7tBgwa5GTNmuFWrViUVXmpFmDl36dKlZi0vXrzY1a1b12211VauatWqZV9YR4iACIiACKSNQCjEl94gwLyefPJJd9ppp1kH+a6ynsDXX3/t3nzzTff888+7N954w82cObPMsd71Z/9PgH/55Re3ZMkSt2jRIof1XK1aNbf11lu7LbbYIvZQfRYBERABEcgggdCIL31s1KiRO/XUU627soINg1msBEsxtovgYu2OHj3aLVu27H8HVODfdevWue+//96s5p9//tksX8SXNXOrVKlSgRp1igiIgAiIQHkIhEp8fcO9xYsAF7MI//HHH+ZSxrU8YMAA99BDD7np06e733//3aOq1DuRz9RH/VyrWbNmbuONNzYxlghXCq1OFgEREIGkBKoEY4GlR+kkPTU7O4kH8wJMcg6+p6OQX5pXuupLR5vi68A9PGLECPfII4+4adOmOSxgopzTXXA9E4TVpk0bd80117g999zTrOB0X0f1iYAIiIAI/I9A6MXX3yhEMt0iTI5pBDidou7bW5l3noeIYB4yZIgbO3as++qrr2wub2XqLOtcgq4233xzt8suu7iePXu6Qw891LVr105u6LLAab8IiIAIVIBA3oiv71usCLMN4cRN7V3V/rhU3hFeBJixTubJ5lqEcSdj7dIuxnc/+OADC4zKhLVbGh9EuFWrVm6//fZzBx98sPFBlDfaaKPSTtF2ERABERCBchLIO/H1/UOgeHlrmO2IJwUh5pVK8dYvxxLwNX/+/JyI8E8//WQWLhYvEd8EWBGZnKtSs2ZN17FjR9evXz+3++67u3r16pllnKv26LoiIAIiUEgE8lZ842+CH7uNFWMvwFhxFP/dn8t3BDx+icNsijAuZubpTpw40aYQvfDCC44I5DAUrGCmIV1yySWuV69erkWLFm6zzTaTKzoMN0dtEAERyGsCBSO+8XcBUeVFeffdd+3df7cvKfzj3dGMu8YLdwqnl3kI7mSCqB588EH38ssvuy+++MKs3TDFwOFu3nLLLV2XLl3cCSec4I488kgT4DI7pwNEQAREQARKJVCw4ltqj2N2eDGOt3z9IQiuH1P229L1jpt58uTJ7oknnnATJkywnMtYwGEtRENj+cIEV3TDhg2VHzqsN0vtEgERCD2BohZf7g7uasZYGev1JZOii1U7e/Zs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RNi7o8kKhgjHL3uY4DRtEgERKHICEt8i/wGo++khwLrJ3h1du3Ztc0efd9556alctYiACBQcAYlvwd1SdSiXBFauXBl1R7OoA5awRDiXd0TXFoFwEpD4hvO+qFV5TgAR9u7o7bff3kT4/PPPz/NeqfkiIALpIiDxTRdJ1SMCCQisWrUq6o5mSUgs4b/+9a8JjtQmERCBYiIg8S2mu62+5ozA6tWro+5oiXDOboMuLAKhISDxDc2tUEOKgcAvv/wSFeFtttnGLOELLrigGLquPoqACMQQkPjGwNBHERABERABEcgGgY2ycRFdQwREQAREQAREYD0Bie96FvokAiIgAiIgAlkhIPHNCmZdRAREQAREQATWE5D4rmehTyIgAgGBhx56yA0cOFAsREAEMkhA4ptBuOWt+plnnnHXXHNNeU/T8SJgBObMmeP+/e9/V5pGjRo13FZbbVXpelSBCIhA6QQkvqWzyfqeTTbZxG2++eZZv25FL3jiiSc65q+qpE5g+fLljsUYSissWbh48eLSdrtIJOIWLVrkfvvttw2O+f33393atWs32B67gfO//vrrpMcdd9xx7uijj449rcTnZG3gQH+NP//8s8R5+iICIrCeQLX1H/Up1wT69u2b6yaU6/oIL3/st9hii3KdV4wHI5g8rCCQjRo1MmaI7Ouvv244fvjhB3f66ae7efPmuTp16pjAPvfcc27XXXe1/aeccopt++OPP1yzZs3cxx9/bFZu7969bT9ekwEDBrgFCxa4zz//3LYxj3jQoEH2mX/++9//umHDhrnWrVtbXZ06dXJ/+9vfovtpI9m3aAv1Xn755dF9fCirDRzzxBNPuEcffdS1bNnSff/992727Nlu9OjR1if2q4iACPwfgeApVSWDBCZMmBAJRDXSvHlzewWLr0dWrFhR4oqfffZZpGvXrva6+eabS+zzXwJ3ou2/9957I8Ef6MgJJ5xg9d133312SK9evWz/+PHjIwcccEAkSOof2XvvvSMvvviir8Legz/+kdtvvz0S/AG28w855JDIjBkzShxT1rWCP6h2rcA1adfwbQ9SJ5aoR1/WE9h3330j77//fnQDDLkHvhxzzDGRQGz918jMmTPt/gQPOLbtu+++i9SvXz8SuJbte5C20thHTwg+TJ8+PfLPf/4zdlPSz/wuA4Hc4JhPP/00csstt2ywPZU2BA8LkcB6j54b5LOOLFmyJPpdH0RABP5HABeRSgYJ8Ec2sEQiiN66desiiGUigQ2WpLM/nv369UvYmsDCjATWTqRjx472RzmwmCJr1qyJ3H///XZ8kDkp0rlzZ9sXWDd2vY8++ijCH/3BgwdH67z66qsjF154YeTXX3+1bYg1DwaBKzJ6TFnX4sBg4YAIwh1YWhHazov2qGxIYNmyZfawEr/nm2++sU3cC4Q4cNOWOCRYFzjy7rvv2jaEj++xhQeu2FKW+PLQxu8F0eXFNefOnRtbhX1OJr5lteH555+33yjH8aDI70NFBERgQwIa882wD6Rp06auXbt2Lvjj6aZOneoOPPBAF4jiBlclwCVZkMvGG2/sttxyS8eY4ciRI10gfK569erOr5Sz2WabuU033dTSFQZ/lF21atVcIMbujjvuMHckFwwsbjdmzBhbbYdjKXvuuacLLGEX/KG07/xT1rU4hrYwRu3bzTvtUdmQAK7mRGzq1q1rBwf/Le1+ValSpcTJ3MN0jZviAj7++OPdTjvt5B555BH31FNPub322qvE9dLx5aijjnKBt8cFFrhjXWPGjr/88st0VK06RKCgCEh8M3w7n376aRO4Y4891j344IMusAgq9Qe1Z8+erkmTJqW2ulu3biX2BZaymzx5sm2bNWuW69Kli6tatWqJYwL3tJsyZUqJbXwp61obnKANCQkgst9++20JxoyVs+Rg4JJ1PDg1btzYDR8+PHo+QVGMB+++++7RbWV94IEoPliLAC4KvwEe2HgwI5qZh8FJkyaVVWW59geucnfOOefYOfQ5sK7dEUcckfbrlKtROlgEQkpAAVcZvDELFy501157rVkCNWvWtCsR6XryySdn7KqvvvpqiUCZsWPHWoAOFySQJ3AzbnBtAm2C8cQNtmtD+gi88MILDquwYcOGrkWLFubBwDOBdUh5+OGH3UknneRuu+02h3AFrl8XuHDNs8BiDKeeeqqbOHGi42GKwCwCm9555x0LuvrHP/5hdWDV4o0gMCoY87c6sG6DYQ4XjMu7wOVs4ojw89skIOvMM8+0eb14aK6//no7h4ArxPnDDz+0+rCSsc7LagMPdQR7USdrGPOwxwPBVVddZe3TPyIgAjEENvREa0u6CBZYe9UAACWqSURBVBA0E0SNRqtjTPSSSy6JxI/V+QMCEYyUNubLMYHbOnLRRRf5wzd4J8CKcbzAtWxjvhzfoUOHSBBtascypnjwwQdHRowYET2XwB0CtMaNGxfdxoeyrsUxjOsxZuwLY8U+IMhv0/t6AkGkso2xJgtAYhyYOAHiAypaCKKiDuIM4gtj+36sOX5fOr9zfR9XkM56VZcIFAoBrWoU8yCSiY9M3QgCXczCYSyMMTDcjT169HBBJLJdEpd08AfRBX+sbGqGn15Cwg1cv8zpZOoH43ZMJWGqCYU6vNXD9/3339+medx9993uk08+sfG9iy++2OFW9gX352mnnWbjw1jC7733nrvyyivNquGYVK/FsdOmTTMrq3379nZeELXtgocLd9ZZZ7FbRQREQAREoBQCEt9SwKRzM4FOiB6iSTBTpgri+9Zbb1nwTlnXYGyQ4C3a5IOvyjon0f7gKdQx1kfAVb169Vx80FCic7RNBERABIqdgMZ8s/AL2HbbbR2vMBXGFXlVtiC2rVq1qmw1Ol8EREAEioqALN8Cud2HH364ua6JnCUaOjazUYF0Ud0QAREQgYIhIPEtmFupjohA5QiQfrJ///6O6OogE5vNGa/MkETlWqOzRaCwCUh8C/v+qnciUG4C99xzj4lwEAlvAhykDa1UXEC5G6ATRKAICEh8i+Amq4siUBECZD3DEg5Sh0ZFmGENFREQgcoTkPhWnqFqEIGCJhArwt4dnU9LXxb0zVHn8paAxDdvb50aLgLZJRAsCmKWMCkrcUXzkghn9x7oaoVDQOJbOPdSPRGBrBAgTSXuaNJQehHWms5ZQa+LFBABiW8B3Ux1RQSyScCLMMlavAiTy1lFBESgbAIS37IZ6QgREIEkBB544AGzhEl/6seEky2PmaQq7RKBoiEg8S2aW62OikBmCQwYMMBEeNmyZVFLWCKcWeaqPX8JSHzz996p5SIQSgJehJcuXRoV4a233jqUbVWjRCBXBCS+uSKv64pAgRN48MEHzRIOllCMuqNr1KhR4L1W90QgNQIS39Q46SgREIEKEnjooYdMhFlJywdmSYQrCFOnFQwBiW/B3Ep1RATCTcCLMGtXexHeZpttwt1otU4EMkRA4pshsKpWBEQgMYGHH37YLOGvv/466o4O25KbiVuurSKQPgIS3/SxVE0iIALlIPDII4+YCC9cuDBqCUuEywFQh+Y1AYlvXt8+NV4E8p/Ao48+6v7zn/+4BQsWREV4u+22y/+OqQcikISAxDcJHO0SARHIHgFEmLSV8+fPj7qja9asmb0G6EoikEUCEt8swtalREAEyibw2GOPmQjPnTvXLGGyZm2//fZln6gjQkXgjz/+cL/99pv79ddf7f333393bPvzzz+tnRtttJGrWrWq23jjjV316tUdy1XyzrZiKBLfYrjL6qMI5CGBxx9/3ER4zpw5UXe0RDicNxJBXbdunUNg165da++rV692ZDsjup33lStXmhAjxhTElhdZ0GrVquXq1atn7yzSgSBvsskm9l6tWjWHUBdakfgW2h1Vf0SgwAh4EZ49e3ZUhHfYYYcC62V+d+fnn3923J/PPvvMff75527q1Klu0aJF7pdffjFrF4s3EolEX/S2SpUq0RfWLi+WqNxpp53cLrvs4nbbbTfXoUMH16xZM1eIGdIkvvn9m1frRaBoCAwcONAs4VmzZkXHhLGYVLJPAEsXwZ00aZKbOHGimzJligXMrVixwrHe808//WRWLqJbnoIAYw2ThIU54ES/N2zY0O26666uY8eOrn379ibEhWAJS3zL88vQsSIgAjkn8MQTT5gIz5w5M2oJS4Szc1vWrFnjvv32W7NuEd5p06a5L7/80qxcxDgTBasXa7hFixauTZs2JsBYxXXq1HGbbrppJi6ZlTolvlnBrIuIgAikm4AX4RkzZkRFuHbt2um+jOoLCGDpkh6UB54JEya4t99+294Z18WdXNHC+C7WLdbuvHnzbNyYurCACb5iDJmxZK6Bm5rj99xzT9etWzd7b9mypatbt25ejglLfCv6q9F5IiACoSDw5JNPmiU8ffr0qDt6xx13DEXb8r0RiC4BVMuXL3eDBw92L7zwghs/fnxUJCvSP4QVixXBZTx3jz32MAG999573Q8//GBCSxBWgwYNHOKOG3vVqlUWMY0QUwjC6tSpkzv22GNdnz59HFPSCNDKJ3e0xLcivx6dIwIiEDoCgwYNMhEm2MfnjpYIV+42IXyffPKJu+OOO9wXX3xh4sj0oYoWRBOh7N69uzvssMPMhUzwHBHQ999/vwVs4b7eeeed3THHHGOuZsaTR44c6caOHeuYfuYLljF1tW3b1l1xxRUm4vmUK1zi6++k3kVABAqCgBdhxMKLMOODKuUjgCfhtddec0OGDHF8xvosbwBV7BXr16/v9ttvP3fccceZVYu7mMAqphVh0c4P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gAjkPwGJb/7fQ/VABERABEQgzwhIfPPshqm5IiACIiAC+U9A4pv/91A9EAEREAERyDMCEt88u2FqrgiIgAiIQP4TkPjm/z1UD0RABERABPKMgMQ3z26YmisCIiACIpD/BCS++X8P1QMREAEREIE8IyDxzbMbpuaKgAiIgAjkPwGJb/7fQ/VABERABEQgzwhIfPPshqm5IiACIiAC+U9A4pv/91A9EAEREAERyDMCEt88u2FqrgiIgAjkM4ELL7zQDR06NJ+7kJa2S3zTglGViIAIiEBxE+jZs2dKALbYYgu38cYbp3Rspg9Ktc2ZaEe1TFSqOkVABERABIqLwI8//phSh2+99daUjsvGQam2ORNtkeWbCaqqUwREQARyTGDNmjXu73//u2vTpo3baaedXPfu3d0111zjZsyYEW3ZihUr3DnnnONatGhhLz6zzZdHHnnE7b///m7IkCFu9913t3r69OlT4pjBgwfbMR988IG9czyvp556yldj74MGDYruHzlyZIl9fEnlWhw3b948Rxtq165t7bnooovcypUr2WUllXpSbbOvMyPvERUREAEREIGCI3DqqadGbr/99sgff/wR+f333yPjxo2LBCISGTt2rPWVbXvvvXckEMXIn3/+aS8+s419FN6POOKISJMmTSLffPNNZN26dZH+/ftHLrvsMtvvj/n5558jHTt2jPDuX74OfyDf2ff4449HBg4c6DdH31O51vLlyyP169ePvPjii5HVq1dHli1bFrnxxhsjhxxySLnq8W0pq83RSjPwQZZvRh5pVKkIiIAI5I7AggUL3OjRo90VV1zhNtpoI1etWjW3zz77mDVap04da9ioUaNcp06d3Mknn+yqVKliLz7vueeejn0Uzqtevbp74403XN26dV3VqlXdueee68aPH2/7/TFbbbWV22STTRzv/sW5sYXv7Ntss81iN0c/p3ItrGfa2LdvX7f55pu7HXbYwaz7VatWuc8++8zqSqUe35ay2hxtXAY+lKSTgQuoShEQAREQgewSmD17tgkUohpbTjrppOhX3M9du3aNfvcfunTp4mbOnOkOO+wwv8nVqFEj+rk08YweUMkPya41a9Ys98orr7jXXnutxFUQ36VLl5bYlqyeEgfm6IvEN0fgdVkREAERyBSBmjVrugkTJiStvl69eg4LOb4sWrTI7bjjjvGbQ/G9adOmZnlff/31oWhPZRoht3Nl6OlcERABEQghAYKsvvvuuxLu4WBc1z366KPu7rvvthYTgDVgwAALYPJdIJjpwQcfdD169PCbUn5fu3at++WXX6LHE0m8ZMmS6Pd0fDjuuOOsfVjmseXdd99106ZNi92U0udstLnUhmRgHFlVioAIiIAI5JhAIEaRDh06RALBigTjtJHevXtHrr766sgPP/wQbVkwdhvZddddI/369bMXnz/++OPofo4PxmktmGrx4sW2PRhztcCtm266KXocH55++ulI586dIxdccIEFabVu3ToSiKIdw7n77ruvBXMRvMWLwC62BYJvx6R6rY8++sjOJ1iKfvHeq1evSGCxl6seDk7WZqssg/9Uoe5SlVk7REAEREAE8pYA1u7ChQtdEPHsdt5554T9YB8WL6Vx48YWVJXwwBQ2YklileLSxvWdqeL7FUQ8O1zRBIVVtGSrzfHtk/jGE9F3ERABERABEcgwAY35ZhiwqhcBERABERCBeAIS33gi+i4CIiACIiACGSYg8c0wYFUvAiIgAiIgAvEEJL7xRPRdBERABERABDJMQOKbYcCqXgREQAREQATiCUh844nouwiIgAiIgAhkmIDEN8OAVb0IiIAIiIAIxBOQ+MYT0XcREAEREAERyDABiW+GAat6ERABERABEYgnIPGNJ6LvIiACIiACIpBhAhLfDANW9SIgAiIgAiIQT0DiG09E30VABERABEQgwwQkvhkGrOpFQAREQAREIJ6AxDeeiL6LgAiIgAiIQIYJSHwzDFjVi4AIiIAIiEA8gf8P+OtrlyF0hHwAAAAASUVORK5CYII=" + } + }, + "cell_type": "markdown", + "id": "6406bbbd-420d-4654-9d95-b31d3c91f6a3", + "metadata": { + "tags": [] + }, + "source": [ + "Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n", + "SPDX-License-Identifier: Apache-2.0\n", + "\n", + "# Vector Similarity Algorithms\n", + "\n", + "Vector similarity algorithms work by using vector based representations of data, a.k.a. embeddings to answer questions about the your data's context and its similarity and connection to other data.\n", + "\n", + "For example, a support agent could translate a question that they receive into a vector and use it to search the support knowledge base for articles that are similar to the words in the question (implicit similarity). For the most applicable articles, they could then collect metadata about the author, previous cases, runbooks, and so on so as to provide additional context when answering the question (explicit data).\n", + "\n", + "A Bioinformatics researcher who are interested in re-purposing existing blood pressure drugs for other treatable diseases, want to use vector similarity search over in-house knowledge graphs to find patterns in protein interaction networks.\n", + "\n", + "For another example, a large online book retailer may need to use known pirated material to quickly identify similar media in conjunction with a knowledge graph to identify patterns of deceptive listing behaviours and find malicious sellers.\n", + "\n", + "In both cases, vector search over a knowledge graph increases accuracy and speed when building the solution. It reduces the operational overhead and complexity using the tools available today.\n", + "\n", + "## Supported Algorithms\n", + "\n", + "Neptune Analytics supports the following vector similarity algorithms:\n", + "\n", + "* [Manage an Embedding](#Manage-an-Embedding) - This set of algorithms manages the stored embedding for a node\n", + "* [Distance](#Distance) - This algorithm computes the distance between two vectors based on their embeddings. The distance is the L2 norm of the vectors.\n", + "* [topK](#TopK) - This algorithm finds the topK nearest neighbors of an embedding based either on an embedding or by comparing against a node.\n", + "\n", + "## Creating the Graph\n", + "\n", + "To use this dataset you need to create a graph that has a vector search index with a dimension of 1536. This must be done prior to running the load commands below. \n", + "\n", + "This can be done using a command similar to the one below, which can be run from a client that has the AWS CLI configured and appropriate permissions. Please refer to the [documentation](https://docs.aws.amazon.com/neptune-analytics/latest/userguide/vector-similarity.html) for the details on setting up a vector search enabled graph.\n", + "\n", + "```\n", + "aws neptune-graph create-graph --graph-name 'air-routes-embeddings' --provisioned-memory 128 --allow-from-public --replica-count 0 --vector-search '{\"dimension\": 1536}'\n", + "```\n", + " \n", + "## Loading Data\n", + "The first step in most projects is to load data to use for analysis. For demonstration purposes, we have provided a set of datasets that can be used to demonstrate the features and functionality of Neptune Analytics. \n", + "\n", + "The cell below makes it easy to load a modified version of the `air-routes` data into your graph. The `air-routes` dataset we will be loading in this notebook is supplied as part of the [Practical Gremlin](https://kelvinlawrence.net/book/Gremlin-Graph-Guide.html#air) book.\n", + "\n", + "The `air-route` graph contains several vertex types that are specified using labels. The most common ones being `airport` and `country`. There are also nodes for each of the seven continents (`continent`) and a single `version` vertex that I provided as a way to test which version of the graph you are using.\n", + "\n", + "Routes between airports are modeled as edges. These edges carry the `route` label and include the distance between the two connected airport vertices as a property called `dist`. Connections between countries and airports are modelled using an edge with a `contains` label.\n", + "\n", + "Each `airport` vertex has many properties associated with it giving various details about that airport including its IATA and ICAO codes, its description, the city it is in and its geographic location.\n", + "\n", + "![image.png](attachment:02e14c92-e464-46c9-9dfd-0ebb4a676358.png)\n", + "\n", + "In addition to the properties of the`air-routes` dataset, the modified version used for this notebook also contains a vector embedding of a JSON version of the node properties. This was accomplished using [LangChain](https://python.langchain.com/docs/get_started/introduction) and [Amazon Bedrock's Titan Text Embedding](https://docs.aws.amazon.com/bedrock/latest/userguide/embeddings.html) model, as shown in the code snippet below.\n", + "\n", + "```\n", + "import boto3\n", + "from langchain.embeddings import BedrockEmbeddings\n", + "import pandas as pd\n", + "\n", + "df = pd.read_csv(\"air-routes-latest-nodes.csv\")\n", + "bedrock_client = boto3.client(service_name=\"bedrock-runtime\", region_name=\"\")\n", + "bedrock_embeddings = BedrockEmbeddings(\n", + " model_id=\"amazon.titan-embed-text-v1\", client=bedrock_client\n", + ")\n", + "for i in df.index:\n", + " if df.loc[i][\"~label\"] == \"airport\":\n", + " json = df.loc[i].to_json()\n", + " embedding = bedrock_embeddings.embed_query(json)\n", + " df.at[i, \"embedding:vector\"] = (\n", + " str(embedding).replace(\", \", \";\").replace(\"[\", \"\").replace(\"]\", \"\")\n", + " )\n", + " if i % 25 == 0:\n", + " print(f\"Embedding row {i}\")\n", + "\n", + "\n", + "df.to_csv(\"air-routes-latest-nodes.csv\", index=False)\n", + "```\n", + "\n", + "To load this dataset, run the two cells below. This first cell will setup a few python variables using the configuration parameters of this Neptune Notebook. The second cell will use Neptune Analytics batch load feature to load the data from the provided S3 bucket. \n", + "\n", + "**Note:** You only need to do this once. If you have already loaded the data previously you do not need to load it again." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f603d491-1e89-46a4-95e4-a19ee8186e05", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import graph_notebook as gn\n", + "config = gn.configuration.get_config.get_config()\n", + "\n", + "s3_bucket = f\"s3://aws-neptune-customer-samples-{config.aws_region}/sample-datasets/gremlin/air-routes-with-embeddings/\"\n", + "region = config.aws_region" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "99e19409-67ef-4aaa-a30d-b3af18eb2d75", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%oc \n", + "\n", + "CALL neptune.load({format: \"csv\", \n", + " source: \"${s3_bucket}\", \n", + " region : \"${region}\"})" + ] + }, + { + "cell_type": "markdown", + "id": "91de3353-d031-4e9d-9fa8-a995b3f4b850", + "metadata": {}, + "source": [ + "## Manage an Embedding\n", + "\n", + "In Neptune Analytics, the embeddings for a node are stored as a kind of \"hidden\" property that is not returned using standard openCypher. To manage these embeddings we provide several algorithms to perform standard CRUD operations:\n", + "\n", + "- `neptune.algo.vectors.get`: This will retrieve and return the specified node's embedding\n", + "\n", + "- `neptune.algo.vectors.upsert`: This will update or insert the provided embedding to the specified node\n", + "\n", + "- `neptune.algo.vectors.remove`: This will remove the specified node's embedding\n", + "\n", + "These algorithms can be combined with other openCypher clauses to perform more complex patterns, such as upserting a node with an externally generated embedding at the time of creation.\n", + "\n", + "Using our air routes data, let's show how to return the embedding of both the Seattle and Anchorage airports." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "eb54e10f-7414-451c-831f-f132cf6960a1", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%oc\n", + "\n", + "MATCH (n) \n", + "WHERE n.code in ['SEA', 'ANC']\n", + "CALL neptune.algo.vectors.get(n)\n", + "YIELD node, embedding\n", + "RETURN n.code, embedding" + ] + }, + { + "cell_type": "markdown", + "id": "e689a29b-8437-4498-bc32-97fab7cb1114", + "metadata": {}, + "source": [ + "## Distance\n", + "\n", + "Vector distance is an algorithm that computes the distance between two vectors based on their embeddings. The distance is the L2 norm of the vectors and can represent the similarity or dissimilarity of the entities.\n", + "\n", + "\n", + "Here are some common uses of vector similarity distance algorithms:\n", + "\n", + "- Document/Description similarity/plagiarism detection. Comparing the vector representations of documents to find similar or duplicate content. Algorithms like SBERT may be used to generate a document embedding for comparison.\n", + "\n", + "- Recommender systems. Calculating the similarity between user/item vectors to recommend content the user may like. This includes uses like movie, product, or article recommendations.\n", + "\n", + "- Semantic search. Mapping words/documents to vectors and using similarity measures to return semantically similar search results compared to just text match.\n", + "\n", + "- Deduplication. Identifying duplicates in datasets by comparing vectors and finding entries with high similarity scores. Helps remove redundant data.\n", + "\n", + "- Anomaly detection. Identifying outliers by comparing vector deviations against expected distributions. Used for fraud or anomaly detection in finance, networks, etc.\n", + "\n", + "In general, vector similarity algorithms leverage distance comparisons in the high-dimensional vector space to understand how related or distinguishable data points are from each other. Choosing the appropriate similarity algorithm depends on the use case and data type.\n", + "\n", + "\n", + "Using our air routes data, let's find the similarity distance between the Anchorage (AK) airport and Fairbanks (AK) and Seattle (WA) airports. When looking at the results the smaller the distance the more similar the two nodes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cc4ee438-71b3-4962-9cbc-4341c64dc9bf", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%oc\n", + "\n", + "MATCH (n {code: 'ANC'}) \n", + "MATCH (m) WHERE m.code in ['SEA', 'FAI'] \n", + "CALL neptune.algo.vectors.distance(n, m)\n", + "YIELD distance\n", + "RETURN n.code, m.code, distance" + ] + }, + { + "cell_type": "markdown", + "id": "e32d532e-23bd-4ade-92ef-fe926a97e936", + "metadata": {}, + "source": [ + "As we see from the results the Fairbanks airport is more similar to tha Anchorage airport, which makes sense as they are both located in Alaska and have similar characteristics in their properties." + ] + }, + { + "cell_type": "markdown", + "id": "2a138e97-fc87-4045-b3b1-f8d1d6369aae", + "metadata": { + "tags": [] + }, + "source": [ + "## TopK \n", + "\n", + "TopK is a vector similarity algorithm that finds the topK nearest neighbors of a node based on the distance of their vector embeddings from a comparison embedding. In Neptune Analytics, the comparison embedding can either by provided directly, using the `neptune.algos.vectors.topKByEmbedding()` algorithm or from an input node `neptune.algos.vectors.topKByNode()`\n", + "\n", + "\n", + "Some common uses of vector similarity topK algorithms:\n", + "\n", + "1. Recommender systems - Finding the most similar items to recommend based on a user's interests or purchase history. TopK allows recommending the most relevant items.\n", + "\n", + "2. Document retrieval - Retrieving the most similar documents to a query document from a corpus. This allows finding documents on the same topic.\n", + "\n", + "3. Deduplication - Identifying duplicate or near-duplicate documents in a large collection by finding those with the greatest vector similarity.\n", + "\n", + "4. Semantic search - Finding documents that are semantically similar to a query, even if they don't contain the exact keywords. The vector similarities allow searching by meaning and concepts.\n", + "\n", + "5. Content-based image retrieval - Finding visually similar images in a database to a query image. The vector similarities capture visual features to find images depicting similar content.\n", + "\n", + "6. Fraud/anomaly detection - Identifying anomalous data points that have low vector similarity to normal data points can help detect fraud or outliers.\n", + "\n", + "So in summary, vector similarity topK algorithms are very useful for finding the closest semantic \"neighbors\" to queries in order to improve search, recommendations, retrieval, etc. Computing top similarities allows focusing only on the most relevant.\n", + "\n", + "Using our air routes data, let's find the topK most similar nodes to the Anchorage airport. Let's first start by fetching the embedding for the Anchorage airport and saving that as a Python variable" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2b176b23-8804-4367-a5f4-00df45145e87", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%oc --store-to res --silent\n", + "\n", + "MATCH ( n:airport {code: 'ANC'} ) \n", + "CALL neptune.algo.vectors.get(n) YIELD embedding\n", + "RETURN embedding" + ] + }, + { + "cell_type": "markdown", + "id": "6eaff4b8-ce7e-42df-99e6-be378a7b9a80", + "metadata": {}, + "source": [ + "We can now see that we successfully retrieved the embedding by printing the length of the returned embedding, which is represented a list of floats." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1c9c54fb-7b9b-4edb-9615-cad7d410311a", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "embedding = res['results'][0]['embedding']\n", + "print(len(embedding))" + ] + }, + { + "cell_type": "markdown", + "id": "7d5c2391-7bbe-4bfd-b2fc-eab1bda421ed", + "metadata": {}, + "source": [ + "Now that we have an embedding let's retrieve the topK most similar nodes to this embedding." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "45b69407-ece3-4820-8c04-3b53bbb6adb9", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%oc\n", + "\n", + "CALL neptune.algo.vectors.topKByEmbedding(\n", + " ${embedding}\n", + ")\n", + "YIELD node, score\n", + "RETURN node.code, node.desc, score" + ] + }, + { + "cell_type": "markdown", + "id": "3fc0fb9b-a201-4a37-be4a-a0260dc4cff5", + "metadata": {}, + "source": [ + "As expected the top result returned is the Anchorage airport, which makes sense given that the embedding passed in was that of the Anchorage airport. Looking at the score we also see that value is ~0. When looking at similarity scores the lower the value the closer the more similar the two items are.\n", + "\n", + "In this example we retrieved an embedding and then used that as the input. In most situations you would use the `topKByEmbedding` algorithm when you have an externally provided embedding that you want to compare against, not one that is already in the graph. If you want to compare against an embedding in the graph you would use the `topKByNode` algorithm. With this algorithm we can find input nodes using openCypher and pass that into the algorithm as input. \n", + "\n", + "Using this approach, let's find the topK most similar nodes to the Anchorage airport." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "275300eb-553c-4f42-a1a9-431ab18a672e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%%oc\n", + "\n", + "MATCH ( n:airport {code: 'ANC'} ) \n", + "CALL neptune.algo.vectors.topKByNode(n)\n", + "YIELD node, score\n", + "RETURN node.code, node.desc, score" + ] + }, + { + "cell_type": "markdown", + "id": "57d8ae64-f9a9-4b72-a7ce-7dfdb98919ab", + "metadata": {}, + "source": [ + "Comparing the results we see that we get back the same topK most similar airports." + ] + }, + { + "cell_type": "markdown", + "id": "d4ec376a-48ef-4952-bd46-cd0ffc23206b", + "metadata": { + "tags": [] + }, + "source": [ + "## Next Steps\n", + "In this notebook, we have demonstrated how to use the vector similarity algorithms provided by Neptune Analytics. If you are interested in the other types of algorithms offered please look at the other notebooks available:\n", + "\n", + "* [Path finding algorithms](./02-Path-Finding-Algorithms.ipynb)\n", + "\n", + "* [Centrality algorithms](./03-Centrality-Algorithms.ipynb)\n", + "\n", + "* [Community Detection algorithms](./04-Community-Detection-Algorithms.ipynb)\n", + "\n", + "* [Similarity algorithms](./05-Similarity-Algorithms.ipynb)" + ] + } + ], + "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.10.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/test/unit/notebooks/test_validate_notebooks.py b/test/unit/notebooks/test_validate_notebooks.py index 87117228..acb82050 100644 --- a/test/unit/notebooks/test_validate_notebooks.py +++ b/test/unit/notebooks/test_validate_notebooks.py @@ -52,6 +52,7 @@ def test_no_extra_notebooks(self): f'{NOTEBOOK_BASE_DIR}/02-Neptune-Analytics/02-Graph-Algorithms/03-Centrality-Algorithms.ipynb', f'{NOTEBOOK_BASE_DIR}/02-Neptune-Analytics/02-Graph-Algorithms/04-Community-Detection-Algorithms.ipynb', f'{NOTEBOOK_BASE_DIR}/02-Neptune-Analytics/02-Graph-Algorithms/05-Similarity-Algorithms.ipynb', + f'{NOTEBOOK_BASE_DIR}/02-Neptune-Analytics/02-Graph-Algorithms/06-Vector-Similarity-Algorithms.ipynb', f'{NOTEBOOK_BASE_DIR}/02-Neptune-Analytics/03-Sample-Use-Cases/Overview.ipynb', f'{NOTEBOOK_BASE_DIR}/02-Neptune-Analytics/03-Sample-Use-Cases/01-FinTech/01-Fraud-Ring-Identifcation.ipynb', f'{NOTEBOOK_BASE_DIR}/02-Neptune-Analytics/03-Sample-Use-Cases/02-Investment-Analysis/01-EDGAR-Competitior-Analysis-using-Knowledge-Graph-Graph-Algorithms-and-Vector-Search.ipynb', From a3dae82c4e4cb2daa57b8ea0894f6649522b4ff8 Mon Sep 17 00:00:00 2001 From: Michael Chin Date: Tue, 23 Jan 2024 18:12:32 -0800 Subject: [PATCH 2/3] Update ChangeLog.md --- ChangeLog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 17be8a1e..049f0e6a 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -3,6 +3,8 @@ Starting with v1.31.6, this file will contain a record of major features and updates made in each release of graph-notebook. ## Upcoming +- New Neptune Analytics notebook - Vector Similarity Algorithms ([Link to PR](https://github.com/aws/graph-notebook/pull/555)) + - Path: 02-Neptune-Analytics > 02-Graph-Algorithms > 06-Vector-Similarity-Algorithms - Deprecated Python 3.7 support ([Link to PR](https://github.com/aws/graph-notebook/pull/551)) ## Release 4.0.2 (Dec 14, 2023) From 80246e1383c31b594ad2b4271873de3618a1a649 Mon Sep 17 00:00:00 2001 From: Michael Chin Date: Tue, 23 Jan 2024 18:59:39 -0800 Subject: [PATCH 3/3] Revisions for readability --- .../06-Vector-Similarity-Algorithms.ipynb | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/06-Vector-Similarity-Algorithms.ipynb b/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/06-Vector-Similarity-Algorithms.ipynb index b1acea1d..a4edabd4 100644 --- a/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/06-Vector-Similarity-Algorithms.ipynb +++ b/src/graph_notebook/notebooks/02-Neptune-Analytics/02-Graph-Algorithms/06-Vector-Similarity-Algorithms.ipynb @@ -17,15 +17,15 @@ "\n", "# Vector Similarity Algorithms\n", "\n", - "Vector similarity algorithms work by using vector based representations of data, a.k.a. embeddings to answer questions about the your data's context and its similarity and connection to other data.\n", + "Vector similarity algorithms work by using vector based representations of data, a.k.a. embeddings, to answer questions about the data's context and its similarity and connection to other data.\n", "\n", "For example, a support agent could translate a question that they receive into a vector and use it to search the support knowledge base for articles that are similar to the words in the question (implicit similarity). For the most applicable articles, they could then collect metadata about the author, previous cases, runbooks, and so on so as to provide additional context when answering the question (explicit data).\n", "\n", - "A Bioinformatics researcher who are interested in re-purposing existing blood pressure drugs for other treatable diseases, want to use vector similarity search over in-house knowledge graphs to find patterns in protein interaction networks.\n", + "A Bioinformatics researcher, who is interested in re-purposing existing blood pressure drugs for other treatable diseases, may want to use vector similarity search over in-house knowledge graphs to find patterns in protein interaction networks.\n", "\n", "For another example, a large online book retailer may need to use known pirated material to quickly identify similar media in conjunction with a knowledge graph to identify patterns of deceptive listing behaviours and find malicious sellers.\n", "\n", - "In both cases, vector search over a knowledge graph increases accuracy and speed when building the solution. It reduces the operational overhead and complexity using the tools available today.\n", + "In both cases, vector search over a knowledge graph increases accuracy and speed when building the solution. In comparison to other tools available today, it provides reduced operational overhead and complexity.\n", "\n", "## Supported Algorithms\n", "\n", @@ -37,7 +37,7 @@ "\n", "## Creating the Graph\n", "\n", - "To use this dataset you need to create a graph that has a vector search index with a dimension of 1536. This must be done prior to running the load commands below. \n", + "To use this dataset, you need to create a graph that has a vector search index with a dimension of 1536. This step must be completed prior to running the following load commands. \n", "\n", "This can be done using a command similar to the one below, which can be run from a client that has the AWS CLI configured and appropriate permissions. Please refer to the [documentation](https://docs.aws.amazon.com/neptune-analytics/latest/userguide/vector-similarity.html) for the details on setting up a vector search enabled graph.\n", "\n", @@ -50,15 +50,15 @@ "\n", "The cell below makes it easy to load a modified version of the `air-routes` data into your graph. The `air-routes` dataset we will be loading in this notebook is supplied as part of the [Practical Gremlin](https://kelvinlawrence.net/book/Gremlin-Graph-Guide.html#air) book.\n", "\n", - "The `air-route` graph contains several vertex types that are specified using labels. The most common ones being `airport` and `country`. There are also nodes for each of the seven continents (`continent`) and a single `version` vertex that I provided as a way to test which version of the graph you are using.\n", + "The `air-route` graph contains several vertex types that are specified using labels. The most common ones being `airport` and `country`. There are also nodes for each of the seven continents (`continent`), in addition to a single `version` vertex that I provided as a way to test which version of the graph you are using.\n", "\n", "Routes between airports are modeled as edges. These edges carry the `route` label and include the distance between the two connected airport vertices as a property called `dist`. Connections between countries and airports are modelled using an edge with a `contains` label.\n", "\n", - "Each `airport` vertex has many properties associated with it giving various details about that airport including its IATA and ICAO codes, its description, the city it is in and its geographic location.\n", + "Each `airport` vertex has many properties associated with it giving various details about the airport, including its IATA and ICAO codes, its description, the city it is in, and its geographic location.\n", "\n", "![image.png](attachment:02e14c92-e464-46c9-9dfd-0ebb4a676358.png)\n", "\n", - "In addition to the properties of the`air-routes` dataset, the modified version used for this notebook also contains a vector embedding of a JSON version of the node properties. This was accomplished using [LangChain](https://python.langchain.com/docs/get_started/introduction) and [Amazon Bedrock's Titan Text Embedding](https://docs.aws.amazon.com/bedrock/latest/userguide/embeddings.html) model, as shown in the code snippet below.\n", + "In addition to the properties of the `air-routes` dataset, the modified version used for this notebook also contains a vector embedding of a JSON version of the node properties. This was accomplished using [LangChain](https://python.langchain.com/docs/get_started/introduction) and [Amazon Bedrock's Titan Text Embedding](https://docs.aws.amazon.com/bedrock/latest/userguide/embeddings.html) model, as shown in the code snippet below.\n", "\n", "```\n", "import boto3\n", @@ -84,9 +84,9 @@ "df.to_csv(\"air-routes-latest-nodes.csv\", index=False)\n", "```\n", "\n", - "To load this dataset, run the two cells below. This first cell will setup a few python variables using the configuration parameters of this Neptune Notebook. The second cell will use Neptune Analytics batch load feature to load the data from the provided S3 bucket. \n", + "To load this dataset, run the two cells below. This first cell will setup a few python variables using the configuration parameters of this Neptune Notebook. The second cell will use Neptune Analytics' batch load feature to load the data from the provided S3 bucket. \n", "\n", - "**Note:** You only need to do this once. If you have already loaded the data previously you do not need to load it again." + "**Note:** You only need to do this once. If you have already loaded the data previously, you do not need to load it again." ] }, { @@ -128,17 +128,17 @@ "source": [ "## Manage an Embedding\n", "\n", - "In Neptune Analytics, the embeddings for a node are stored as a kind of \"hidden\" property that is not returned using standard openCypher. To manage these embeddings we provide several algorithms to perform standard CRUD operations:\n", + "In Neptune Analytics, the embedding for each node is stored as a kind of \"hidden\" property that is not returned using standard openCypher. To manage these embeddings, we provide several algorithms to perform standard CRUD operations:\n", "\n", - "- `neptune.algo.vectors.get`: This will retrieve and return the specified node's embedding\n", + "- `neptune.algo.vectors.get`: This will retrieve and return the specified node's embedding.\n", "\n", - "- `neptune.algo.vectors.upsert`: This will update or insert the provided embedding to the specified node\n", + "- `neptune.algo.vectors.upsert`: This will update or insert the provided embedding to the specified node.\n", "\n", - "- `neptune.algo.vectors.remove`: This will remove the specified node's embedding\n", + "- `neptune.algo.vectors.remove`: This will remove the specified node's embedding.\n", "\n", "These algorithms can be combined with other openCypher clauses to perform more complex patterns, such as upserting a node with an externally generated embedding at the time of creation.\n", "\n", - "Using our air routes data, let's show how to return the embedding of both the Seattle and Anchorage airports." + "Using our air routes data, let's show how to return the embeddings of both the Seattle and Anchorage airports." ] }, { @@ -166,7 +166,7 @@ "source": [ "## Distance\n", "\n", - "Vector distance is an algorithm that computes the distance between two vectors based on their embeddings. The distance is the L2 norm of the vectors and can represent the similarity or dissimilarity of the entities.\n", + "Vector distance is an algorithm that computes the distance between two vectors based on their embeddings. The distance is calculated from the L2 norm of the vectors and can represent the similarity or dissimilarity of the entities.\n", "\n", "\n", "Here are some common uses of vector similarity distance algorithms:\n", @@ -184,7 +184,7 @@ "In general, vector similarity algorithms leverage distance comparisons in the high-dimensional vector space to understand how related or distinguishable data points are from each other. Choosing the appropriate similarity algorithm depends on the use case and data type.\n", "\n", "\n", - "Using our air routes data, let's find the similarity distance between the Anchorage (AK) airport and Fairbanks (AK) and Seattle (WA) airports. When looking at the results the smaller the distance the more similar the two nodes." + "Using our air routes data, let's find the similarity distance between the Anchorage (AK) airport and Fairbanks (AK) and Seattle (WA) airports. When looking at the results, the smaller the distance, the more similar the two nodes are." ] }, { @@ -210,7 +210,7 @@ "id": "e32d532e-23bd-4ade-92ef-fe926a97e936", "metadata": {}, "source": [ - "As we see from the results the Fairbanks airport is more similar to tha Anchorage airport, which makes sense as they are both located in Alaska and have similar characteristics in their properties." + "As we see from the results, the Fairbanks airport is more similar to the Anchorage airport, which makes sense as they are both located in Alaska and have similar characteristics in their properties." ] }, { @@ -222,7 +222,7 @@ "source": [ "## TopK \n", "\n", - "TopK is a vector similarity algorithm that finds the topK nearest neighbors of a node based on the distance of their vector embeddings from a comparison embedding. In Neptune Analytics, the comparison embedding can either by provided directly, using the `neptune.algos.vectors.topKByEmbedding()` algorithm or from an input node `neptune.algos.vectors.topKByNode()`\n", + "TopK is a vector similarity algorithm that finds the topK nearest neighbors of a node based on the distance of their vector embeddings from a comparison embedding. In Neptune Analytics, the comparison embedding can either be provided directly using the `neptune.algos.vectors.topKByEmbedding()` algorithm, or from an input node `neptune.algos.vectors.topKByNode()`\n", "\n", "\n", "Some common uses of vector similarity topK algorithms:\n", @@ -239,7 +239,7 @@ "\n", "6. Fraud/anomaly detection - Identifying anomalous data points that have low vector similarity to normal data points can help detect fraud or outliers.\n", "\n", - "So in summary, vector similarity topK algorithms are very useful for finding the closest semantic \"neighbors\" to queries in order to improve search, recommendations, retrieval, etc. Computing top similarities allows focusing only on the most relevant.\n", + "So in summary, vector similarity topK algorithms are very useful for finding the closest semantic \"neighbors\" to queries in order to improve search, recommendations, retrieval, etc. Computing top similarities allows focusing only on the most relevant data.\n", "\n", "Using our air routes data, let's find the topK most similar nodes to the Anchorage airport. Let's first start by fetching the embedding for the Anchorage airport and saving that as a Python variable" ] @@ -286,7 +286,7 @@ "id": "7d5c2391-7bbe-4bfd-b2fc-eab1bda421ed", "metadata": {}, "source": [ - "Now that we have an embedding let's retrieve the topK most similar nodes to this embedding." + "Now that we have an embedding, let's retrieve the topK most similar nodes to this embedding." ] }, { @@ -312,9 +312,9 @@ "id": "3fc0fb9b-a201-4a37-be4a-a0260dc4cff5", "metadata": {}, "source": [ - "As expected the top result returned is the Anchorage airport, which makes sense given that the embedding passed in was that of the Anchorage airport. Looking at the score we also see that value is ~0. When looking at similarity scores the lower the value the closer the more similar the two items are.\n", + "As expected, the top result returned is the Anchorage airport, which makes sense given that the embedding passed in was that of the Anchorage airport. Looking at the score, we also see that value is ~0. When looking at similarity scores, the lower the value, the more similar the two items are.\n", "\n", - "In this example we retrieved an embedding and then used that as the input. In most situations you would use the `topKByEmbedding` algorithm when you have an externally provided embedding that you want to compare against, not one that is already in the graph. If you want to compare against an embedding in the graph you would use the `topKByNode` algorithm. With this algorithm we can find input nodes using openCypher and pass that into the algorithm as input. \n", + "In this example, we retrieved an embedding and then used that as the input. In most situations, you should use the `topKByEmbedding` algorithm only when you have an externally provided embedding that you want to compare against. If you want to compare against an embedding inside the graph, you should instead use the `topKByNode` algorithm. With this algorithm, we can find input nodes using openCypher, then pass that into the algorithm as input. \n", "\n", "Using this approach, let's find the topK most similar nodes to the Anchorage airport." ] @@ -341,7 +341,7 @@ "id": "57d8ae64-f9a9-4b72-a7ce-7dfdb98919ab", "metadata": {}, "source": [ - "Comparing the results we see that we get back the same topK most similar airports." + "Comparing the results, we see that we get back the same topK most similar airports." ] }, { @@ -352,7 +352,7 @@ }, "source": [ "## Next Steps\n", - "In this notebook, we have demonstrated how to use the vector similarity algorithms provided by Neptune Analytics. If you are interested in the other types of algorithms offered please look at the other notebooks available:\n", + "In this notebook, we have demonstrated how to use the vector similarity algorithms provided by Neptune Analytics. If you are interested in the other types of algorithms offered, please look at the other notebooks available:\n", "\n", "* [Path finding algorithms](./02-Path-Finding-Algorithms.ipynb)\n", "\n",