Train a domain classifier on the semantic scholar dataset¶
-Part 1: obtain and clean data
-
The blue boxes show the steps implemented in this notebook.
+Simple example: data engineering¶
Here, we solve a problem similar to the tutorial's but with an explainable Naive Bayes classifier and more best-practices. In short, we train a domain classifier on the semantic scholar dataset by taking full advantage of
+great-ai. Subsequently, we create a production-ready deployment.+
+The blue boxes show the steps of a typical AI-development lifecycle implemented in this notebook.
Since the true scope of
great-aiis the phase between proof-of-concept code and production-ready service, it is predominantly used in the deployment notebook. Feel free to skip there, or continue reading if you'd like to see the full picture.Extract¶
This can be achieved by downloading a public dataset (such as in this case), or by having a Data Engineer setup and give us access to the organisation's data.
-In this case, we download the semantic scholar dataset from a public S3 bucket.
+In this example, we download the semantic scholar dataset from a public S3 bucket.
MAX_CHUNK_COUNT = 1
+ MAX_CHUNK_COUNT = 4
-MAX_CHUNK_COUNT = 1
+MAX_CHUNK_COUNT = 4
'Processing 1 out of the 6002 available chunks'+
'Processing 4 out of the 6002 available chunks'
Transform¶
- Filter out non-English abstracts using
great_ai.utilities.predict_language - Project it to only keep the necessary components (text and labels), clean the textual content using
great_ai.utilities.clean
- - We will speed up processing using
great_ai.utilities.parallel_map.
+ - We will speed up processing using
great_ai.utilities.simple_parallel_map.
from typing import List, Tuple
import json
import gzip
-from great_ai import parallel_map, clean, is_english, predict_language
+from great_ai.utilities import (
+ simple_parallel_map,
+ clean,
+ is_english,
+ predict_language,
+ unchunk,
+)
def preprocess_chunk(chunk_key: str) -> List[Tuple[str, List[str]]]:
@@ -2068,12 +2102,20 @@ f"Processing {len(chunks)} out of the {len(manifest.split())} available chunks"<
]
-preprocessed_chunks = parallel_map(preprocess_chunk, chunks)
+preprocessed_data = unchunk(
+ simple_parallel_map(preprocess_chunk, chunks, concurrency=4)
+)
Spacy model en_core_web_sm not found locally, downloading... -Collecting en-core-web-sm==3.3.0 - Downloading https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.3.0/en_core_web_sm-3.3.0-py3-none-any.whl (12.8 MB) - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 12.8/12.8 MB 3.6 MB/s eta 0:00:00 -Requirement already satisfied: spacy<3.4.0,>=3.3.0.dev0 in ./.env/lib/python3.10/site-packages (from en-core-web-sm==3.3.0) (3.3.1) -Requirement already satisfied: tqdm<5.0.0,>=4.38.0 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (4.64.0) -Requirement already satisfied: wasabi<1.1.0,>=0.9.1 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (0.9.1) -Requirement already satisfied: srsly<3.0.0,>=2.4.3 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (2.4.3) -Requirement already satisfied: typer<0.5.0,>=0.3.0 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (0.4.1) -Requirement already satisfied: setuptools in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (59.6.0) -Requirement already satisfied: catalogue<2.1.0,>=2.0.6 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (2.0.7) -Requirement already satisfied: spacy-loggers<2.0.0,>=1.0.0 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (1.0.2) -Requirement already satisfied: blis<0.8.0,>=0.4.0 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (0.7.8) -Requirement already satisfied: murmurhash<1.1.0,>=0.28.0 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (1.0.7) -Requirement already satisfied: spacy-legacy<3.1.0,>=3.0.9 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (3.0.9) -Requirement already satisfied: requests<3.0.0,>=2.13.0 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (2.28.0) -Requirement already satisfied: numpy>=1.15.0 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (1.23.0) -Requirement already satisfied: cymem<2.1.0,>=2.0.2 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (2.0.6) -Requirement already satisfied: pathy>=0.3.5 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (0.6.1) -Requirement already satisfied: jinja2 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (3.1.2) -Requirement already satisfied: langcodes<4.0.0,>=3.2.0 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (3.3.0) -Requirement already satisfied: pydantic!=1.8,!=1.8.1,<1.9.0,>=1.7.4 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (1.8.2) -Requirement already satisfied: preshed<3.1.0,>=3.0.2 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (3.0.6) -Requirement already satisfied: thinc<8.1.0,>=8.0.14 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (8.0.17) -Requirement already satisfied: packaging>=20.0 in ./.env/lib/python3.10/site-packages (from spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (21.3) -Requirement already satisfied: pyparsing!=3.0.5,>=2.0.2 in ./.env/lib/python3.10/site-packages (from packaging>=20.0->spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (3.0.9) -Requirement already satisfied: smart-open<6.0.0,>=5.0.0 in ./.env/lib/python3.10/site-packages (from pathy>=0.3.5->spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (5.2.1) -Requirement already satisfied: typing-extensions>=3.7.4.3 in ./.env/lib/python3.10/site-packages (from pydantic!=1.8,!=1.8.1,<1.9.0,>=1.7.4->spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (4.2.0) -Requirement already satisfied: charset-normalizer~=2.0.0 in ./.env/lib/python3.10/site-packages (from requests<3.0.0,>=2.13.0->spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (2.0.12) -Requirement already satisfied: certifi>=2017.4.17 in ./.env/lib/python3.10/site-packages (from requests<3.0.0,>=2.13.0->spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (2022.6.15) -Requirement already satisfied: idna<4,>=2.5 in ./.env/lib/python3.10/site-packages (from requests<3.0.0,>=2.13.0->spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (3.3) -Requirement already satisfied: urllib3<1.27,>=1.21.1 in ./.env/lib/python3.10/site-packages (from requests<3.0.0,>=2.13.0->spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (1.26.9) -Requirement already satisfied: click<9.0.0,>=7.1.1 in ./.env/lib/python3.10/site-packages (from typer<0.5.0,>=0.3.0->spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (8.1.3) -Requirement already satisfied: MarkupSafe>=2.0 in ./.env/lib/python3.10/site-packages (from jinja2->spacy<3.4.0,>=3.3.0.dev0->en-core-web-sm==3.3.0) (2.1.1) -Installing collected packages: en-core-web-sm -Successfully installed en-core-web-sm-3.3.0 --
2022-06-25 14:21:57,983 | WARNING | Limiting concurrency to 1 because there are only 1 chunks -2022-06-25 14:21:57,984 | INFO | Starting parallel map (concurrency: 1, chunk size: 1) -2022-06-25 14:21:57,984 | WARNING | Running in series, there is no reason for parallelism -100%|██████████| 1/1 [03:26<00:00, 206.86s/it] +100%|██████████| 4/4 [04:42<00:00, 70.62s/it]
from itertools import chain
-
-preprocessed_data = list(chain(*preprocessed_chunks))
-X, y = zip(
- *preprocessed_data
-) # X is the input, y is the expected (ground truth) output
+ X, y = zip(*preprocessed_data) # X is the input, y is the expected output
-from itertools import chain
-
-preprocessed_data = list(chain(*preprocessed_chunks))
-X, y = zip(
- *preprocessed_data
-) # X is the input, y is the expected (ground truth) output
+X, y = zip(*preprocessed_data) # X is the input, y is the expected output
+You can install MongoDB from here or use it as a service
Otherwise, TinyDB is used which is just a local JSON file.
-2022-06-25 14:25:24,989 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️ -2022-06-25 14:25:24,990 | INFO | Found credentials file (/data/projects/great_ai_example/mongo.ini), initialising MongoDbDriver -2022-06-25 14:25:24,991 | INFO | Found credentials file (/data/projects/great_ai_example/mongo.ini), initialising LargeFileMongo -2022-06-25 14:25:24,992 | INFO | Settings: configured ✅ -2022-06-25 14:25:24,993 | INFO | 🔩 tracing_database: MongoDbDriver -2022-06-25 14:25:24,994 | INFO | 🔩 large_file_implementation: LargeFileMongo -2022-06-25 14:25:24,994 | INFO | 🔩 is_production: False -2022-06-25 14:25:24,995 | INFO | 🔩 should_log_exception_stack: True -2022-06-25 14:25:24,996 | INFO | 🔩 prediction_cache_size: 512 -2022-06-25 14:25:24,997 | INFO | 🔩 dashboard_table_size: 50 -2022-06-25 14:25:24,998 | WARNING | You still need to check whether you follow all best practices before trusting your deployment. -2022-06-25 14:25:24,998 | WARNING | > Find out more at https://se-ml.github.io/practices/ --
Train a domain classifier on the semantic scholar dataset¶
Part 3: Create production inference function
+Hardening and deployment¶
-Part 3: Create production inference function
+
-The blue boxes show the steps implemented in this notebook.
In Part 2, we trained our AI model. Now, it's time to create General Robust End-to-end Automated Trustworthy deployment from it using the
+GreatAIPython package.In Part 2, we trained our AI model. Now, it's time to create General Robust End-to-end Automated Trustworthy deployment.
+Create the inference function¶
Next to the prediction, we also return the top-n most influential words based on their weights.
2022-06-25 14:57:20,629 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️ -2022-06-25 14:57:20,629 | INFO | Found credentials file (/data/projects/great_ai_example/mongo.ini), initialising MongoDbDriver -2022-06-25 14:57:20,630 | INFO | Found credentials file (/data/projects/great_ai_example/mongo.ini), initialising LargeFileMongo -2022-06-25 14:57:20,631 | INFO | Settings: configured ✅ -2022-06-25 14:57:20,631 | INFO | 🔩 tracing_database: MongoDbDriver -2022-06-25 14:57:20,631 | INFO | 🔩 large_file_implementation: LargeFileMongo -2022-06-25 14:57:20,632 | INFO | 🔩 is_production: False -2022-06-25 14:57:20,633 | INFO | 🔩 should_log_exception_stack: True -2022-06-25 14:57:20,633 | INFO | 🔩 prediction_cache_size: 512 -2022-06-25 14:57:20,634 | INFO | 🔩 dashboard_table_size: 50 -2022-06-25 14:57:20,634 | WARNING | You still need to check whether you follow all best practices before trusting your deployment. -2022-06-25 14:57:20,635 | WARNING | > Find out more at https://se-ml.github.io/practices/ -2022-06-25 14:57:20,642 | INFO | Latest version of small-domain-prediction is 0 (from versions: 0) -2022-06-25 14:57:20,643 | INFO | File small-domain-prediction-0 found in cache +Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️ +Cannot find credentials files, defaulting to using ParallelTinyDbDriver +The selected tracing database (ParallelTinyDbDriver) is not recommended for production +Cannot find credentials files, defaulting to using LargeFileLocal +GreatAI (v0.1.4): configured ✅ + 🔩 tracing_database: ParallelTinyDbDriver + 🔩 large_file_implementation: LargeFileLocal + 🔩 is_production: False + 🔩 should_log_exception_stack: True + 🔩 prediction_cache_size: 512 + 🔩 dashboard_table_size: 50 +You still need to check whether you follow all best practices before trusting your deployment. +> Find out more at https://se-ml.github.io/practices +Fetching cached versions of small-domain-prediction +Latest version of small-domain-prediction is 0 (from versions: 0) +File small-domain-prediction-0 found in cache
Check accuracy on the test split¶
+Check accuracy on the test split¶
Anything under if __name__ == "__main__": will not be run when the script is executed by the great-ai CLI app. This, combined with query_ground_truth and the /traces/{trace_id}/feedback endpoint are ideal for creating a continuous-integration job for checking the quality of the model before deployment.
2022-06-25 14:57:21,004 | INFO | Starting parallel map (concurrency: 12, chunk size: 26) -100%|██████████| 3054/3054 [00:31<00:00, 96.38it/s] +100%|██████████| 12332/12332 [01:27<00:00, 141.08it/s]
precision recall f1-score support - Art 0.35 0.27 0.31 33 - Biology 0.77 0.84 0.80 299 - Business 0.44 0.61 0.51 82 - Chemistry 0.79 0.67 0.72 289 - Computer Science 0.74 0.79 0.77 341 - Economics 0.65 0.56 0.60 61 - Engineering 0.53 0.52 0.53 202 -Environmental Science 0.51 0.49 0.50 61 - Geography 0.54 0.26 0.35 58 - Geology 0.69 0.56 0.62 48 - History 0.36 0.17 0.23 29 - Materials Science 0.68 0.83 0.74 248 - Mathematics 0.77 0.57 0.66 122 - Medicine 0.97 0.79 0.87 715 - Philosophy 0.50 0.05 0.10 19 - Physics 0.72 0.75 0.74 162 - Political Science 0.39 0.49 0.43 57 - Psychology 0.49 0.81 0.61 141 - Sociology 0.32 0.53 0.40 87 + Art 0.43 0.35 0.39 125 + Biology 0.77 0.83 0.80 1209 + Business 0.50 0.71 0.59 312 + Chemistry 0.80 0.67 0.73 1194 + Computer Science 0.77 0.76 0.77 1293 + Economics 0.64 0.58 0.61 251 + Engineering 0.55 0.53 0.54 815 +Environmental Science 0.54 0.56 0.55 230 + Geography 0.54 0.44 0.48 277 + Geology 0.76 0.67 0.71 228 + History 0.29 0.21 0.24 102 + Materials Science 0.73 0.81 0.77 1053 + Mathematics 0.80 0.70 0.75 551 + Medicine 0.95 0.77 0.85 2794 + Philosophy 0.61 0.12 0.21 88 + Physics 0.67 0.76 0.72 605 + Political Science 0.43 0.52 0.47 297 + Psychology 0.53 0.80 0.63 600 + Sociology 0.32 0.60 0.42 308 - accuracy 0.70 3054 - macro avg 0.59 0.56 0.55 3054 - weighted avg 0.72 0.70 0.70 3054 + accuracy 0.71 12332 + macro avg 0.61 0.60 0.59 12332 + weighted avg 0.73 0.71 0.71 12332
Train a domain classifier on the semantic scholar dataset¶
-Part 2: train a model
-
Optimise and train a model¶
-The blue boxes show the steps implemented in this notebook.
In Part 1, 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.
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.
In this part, we hyperparameter-optimise and train a simple, Naive Bayes classifier which we then export for deployment using great_ai.save_model.
2022-06-25 14:50:29,879 | WARNING | Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️ -2022-06-25 14:50:29,880 | INFO | Found credentials file (/data/projects/great_ai_example/mongo.ini), initialising MongoDbDriver -2022-06-25 14:50:29,881 | INFO | Found credentials file (/data/projects/great_ai_example/mongo.ini), initialising LargeFileMongo -2022-06-25 14:50:29,881 | INFO | Settings: configured ✅ -2022-06-25 14:50:29,882 | INFO | 🔩 tracing_database: MongoDbDriver -2022-06-25 14:50:29,883 | INFO | 🔩 large_file_implementation: LargeFileMongo -2022-06-25 14:50:29,883 | INFO | 🔩 is_production: False -2022-06-25 14:50:29,884 | INFO | 🔩 should_log_exception_stack: True -2022-06-25 14:50:29,884 | INFO | 🔩 prediction_cache_size: 512 -2022-06-25 14:50:29,885 | INFO | 🔩 dashboard_table_size: 50 -2022-06-25 14:50:29,885 | WARNING | You still need to check whether you follow all best practices before trusting your deployment. -2022-06-25 14:50:29,885 | WARNING | > Find out more at https://se-ml.github.io/practices/ +Environment variable ENVIRONMENT is not set, defaulting to development mode ‼️ +Cannot find credentials files, defaulting to using ParallelTinyDbDriver +The selected tracing database (ParallelTinyDbDriver) is not recommended for production +Cannot find credentials files, defaulting to using LargeFileLocal +GreatAI (v0.1.4): configured ✅ + 🔩 tracing_database: ParallelTinyDbDriver + 🔩 large_file_implementation: LargeFileLocal + 🔩 is_production: False + 🔩 should_log_exception_stack: True + 🔩 prediction_cache_size: 512 + 🔩 dashboard_table_size: 50 +You still need to check whether you follow all best practices before trusting your deployment. +> Find out more at https://se-ml.github.io/practices
import pandas as pd
-from collections import Counter
-import plotly.express as px
+ from collections import Counter
+import matplotlib.pyplot as plt
-df = pd.DataFrame(Counter(y).most_common(), columns=["domain", "count"])
-px.bar(df, "domain", "count", width=1200, height=400).show()
+domains, counts = zip(*Counter(y).most_common())
+
+# Configure matplotlib to have nice, high-resolution charts
+%matplotlib inline
+plt.rcParams["figure.figsize"] = (20, 5)
+plt.rcParams["figure.facecolor"] = "white"
+plt.rcParams["font.size"] = 12
+
+plt.xticks(rotation=90)
+plt.bar(domains, counts)
+None
-import pandas as pd
-from collections import Counter
-import plotly.express as px
+from collections import Counter
+import matplotlib.pyplot as plt
-df = pd.DataFrame(Counter(y).most_common(), columns=["domain", "count"])
-px.bar(df, "domain", "count", width=1200, height=400).show()
+domains, counts = zip(*Counter(y).most_common())
+
+# Configure matplotlib to have nice, high-resolution charts
+%matplotlib inline
+plt.rcParams["figure.figsize"] = (20, 5)
+plt.rcParams["figure.facecolor"] = "white"
+plt.rcParams["font.size"] = 12
+
+plt.xticks(rotation=90)
+plt.bar(domains, counts)
+None
2022-06-25 14:50:53,592 | INFO | Copying file for small-domain-prediction-0 -2022-06-25 14:50:53,613 | INFO | Compressing small-domain-prediction-0 -2022-06-25 14:50:53,917 | INFO | Uploading /tmp/tmpvxez8op8/small-domain-prediction-0.tar.gz to Mongo (GridFS) -2022-06-25 14:50:53,972 | INFO | Uploading small-domain-prediction-0.tar.gz 0.26/1.85 MB (14.1%) -2022-06-25 14:50:53,974 | INFO | Uploading small-domain-prediction-0.tar.gz 0.52/1.85 MB (28.2%) -2022-06-25 14:50:53,975 | INFO | Uploading small-domain-prediction-0.tar.gz 0.78/1.85 MB (42.3%) -2022-06-25 14:50:53,977 | INFO | Uploading small-domain-prediction-0.tar.gz 1.04/1.85 MB (56.4%) -2022-06-25 14:50:53,979 | INFO | Uploading small-domain-prediction-0.tar.gz 1.31/1.85 MB (70.5%) -2022-06-25 14:50:53,980 | INFO | Uploading small-domain-prediction-0.tar.gz 1.57/1.85 MB (84.7%) -2022-06-25 14:50:53,982 | INFO | Uploading small-domain-prediction-0.tar.gz 1.83/1.85 MB (98.8%) -2022-06-25 14:50:53,982 | INFO | Uploading small-domain-prediction-0.tar.gz 1.85/1.85 MB (100.0%) -2022-06-25 14:50:53,985 | INFO | Model small-domain-prediction uploaded with version 0 +Fetching cached versions of small-domain-prediction +Copying file for small-domain-prediction-1 +Compressing small-domain-prediction-1 +Model small-domain-prediction uploaded with version 1
'small-domain-prediction:0'+
'small-domain-prediction:1'