great-ai/examples/simple/train/train.ipynb

268 lines
59 KiB
Text

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Optimise and train a model\n",
"\n",
"![position of this step in the lifecycle](/media/scope-train.svg)\n",
"> The blue boxes show the steps implemented in this notebook.\n",
"\n",
"In the first part, we have cleaned and transformed our training data. We can now access this data using `great_ai.LargeFile`. Locally, it will gives us the cached version, otherwise, the latest version is downloaded from S3 or GridFS. \n",
"\n",
"In this part, we hyperparameter-optimise and train a simple Naive Bayes classifier which we then export for deployment using `great_ai.save_model`.\n",
"\n",
"## Load data that has been extracted in [part 1](/examples/simple/data)"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[38;5;226mEnvironment variable ENVIRONMENT is not set, defaulting to development mode ‼️\u001b[0m\n",
"\u001b[38;5;226mCannot find credentials files, defaulting to using ParallelTinyDbDriver\u001b[0m\n",
"\u001b[38;5;226mThe selected tracing database (ParallelTinyDbDriver) is not recommended for production\u001b[0m\n",
"\u001b[38;5;226mCannot find credentials files, defaulting to using LargeFileLocal\u001b[0m\n",
"\u001b[38;5;39mGreatAI (v0.1.6): configured ✅\u001b[0m\n",
"\u001b[38;5;39m 🔩 tracing_database: ParallelTinyDbDriver\u001b[0m\n",
"\u001b[38;5;39m 🔩 large_file_implementation: LargeFileLocal\u001b[0m\n",
"\u001b[38;5;39m 🔩 is_production: False\u001b[0m\n",
"\u001b[38;5;39m 🔩 should_log_exception_stack: True\u001b[0m\n",
"\u001b[38;5;39m 🔩 prediction_cache_size: 512\u001b[0m\n",
"\u001b[38;5;39m 🔩 dashboard_table_size: 50\u001b[0m\n",
"\u001b[38;5;226mYou still need to check whether you follow all best practices before trusting your deployment.\u001b[0m\n",
"\u001b[38;5;226m> Find out more at https://se-ml.github.io/practices\u001b[0m\n"
]
}
],
"source": [
"from great_ai import query_ground_truth\n",
"\n",
"data = query_ground_truth(\"train\")\n",
"X = [d.input for d in data for domain in d.feedback]\n",
"y = [domain for d in data for domain in d.feedback]"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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AACAwyguAQAAAAAAwGEUlwAAAAAAAOAwiksAAAAAAABwGMUlAAAAAAAAOCzXiktLly5V1apVVaRIEQUFBek///mPJOmnn35SlSpV5O7urkaNGik6Otp2Tlpamnr37i1PT0+VKlVKU6dOtftv3upcAAAAAAAAmC9XikubNm3SiBEjNHfuXCUnJ2v79u2qWLGiEhIS1K5dO7377rs6f/68QkJC1LFjR9t548eP1+HDhxUdHa0tW7Zo8uTJ2rBhgyTd9lwAAAAAAACYL1eKS++8847GjRununXrytXVVWXKlFGZMmX03XffKTg4WO3bt1ehQoU0fvx4RURE6MCBA5Kk+fPna+zYsfL29lbVqlXVr18/zZs3T5Juey4AAAAAAADMl+PiUkZGhsLDwxUfH69KlSqpbNmyGjx4sP766y9FRkaqVq1atudmLZmLjIxUYmKi4uLi7MZr1aqlyMhISbrluQAAAAAAAMgb8uf0P3DmzBldvXpV3377rf7zn/+oQIECat26tcLCwpSSkiI/Pz+753t5eSk5OVkpKSm2x9ePSbrludebNWuWZs2aJUmKj4/P6UsCAAAAAADAHcrxzKXChQtLkl577TX5+/vL19dXw4YN0/r16+Xh4aGkpCS75yclJalo0aLy8PCwPb5+TNItz71e//79FR4ervDw8GwFKQAAAAAAANw7OZ655O3trbJly8rFxcV2LOvn4OBgzZ8/33b80qVLioqKUnBwsLy9veXv76+IiAg1bdpUkhQREaHg4ODbngtrKz9yndkR7tjxSS+YHQEAAAAAgDwtVxp69+rVS59++qnOnj2rxMRETZs2TS1btlTbtm21b98+rVixQqmpqZo4caJq1qypKlWqSJJ69OihsLAwJSYm6sCBA5o9e7Z69uwpSbc9FwAAAAAAAObLleLS2LFj9fjjj6ty5cqqWrWqHn30UY0ePVp+fn5asWKFRo8eLW9vb+3atUtLly61nTdhwgQFBQUpMDBQDRs21PDhw9W8eXNJuu25AAAAAAAAMJ+LYRiG2SFyU0hIiMLDw82OkSucdfmYs74uAAAAAACc1a3qLbkycwkAAAAAAAAPJopLAAAAAAAAcBjFJQAAAAAAADgsv9kBAGdBLykAAAAAwIOImUsAAAAAAABwGMUlAAAAAAAAOIziEgAAAAAAABxGzyUAt0QvKQAAAADArTBz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eVf+Zq7tF+BMKleurN9++01FixY1O0qu27hxo61hqCSFh4crKSnJ0k1RnVFgYKD27NljWx4s/b3r5KOPPqro6GgTk+XMoEGD9PDDD+v111+3Hfvss8904MABffrpp3rvvfe0bt067dy508SUd+/YsWMaPXr0DZfSWnnnzDfffFNHjhzRtGnTVLt2bUVGRmrIkCGqVKmS3nvvPbPjOSwzM1O7d++2XUM98cQTTtdCwRllFTidTWZmps6cOaOSJUvyPnQQxaUHgDM2AbzWpk2btG/fPtWtW1f16tUzO47DWrVqpRIlSujll1/WsmXL9OOPP+rTTz9V27ZttWrVKo0dO1Z79+41OyZu4sKFCzp27JgefvhhS+72dCNZ/R2io6MVEBCgbt26WfZuYu/evRUeHq7mzZtr/fr1atSokT799FOzY+WaYcOG6ZFHHlGPHj3MjpJj1zYF3bRpk9atW6e3334726zHihUr3u9ouM6GDRvk6elp2+0pKipKPXr00L59+1SvXj3NnTvXbgc5K/L29lZCQoLdBiIZGRkqXrx4tibmVnK7XdXS0tJUokQJy73GevXqKSgoSF27ds32u7hhw4Ympcq5K1euaMSIEZo9e7YuX74sd3d39evXT5MmTXKKGyUHDx7U/v379dhjjykwMNDsOLgNZysuJSUl6bXXXtPSpUt19epVFShQQJ06ddL06dPl5eVldjxLobj0ABg4cKBiYmI0cuRItWjRQhcuXFBMTIyaNWumyMhIs+Pdlc6dO6tJkybq27evJGny5MkaO3asatasqf3792vmzJmWnabu4+OjuLg4ubm56fLlyypWrJjS0tJsMxFutBuPlWzatElLly7V2bNntWbNGkvfpZ88ebIqVaqkdu3aSfr7C1aHDh2UkpIib29vrV+/XnXq1DE5Ja7l7++v33//Xf7+/jp58qQaNGjgVI0pn376ae3evVsVKlTIVoSxWh8EV1fXmy5fzGL1XlK36l9hpb+vxx9/XNOnT7fd2GnYsKGKFCmiQYMGac6cOSpUqJC+/vprk1PmzFNPPaV//OMf6tChg+3Yt99+qylTpujXX381MVnOVKlSRR9++KFat25tO7Z69WoNHz5cBw8e1MWLFxUUFKSEhAQTU949T09PXbhwwalmHWR92ZX+/nw4e/asfHx8lC9fPj355JPKn99aLXSHDRumxx57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",
"text/plain": [
"<Figure size 1440x360 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from collections import Counter\n",
"import matplotlib.pyplot as plt\n",
"\n",
"domains, counts = zip(*Counter(y).most_common())\n",
"\n",
"# Configure matplotlib to have nice, high-resolution charts\n",
"%matplotlib inline\n",
"plt.rcParams[\"figure.figsize\"] = (20, 5)\n",
"plt.rcParams[\"figure.facecolor\"] = \"white\"\n",
"plt.rcParams[\"font.size\"] = 12\n",
"\n",
"plt.xticks(rotation=90)\n",
"plt.bar(domains, counts)\n",
"None"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Optimise and train Multinomial Naive Bayes classifier"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.naive_bayes import MultinomialNB\n",
"from sklearn.pipeline import Pipeline\n",
"from sklearn.feature_extraction.text import TfidfVectorizer\n",
"\n",
"\n",
"def create_pipeline() -> Pipeline:\n",
" return Pipeline(\n",
" steps=[\n",
" (\"vectorizer\", TfidfVectorizer(sublinear_tf=True)),\n",
" (\"classifier\", MultinomialNB()),\n",
" ]\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Fitting 3 folds for each of 24 candidates, totalling 72 fits\n"
]
},
{
"ename": "NameError",
"evalue": "name 'pd' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m/data/projects/great-ai/docs/examples/simple/train.ipynb Cell 6\u001b[0m in \u001b[0;36m<cell line: 18>\u001b[0;34m()\u001b[0m\n\u001b[1;32m <a href='vscode-notebook-cell:/data/projects/great-ai/docs/examples/simple/train.ipynb#ch0000005?line=2'>3</a>\u001b[0m optimisation_pipeline \u001b[39m=\u001b[39m GridSearchCV(\n\u001b[1;32m <a href='vscode-notebook-cell:/data/projects/great-ai/docs/examples/simple/train.ipynb#ch0000005?line=3'>4</a>\u001b[0m create_pipeline(),\n\u001b[1;32m <a href='vscode-notebook-cell:/data/projects/great-ai/docs/examples/simple/train.ipynb#ch0000005?line=4'>5</a>\u001b[0m {\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m <a href='vscode-notebook-cell:/data/projects/great-ai/docs/examples/simple/train.ipynb#ch0000005?line=13'>14</a>\u001b[0m verbose\u001b[39m=\u001b[39m\u001b[39m1\u001b[39m,\n\u001b[1;32m <a href='vscode-notebook-cell:/data/projects/great-ai/docs/examples/simple/train.ipynb#ch0000005?line=14'>15</a>\u001b[0m )\n\u001b[1;32m <a href='vscode-notebook-cell:/data/projects/great-ai/docs/examples/simple/train.ipynb#ch0000005?line=15'>16</a>\u001b[0m optimisation_pipeline\u001b[39m.\u001b[39mfit(X, y)\n\u001b[0;32m---> <a href='vscode-notebook-cell:/data/projects/great-ai/docs/examples/simple/train.ipynb#ch0000005?line=17'>18</a>\u001b[0m results \u001b[39m=\u001b[39m pd\u001b[39m.\u001b[39mDataFrame(optimisation_pipeline\u001b[39m.\u001b[39mcv_results_)\n\u001b[1;32m <a href='vscode-notebook-cell:/data/projects/great-ai/docs/examples/simple/train.ipynb#ch0000005?line=18'>19</a>\u001b[0m results\u001b[39m.\u001b[39msort_values(\u001b[39m\"\u001b[39m\u001b[39mrank_test_score\u001b[39m\u001b[39m\"\u001b[39m)\n",
"\u001b[0;31mNameError\u001b[0m: name 'pd' is not defined"
]
}
],
"source": [
"from sklearn.model_selection import GridSearchCV\n",
"\n",
"optimisation_pipeline = GridSearchCV(\n",
" create_pipeline(),\n",
" {\n",
" \"vectorizer__min_df\": [5, 20, 100],\n",
" \"vectorizer__max_df\": [0.05, 0.1],\n",
" \"classifier__alpha\": [0.5, 1],\n",
" \"classifier__fit_prior\": [True, False],\n",
" },\n",
" scoring=\"f1_macro\",\n",
" cv=3,\n",
" n_jobs=-1,\n",
" verbose=1,\n",
")\n",
"optimisation_pipeline.fit(X, y)\n",
"\n",
"results = pd.DataFrame(optimisation_pipeline.cv_results_)\n",
"results.sort_values(\"rank_test_score\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style>#sk-container-id-1 {color: black;background-color: white;}#sk-container-id-1 pre{padding: 0;}#sk-container-id-1 div.sk-toggleable {background-color: white;}#sk-container-id-1 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-1 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-1 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-1 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-1 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-1 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-1 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-1 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-1 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-1 div.sk-item {position: relative;z-index: 1;}#sk-container-id-1 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-1 div.sk-item::before, #sk-container-id-1 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-1 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-1 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-1 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-1 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-1 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-1 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-1 div.sk-label-container {text-align: center;}#sk-container-id-1 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-1 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>Pipeline(steps=[(&#x27;vectorizer&#x27;,\n",
" TfidfVectorizer(max_df=0.05, min_df=20, sublinear_tf=True)),\n",
" (&#x27;classifier&#x27;, MultinomialNB(alpha=0.5, fit_prior=False))])</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item sk-dashed-wrapped\"><div class=\"sk-label-container\"><div class=\"sk-label sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" ><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">Pipeline</label><div class=\"sk-toggleable__content\"><pre>Pipeline(steps=[(&#x27;vectorizer&#x27;,\n",
" TfidfVectorizer(max_df=0.05, min_df=20, sublinear_tf=True)),\n",
" (&#x27;classifier&#x27;, MultinomialNB(alpha=0.5, fit_prior=False))])</pre></div></div></div><div class=\"sk-serial\"><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-2\" type=\"checkbox\" ><label for=\"sk-estimator-id-2\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">TfidfVectorizer</label><div class=\"sk-toggleable__content\"><pre>TfidfVectorizer(max_df=0.05, min_df=20, sublinear_tf=True)</pre></div></div></div><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-3\" type=\"checkbox\" ><label for=\"sk-estimator-id-3\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">MultinomialNB</label><div class=\"sk-toggleable__content\"><pre>MultinomialNB(alpha=0.5, fit_prior=False)</pre></div></div></div></div></div></div></div>"
],
"text/plain": [
"Pipeline(steps=[('vectorizer',\n",
" TfidfVectorizer(max_df=0.05, min_df=20, sublinear_tf=True)),\n",
" ('classifier', MultinomialNB(alpha=0.5, fit_prior=False))])"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from sklearn import set_config\n",
"\n",
"set_config(display=\"diagram\")\n",
"\n",
"classifier = create_pipeline()\n",
"classifier.set_params(**optimisation_pipeline.best_params_)\n",
"classifier.fit(X, y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Export the model using GreatAI"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[38;5;39mFetching cached versions of small-domain-prediction\u001b[0m\n",
"\u001b[38;5;39mCopying file for small-domain-prediction-1\u001b[0m\n",
"\u001b[38;5;39mCompressing small-domain-prediction-1\u001b[0m\n",
"\u001b[38;5;39mModel small-domain-prediction uploaded with version 1\u001b[0m\n"
]
},
{
"data": {
"text/plain": [
"'small-domain-prediction:1'"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from great_ai import save_model\n",
"\n",
"\n",
"save_model(classifier, key=\"small-domain-prediction\", keep_last_n=5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Next: [Part 3](/examples/simple/deploy)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.10.4 ('.env': venv)",
"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.4"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "02dd6d3afbfa9fbbe1037d64ad9014965528a1ccad21929d6e72f466389a68ad"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}