From cf0ac4b1611f33961f6ddd66e2f9bbe17b439b32 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Sat, 25 Jun 2022 13:01:44 +0200 Subject: [PATCH] Integrate MongoDB --- .vscode/settings.json | 1 + examples/simple/data.ipynb | 80 +- examples/simple/deploy.ipynb | 151 +-- examples/simple/diagrams/ss-confusion.png | Bin 0 -> 164208 bytes examples/simple/diagrams/ss-distribution.png | Bin 0 -> 65683 bytes examples/simple/mongo.ini | 5 +- examples/simple/train.ipynb | 928 +++++++++--------- great_ai/example_secrets.ini | 1 - great_ai/open_s3.md | 1 - great_ai/setup.cfg | 1 - great_ai/src/great_ai/__main__.py | 2 +- great_ai/src/great_ai/great_ai/__init__.py | 4 +- great_ai/src/great_ai/great_ai/constants.py | 18 +- great_ai/src/great_ai/great_ai/context.py | 93 +- .../src/great_ai/great_ai/deploy/great_ai.py | 5 +- .../routes/bootstrap_trace_endpoints.py | 4 + .../routes/dashboard/create_dash_app.py | 203 ++-- .../routes/dashboard/get_traces_table.py | 5 +- .../great_ai/great_ai/persistence/__init__.py | 2 +- .../great_ai/persistence/mongodb_driver.py | 134 ++- .../persistence/parallel_tinydb_driver.py | 21 +- .../persistence/tracing_database_driver.py | 33 +- .../src/great_ai/great_ai/tracing/__init__.py | 1 + .../great_ai/tracing/add_ground_truth.py | 2 +- .../great_ai/tracing/delete_ground_truth.py | 22 + .../great_ai/tracing/query_ground_truth.py | 8 +- great_ai/src/great_ai/great_ai/views/query.py | 9 +- .../src/great_ai/great_ai/views/sort_by.py | 4 +- great_ai/src/great_ai/great_ai/views/trace.py | 39 +- .../large_file/large_file/large_file_mongo.py | 16 +- 30 files changed, 1024 insertions(+), 769 deletions(-) create mode 100644 examples/simple/diagrams/ss-confusion.png create mode 100644 examples/simple/diagrams/ss-distribution.png create mode 100644 great_ai/src/great_ai/great_ai/tracing/delete_ground_truth.py diff --git a/.vscode/settings.json b/.vscode/settings.json index 98e49e4..ee745e6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,7 @@ "iloc", "initialisation", "initialised", + "initialising", "inplace", "ipynb", "joblib", diff --git a/examples/simple/data.ipynb b/examples/simple/data.ipynb index 51419cd..8c55da6 100644 --- a/examples/simple/data.ipynb +++ b/examples/simple/data.ipynb @@ -11,15 +11,6 @@ "> The blue boxes show the steps implemented in this notebook." ] }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "MAX_CHUNK_COUNT = 4" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -31,6 +22,15 @@ "In this case, we download the semantic scholar dataset from a public S3 bucket." ] }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "MAX_CHUNK_COUNT = 1" + ] + }, { "cell_type": "code", "execution_count": 2, @@ -39,7 +39,7 @@ { "data": { "text/plain": [ - "'Processing 4 out of the 6002 available chunks'" + "'Processing 1 out of the 6002 available chunks'" ] }, "execution_count": 2, @@ -49,6 +49,7 @@ ], "source": [ "import urllib.request\n", + "from random import shuffle\n", "\n", "manifest = (\n", " urllib.request.urlopen(\n", @@ -58,7 +59,9 @@ " .decode()\n", ") # a list of available chunks separated by '\\n' characters\n", "\n", - "chunks = manifest.split()[:MAX_CHUNK_COUNT]\n", + "lines = manifest.split()\n", + "shuffle(lines)\n", + "chunks = lines[:MAX_CHUNK_COUNT]\n", "\n", "f\"Processing {len(chunks)} out of the {len(manifest.split())} available chunks\"" ] @@ -83,23 +86,11 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[38;5;226m2022-06-19 14:59:12,562 | WARNING | Limiting concurrency to 4 because there are only 4 chunks\u001b[0m\n", - "\u001b[38;5;39m2022-06-19 14:59:12,563 | INFO | Starting parallel map (concurrency: 4, chunk size: 1)\u001b[0m\n" + "\u001b[38;5;226m2022-06-25 11:20:01,955 | WARNING | Limiting concurrency to 1 because there are only 1 chunks\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:20:01,956 | INFO | Starting parallel map (concurrency: 1, chunk size: 1)\u001b[0m\n", + "\u001b[38;5;226m2022-06-25 11:20:01,956 | WARNING | Running in series, there is no reason for parallelism\u001b[0m\n", + "100%|██████████| 1/1 [04:02<00:00, 242.61s/it]\n" ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ff8fc113515944cfa75127f4aba3d491", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 0/4 [00:00 You can install MongoDB from [here](https://www.mongodb.com/docs/manual/installation) or [use it as a service](https://www.mongodb.com/cloud/atlas/register)\n" ] }, { @@ -181,9 +169,17 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[38;5;226m2022-06-19 15:03:30,300 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n", - "\u001b[38;5;226m2022-06-19 15:03:30,301 | WARNING | The selected persistence driver (ParallelTinyDbDriver) is not recommended for production\u001b[0m\n", - "\u001b[38;5;39m2022-06-19 15:03:30,301 | INFO | Options: configured ✅\u001b[0m\n" + "\u001b[38;5;226m2022-06-25 11:24:04,668 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:24:04,669 | INFO | Found credentials file (/data/projects/great-ai/examples/simple/mongo.ini), initialising MongodbDriver\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:24:04,670 | INFO | Found credentials file (/data/projects/great-ai/examples/simple/mongo.ini), initialising LargeFileMongo\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:24:04,671 | INFO | Settings: configured ✅\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:24:04,672 | INFO | 🔩 tracing_database: MongodbDriver\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:24:04,672 | INFO | 🔩 large_file_implementation: LargeFileMongo\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:24:04,673 | INFO | 🔩 is_production: False\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:24:04,673 | INFO | 🔩 should_log_exception_stack: True\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:24:04,674 | INFO | 🔩 prediction_cache_size: 512\u001b[0m\n", + "\u001b[38;5;226m2022-06-25 11:24:04,674 | WARNING | You still need to check whether you follow all best practices before trusting your deployment.\u001b[0m\n", + "\u001b[38;5;226m2022-06-25 11:24:04,674 | WARNING | > Find out more at https://se-ml.github.io/practices/\u001b[0m\n" ] } ], diff --git a/examples/simple/deploy.ipynb b/examples/simple/deploy.ipynb index b946ae5..387ea54 100644 --- a/examples/simple/deploy.ipynb +++ b/examples/simple/deploy.ipynb @@ -23,17 +23,25 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[38;5;226m2022-06-19 15:16:23,856 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n", - "\u001b[38;5;226m2022-06-19 15:16:23,857 | WARNING | The selected tracing database (ParallelTinyDbDriver) is not recommended for production\u001b[0m\n", - "\u001b[38;5;39m2022-06-19 15:16:23,858 | INFO | Options: configured ✅\u001b[0m\n", - "\u001b[38;5;39m2022-06-19 15:16:23,858 | INFO | Fetching cached versions of small-domain-prediction\u001b[0m\n", - "\u001b[38;5;39m2022-06-19 15:16:23,859 | INFO | Latest version of small-domain-prediction is 12 (from versions: 9, 10, 11, 12)\u001b[0m\n", - "\u001b[38;5;39m2022-06-19 15:16:23,860 | INFO | File small-domain-prediction-12 found in cache\u001b[0m\n" + "\u001b[38;5;226m2022-06-24 22:38:15,518 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n", + "\u001b[38;5;39m2022-06-24 22:38:15,518 | INFO | Found credentials file (/data/projects/great-ai/examples/simple/mongo.ini), initialising MongodbDriver\u001b[0m\n", + "\u001b[38;5;39m2022-06-24 22:38:15,519 | INFO | Found credentials file (/data/projects/great-ai/examples/simple/mongo.ini), initialising LargeFileMongo\u001b[0m\n", + "\u001b[38;5;39m2022-06-24 22:38:15,520 | INFO | Settings: configured ✅\u001b[0m\n", + "\u001b[38;5;39m2022-06-24 22:38:15,520 | INFO | 🔩 tracing_database: MongodbDriver\u001b[0m\n", + "\u001b[38;5;39m2022-06-24 22:38:15,520 | INFO | 🔩 large_file_implementation: LargeFileMongo\u001b[0m\n", + "\u001b[38;5;39m2022-06-24 22:38:15,521 | INFO | 🔩 is_production: False\u001b[0m\n", + "\u001b[38;5;39m2022-06-24 22:38:15,521 | INFO | 🔩 should_log_exception_stack: True\u001b[0m\n", + "\u001b[38;5;39m2022-06-24 22:38:15,521 | INFO | 🔩 prediction_cache_size: 512\u001b[0m\n", + "\u001b[38;5;226m2022-06-24 22:38:15,521 | WARNING | You still need to check whether you follow all best practices before trusting your deployment.\u001b[0m\n", + "\u001b[38;5;226m2022-06-24 22:38:15,522 | WARNING | > Find out more at https://se-ml.github.io/practices/\u001b[0m\n", + "\u001b[38;5;39m2022-06-24 22:38:15,531 | INFO | Latest version of small-domain-prediction is 0 (from versions: 0)\u001b[0m\n", + "\u001b[38;5;39m2022-06-24 22:38:15,532 | INFO | File small-domain-prediction-0 found in cache\u001b[0m\n" ] } ], "source": [ "import re\n", + "import numpy as np\n", "from sklearn.pipeline import Pipeline\n", "from great_ai.utilities import clean\n", "from great_ai import (\n", @@ -47,15 +55,14 @@ "\n", "@GreatAI.deploy\n", "@use_model(\"small-domain-prediction\", version=\"latest\")\n", - "@parameter(\"explanation_length\", disable_logging=True)\n", + "@parameter(\"target_confidence\", validator=lambda c: 0 <= c <= 100)\n", "def predict_domain(\n", - " text: str, model: Pipeline, target_confidence: int = 50, explanation_length: int = 5\n", + " text: str, model: Pipeline, target_confidence: int = 50\n", ") -> MultiLabelClassificationOutput:\n", " \"\"\"\n", " Predict the scientific domain of the input text.\n", " Return labels until their sum likelihood is larger than `target_confidence`.\n", " \"\"\"\n", - " assert 0 <= target_confidence <= 100, \"invalid argument\"\n", "\n", " preprocessed = re.sub(r\"[^a-zA-Z\\s]\", \"\", clean(text, convert_to_ascii=True))\n", " features = model.named_steps[\"vectorizer\"].transform([preprocessed])\n", @@ -66,33 +73,42 @@ " results = MultiLabelClassificationOutput()\n", " for class_index, probability in best_classes:\n", " results.labels.append(\n", - " ClassificationOutput(\n", - " label=model.named_steps[\"classifier\"].classes_[class_index],\n", - " confidence=round(probability * 100),\n", - " explanation=[\n", - " word\n", - " for _, word in sorted(\n", - " (\n", - " (weight, word)\n", - " for weight, word, count in zip(\n", - " model.named_steps[\"classifier\"].feature_log_prob_[\n", - " class_index\n", - " ],\n", - " model.named_steps[\"vectorizer\"].get_feature_names_out(),\n", - " features.A[0],\n", - " )\n", - " if count > 0\n", - " ),\n", - " reverse=True,\n", - " )\n", - " ][:explanation_length],\n", + " get_label(\n", + " model=model,\n", + " features=features,\n", + " class_index=class_index,\n", + " probability=probability,\n", " )\n", " )\n", "\n", " if sum(r.confidence for r in results.labels) >= target_confidence:\n", " break\n", "\n", - " return results" + " return results\n", + "\n", + "\n", + "def get_label(\n", + " model: Pipeline, features: np.ndarray, class_index: int, probability: float\n", + ") -> ClassificationOutput:\n", + " return ClassificationOutput(\n", + " label=model.named_steps[\"classifier\"].classes_[class_index],\n", + " confidence=round(probability * 100),\n", + " explanation=[\n", + " word\n", + " for _, word in sorted(\n", + " (\n", + " (weight, word)\n", + " for weight, word, count in zip(\n", + " model.named_steps[\"classifier\"].feature_log_prob_[class_index],\n", + " model.named_steps[\"vectorizer\"].get_feature_names_out(),\n", + " features.A[0],\n", + " )\n", + " if count > 0\n", + " ),\n", + " reverse=True,\n", + " )\n", + " ][:5],\n", + " )" ] }, { @@ -104,72 +120,59 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [ { - "name": "stderr", + "name": "stdout", "output_type": "stream", "text": [ - "\u001b[38;5;226m2022-06-19 15:16:29,300 | WARNING | Limiting concurrency to 10 because there are only 10 chunks\u001b[0m\n", - "\u001b[38;5;39m2022-06-19 15:16:29,301 | INFO | Starting parallel map (concurrency: 10, chunk size: 1)\u001b[0m\n" + "{'filter': {'$and': [{'tags': 'test'}, {'feedback': {'$ne': None}}]}, 'sort': []}\n" ] }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "34e54eabd5f945b8aa2809907964eec8", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - " 0%| | 0/10 [00:00" ] @@ -183,7 +186,7 @@ " from great_ai import query_ground_truth\n", " from sklearn import metrics\n", "\n", - " data = query_ground_truth(\"test\", return_max_count=10)\n", + " data = query_ground_truth(\"test\")\n", "\n", " X = [d.input for d in data]\n", " y_actual = [d.feedback for d in data]\n", @@ -193,7 +196,7 @@ "\n", " import matplotlib.pyplot as plt\n", "\n", - " # Configure matplotlib to have nice, high-resolution charts.\n", + " # Configure matplotlib to have nice, high-resolution charts\n", "\n", " %matplotlib inline\n", "\n", diff --git a/examples/simple/diagrams/ss-confusion.png b/examples/simple/diagrams/ss-confusion.png new file mode 100644 index 0000000000000000000000000000000000000000..46101984a38eff730eed600e6cabe6383db03874 GIT binary patch literal 164208 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 literal 0 HcmV?d00001 diff --git a/examples/simple/diagrams/ss-distribution.png b/examples/simple/diagrams/ss-distribution.png new file mode 100644 index 0000000000000000000000000000000000000000..721684d49ff6986051be3c20b433e1f3bfde3fea GIT binary patch literal 65683 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 P;7?XkNuv0zanSz<&OTcy literal 0 HcmV?d00001 diff --git a/examples/simple/mongo.ini b/examples/simple/mongo.ini index 3f5dfb1..8151869 100644 --- a/examples/simple/mongo.ini +++ b/examples/simple/mongo.ini @@ -1,3 +1,2 @@ -[DEFAULT] -connection_string=mongodb://localhost:27017/ -database=large_file_tests +mongo_connection_string=mongodb://localhost:27017/ # change this +mongo_database=great_ai_db2 # this will be automatically created diff --git a/examples/simple/train.ipynb b/examples/simple/train.ipynb index e558aa6..4f951f7 100644 --- a/examples/simple/train.ipynb +++ b/examples/simple/train.ipynb @@ -16,15 +16,6 @@ "In this part, we hyperparameter-optimise and train a simple, Naive Bayes classifier which we then export for deployment using `great_ai.save_model`." ] }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "MODEL_KEY = \"small-domain-prediction\"" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -34,16 +25,31 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "\u001b[38;5;226m2022-06-19 15:08:22,338 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n", - "\u001b[38;5;226m2022-06-19 15:08:22,338 | WARNING | The selected persistence driver (ParallelTinyDbDriver) is not recommended for production\u001b[0m\n", - "\u001b[38;5;39m2022-06-19 15:08:22,339 | INFO | Options: configured ✅\u001b[0m\n" + "\u001b[38;5;226m2022-06-25 11:25:08,430 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:08,431 | INFO | Found credentials file (/data/projects/great-ai/examples/simple/mongo.ini), initialising MongodbDriver\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:08,432 | INFO | Found credentials file (/data/projects/great-ai/examples/simple/mongo.ini), initialising LargeFileMongo\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:08,432 | INFO | Settings: configured ✅\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:08,433 | INFO | 🔩 tracing_database: MongodbDriver\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:08,433 | INFO | 🔩 large_file_implementation: LargeFileMongo\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:08,434 | INFO | 🔩 is_production: False\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:08,434 | INFO | 🔩 should_log_exception_stack: True\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:08,434 | INFO | 🔩 prediction_cache_size: 512\u001b[0m\n", + "\u001b[38;5;226m2022-06-25 11:25:08,435 | WARNING | You still need to check whether you follow all best practices before trusting your deployment.\u001b[0m\n", + "\u001b[38;5;226m2022-06-25 11:25:08,435 | WARNING | > Find out more at https://se-ml.github.io/practices/\u001b[0m\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'filter': {'$and': [{'tags': 'train'}, {'feedback': {'$ne': None}}]}, 'sort': []}\n" ] } ], @@ -57,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -69,7 +75,7 @@ "data": [ { "alignmentgroup": "True", - "hovertemplate": "x=%{x}
y=%{y}", + "hovertemplate": "domain=%{x}
count=%{y}", "legendgroup": "", "marker": { "color": "#636efa", @@ -93,38 +99,38 @@ "Physics", "Psychology", "Mathematics", - "Business", "Political Science", + "Business", "Sociology", "Economics", "Geography", - "Environmental Science", "Geology", - "Art", + "Environmental Science", "History", + "Art", "Philosophy" ], "xaxis": "x", "y": [ - 16996, - 5836, - 5354, - 5135, - 4200, - 3663, - 2643, - 2463, - 2386, - 1362, - 1304, - 1297, - 1087, - 1060, - 968, - 943, - 515, - 497, - 332 + 4409, + 1422, + 1369, + 1352, + 1026, + 887, + 638, + 619, + 582, + 340, + 333, + 303, + 256, + 254, + 229, + 217, + 113, + 112, + 65 ], "yaxis": "y" } @@ -962,7 +968,7 @@ 1 ], "title": { - "text": "x" + "text": "domain" } }, "yaxis": { @@ -972,7 +978,7 @@ 1 ], "title": { - "text": "y" + "text": "count" } } } @@ -988,7 +994,7 @@ "import plotly.express as px\n", "\n", "df = pd.DataFrame(Counter(y).most_common(), columns=[\"domain\", \"count\"])\n", - "px.bar(x=df[\"domain\"], y=df[\"count\"], width=1200, height=400).show()" + "px.bar(df, \"domain\", \"count\", width=1200, height=400).show()" ] }, { @@ -1000,7 +1006,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -1020,7 +1026,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -1071,434 +1077,434 @@ " \n", " \n", " 7\n", - " 7.796924\n", - " 0.321314\n", - " 3.756043\n", - " 0.027860\n", + " 1.986588\n", + " 0.050896\n", + " 1.090251\n", + " 0.135508\n", " 0.5\n", " False\n", " 0.05\n", " 20\n", " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.508013\n", - " 0.509086\n", - " 0.514455\n", - " 0.510518\n", - " 0.002818\n", + " 0.459165\n", + " 0.473024\n", + " 0.475462\n", + " 0.469217\n", + " 0.007177\n", " 1\n", " \n", " \n", " 10\n", - " 8.055664\n", - " 0.206984\n", - " 3.748517\n", - " 0.088012\n", + " 2.070333\n", + " 0.038396\n", + " 0.976315\n", + " 0.033742\n", " 0.5\n", " False\n", " 0.1\n", " 20\n", " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.503729\n", - " 0.506417\n", - " 0.511895\n", - " 0.507347\n", - " 0.003398\n", + " 0.457524\n", + " 0.463575\n", + " 0.458007\n", + " 0.459702\n", + " 0.002745\n", " 2\n", " \n", " \n", - " 11\n", - " 7.748360\n", - " 0.484361\n", - " 3.863216\n", - " 0.072048\n", - " 0.5\n", - " False\n", - " 0.1\n", - " 100\n", - " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.502211\n", - " 0.498949\n", - " 0.503744\n", - " 0.501635\n", - " 0.002000\n", - " 3\n", - " \n", - " \n", - " 8\n", - " 7.400649\n", - " 0.087320\n", - " 3.658442\n", - " 0.011735\n", - " 0.5\n", - " False\n", - " 0.05\n", - " 100\n", - " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.501432\n", - " 0.493970\n", - " 0.501386\n", - " 0.498929\n", - " 0.003507\n", - " 4\n", - " \n", - " \n", " 19\n", - " 8.147969\n", - " 0.401980\n", - " 3.977119\n", - " 0.284028\n", + " 2.049166\n", + " 0.193113\n", + " 1.064576\n", + " 0.087034\n", " 1\n", " False\n", " 0.05\n", " 20\n", " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.486410\n", - " 0.491891\n", - " 0.492515\n", - " 0.490272\n", - " 0.002743\n", + " 0.441657\n", + " 0.452933\n", + " 0.451286\n", + " 0.448625\n", + " 0.004973\n", + " 3\n", + " \n", + " \n", + " 6\n", + " 2.288145\n", + " 0.131338\n", + " 1.133445\n", + " 0.099583\n", + " 0.5\n", + " False\n", + " 0.05\n", + " 5\n", + " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", + " 0.436976\n", + " 0.449693\n", + " 0.437911\n", + " 0.441527\n", + " 0.005787\n", + " 4\n", + " \n", + " \n", + " 22\n", + " 1.872234\n", + " 0.072997\n", + " 0.748070\n", + " 0.085882\n", + " 1\n", + " False\n", + " 0.1\n", + " 20\n", + " {'classifier__alpha': 1, 'classifier__fit_prio...\n", + " 0.432322\n", + " 0.438805\n", + " 0.428209\n", + " 0.433112\n", + " 0.004362\n", " 5\n", " \n", " \n", - " 20\n", - " 7.472414\n", - " 0.130320\n", - " 3.771136\n", - " 0.146406\n", - " 1\n", + " 11\n", + " 2.067691\n", + " 0.126923\n", + " 0.910947\n", + " 0.078748\n", + " 0.5\n", " False\n", - " 0.05\n", + " 0.1\n", " 100\n", - " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.486868\n", - " 0.489142\n", - " 0.492665\n", - " 0.489558\n", - " 0.002385\n", + " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", + " 0.426436\n", + " 0.429182\n", + " 0.437410\n", + " 0.431009\n", + " 0.004662\n", " 6\n", " \n", " \n", " 23\n", - " 7.395585\n", - " 0.326162\n", - " 2.332031\n", - " 0.254146\n", + " 1.847330\n", + " 0.147504\n", + " 0.495354\n", + " 0.018589\n", " 1\n", " False\n", " 0.1\n", " 100\n", " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.489489\n", - " 0.489987\n", - " 0.488543\n", - " 0.489340\n", - " 0.000599\n", + " 0.422130\n", + " 0.430875\n", + " 0.430829\n", + " 0.427945\n", + " 0.004112\n", " 7\n", " \n", " \n", - " 22\n", - " 7.452060\n", - " 0.162072\n", - " 2.937473\n", - " 0.116443\n", - " 1\n", + " 9\n", + " 2.071489\n", + " 0.256086\n", + " 1.055936\n", + " 0.037198\n", + " 0.5\n", " False\n", " 0.1\n", - " 20\n", - " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.478748\n", - " 0.485174\n", - " 0.484685\n", - " 0.482869\n", - " 0.002921\n", + " 5\n", + " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", + " 0.416746\n", + " 0.425938\n", + " 0.417381\n", + " 0.420022\n", + " 0.004192\n", " 8\n", " \n", " \n", - " 6\n", - " 7.836380\n", - " 0.374669\n", - " 4.007429\n", - " 0.251199\n", - " 0.5\n", + " 20\n", + " 1.776546\n", + " 0.064677\n", + " 0.888485\n", + " 0.093302\n", + " 1\n", " False\n", " 0.05\n", - " 5\n", - " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.472793\n", - " 0.476460\n", - " 0.479583\n", - " 0.476279\n", - " 0.002775\n", + " 100\n", + " {'classifier__alpha': 1, 'classifier__fit_prio...\n", + " 0.413441\n", + " 0.417122\n", + " 0.427196\n", + " 0.419253\n", + " 0.005814\n", " 9\n", " \n", " \n", - " 2\n", - " 7.839444\n", - " 0.174964\n", - " 3.914105\n", - " 0.379735\n", + " 8\n", + " 2.015992\n", + " 0.062583\n", + " 0.974434\n", + " 0.082582\n", " 0.5\n", - " True\n", + " False\n", " 0.05\n", " 100\n", " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.469224\n", - " 0.472179\n", - " 0.476758\n", - " 0.472720\n", - " 0.003100\n", + " 0.412522\n", + " 0.410409\n", + " 0.425047\n", + " 0.415993\n", + " 0.006460\n", " 10\n", " \n", " \n", - " 5\n", - " 7.948454\n", - " 0.411364\n", - " 3.968444\n", - " 0.090030\n", - " 0.5\n", - " True\n", - " 0.1\n", - " 100\n", - " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.469310\n", - " 0.471916\n", - " 0.476900\n", - " 0.472708\n", - " 0.003149\n", + " 18\n", + " 2.032050\n", + " 0.104313\n", + " 0.969210\n", + " 0.070997\n", + " 1\n", + " False\n", + " 0.05\n", + " 5\n", + " {'classifier__alpha': 1, 'classifier__fit_prio...\n", + " 0.392393\n", + " 0.396143\n", + " 0.386439\n", + " 0.391659\n", + " 0.003996\n", " 11\n", " \n", " \n", - " 9\n", - " 7.373592\n", - " 0.143028\n", - " 3.777698\n", - " 0.008990\n", + " 1\n", + " 2.307611\n", + " 0.142902\n", + " 1.102178\n", + " 0.078755\n", " 0.5\n", - " False\n", - " 0.1\n", - " 5\n", + " True\n", + " 0.05\n", + " 20\n", " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.463156\n", - " 0.466783\n", - " 0.463460\n", - " 0.464466\n", - " 0.001643\n", + " 0.385834\n", + " 0.392225\n", + " 0.366549\n", + " 0.381536\n", + " 0.010914\n", " 12\n", " \n", " \n", - " 1\n", - " 7.406839\n", - " 0.041973\n", - " 3.838634\n", - " 0.116634\n", + " 4\n", + " 1.876958\n", + " 0.050648\n", + " 1.031975\n", + " 0.029341\n", " 0.5\n", " True\n", - " 0.05\n", + " 0.1\n", " 20\n", " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.462315\n", - " 0.462975\n", - " 0.463192\n", - " 0.462827\n", - " 0.000373\n", + " 0.377309\n", + " 0.384224\n", + " 0.366632\n", + " 0.376055\n", + " 0.007236\n", " 13\n", " \n", " \n", - " 4\n", - " 7.481533\n", - " 0.224344\n", - " 3.789821\n", - " 0.098098\n", - " 0.5\n", - " True\n", + " 21\n", + " 1.897479\n", + " 0.094903\n", + " 0.740516\n", + " 0.143821\n", + " 1\n", + " False\n", " 0.1\n", - " 20\n", - " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.457504\n", - " 0.460853\n", - " 0.459941\n", - " 0.459433\n", - " 0.001414\n", + " 5\n", + " {'classifier__alpha': 1, 'classifier__fit_prio...\n", + " 0.360551\n", + " 0.366311\n", + " 0.350439\n", + " 0.359101\n", + " 0.006561\n", " 14\n", " \n", " \n", - " 14\n", - " 7.749725\n", - " 0.468469\n", - " 4.139534\n", - " 0.140173\n", - " 1\n", + " 5\n", + " 1.824982\n", + " 0.038113\n", + " 0.960814\n", + " 0.041330\n", + " 0.5\n", " True\n", - " 0.05\n", + " 0.1\n", " 100\n", - " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.442930\n", - " 0.443183\n", - " 0.449577\n", - " 0.445230\n", - " 0.003076\n", + " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", + " 0.347831\n", + " 0.350708\n", + " 0.349963\n", + " 0.349501\n", + " 0.001219\n", " 15\n", " \n", " \n", + " 2\n", + " 2.151446\n", + " 0.120440\n", + " 0.887620\n", + " 0.037900\n", + " 0.5\n", + " True\n", + " 0.05\n", + " 100\n", + " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", + " 0.335093\n", + " 0.340020\n", + " 0.341502\n", + " 0.338872\n", + " 0.002739\n", + " 16\n", + " \n", + " \n", " 17\n", - " 7.703846\n", - " 0.357508\n", - " 4.034154\n", - " 0.265509\n", + " 2.004961\n", + " 0.196640\n", + " 0.953482\n", + " 0.113914\n", " 1\n", " True\n", " 0.1\n", " 100\n", " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.439058\n", - " 0.443429\n", - " 0.449336\n", - " 0.443941\n", - " 0.004212\n", - " 16\n", - " \n", - " \n", - " 18\n", - " 7.553105\n", - " 0.056077\n", - " 4.094978\n", - " 0.198813\n", - " 1\n", - " False\n", - " 0.05\n", - " 5\n", - " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.421488\n", - " 0.427530\n", - " 0.422329\n", - " 0.423782\n", - " 0.002672\n", + " 0.300093\n", + " 0.306020\n", + " 0.305047\n", + " 0.303720\n", + " 0.002595\n", " 17\n", " \n", " \n", " 13\n", - " 7.438030\n", - " 0.237545\n", - " 3.915824\n", - " 0.029823\n", + " 1.890709\n", + " 0.056234\n", + " 1.006219\n", + " 0.042628\n", " 1\n", " True\n", " 0.05\n", " 20\n", " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.404152\n", - " 0.411373\n", - " 0.406858\n", - " 0.407461\n", - " 0.002979\n", + " 0.297119\n", + " 0.302061\n", + " 0.298975\n", + " 0.299385\n", + " 0.002038\n", " 18\n", " \n", " \n", - " 21\n", - " 8.057189\n", - " 0.435052\n", - " 3.305222\n", - " 0.348995\n", + " 14\n", + " 2.022432\n", + " 0.201745\n", + " 0.931837\n", + " 0.047467\n", " 1\n", - " False\n", - " 0.1\n", - " 5\n", + " True\n", + " 0.05\n", + " 100\n", " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.397182\n", - " 0.405247\n", - " 0.401505\n", - " 0.401311\n", - " 0.003295\n", + " 0.300746\n", + " 0.291492\n", + " 0.297456\n", + " 0.296565\n", + " 0.003830\n", " 19\n", " \n", " \n", - " 16\n", - " 7.710748\n", - " 0.559283\n", - " 4.034421\n", - " 0.073522\n", - " 1\n", - " True\n", - " 0.1\n", - " 20\n", - " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.392046\n", - " 0.397995\n", - " 0.396114\n", - " 0.395385\n", - " 0.002483\n", - " 20\n", - " \n", - " \n", " 0\n", - " 7.614647\n", - " 0.466252\n", - " 3.898220\n", - " 0.098618\n", + " 2.081572\n", + " 0.123875\n", + " 1.058692\n", + " 0.034084\n", " 0.5\n", " True\n", " 0.05\n", " 5\n", " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.385156\n", - " 0.388866\n", - " 0.386509\n", - " 0.386844\n", - " 0.001533\n", + " 0.296667\n", + " 0.294715\n", + " 0.292144\n", + " 0.294509\n", + " 0.001852\n", + " 20\n", + " \n", + " \n", + " 16\n", + " 1.961700\n", + " 0.108977\n", + " 0.964816\n", + " 0.089735\n", + " 1\n", + " True\n", + " 0.1\n", + " 20\n", + " {'classifier__alpha': 1, 'classifier__fit_prio...\n", + " 0.278389\n", + " 0.287134\n", + " 0.286320\n", + " 0.283948\n", + " 0.003945\n", " 21\n", " \n", " \n", " 3\n", - " 8.176893\n", - " 0.252821\n", - " 4.071952\n", - " 0.265773\n", + " 2.272779\n", + " 0.155897\n", + " 0.982528\n", + " 0.045744\n", " 0.5\n", " True\n", " 0.1\n", " 5\n", " {'classifier__alpha': 0.5, 'classifier__fit_pr...\n", - " 0.371079\n", - " 0.377072\n", - " 0.374531\n", - " 0.374228\n", - " 0.002456\n", + " 0.275833\n", + " 0.272693\n", + " 0.278427\n", + " 0.275651\n", + " 0.002344\n", " 22\n", " \n", " \n", " 12\n", - " 7.606435\n", - " 0.239001\n", - " 3.875793\n", - " 0.109225\n", + " 1.979826\n", + " 0.106524\n", + " 0.938829\n", + " 0.050975\n", " 1\n", " True\n", " 0.05\n", " 5\n", " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.277031\n", - " 0.288065\n", - " 0.287913\n", - " 0.284336\n", - " 0.005166\n", + " 0.181309\n", + " 0.186707\n", + " 0.193406\n", + " 0.187141\n", + " 0.004948\n", " 23\n", " \n", " \n", " 15\n", - " 8.077971\n", - " 0.733700\n", - " 4.135721\n", - " 0.235307\n", + " 1.952817\n", + " 0.107900\n", + " 0.938851\n", + " 0.048295\n", " 1\n", " True\n", " 0.1\n", " 5\n", " {'classifier__alpha': 1, 'classifier__fit_prio...\n", - " 0.260415\n", - " 0.267201\n", - " 0.266981\n", - " 0.264866\n", - " 0.003148\n", + " 0.160402\n", + " 0.172025\n", + " 0.171455\n", + " 0.167960\n", + " 0.005350\n", " 24\n", " \n", " \n", @@ -1507,53 +1513,53 @@ ], "text/plain": [ " mean_fit_time std_fit_time mean_score_time std_score_time \\\n", - "7 7.796924 0.321314 3.756043 0.027860 \n", - "10 8.055664 0.206984 3.748517 0.088012 \n", - "11 7.748360 0.484361 3.863216 0.072048 \n", - "8 7.400649 0.087320 3.658442 0.011735 \n", - "19 8.147969 0.401980 3.977119 0.284028 \n", - "20 7.472414 0.130320 3.771136 0.146406 \n", - "23 7.395585 0.326162 2.332031 0.254146 \n", - "22 7.452060 0.162072 2.937473 0.116443 \n", - "6 7.836380 0.374669 4.007429 0.251199 \n", - "2 7.839444 0.174964 3.914105 0.379735 \n", - "5 7.948454 0.411364 3.968444 0.090030 \n", - "9 7.373592 0.143028 3.777698 0.008990 \n", - "1 7.406839 0.041973 3.838634 0.116634 \n", - "4 7.481533 0.224344 3.789821 0.098098 \n", - "14 7.749725 0.468469 4.139534 0.140173 \n", - "17 7.703846 0.357508 4.034154 0.265509 \n", - "18 7.553105 0.056077 4.094978 0.198813 \n", - "13 7.438030 0.237545 3.915824 0.029823 \n", - "21 8.057189 0.435052 3.305222 0.348995 \n", - "16 7.710748 0.559283 4.034421 0.073522 \n", - "0 7.614647 0.466252 3.898220 0.098618 \n", - "3 8.176893 0.252821 4.071952 0.265773 \n", - "12 7.606435 0.239001 3.875793 0.109225 \n", - "15 8.077971 0.733700 4.135721 0.235307 \n", + "7 1.986588 0.050896 1.090251 0.135508 \n", + "10 2.070333 0.038396 0.976315 0.033742 \n", + "19 2.049166 0.193113 1.064576 0.087034 \n", + "6 2.288145 0.131338 1.133445 0.099583 \n", + "22 1.872234 0.072997 0.748070 0.085882 \n", + "11 2.067691 0.126923 0.910947 0.078748 \n", + "23 1.847330 0.147504 0.495354 0.018589 \n", + "9 2.071489 0.256086 1.055936 0.037198 \n", + "20 1.776546 0.064677 0.888485 0.093302 \n", + "8 2.015992 0.062583 0.974434 0.082582 \n", + "18 2.032050 0.104313 0.969210 0.070997 \n", + "1 2.307611 0.142902 1.102178 0.078755 \n", + "4 1.876958 0.050648 1.031975 0.029341 \n", + "21 1.897479 0.094903 0.740516 0.143821 \n", + "5 1.824982 0.038113 0.960814 0.041330 \n", + "2 2.151446 0.120440 0.887620 0.037900 \n", + "17 2.004961 0.196640 0.953482 0.113914 \n", + "13 1.890709 0.056234 1.006219 0.042628 \n", + "14 2.022432 0.201745 0.931837 0.047467 \n", + "0 2.081572 0.123875 1.058692 0.034084 \n", + "16 1.961700 0.108977 0.964816 0.089735 \n", + "3 2.272779 0.155897 0.982528 0.045744 \n", + "12 1.979826 0.106524 0.938829 0.050975 \n", + "15 1.952817 0.107900 0.938851 0.048295 \n", "\n", " param_classifier__alpha param_classifier__fit_prior \\\n", "7 0.5 False \n", "10 0.5 False \n", - "11 0.5 False \n", - "8 0.5 False \n", "19 1 False \n", - "20 1 False \n", - "23 1 False \n", - "22 1 False \n", "6 0.5 False \n", - "2 0.5 True \n", - "5 0.5 True \n", + "22 1 False \n", + "11 0.5 False \n", + "23 1 False \n", "9 0.5 False \n", + "20 1 False \n", + "8 0.5 False \n", + "18 1 False \n", "1 0.5 True \n", "4 0.5 True \n", - "14 1 True \n", - "17 1 True \n", - "18 1 False \n", - "13 1 True \n", "21 1 False \n", - "16 1 True \n", + "5 0.5 True \n", + "2 0.5 True \n", + "17 1 True \n", + "13 1 True \n", + "14 1 True \n", "0 0.5 True \n", + "16 1 True \n", "3 0.5 True \n", "12 1 True \n", "15 1 True \n", @@ -1561,109 +1567,109 @@ " param_vectorizer__max_df param_vectorizer__min_df \\\n", "7 0.05 20 \n", "10 0.1 20 \n", - "11 0.1 100 \n", - "8 0.05 100 \n", "19 0.05 20 \n", - "20 0.05 100 \n", - "23 0.1 100 \n", - "22 0.1 20 \n", "6 0.05 5 \n", - "2 0.05 100 \n", - "5 0.1 100 \n", + "22 0.1 20 \n", + "11 0.1 100 \n", + "23 0.1 100 \n", "9 0.1 5 \n", + "20 0.05 100 \n", + "8 0.05 100 \n", + "18 0.05 5 \n", "1 0.05 20 \n", "4 0.1 20 \n", - "14 0.05 100 \n", - "17 0.1 100 \n", - "18 0.05 5 \n", - "13 0.05 20 \n", "21 0.1 5 \n", - "16 0.1 20 \n", + "5 0.1 100 \n", + "2 0.05 100 \n", + "17 0.1 100 \n", + "13 0.05 20 \n", + "14 0.05 100 \n", "0 0.05 5 \n", + "16 0.1 20 \n", "3 0.1 5 \n", "12 0.05 5 \n", "15 0.1 5 \n", "\n", " params split0_test_score \\\n", - "7 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.508013 \n", - "10 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.503729 \n", - "11 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.502211 \n", - "8 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.501432 \n", - "19 {'classifier__alpha': 1, 'classifier__fit_prio... 0.486410 \n", - "20 {'classifier__alpha': 1, 'classifier__fit_prio... 0.486868 \n", - "23 {'classifier__alpha': 1, 'classifier__fit_prio... 0.489489 \n", - "22 {'classifier__alpha': 1, 'classifier__fit_prio... 0.478748 \n", - "6 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.472793 \n", - "2 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.469224 \n", - "5 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.469310 \n", - "9 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.463156 \n", - "1 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.462315 \n", - "4 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.457504 \n", - "14 {'classifier__alpha': 1, 'classifier__fit_prio... 0.442930 \n", - "17 {'classifier__alpha': 1, 'classifier__fit_prio... 0.439058 \n", - "18 {'classifier__alpha': 1, 'classifier__fit_prio... 0.421488 \n", - "13 {'classifier__alpha': 1, 'classifier__fit_prio... 0.404152 \n", - "21 {'classifier__alpha': 1, 'classifier__fit_prio... 0.397182 \n", - "16 {'classifier__alpha': 1, 'classifier__fit_prio... 0.392046 \n", - "0 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.385156 \n", - "3 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.371079 \n", - "12 {'classifier__alpha': 1, 'classifier__fit_prio... 0.277031 \n", - "15 {'classifier__alpha': 1, 'classifier__fit_prio... 0.260415 \n", + "7 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.459165 \n", + "10 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.457524 \n", + "19 {'classifier__alpha': 1, 'classifier__fit_prio... 0.441657 \n", + "6 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.436976 \n", + "22 {'classifier__alpha': 1, 'classifier__fit_prio... 0.432322 \n", + "11 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.426436 \n", + "23 {'classifier__alpha': 1, 'classifier__fit_prio... 0.422130 \n", + "9 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.416746 \n", + "20 {'classifier__alpha': 1, 'classifier__fit_prio... 0.413441 \n", + "8 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.412522 \n", + "18 {'classifier__alpha': 1, 'classifier__fit_prio... 0.392393 \n", + "1 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.385834 \n", + "4 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.377309 \n", + "21 {'classifier__alpha': 1, 'classifier__fit_prio... 0.360551 \n", + "5 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.347831 \n", + "2 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.335093 \n", + "17 {'classifier__alpha': 1, 'classifier__fit_prio... 0.300093 \n", + "13 {'classifier__alpha': 1, 'classifier__fit_prio... 0.297119 \n", + "14 {'classifier__alpha': 1, 'classifier__fit_prio... 0.300746 \n", + "0 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.296667 \n", + "16 {'classifier__alpha': 1, 'classifier__fit_prio... 0.278389 \n", + "3 {'classifier__alpha': 0.5, 'classifier__fit_pr... 0.275833 \n", + "12 {'classifier__alpha': 1, 'classifier__fit_prio... 0.181309 \n", + "15 {'classifier__alpha': 1, 'classifier__fit_prio... 0.160402 \n", "\n", " split1_test_score split2_test_score mean_test_score std_test_score \\\n", - "7 0.509086 0.514455 0.510518 0.002818 \n", - "10 0.506417 0.511895 0.507347 0.003398 \n", - "11 0.498949 0.503744 0.501635 0.002000 \n", - "8 0.493970 0.501386 0.498929 0.003507 \n", - "19 0.491891 0.492515 0.490272 0.002743 \n", - "20 0.489142 0.492665 0.489558 0.002385 \n", - "23 0.489987 0.488543 0.489340 0.000599 \n", - "22 0.485174 0.484685 0.482869 0.002921 \n", - "6 0.476460 0.479583 0.476279 0.002775 \n", - "2 0.472179 0.476758 0.472720 0.003100 \n", - "5 0.471916 0.476900 0.472708 0.003149 \n", - "9 0.466783 0.463460 0.464466 0.001643 \n", - "1 0.462975 0.463192 0.462827 0.000373 \n", - "4 0.460853 0.459941 0.459433 0.001414 \n", - "14 0.443183 0.449577 0.445230 0.003076 \n", - "17 0.443429 0.449336 0.443941 0.004212 \n", - "18 0.427530 0.422329 0.423782 0.002672 \n", - "13 0.411373 0.406858 0.407461 0.002979 \n", - "21 0.405247 0.401505 0.401311 0.003295 \n", - "16 0.397995 0.396114 0.395385 0.002483 \n", - "0 0.388866 0.386509 0.386844 0.001533 \n", - "3 0.377072 0.374531 0.374228 0.002456 \n", - "12 0.288065 0.287913 0.284336 0.005166 \n", - "15 0.267201 0.266981 0.264866 0.003148 \n", + "7 0.473024 0.475462 0.469217 0.007177 \n", + "10 0.463575 0.458007 0.459702 0.002745 \n", + "19 0.452933 0.451286 0.448625 0.004973 \n", + "6 0.449693 0.437911 0.441527 0.005787 \n", + "22 0.438805 0.428209 0.433112 0.004362 \n", + "11 0.429182 0.437410 0.431009 0.004662 \n", + "23 0.430875 0.430829 0.427945 0.004112 \n", + "9 0.425938 0.417381 0.420022 0.004192 \n", + "20 0.417122 0.427196 0.419253 0.005814 \n", + "8 0.410409 0.425047 0.415993 0.006460 \n", + "18 0.396143 0.386439 0.391659 0.003996 \n", + "1 0.392225 0.366549 0.381536 0.010914 \n", + "4 0.384224 0.366632 0.376055 0.007236 \n", + "21 0.366311 0.350439 0.359101 0.006561 \n", + "5 0.350708 0.349963 0.349501 0.001219 \n", + "2 0.340020 0.341502 0.338872 0.002739 \n", + "17 0.306020 0.305047 0.303720 0.002595 \n", + "13 0.302061 0.298975 0.299385 0.002038 \n", + "14 0.291492 0.297456 0.296565 0.003830 \n", + "0 0.294715 0.292144 0.294509 0.001852 \n", + "16 0.287134 0.286320 0.283948 0.003945 \n", + "3 0.272693 0.278427 0.275651 0.002344 \n", + "12 0.186707 0.193406 0.187141 0.004948 \n", + "15 0.172025 0.171455 0.167960 0.005350 \n", "\n", " rank_test_score \n", "7 1 \n", "10 2 \n", - "11 3 \n", - "8 4 \n", - "19 5 \n", - "20 6 \n", + "19 3 \n", + "6 4 \n", + "22 5 \n", + "11 6 \n", "23 7 \n", - "22 8 \n", - "6 9 \n", - "2 10 \n", - "5 11 \n", - "9 12 \n", - "1 13 \n", - "4 14 \n", - "14 15 \n", - "17 16 \n", - "18 17 \n", + "9 8 \n", + "20 9 \n", + "8 10 \n", + "18 11 \n", + "1 12 \n", + "4 13 \n", + "21 14 \n", + "5 15 \n", + "2 16 \n", + "17 17 \n", "13 18 \n", - "21 19 \n", - "16 20 \n", - "0 21 \n", + "14 19 \n", + "0 20 \n", + "16 21 \n", "3 22 \n", "12 23 \n", "15 24 " ] }, - "execution_count": 6, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -1692,7 +1698,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -1710,7 +1716,7 @@ " ('classifier', MultinomialNB(alpha=0.5, fit_prior=False))])" ] }, - "execution_count": 7, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -1734,26 +1740,34 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "\u001b[38;5;39m2022-06-19 15:12:58,312 | INFO | Fetching cached versions of small-domain-prediction\u001b[0m\n", - "\u001b[38;5;39m2022-06-19 15:12:59,027 | INFO | Copying file for small-domain-prediction-12\u001b[0m\n", - "\u001b[38;5;39m2022-06-19 15:12:59,039 | INFO | Compressing small-domain-prediction-12\u001b[0m\n", - "\u001b[38;5;39m2022-06-19 15:12:59,842 | INFO | Model small-domain-prediction uploaded with version 12\u001b[0m\n" + "\u001b[38;5;39m2022-06-25 11:25:32,714 | INFO | Copying file for small-domain-prediction-0\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:32,737 | INFO | Compressing small-domain-prediction-0\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:33,050 | INFO | Uploading /tmp/tmpgerx8x95/small-domain-prediction-0.tar.gz to Mongo (GridFS)\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:33,107 | INFO | Uploading small-domain-prediction-0.tar.gz 0.26/1.85 MB (14.2%)\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:33,109 | INFO | Uploading small-domain-prediction-0.tar.gz 0.52/1.85 MB (28.3%)\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:33,112 | INFO | Uploading small-domain-prediction-0.tar.gz 0.78/1.85 MB (42.5%)\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:33,114 | INFO | Uploading small-domain-prediction-0.tar.gz 1.04/1.85 MB (56.6%)\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:33,116 | INFO | Uploading small-domain-prediction-0.tar.gz 1.31/1.85 MB (70.8%)\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:33,117 | INFO | Uploading small-domain-prediction-0.tar.gz 1.57/1.85 MB (84.9%)\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:33,120 | INFO | Uploading small-domain-prediction-0.tar.gz 1.83/1.85 MB (99.1%)\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:33,120 | INFO | Uploading small-domain-prediction-0.tar.gz 1.85/1.85 MB (100.0%)\u001b[0m\n", + "\u001b[38;5;39m2022-06-25 11:25:33,124 | INFO | Model small-domain-prediction uploaded with version 0\u001b[0m\n" ] }, { "data": { "text/plain": [ - "'small-domain-prediction:12'" + "'small-domain-prediction:0'" ] }, - "execution_count": 8, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -1762,7 +1776,7 @@ "from great_ai import save_model\n", "\n", "\n", - "save_model(classifier, key=MODEL_KEY, keep_last_n=5)" + "save_model(classifier, key=\"small-domain-prediction\", keep_last_n=5)" ] } ], diff --git a/great_ai/example_secrets.ini b/great_ai/example_secrets.ini index 439d79a..9d8f335 100644 --- a/great_ai/example_secrets.ini +++ b/great_ai/example_secrets.ini @@ -1,4 +1,3 @@ -[DEFAULT] aws_region_name = your_region_like_eu-west-2 aws_access_key_id = YOUR_ACCESS_KEY_ID aws_secret_access_key = YOUR_VERY_SECRET_ACCESS_KEY diff --git a/great_ai/open_s3.md b/great_ai/open_s3.md index 49acb9e..04708e7 100644 --- a/great_ai/open_s3.md +++ b/great_ai/open_s3.md @@ -78,7 +78,6 @@ The package can be used as a module from the command-line to give you more flexi Create an .ini file (or use _~/.aws/credentials_). It may look like this: ```ini -[DEFAULT] aws_region_name = your_region_like_eu-west-2 aws_access_key_id = YOUR_ACCESS_KEY_ID aws_secret_access_key = YOUR_VERY_SECRET_ACCESS_KEY diff --git a/great_ai/setup.cfg b/great_ai/setup.cfg index 1ca9e8f..f733e59 100644 --- a/great_ai/setup.cfg +++ b/great_ai/setup.cfg @@ -20,7 +20,6 @@ packages = find: include_package_data = True python_requires = >=3.8 install_requires = - click < 8.1.0 unidecode >= 1.3.0 multiprocess >= 0.70.0.0 tqdm >= 4.0.0 diff --git a/great_ai/src/great_ai/__main__.py b/great_ai/src/great_ai/__main__.py index 5d1a3d7..b42c462 100644 --- a/great_ai/src/great_ai/__main__.py +++ b/great_ai/src/great_ai/__main__.py @@ -19,7 +19,7 @@ from .great_ai.context import _is_in_production_mode from .great_ai.deploy import GreatAI from .great_ai.exceptions import ArgumentValidationError, MissingArgumentError from .parse_arguments import parse_arguments -from .utilities.logger import get_logger +from .utilities import get_logger logger = get_logger(SERVER_NAME) diff --git a/great_ai/src/great_ai/great_ai/__init__.py b/great_ai/src/great_ai/great_ai/__init__.py index 210d2f3..edf03ff 100644 --- a/great_ai/src/great_ai/great_ai/__init__.py +++ b/great_ai/src/great_ai/great_ai/__init__.py @@ -7,5 +7,5 @@ from .output_models import ( RegressionOutput, ) from .parameters import log_metric, parameter -from .persistence import MongoDbDriver, ParallelTinyDbDriver, TracingDatabaseDriver -from .tracing import add_ground_truth, query_ground_truth +from .persistence import MongodbDriver, ParallelTinyDbDriver, TracingDatabaseDriver +from .tracing import add_ground_truth, delete_ground_truth, query_ground_truth diff --git a/great_ai/src/great_ai/great_ai/constants.py b/great_ai/src/great_ai/great_ai/constants.py index 170d15e..a60bb55 100644 --- a/great_ai/src/great_ai/great_ai/constants.py +++ b/great_ai/src/great_ai/great_ai/constants.py @@ -1,16 +1,18 @@ -from pathlib import Path - -from great_ai.large_file import LargeFileLocal, LargeFileMongo, LargeFileS3 +from ..large_file import LargeFileMongo, LargeFileS3 +from .persistence.mongodb_driver import MongodbDriver ENV_VAR_KEY = "ENVIRONMENT" PRODUCTION_KEY = "production" -DEFAULT_TRACING_DB_FILENAME = "tracing_database.json" DASHBOARD_PATH = "/dashboard" +MONGO_CONFIG_PATHS = ["mongodb.ini", "mongo.ini", "mongo_db.ini", "mongo-db.ini"] +DEFAULT_TRACING_DATABASE_CONFIG_PATHS = { + MongodbDriver: MONGO_CONFIG_PATHS, +} + DEFAULT_LARGE_FILE_CONFIG_PATHS = { - LargeFileLocal: None, - LargeFileMongo: Path("mongodb.ini"), - LargeFileS3: Path("s3.ini"), + LargeFileS3: ["s3.ini", "b2.ini"], + LargeFileMongo: MONGO_CONFIG_PATHS, } GITHUB_LINK = "https://github.com/ScoutinScience/great-ai" @@ -25,4 +27,4 @@ ONLINE_TAG_NAME = "online" SERVER_NAME = "GreatAI-Server" -SE4ML_WEBSITE = 'https://se-ml.github.io/practices/' +SE4ML_WEBSITE = "https://se-ml.github.io/practices/" diff --git a/great_ai/src/great_ai/great_ai/context.py b/great_ai/src/great_ai/great_ai/context.py index 39d0c3a..d27b0d3 100644 --- a/great_ai/src/great_ai/great_ai/context.py +++ b/great_ai/src/great_ai/great_ai/context.py @@ -7,11 +7,11 @@ from typing import Any, Dict, Optional, Type, cast from pydantic import BaseModel from great_ai.large_file import LargeFile, LargeFileLocal -from great_ai.utilities.logger import get_logger -import yaml +from great_ai.utilities import get_logger + from .constants import ( DEFAULT_LARGE_FILE_CONFIG_PATHS, - DEFAULT_TRACING_DB_FILENAME, + DEFAULT_TRACING_DATABASE_CONFIG_PATHS, ENV_VAR_KEY, PRODUCTION_KEY, SE4ML_WEBSITE, @@ -26,6 +26,7 @@ class Context(BaseModel): logger: Logger should_log_exception_stack: bool prediction_cache_size: int + dashboard_table_size: int class Config: arbitrary_types_allowed = True @@ -37,6 +38,7 @@ class Context(BaseModel): "is_production": self.is_production, "should_log_exception_stack": self.should_log_exception_stack, "prediction_cache_size": self.prediction_cache_size, + "dashboard_table_size": self.dashboard_table_size, } @@ -54,13 +56,12 @@ def configure( *, log_level: int = DEBUG, seed: int = 42, - tracing_database: TracingDatabaseDriver = ParallelTinyDbDriver( - Path(DEFAULT_TRACING_DB_FILENAME) - ), - large_file_implementation: Type[LargeFile] = LargeFileLocal, + tracing_database: Optional[Type[TracingDatabaseDriver]] = None, + large_file_implementation: Optional[Type[LargeFile]] = None, should_log_exception_stack: Optional[bool] = None, prediction_cache_size: int = 512, - disable_se4ml_banner: bool=False + disable_se4ml_banner: bool = False, + dashboard_table_size: int = 50, ) -> None: global _context logger = get_logger("great_ai", level=log_level) @@ -72,9 +73,11 @@ def configure( ) is_production = _is_in_production_mode(logger=logger) - _initialize_large_file(large_file_implementation, logger=logger) + _set_seed(seed) + tracing_database = _initialize_tracing_database(tracing_database, logger=logger)() + if not tracing_database.is_production_ready: if is_production: logger.error( @@ -87,23 +90,27 @@ def configure( _context = Context( tracing_database=tracing_database, - large_file_implementation=large_file_implementation, + large_file_implementation=_initialize_large_file( + large_file_implementation, logger=logger + ), is_production=is_production, logger=logger, should_log_exception_stack=not is_production if should_log_exception_stack is None else should_log_exception_stack, prediction_cache_size=prediction_cache_size, + dashboard_table_size=dashboard_table_size, ) - logger.info("Setting: configured ✅") + logger.info("Settings: configured ✅") for k, v in get_context().to_flat_dict().items(): - logger.info(f'🔩 {k}: {v}') + logger.info(f"🔩 {k}: {v}") if not is_production and not disable_se4ml_banner: - logger.warning(f'You still need to check whether you follow all best practices so that you and others can trust your deployment.') - logger.warning(f'> Find out more at {SE4ML_WEBSITE}') - + logger.warning( + "You still need to check whether you follow all best practices before trusting your deployment." + ) + logger.warning(f"> Find out more at {SE4ML_WEBSITE}") def _is_in_production_mode(logger: Optional[Logger]) -> bool: @@ -129,24 +136,48 @@ def _is_in_production_mode(logger: Optional[Logger]) -> bool: return is_production -def _initialize_large_file(large_file: Type[LargeFile], logger: Logger) -> None: - path = DEFAULT_LARGE_FILE_CONFIG_PATHS[large_file] - if path is None: - return +def _initialize_tracing_database( + selected: Optional[Type[TracingDatabaseDriver]], logger: Logger +) -> Type[TracingDatabaseDriver]: + for tracing_driver, paths in DEFAULT_TRACING_DATABASE_CONFIG_PATHS.items(): + if selected is None or selected == tracing_driver: + if tracing_driver.initialized: + logger.warning( + f"{tracing_driver.__name__} has been already configured: skipping initialisation" + ) + return tracing_driver + for p in paths: + if Path(p).exists(): + logger.info( + f"Found credentials file ({Path(p).absolute()}), initialising {tracing_driver.__name__}" + ) + tracing_driver.configure_credentials_from_file(p) + return tracing_driver + logger.warning( + "Cannot find credentials files, defaulting to using ParallelTinyDbDriver" + ) + return ParallelTinyDbDriver - if large_file.initialized: - logger.warning( - f"{large_file.__name__} has been already configured: skipping initialisation" - ) - return - if path.exists(): - large_file.configure_credentials_from_file(path) - logger.info(f"{large_file.__name__} initialised with config ({path.resolve()})") - else: - logger.warning( - f"Default {large_file.__name__} config ({path.resolve()}) not found, skipping {large_file.__name__} initialisation" - ) +def _initialize_large_file( + selected: Optional[Type[LargeFile]], logger: Logger +) -> Type[LargeFile]: + for large_file, paths in DEFAULT_LARGE_FILE_CONFIG_PATHS.items(): + if selected is None or selected == large_file: + if large_file.initialized: + logger.warning( + f"{large_file.__name__} has been already configured: skipping initialisation" + ) + return large_file + for p in paths: + if Path(p).exists(): + logger.info( + f"Found credentials file ({Path(p).absolute()}), initialising {large_file.__name__}" + ) + large_file.configure_credentials_from_file(p) + return large_file + logger.warning("Cannot find credentials files, defaulting to using LargeFileLocal") + return LargeFileLocal def _set_seed(seed: int) -> None: diff --git a/great_ai/src/great_ai/great_ai/deploy/great_ai.py b/great_ai/src/great_ai/great_ai/deploy/great_ai.py index 92a8181..295b434 100644 --- a/great_ai/src/great_ai/great_ai/deploy/great_ai.py +++ b/great_ai/src/great_ai/great_ai/deploy/great_ai.py @@ -13,13 +13,12 @@ from typing import ( cast, ) -import yaml from fastapi import APIRouter, FastAPI, status from pydantic import BaseModel, create_model from great_ai.great_ai.deploy.routes.bootstrap_dashboard import bootstrap_dashboard from great_ai.great_ai.views.cache_statistics import CacheStatistics -from great_ai.utilities.parallel_map import parallel_map +from great_ai.utilities import parallel_map from ..constants import DASHBOARD_PATH from ..context import get_context @@ -40,6 +39,7 @@ from .routes import ( T = TypeVar("T") + class GreatAI(Generic[T]): def __init__(self, func: Callable[..., Any], version: str): func = automatically_decorate_parameters(func) @@ -70,7 +70,6 @@ class GreatAI(Generic[T]): redoc_url=None, ) - @staticmethod def deploy( func: Optional[Callable[..., T]] = None, diff --git a/great_ai/src/great_ai/great_ai/deploy/routes/bootstrap_trace_endpoints.py b/great_ai/src/great_ai/great_ai/deploy/routes/bootstrap_trace_endpoints.py index 754cea5..7c951a7 100644 --- a/great_ai/src/great_ai/great_ai/deploy/routes/bootstrap_trace_endpoints.py +++ b/great_ai/src/great_ai/great_ai/deploy/routes/bootstrap_trace_endpoints.py @@ -20,6 +20,10 @@ def bootstrap_trace_endpoints(app: FastAPI) -> None: ) -> List[Trace]: return get_context().tracing_database.query( conjunctive_filters=query.filter, + conjunctive_tags=query.conjunctive_tags, + since=query.since, + until=query.until, + has_feedback=query.has_feedback, sort_by=query.sort, skip=skip, take=take, diff --git a/great_ai/src/great_ai/great_ai/deploy/routes/dashboard/create_dash_app.py b/great_ai/src/great_ai/great_ai/deploy/routes/dashboard/create_dash_app.py index 61f8432..45fe646 100644 --- a/great_ai/src/great_ai/great_ai/deploy/routes/dashboard/create_dash_app.py +++ b/great_ai/src/great_ai/great_ai/deploy/routes/dashboard/create_dash_app.py @@ -1,5 +1,5 @@ from math import ceil -from typing import Any, Dict, List, Sequence, Tuple +from typing import Any, Dict, List, Optional, Sequence, Tuple, Union import pandas as pd import plotly.express as px @@ -8,12 +8,12 @@ from dash import Dash, dcc, html from dash.dependencies import Input, Output from flask import Flask -from great_ai.utilities.unique import unique +from great_ai.utilities import unique from ....constants import DASHBOARD_PATH, ONLINE_TAG_NAME from ....context import get_context from ....helper import snake_case_to_text, text_to_hex_color -from ....views import SortBy +from ....views import SortBy, Trace from .get_description import get_description from .get_filter_from_datatable import get_filter_from_datatable from .get_footer import get_footer @@ -105,19 +105,32 @@ def create_dash_app(function_name: str, function_docs: str) -> Flask: @app.callback( Output(table, "data"), Output(table, "page_count"), + Output(table, "columns"), + Output(traces_table_container, "style"), + Output(execution_time_histogram_container, "children"), + Output(parallel_coordinates, "figure"), + Output(parallel_coordinates, "style"), Input(table, "page_current"), Input(table, "page_size"), Input(table, "sort_by"), Input(table, "filter_query"), Input(interval, "n_intervals"), ) - def update_table( + def update_page( page_current: int, page_size: int, - sort_by: List[SortBy], + sort_by: List[Dict[str, Union[str, int]]], filter_query: str, n_intervals: int, - ) -> Tuple[List[Dict[str, Any]], int]: + ) -> Tuple[ + List[Dict[str, Any]], + int, + List[Dict[str, Sequence[str]]], + Dict[str, Any], + Any, + go.Figure, + Dict[str, Any], + ]: conjunctive_filters = ( [get_filter_from_datatable(f) for f in filter_query.split(" && ")] if filter_query @@ -128,114 +141,98 @@ def create_dash_app(function_name: str, function_docs: str) -> Flask: elements, count = get_context().tracing_database.query( skip=page_current * page_size, take=page_size, - conjunctive_tags=[ONLINE_TAG_NAME], conjunctive_filters=non_null_conjunctive_filters, - sort_by=sort_by, + conjunctive_tags=[ONLINE_TAG_NAME], + sort_by=[SortBy.parse_obj(s) for s in sort_by], + ) + + columns, style = update_layout(elements[0] if elements else None) + execution_time_histogram, parallel_coords_fig, style = update_charts( + elements=elements, function_name=function_name, accent_color=accent_color ) return ( - [e.to_flat_dict() for e in elements], + [e.to_flat_dict(include_original=False) for e in elements], max(1, ceil(count / page_size)), - ) - - @app.callback( - Output(table, "columns"), - Output(traces_table_container, "style"), - Input(interval, "n_intervals"), - ) - def update_layout( - n_intervals: int, - ) -> Tuple[List[Dict[str, Sequence[str]]], Dict[str, Any]]: - elements, count = get_context().tracing_database.query( - take=1, conjunctive_tags=[ONLINE_TAG_NAME] - ) - - if elements: - keys = list(elements[0].to_flat_dict().keys()) - header_height = max(len(i.split(":")) for i in keys) - columns = [ - { - "name": [""] * (header_height - len(k.split(":"))) - + k.replace("_flat", "").split(":"), - "id": k, - } - for k in keys - ] - else: - columns = [] - - return ( columns, - {"display": "block" if count > 0 else "none"}, + style, + execution_time_histogram, + parallel_coords_fig, + style, ) - @app.callback( - Output(execution_time_histogram_container, "children"), - Output(parallel_coordinates, "figure"), - Output(parallel_coordinates, "style"), - Input(table, "filter_query"), - Input(interval, "n_intervals"), - ) - def update_charts( - filter_query: str, n_intervals: int - ) -> Tuple[Any, go.Figure, Dict[str, Any]]: - conjunctive_filters = ( - [get_filter_from_datatable(f) for f in filter_query.split(" && ")] - if filter_query - else [] - ) - non_null_conjunctive_filters = [f for f in conjunctive_filters if f is not None] - - elements, count = get_context().tracing_database.query( - conjunctive_tags=[ONLINE_TAG_NAME], - conjunctive_filters=non_null_conjunctive_filters, - ) - - if not elements: - return ( - html.Span( - f"No traces yet: call your function ({function_name}) to create one.", - className="placeholder", - ), - go.Figure(), - {"display": "none"}, - ) - - flat_elements = [e.to_flat_dict() for e in elements] - - execution_time_histogram = dcc.Graph(config={"displaylogo": False}) - df = pd.DataFrame(flat_elements) - fig = px.histogram( - df, - x="original_execution_time_ms", - labels={"original_execution_time_ms": "Execution time (ms)"}, - nbins=20, - height=400, - log_y=True, - color_discrete_sequence=[accent_color], - ) - fig.update_layout( - margin=dict(l=0, r=0, b=0, t=0, pad=0), - ) - execution_time_histogram.figure = fig - - parallel_coords_fig = go.Figure( - go.Parcoords( - dimensions=[ - get_dimension_descriptor(df, c) - for c in df.columns - if c - not in {"trace_id", "created", "output", "exception", "feedback"} - and "_flat" not in c - ], - line_color=accent_color, - ) - ) - return execution_time_histogram, parallel_coords_fig, {} - return app.server +def update_layout( + first_element: Optional[Trace], +) -> Tuple[List[Dict[str, Sequence[str]]], Dict[str, Any]]: + + if first_element: + keys = list(first_element.to_flat_dict(include_original=False).keys()) + header_height = max(len(i.split(":")) for i in keys) + columns = [ + { + "name": [""] * (header_height - len(k.split(":"))) + + k.replace("_flat", "").split(":"), + "id": k, + } + for k in keys + ] + else: + columns = [] + + return ( + columns, + {"display": "none" if first_element is None else "block"}, + ) + + +def update_charts( + elements: List[Trace], function_name: str, accent_color: str +) -> Tuple[Any, go.Figure, Dict[str, Any]]: + if not elements: + return ( + html.Span( + f"No traces yet: call your function ({function_name}) to create one.", + className="placeholder", + ), + go.Figure(), + {"display": "none"}, + ) + + flat_elements = [e.to_flat_dict(include_original=False) for e in elements] + + execution_time_histogram = dcc.Graph(config={"displaylogo": False}) + df = pd.DataFrame(flat_elements) + fig = px.histogram( + df, + x="original_execution_time_ms", + labels={"original_execution_time_ms": "Execution time (ms)"}, + nbins=20, + height=400, + log_y=True, + color_discrete_sequence=[accent_color], + ) + fig.update_layout( + margin=dict(l=0, r=0, b=0, t=0, pad=0), + ) + execution_time_histogram.figure = fig + + parallel_coords_fig = go.Figure( + go.Parcoords( + dimensions=[ + get_dimension_descriptor(df, c) + for c in df.columns + if c not in {"trace_id", "created", "output", "exception", "feedback"} + and "_flat" not in c + ], + line_color=accent_color, + ) + ) + return execution_time_histogram, parallel_coords_fig, {} + + def get_dimension_descriptor(df: pd.DataFrame, column: str) -> Dict[str, Any]: dimension: Dict[str, Any] = { "label": snake_case_to_text(column), diff --git a/great_ai/src/great_ai/great_ai/deploy/routes/dashboard/get_traces_table.py b/great_ai/src/great_ai/great_ai/deploy/routes/dashboard/get_traces_table.py index 629de70..2acdfce 100644 --- a/great_ai/src/great_ai/great_ai/deploy/routes/dashboard/get_traces_table.py +++ b/great_ai/src/great_ai/great_ai/deploy/routes/dashboard/get_traces_table.py @@ -1,10 +1,12 @@ from dash import dash_table +from great_ai.great_ai.context import get_context + def get_traces_table() -> dash_table.DataTable: return dash_table.DataTable( page_current=0, - page_size=20, + page_size=get_context().dashboard_table_size, page_action="custom", filter_action="custom", sort_action="custom", @@ -24,7 +26,6 @@ def get_traces_table() -> dash_table.DataTable: "background-color": "white", "font-weight": "bold", }, - style_table={"max-height": "70vh", "overflow": "auto"}, merge_duplicate_headers=True, style_cell_conditional=[ {"if": {"column_id": "output"}, "width": 1500}, diff --git a/great_ai/src/great_ai/great_ai/persistence/__init__.py b/great_ai/src/great_ai/great_ai/persistence/__init__.py index ff5f8b6..a2a97fe 100644 --- a/great_ai/src/great_ai/great_ai/persistence/__init__.py +++ b/great_ai/src/great_ai/great_ai/persistence/__init__.py @@ -1,3 +1,3 @@ -from .mongodb_driver import MongoDbDriver +from .mongodb_driver import MongodbDriver from .parallel_tinydb_driver import ParallelTinyDbDriver from .tracing_database_driver import TracingDatabaseDriver diff --git a/great_ai/src/great_ai/great_ai/persistence/mongodb_driver.py b/great_ai/src/great_ai/great_ai/persistence/mongodb_driver.py index 6c9cc58..97926ca 100644 --- a/great_ai/src/great_ai/great_ai/persistence/mongodb_driver.py +++ b/great_ai/src/great_ai/great_ai/persistence/mongodb_driver.py @@ -1,5 +1,137 @@ +from datetime import datetime +from typing import Any, List, Mapping, Optional, Sequence, Tuple + +from pymongo import MongoClient + +from ..views import Filter, SortBy, Trace from .tracing_database_driver import TracingDatabaseDriver +operator_mapping = { + "=": "$eq", + "!=": "$ne", + "<": "$lt", + "<=": "$lte", + ">": "$gt", + ">=": "$gte", + "contains": "$regex", +} -class MongoDbDriver(TracingDatabaseDriver): + +class MongodbDriver(TracingDatabaseDriver): is_production_ready = True + + def __init__(self) -> None: + super().__init__() + if self.mongo_connection_string is None or self.mongo_database is None: + raise ValueError( + "Please configure the MongoDB access options by calling MongodbDriver.configure_credentials" + ) + + @classmethod + def configure_credentials( # type: ignore + cls, + *, + mongo_connection_string: str, + mongo_database: str, + **_: Mapping[str, Any], + ) -> None: + cls.mongo_connection_string = mongo_connection_string + cls.mongo_database = mongo_database + super().configure_credentials() + + def save(self, trace: Trace) -> str: + serialized = trace.to_flat_dict() + serialized["_id"] = trace.trace_id + + with MongoClient(self.mongo_connection_string) as client: + return client[self.mongo_database].traces.insert_one(serialized) + + def save_batch(self, documents: List[Trace]) -> List[str]: + serialized = [d.to_flat_dict() for d in documents] + for s in serialized: + s["_id"] = s["trace_id"] + + with MongoClient(self.mongo_connection_string) as client: + return client[self.mongo_database].traces.insert_many( + serialized, ordered=False + ) + + def get(self, id: str) -> Optional[Trace]: + with MongoClient(self.mongo_connection_string) as client: + value = client[self.mongo_database].traces.find_one(id) + + if value: + value = Trace.parse_obj(value) + + return value + + def _get_operator(self, filter: Filter) -> str: + if filter.operator == "contains" and not isinstance(filter.value, str): + return operator_mapping["="] + return operator_mapping[filter.operator] + + def query( + self, + *, + skip: int = 0, + take: Optional[int] = None, + conjunctive_filters: Sequence[Filter] = [], + conjunctive_tags: Sequence[str] = [], + since: Optional[datetime] = None, + until: Optional[datetime] = None, + has_feedback: Optional[bool] = None, + sort_by: Sequence[SortBy] = [], + ) -> Tuple[List[Trace], int]: + + query = { + "filter": { + "$and": [{"tags": tag} for tag in conjunctive_tags] + + [ + {f.property: {self._get_operator(f): f.value}} + for f in conjunctive_filters + ] + + [{}] + }, + "sort": [ + (col.column_id, 1 if col.direction == "asc" else -1) for col in sort_by + ], + } + + if skip: + query["skip"] = skip + + if take: + query["limit"] = take + + if since: + query["filter"]["$and"].append({"created": {"$gte": since}}) + + if until: + query["filter"]["$and"].append({"created": {"$lte": until}}) + + if has_feedback is not None: + query["filter"]["$and"].append( + {"feedback": {"$ne": None}} if has_feedback else {"feedback": None} + ) + + with MongoClient(self.mongo_connection_string) as client: + values = client[self.mongo_database].traces.find(**query) + documents = [Trace.parse_obj(t) for t in values] + + return documents, len(documents) + + def update(self, id: str, new_version: Trace) -> None: + serialized = new_version.dict() + serialized["_id"] = new_version.trace_id + with MongoClient(self.mongo_connection_string) as client: + client[self.mongo_database].traces.update_one(id, new_version) + + def delete(self, id: str) -> None: + with MongoClient(self.mongo_connection_string) as client: + client[self.mongo_database].traces.delete_one(id) + + def delete_batch(self, ids: List[str]) -> List[str]: + delete_filter = {"_id": {"$in": ids}} + + with MongoClient(self.mongo_connection_string) as client: + return client[self.mongo_database].traces.delete_many(delete_filter) diff --git a/great_ai/src/great_ai/great_ai/persistence/parallel_tinydb_driver.py b/great_ai/src/great_ai/great_ai/persistence/parallel_tinydb_driver.py index 11929f5..1243ab0 100644 --- a/great_ai/src/great_ai/great_ai/persistence/parallel_tinydb_driver.py +++ b/great_ai/src/great_ai/great_ai/persistence/parallel_tinydb_driver.py @@ -9,6 +9,7 @@ from tinydb import TinyDB from ..views import Filter, SortBy, Trace from .tracing_database_driver import TracingDatabaseDriver +DEFAULT_TRACING_DB_FILENAME = "tracing_database.json" lock = Lock() @@ -17,10 +18,7 @@ operator_mapping = {"=": "eq", "!=": "ne", "<": "lt", "<=": "le", ">": "gt", ">= class ParallelTinyDbDriver(TracingDatabaseDriver): is_production_ready = False - - def __init__(self, path_to_db: Path) -> None: - super().__init__() - self._path_to_db = path_to_db + path_to_db = Path(DEFAULT_TRACING_DB_FILENAME) def save(self, trace: Trace) -> str: return self._safe_execute(lambda db: db.insert(trace.dict())) @@ -43,8 +41,9 @@ class ParallelTinyDbDriver(TracingDatabaseDriver): conjunctive_filters: Sequence[Filter] = [], conjunctive_tags: Sequence[str] = [], since: Optional[datetime] = None, - sort_by: Sequence[SortBy] = [], - has_feedback: Optional[bool] = None + until: Optional[datetime] = None, + has_feedback: Optional[bool] = None, + sort_by: Sequence[SortBy] = [] ) -> Tuple[List[Trace], int]: def does_match(d: Dict[str, Any]) -> bool: return ( @@ -53,6 +52,10 @@ class ParallelTinyDbDriver(TracingDatabaseDriver): since is None or cast(datetime, datetime.fromisoformat(d["created"])) >= since ) + and ( + until is None + or cast(datetime, datetime.fromisoformat(d["created"])) <= until + ) and ( has_feedback is None or has_feedback == (d["feedback"] is not None) ) @@ -99,7 +102,11 @@ class ParallelTinyDbDriver(TracingDatabaseDriver): def delete(self, id: str) -> None: self._safe_execute(lambda db: db.remove(lambda d: d["trace_id"] == id)) + def delete_batch(self, ids: List[str]) -> List[str]: + for i in ids: + self.delete(i) + def _safe_execute(self, func: Callable[[TinyDB], Any]) -> Any: with lock: - with TinyDB(self._path_to_db) as db: + with TinyDB(self.path_to_db) as db: return func(db) diff --git a/great_ai/src/great_ai/great_ai/persistence/tracing_database_driver.py b/great_ai/src/great_ai/great_ai/persistence/tracing_database_driver.py index 5cc1ac1..a4bab9d 100644 --- a/great_ai/src/great_ai/great_ai/persistence/tracing_database_driver.py +++ b/great_ai/src/great_ai/great_ai/persistence/tracing_database_driver.py @@ -1,12 +1,29 @@ -from abc import ABC, abstractmethod +from abc import ABC, abstractclassmethod, abstractmethod from datetime import datetime -from typing import List, Optional, Sequence, Tuple +from pathlib import Path +from typing import List, Optional, Sequence, Tuple, Union + +from great_ai.utilities import ConfigFile from ..views import Filter, SortBy, Trace class TracingDatabaseDriver(ABC): is_production_ready: bool + initialized: bool = False + + @classmethod + def configure_credentials_from_file( + cls, + secrets_path: Union[Path, str], + ) -> None: + cls.configure_credentials(**ConfigFile(secrets_path)) + + @abstractclassmethod + def configure_credentials( + cls, + ) -> None: + cls.initialized = True @abstractmethod def save(self, document: Trace) -> str: @@ -31,9 +48,10 @@ class TracingDatabaseDriver(ABC): take: Optional[int] = None, conjunctive_filters: Sequence[Filter] = [], conjunctive_tags: Sequence[str] = [], + until: Optional[datetime] = None, since: Optional[datetime] = None, - sort_by: Sequence[SortBy] = [], - has_feedback: Optional[bool] = None + has_feedback: Optional[bool] = None, + sort_by: Sequence[SortBy] = [] ) -> Tuple[List[Trace], int]: pass @@ -44,3 +62,10 @@ class TracingDatabaseDriver(ABC): @abstractmethod def delete(self, id: str) -> None: pass + + @abstractmethod + def delete_batch( + self, + ids: List[str], + ) -> None: + pass diff --git a/great_ai/src/great_ai/great_ai/tracing/__init__.py b/great_ai/src/great_ai/great_ai/tracing/__init__.py index fda4bb0..e34184c 100644 --- a/great_ai/src/great_ai/great_ai/tracing/__init__.py +++ b/great_ai/src/great_ai/great_ai/tracing/__init__.py @@ -1,3 +1,4 @@ from .add_ground_truth import add_ground_truth +from .delete_ground_truth import delete_ground_truth from .query_ground_truth import query_ground_truth from .tracing_context import TracingContext diff --git a/great_ai/src/great_ai/great_ai/tracing/add_ground_truth.py b/great_ai/src/great_ai/great_ai/tracing/add_ground_truth.py index affcc78..3702756 100644 --- a/great_ai/src/great_ai/great_ai/tracing/add_ground_truth.py +++ b/great_ai/src/great_ai/great_ai/tracing/add_ground_truth.py @@ -51,7 +51,7 @@ def add_ground_truth( created = datetime.utcnow().isoformat() traces = [ - Trace[T]( + Trace( created=created, original_execution_time_ms=0, logged_values=X if isinstance(X, dict) else {"input": X}, diff --git a/great_ai/src/great_ai/great_ai/tracing/delete_ground_truth.py b/great_ai/src/great_ai/great_ai/tracing/delete_ground_truth.py new file mode 100644 index 0000000..ef1620e --- /dev/null +++ b/great_ai/src/great_ai/great_ai/tracing/delete_ground_truth.py @@ -0,0 +1,22 @@ +from datetime import datetime +from typing import List, Optional, Union + +from ..context import get_context + + +def delete_ground_truth( + conjunctive_tags: Union[List[str], str] = [], + *, + until: Optional[datetime] = None, + since: Optional[datetime] = None, +) -> None: + tags = ( + conjunctive_tags if isinstance(conjunctive_tags, list) else [conjunctive_tags] + ) + db = get_context().tracing_database + + items, length = db.query( + conjunctive_tags=tags, until=until, since=since, has_feedback=True + ) + + db.delete_batch([i.trace_id for i in items]) diff --git a/great_ai/src/great_ai/great_ai/tracing/query_ground_truth.py b/great_ai/src/great_ai/great_ai/tracing/query_ground_truth.py index b515f51..b58d3ea 100644 --- a/great_ai/src/great_ai/great_ai/tracing/query_ground_truth.py +++ b/great_ai/src/great_ai/great_ai/tracing/query_ground_truth.py @@ -1,10 +1,8 @@ from datetime import datetime -from typing import List, Optional, TypeVar, Union +from typing import List, Optional, Union from ..context import get_context -from ..views.trace import Trace - -T = TypeVar("T") +from ..views import Trace def query_ground_truth( @@ -12,7 +10,7 @@ def query_ground_truth( *, since: Optional[datetime] = None, return_max_count: Optional[int] = None -) -> List[Trace[T]]: +) -> List[Trace]: tags = ( conjunctive_tags if isinstance(conjunctive_tags, list) else [conjunctive_tags] ) diff --git a/great_ai/src/great_ai/great_ai/views/query.py b/great_ai/src/great_ai/great_ai/views/query.py index e46b567..7257a7b 100644 --- a/great_ai/src/great_ai/great_ai/views/query.py +++ b/great_ai/src/great_ai/great_ai/views/query.py @@ -1,4 +1,5 @@ -from typing import List +from datetime import datetime +from typing import List, Optional, Sequence from pydantic import BaseModel @@ -9,6 +10,10 @@ from .sort_by import SortBy class Query(BaseModel): filter: List[Filter] = [] sort: List[SortBy] = [] + conjunctive_tags: Sequence[str] = [] + since: Optional[datetime] = None + until: Optional[datetime] = None + has_feedback: Optional[bool] = None class Config: schema_extra = { @@ -24,5 +29,7 @@ class Query(BaseModel): {"column_id": "original_execution_time_ms", "direction": "asc"}, {"column_id": "id", "direction": "desc"}, ], + "conjunctive_tags": ["online"], + "has_feedback": False, } } diff --git a/great_ai/src/great_ai/great_ai/views/sort_by.py b/great_ai/src/great_ai/great_ai/views/sort_by.py index 868000e..d0f8eff 100644 --- a/great_ai/src/great_ai/great_ai/views/sort_by.py +++ b/great_ai/src/great_ai/great_ai/views/sort_by.py @@ -1,8 +1,8 @@ from typing import Literal -from typing_extensions import TypedDict +from pydantic import BaseModel -class SortBy(TypedDict): +class SortBy(BaseModel): column_id: str direction: Literal["asc", "desc"] diff --git a/great_ai/src/great_ai/great_ai/views/trace.py b/great_ai/src/great_ai/great_ai/views/trace.py index 6182f2a..adc744b 100644 --- a/great_ai/src/great_ai/great_ai/views/trace.py +++ b/great_ai/src/great_ai/great_ai/views/trace.py @@ -1,8 +1,8 @@ +from pprint import pformat from typing import Any, Dict, Generic, List, Optional, TypeVar from uuid import uuid4 -import yaml -from pydantic import validator +from pydantic import Extra, validator from ..helper import HashableBaseModel from .model import Model @@ -10,7 +10,7 @@ from .model import Model T = TypeVar("T") -class Trace(HashableBaseModel, Generic[T]): +class Trace(Generic[T], HashableBaseModel): trace_id: Optional[str] created: str original_execution_time_ms: float @@ -21,6 +21,9 @@ class Trace(HashableBaseModel, Generic[T]): feedback: Any = None tags: List[str] + class Config: + extra = Extra.ignore + @validator("trace_id", always=True) def generate_id(cls, v: Optional[str], values: Dict[str, Any]) -> Optional[str]: if not v: @@ -41,26 +44,42 @@ class Trace(HashableBaseModel, Generic[T]): @property def output_flat(self) -> str: - return yaml.dump(self.output, stream=None) + return pformat(self.output, indent=2, compact=True) + + @property + def exception_flat(self) -> str: + return ( + "null" + if self.exception is None + else pformat(self.exception, indent=2, compact=True) + ) @property def feedback_flat(self) -> str: return ( - "null" if self.feedback is None else yaml.dump(self.feedback, stream=None) + "null" + if self.feedback is None + else pformat(self.feedback, indent=2, compact=True) ) @property def tags_flat(self) -> str: return ",\n".join(self.tags) - def to_flat_dict(self) -> Dict[str, Any]: + def to_flat_dict(self, include_original: bool = True) -> Dict[str, Any]: return { - "trace_id": self.trace_id, - "created": self.created, - "original_execution_time_ms": self.original_execution_time_ms, + **( + self.dict() + if include_original + else { + "trace_id": self.trace_id, + "created": self.created, + "original_execution_time_ms": self.original_execution_time_ms, + } + ), **self.logged_values, "models_flat": self.models_flat, - "exception": "null" if self.exception is None else self.exception, + "exception_flat": self.exception_flat, "output_flat": self.output_flat, "feedback_flat": self.feedback_flat, "tags_flat": self.tags_flat, diff --git a/great_ai/src/great_ai/large_file/large_file/large_file_mongo.py b/great_ai/src/great_ai/large_file/large_file/large_file_mongo.py index 4cf2118..07bb25c 100644 --- a/great_ai/src/great_ai/large_file/large_file/large_file_mongo.py +++ b/great_ai/src/great_ai/large_file/large_file/large_file_mongo.py @@ -19,29 +19,29 @@ MONGO_NAME_VERSION_SEPARATOR = "_" class LargeFileMongo(LargeFile): - connection_string = None - database = None + mongo_connection_string = None + mongo_database = None @classmethod def configure_credentials( # type: ignore cls, *, - connection_string: str, - database: str, + mongo_connection_string: str, + mongo_database: str, **_: Mapping[str, Any], ) -> None: - cls.connection_string = connection_string - cls.database = database + cls.mongo_connection_string = mongo_connection_string + cls.mongo_database = mongo_database super().configure_credentials() @cached_property def _client(self) -> GridFSBucket: - if self.connection_string is None or self.database is None: + if self.mongo_connection_string is None or self.mongo_database is None: raise ValueError( "Please configure the MongoDB access options by calling LargeFileMongo.configure_credentials or set offline_mode=True in the constructor." ) - db: Database = MongoClient(self.connection_string)[self.database] + db: Database = MongoClient(self.mongo_connection_string)[self.mongo_database] return GridFSBucket(db) def _find_remote_instances(self) -> List[DataInstance]: