diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..337f16e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,16 @@ +.git +.gitignore +.idea +.vscode +__pycache__ +.ruff_cache +.venv +*.pyc +*.pyo +*.pyd +*.swp +*.swo +*.DS_Store +dist +build +*.egg-info diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..2c07333 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.11 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1c44413 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,49 @@ +# syntax=docker/dockerfile:1 + +# Minimal Linux base (glibc) – Python will be installed by uv +FROM debian:bookworm-slim + +ENV DEBIAN_FRONTEND=noninteractive \ + PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + UV_INSTALL_DIR=/usr/local/bin \ + UV_LINK_MODE=copy \ + UV_PYTHON_DOWNLOADS=1 \ + UV_PROJECT_ENVIRONMENT=/app/.venv \ + PATH=/app/.venv/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin + +WORKDIR /app + +# System deps for building/using common scientific stack +# Keep minimal; rely on wheels where possible +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates curl git \ + build-essential pkg-config \ + libssl-dev libffi-dev \ + libopenblas0 libstdc++6 \ + libfreetype6 libpng16-16 libjpeg62-turbo \ + && rm -rf /var/lib/apt/lists/* + +# Install uv (static binary) +RUN curl -LsSf https://astral.sh/uv/install.sh | sh + +# Copy project metadata first for layer caching +COPY pyproject.toml README.md ./ + +# Install a managed Python via uv and create the project venv +RUN uv python install 3.11 \ + && uv venv /app/.venv --python 3.11 + +# Resolve and install runtime deps into project venv +# Use lockfile if present for reproducibility +RUN if [ -f uv.lock ]; then uv sync --no-dev --no-install-project --frozen; else uv sync --no-dev --no-install-project; fi + +# Copy source code and optional templates +COPY src ./src + +# Re-sync to ensure the local package is installed +RUN uv sync --no-dev \ + && rm -rf /root/.cache + +# Default command shows help; override in compose or docker run +CMD ["ners", "--help"] diff --git a/README.md b/README.md index dc429bb..91886e7 100644 --- a/README.md +++ b/README.md @@ -10,37 +10,23 @@ million names from the Democratic Republic of Congo (DRC) annotated with gender ### Installation & Setup -Instructions and command line snippets bellow are provided to help you set up the project environment quickly and -efficiently. -assuming you have Python 3.11 and Git installed and working on a Unix-like system (Linux, macOS, etc.). - -**Using Makefile (Recommended)** - +**Unix based** ```bash +curl -LsSf https://astral.sh/uv/install.sh | sh + git clone https://github.com/bernard-ng/drc-ners-nlp.git cd drc-ners-nlp -# Setup environment -make setup -make activate +uv sync ``` -**Manual Setup** - +**Macos & windows** ```bash -git clone https://github.com/bernard-ng/drc-ners-nlp.git -cd drc-ners-nlp - -# Setup environment -python -m venv .venv -.venv/bin/pip install --upgrade pip -.venv/bin/pip install -r requirements.txt - -pip install --upgrade pip -pip install -r requirements.txt -pip install jupyter notebook ipykernel pytest black flake8 mypy - -source .venv/bin/activate +docker compose build +docker compose run --rm app +docker compose run --rm app ners pipeline run --env=production +docker compose run --rm app ners research train --name=lightgbm --type=baseline --env=production +docker compose run --rm --service-ports app ners web run --env=production ``` ## Data Processing @@ -55,6 +41,7 @@ the `drc-ners-nlp/config/pipeline.yaml` file. ```yaml stages: - "data_cleaning" + - "data_selection" - "feature_extraction" - "data_splitting" ``` @@ -62,37 +49,7 @@ stages: **Running the Pipeline** ```bash -python main.py --env production -``` - -## NER Processing (Optional) - -This project implements a custom named entity recognition (NER) pipeline tailored for Congolese names. -Its main objective is to accurately identify and tag the different components of a Congolese name, -specifically distinguishing between the native part and the surname. - -```bash -python ner.py --env production -``` - -Once you've built and train the NER model you can use it to annotate **COMPOSE** name in the original dataset - -**Running the Pipeline with NER Annotation** -```yaml -stages: - - "data_cleaning" - - "feature_extraction" - - "ner_annotation" - - "data_splitting" -``` - -**Running the Pipeline with LLM Annotation** -```yaml -stages: - - "data_cleaning" - - "feature_extraction" - - "llm_annotation" - - "data_splitting" +uv run ners pipeline run --env="production" ``` ## Experiments @@ -105,54 +62,94 @@ you can define model features, training parameters, and evaluation metrics in th ```bash # bigru -python train.py --name="bigru" --type="baseline" --env="production" -python train.py --name="bigru_native" --type="baseline" --env="production" -python train.py --name="bigru_surname" --type="baseline" --env="production" +uv run ners research train --name="bigru" --type="baseline" --env="production" +uv run ners research train --name="bigru_native" --type="baseline" --env="production" +uv run ners research train --name="bigru_surname" --type="baseline" --env="production" # cnn -python train.py --name="cnn" --type="baseline" --env="production" -python train.py --name="cnn_native" --type="baseline" --env="production" -python train.py --name="cnn_surname" --type="baseline" --env="production" +uv run ners research train --name="cnn" --type="baseline" --env="production" +uv run ners research train --name="cnn_native" --type="baseline" --env="production" +uv run ners research train --name="cnn_surname" --type="baseline" --env="production" # lightgbm -python train.py --name="lightgbm" --type="baseline" --env="production" -python train.py --name="lightgbm_native" --type="baseline" --env="production" -python train.py --name="lightgbm_surname" --type="baseline" --env="production" +uv run ners research train --name="lightgbm" --type="baseline" --env="production" +uv run ners research train --name="lightgbm_native" --type="baseline" --env="production" +uv run ners research train --name="lightgbm_surname" --type="baseline" --env="production" # logistic regression -python train.py --name="logistic_regression" --type="baseline" --env="production" -python train.py --name="logistic_regression_native" --type="baseline" --env="production" -python train.py --name="logistic_regression_surname" --type="baseline" --env="production" +uv run ners research train --name="logistic_regression" --type="baseline" --env="production" +uv run ners research train --name="logistic_regression_native" --type="baseline" --env="production" +uv run ners research train --name="logistic_regression_surname" --type="baseline" --env="production" # lstm -python train.py --name="lstm" --type="baseline" --env="production" -python train.py --name="lstm_native" --type="baseline" --env="production" -python train.py --name="lstm_surname" --type="baseline" --env="production" +uv run ners research train --name="lstm" --type="baseline" --env="production" +uv run ners research train --name="lstm_native" --type="baseline" --env="production" +uv run ners research train --name="lstm_surname" --type="baseline" --env="production" # random forest -python train.py --name="random_forest" --type="baseline" --env="production" -python train.py --name="random_forest_native" --type="baseline" --env="production" -python train.py --name="random_forest_surname" --type="baseline" --env="production" +uv run ners research train --name="random_forest" --type="baseline" --env="production" +uv run ners research train --name="random_forest_native" --type="baseline" --env="production" +uv run ners research train --name="random_forest_surname" --type="baseline" --env="production" # svm -python train.py --name="svm" --type="baseline" --env="production" -python train.py --name="svm_native" --type="baseline" --env="production" -python train.py --name="svm_surname" --type="baseline" --env="production" +uv run ners research train --name="svm" --type="baseline" --env="production" +uv run ners research train --name="svm_native" --type="baseline" --env="production" +uv run ners research train --name="svm_surname" --type="baseline" --env="production" # naive bayes -python train.py --name="naive_bayes" --type="baseline" --env="production" -python train.py --name="naive_bayes_native" --type="baseline" --env="production" -python train.py --name="naive_bayes_surname" --type="baseline" --env="production" +uv run ners research train --name="naive_bayes" --type="baseline" --env="production" +uv run ners research train --name="naive_bayes_native" --type="baseline" --env="production" +uv run ners research train --name="naive_bayes_surname" --type="baseline" --env="production" # transformer -python train.py --name="transformer" --type="baseline" --env="production" -python train.py --name="transformer_native" --type="baseline" --env="production" -python train.py --name="transformer_surname" --type="baseline" --env="production" +uv run ners research train --name="transformer" --type="baseline" --env="production" +uv run ners research train --name="transformer_native" --type="baseline" --env="production" +uv run ners research train --name="transformer_surname" --type="baseline" --env="production" # xgboost -python train.py --name="xgboost" --type="baseline" --env="production" -python train.py --name="xgboost_native" --type="baseline" --env="production" -python train.py --name="xgboost_surname" --type="baseline" --env="production" +uv run ners research train --name="xgboost" --type="baseline" --env="production" +uv run ners research train --name="xgboost_native" --type="baseline" --env="production" +uv run ners research train --name="xgboost_surname" --type="baseline" --env="production" +``` + +## TensorFlow on macOS (Intel) with uv + +TensorFlow no longer publishes wheels for macOS Intel. To keep using uv and run TF reliably, use a Linux container with TF preinstalled and install project code with minimal extras inside the container. + +### One-time build + +```bash +docker compose -f docker/compose.tf.yml build + +If you see a message like `tensorflow/tensorflow:: not found`, update `docker/Dockerfile.tf-cpu` to a tag that exists (e.g., `2.17.0`) and rebuild: + +```bash +sed -n '1,20p' docker/Dockerfile.tf-cpu # verify the FROM line +docker pull tensorflow/tensorflow:2.17.0 # quick availability check +docker compose -f docker/compose.tf.yml build +``` +``` + +### Start a shell with uv and TF available + +```bash +docker compose -f docker/compose.tf.yml run --rm tf bash +``` + +Inside the container: + +```bash +# Install project in editable mode without pulling full deps +uv pip install -e . --no-deps + +# Install only what research needs alongside TensorFlow +uv pip install typer pandas scikit-learn seaborn plotly + +# Sanity check +uv run python -c "import tensorflow as tf; print(tf.__version__)" + +# Run an experiment +uv run ners research train --name="lstm" --type="baseline" --env="production" ``` ## Web Interface @@ -163,60 +160,9 @@ experiments and make predictions without needing to understand the underlying co ### Running the Web Interface ```bash -streamlit run web/app.py +uv run ners web run --env="production" ``` -## GPU Acceleration - -This project can leverage GPUs for faster training when supported libraries and hardware are available. - -- TensorFlow/Keras models (BiGRU, LSTM, CNN, Transformer) - - Uses GPU automatically if a TensorFlow GPU build is installed. - - The code enables safe GPU memory growth by default; optionally enable mixed precision for additional speed: - - Add `mixed_precision: true` in the experiment `model_params` (e.g., in `config/research_templates.yaml`). - - The final layer outputs are set to float32 for numerical stability under mixed precision. - -- spaCy NER - - Automatically prefers GPU if available; otherwise falls back to CPU. - - Ensure a compatible CUDA-enabled spaCy/thinc stack is installed to use GPU. - -- XGBoost - - Enable GPU by adding to the experiment `model_params`: - - `use_gpu: true` (sets `tree_method: gpu_hist` and `predictor: gpu_predictor`). - -- LightGBM - - Enable GPU by adding to the experiment `model_params`: - - `use_gpu: true` (sets `device: gpu`). Optional: `gpu_platform_id`, `gpu_device_id`. - -Example template snippet (GPU on): - -```yaml -- name: "lstm_gpu" - description: "LSTM with GPU + mixed precision" - model_type: "lstm" - features: ["full_name"] - model_params: - embedding_dim: 128 - lstm_units: 64 - epochs: 5 - batch_size: 128 - use_gpu: true - mixed_precision: true - tags: ["gpu", "mixed_precision"] - -- name: "xgboost_gpu" - description: "XGBoost with GPU" - model_type: "xgboost" - features: ["full_name"] - model_params: - n_estimators: 200 - use_gpu: true -``` - -Notes: -- Install CUDA‑enabled binaries for TensorFlow/spaCy/LightGBM/XGBoost to actually use GPU. -- If GPU is requested but not available, training will proceed on CPU with a warning. - ## Contributors diff --git a/osm/provinces.cpg b/assets/osm/provinces.cpg similarity index 100% rename from osm/provinces.cpg rename to assets/osm/provinces.cpg diff --git a/osm/provinces.dbf b/assets/osm/provinces.dbf similarity index 100% rename from osm/provinces.dbf rename to assets/osm/provinces.dbf diff --git a/osm/provinces.prj b/assets/osm/provinces.prj similarity index 100% rename from osm/provinces.prj rename to assets/osm/provinces.prj diff --git a/osm/provinces.shp b/assets/osm/provinces.shp similarity index 100% rename from osm/provinces.shp rename to assets/osm/provinces.shp diff --git a/osm/provinces.shx b/assets/osm/provinces.shx similarity index 100% rename from osm/provinces.shx rename to assets/osm/provinces.shx diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..640b4cb --- /dev/null +++ b/compose.yml @@ -0,0 +1,21 @@ +services: + app: + build: + context: . + dockerfile: Dockerfile + image: drc-ners:uv + working_dir: /app + tty: true + stdin_open: true + environment: + NERS_ENV: production + STREAMLIT_SERVER_ADDRESS: 0.0.0.0 + # expose Streamlit for `ners web run` + ports: + - "8501:8501" + volumes: + - ./assets:/app/assets + - ./config:/app/config + - ./data:/app/data + # default command shows CLI help; override per run + command: ["ners", "--help"] diff --git a/monitor.py b/monitor.py deleted file mode 100755 index a173fcc..0000000 --- a/monitor.py +++ /dev/null @@ -1,90 +0,0 @@ -#!.venv/bin/python3 -import argparse -import sys -import traceback -from pathlib import Path - -from core.config import setup_config -from processing.monitoring.pipeline_monitor import PipelineMonitor - - -def main(): - choices = [ - "data_cleaning", - "data_selection", - "feature_extraction", - "ner_annotation", - "llm_annotation", - "data_splitting", - ] - - parser = argparse.ArgumentParser(description="DRC NERS Processing Monitoring") - parser.add_argument("--config", type=Path, help="Path to configuration file") - parser.add_argument("--env", type=str, default="development", help="Environment") - subparsers = parser.add_subparsers(dest="command", help="Available commands") - - # Clean command - clean_parser = subparsers.add_parser("clean", help="Clean checkpoint files") - clean_parser.add_argument("--step", type=str, choices=choices, help="default: all") - clean_parser.add_argument("--keep-last", type=int, default=1, help="(default: 1)") - clean_parser.add_argument("--force", action="store_true", help="Clean without confirmation") - - # Reset command - reset_parser = subparsers.add_parser("reset", help="Reset pipeline step") - reset_parser.add_argument("--step", type=str, choices=choices, help="(default: all)") - reset_parser.add_argument("--all", action="store_true", help="Reset all steps") - reset_parser.add_argument("--force", action="store_true", help="Reset without confirmation") - args = parser.parse_args() - - try: - setup_config(config_path=args.config, env=args.env) - monitor = PipelineMonitor() - - if not args.command: - parser.print_help() - monitor.print_status(detailed=True) - return 1 - - elif args.command == "clean": - checkpoint_info = monitor.count_checkpoint_files() - print(f"Current checkpoint storage: {checkpoint_info['total_size_mb']:.1f} MB") - - if not args.force: - response = input("Are you sure you want to clean checkpoints? (y/N): ") - if response.lower() != "y": - print("Cancelled") - return 0 - - if args.step: - monitor.clean_step_checkpoints(args.step, args.keep_last) - else: - for step in monitor.steps: - monitor.clean_step_checkpoints(step, args.keep_last) - - print("Checkpoint cleaning completed") - - elif args.command == "reset": - if not args.force: - response = input( - f"Are you sure you want to reset {args.step}? This will delete all checkpoints. (y/N): " - ) - if response.lower() != "y": - print("Cancelled") - return 0 - - if args.step: - monitor.reset_step(args.step) - else: - for step in monitor.steps: - monitor.reset_step(step) - - print(f"Reset completed") - - except Exception as e: - print(f"Monitoring failed: {e}") - traceback.print_exc() - return 1 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/notebooks/analysis.ipynb b/notebooks/analysis.ipynb deleted file mode 100644 index 32874cb..0000000 --- a/notebooks/analysis.ipynb +++ /dev/null @@ -1,499 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "id": "initial_id", - "metadata": { - "collapsed": true, - "ExecuteTime": { - "end_time": "2025-09-21T12:06:07.309139Z", - "start_time": "2025-09-21T12:06:07.086638Z" - } - }, - "source": [ - "import pandas as pd\n", - "import matplotlib.pyplot as plt\n", - "import seaborn as sns\n", - "import sys\n", - "import os\n", - "\n", - "sys.path.append(os.path.abspath(\"..\"))\n", - "from core.utils.data_loader import DataLoader\n", - "from core.config.pipeline_config import PipelineConfig" - ], - "outputs": [], - "execution_count": 1 - }, - { - "cell_type": "code", - "id": "74a8a262bc55d976", - "metadata": { - "ExecuteTime": { - "end_time": "2025-09-21T12:06:14.601682Z", - "start_time": "2025-09-21T12:06:14.598078Z" - } - }, - "source": [ - "config = PipelineConfig(\n", - " paths={\n", - " \"root_dir\": \"../data\",\n", - " \"data_dir\": \"../data/dataset\",\n", - " \"models_dir\": \"../models\",\n", - " \"outputs_dir\": \"../data/processed\",\n", - " \"logs_dir\": \"../logs\",\n", - " \"configs_dir\": \"../configs\",\n", - " \"checkpoints_dir\": \"../checkpoints\"\n", - " }\n", - ")\n", - "\n", - "loader = DataLoader(config)" - ], - "outputs": [], - "execution_count": 2 - }, - { - "metadata": { - "ExecuteTime": { - "end_time": "2025-09-21T12:07:02.954766Z", - "start_time": "2025-09-21T12:06:29.300866Z" - } - }, - "cell_type": "code", - "source": "df = loader.load_csv_complete(config.paths.data_dir / \"names_featured.csv\")", - "id": "171054a786856d23", - "outputs": [], - "execution_count": 3 - }, - { - "cell_type": "code", - "id": "295eda175081129c", - "metadata": { - "ExecuteTime": { - "end_time": "2025-09-21T12:08:17.955798Z", - "start_time": "2025-09-21T12:08:17.165693Z" - } - }, - "source": [ - "df.describe().T" - ], - "outputs": [ - { - "data": { - "text/plain": [ - " count mean std min 25% 50% 75% max\n", - "words 7901815.0 2.872912 0.466004 1.0 3.0 3.0 3.0 11.0\n", - "length 7901815.0 20.161653 3.796664 0.0 18.0 21.0 23.0 60.0\n", - "ner_tagged 6150395.0 0.998319 0.04097 0.0 1.0 1.0 1.0 1.0\n", - "annotated 6150395.0 0.998319 0.04097 0.0 1.0 1.0 1.0 1.0" - ], - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
countmeanstdmin25%50%75%max
words7901815.02.8729120.4660041.03.03.03.011.0
length7901815.020.1616533.7966640.018.021.023.060.0
ner_tagged6150395.00.9983190.040970.01.01.01.01.0
annotated6150395.00.9983190.040970.01.01.01.01.0
\n", - "
" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 6 - }, - { - "cell_type": "code", - "id": "c6f41484d947a77a", - "metadata": { - "ExecuteTime": { - "end_time": "2025-09-21T12:08:26.820519Z", - "start_time": "2025-09-21T12:08:26.426014Z" - } - }, - "source": [ - "import matplotlib.pyplot as plt\n", - "import seaborn as sns\n", - "import numpy as np\n", - "from scipy.interpolate import make_interp_spline\n", - "\n", - "# Step 1: Count frequencies\n", - "word_counts = df[\"words\"].value_counts().sort_index()\n", - "x = word_counts.index.values # distinct word counts\n", - "y = word_counts.values # their frequencies\n", - "\n", - "# Step 2: Create smoother X values (interpolation)\n", - "x_smooth = np.linspace(x.min(), x.max(), 300)\n", - "spline = make_interp_spline(x, y, k=3) # cubic spline\n", - "y_smooth = spline(x_smooth)\n", - "\n", - "# Step 3: Plot\n", - "plt.figure(figsize=(10, 6))\n", - "plt.plot(x_smooth, y_smooth, color='blue', label='Smoothed Curve')\n", - "plt.scatter(x, y, color='black', zorder=5, label='Actual Counts')\n", - "plt.title(\"Smoothed Word Count Distribution\")\n", - "plt.xlabel(\"Number of Words in Name\")\n", - "plt.ylabel(\"Frequency\")\n", - "plt.grid(True)\n", - "plt.legend()\n", - "plt.show()\n" - ], - "outputs": [ - { - "data": { - "text/plain": [ - "
" - ], - "image/png": "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UOSo7gPRe7GCnWnw9GSpbyIiIjJtOerFhIaGYurUqbh+/ToEQUBiYiKOHz+Ob775Bi1btjR0jESsYGciqlTRXJ/r12VITZU4GCIiIqIcyPGNYn19fdGhQwckJiaibdu26Nu3L+rUqYORI0caOkaidFPsyHiVKiWiQAERqakCIiM5ikRERESmJ0fz4aytrTF69GgMGzYMUVFRUKlUKFWqFAoUKGDo+Ijw+DHw4AEr2JkCmUwzihQWJseVKzLdiBIRERGRqchRgpRRIYaIiAjd/2vXrp3ziIjeol1/VLq0Gg4OEgdDWfL0VCEsTI7Ll2Vo107qaIiIiIj0k6MEqWfPnhlut7a2RtGiRbFnz55cBUX0Jt4g1rSwkh0RERGZshwlSFeuXEn3vUqlwt27dzF58mS0bt3aIIERaWkLNHB6nWngvZCIiIjIlBnkI165XI5y5cph9OjR+Pnnnw2xSyIdbUebFexMg3bd0Z07Mrx4IXEwRERERHoy6ByY+Ph4PHv2zJC7JAunVr9ZwY4JkilwcRFRtKjmWl29yml2REREZFpyNMVuzJgx72x7+fIljh49iubNm+c6KCKtO3cEJCYKsLERUb48EyRT4empxqNHMly+LIefH68bERERmY4cJUgZKVSoEEaNGoW2bdsaapdEuul1lSuroTBYa6W85umpxsGDwJUrHEEiIiIi05KjLue0adMMHQdRhji9zjRpKw6ykh0RERGZmhwlSPPnz8/2c4cMGZKTQxABSKtgxxLfpkVbqIEJEhEREZmaHCVId+7cwX///YdChQrB29sb1tbWuHLlCu7evYvq1atD8XoulCAIBg2WLA9HkEyTh4cagiAiLk6Ghw8FFCsmSh0SERERUbbkKEGytrZG69at8d1338HKykq3ffr06UhISMD3339vsADJciUlATdvakeQmCCZEnt7oGxZEbduCbhyRYZixTgCSERERKYhR/Nftm/fjk8//TRdcgQAnTp1wvbt2w0SGNG1azKo1QKKFFFzBMIEeXpyHRIRERGZnhz1XFxdXXHo0KF3tu/YsQOlSpXKdVBEQPrpdZytaXq4DomIiIhMUY6m2H311VcYNmwY9u/fjypVqgAALly4gIiICCxevNigAZLliojQlPjm+iPTpJ0WqS3VTkRERGQKcvTR7gcffICNGzeicuXKiIyMxP379+Hv748dO3bA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Gzcafprd3r1yRETIYW8volMnTq8jIiIiIgJMJEGyVJ07axKXZcusoTLgDDhRBH780RoA0KtXKpydDbdvIiIiIiJTxgTJiHXsmApnZxF378rw33+GG0U6dkyOkycVsLYWMWhQisH2S0RERERk6pggGTF7e+DjjzUJzOLFhivWoB096to1FcWLsx4lEREREZEWEyQj16dPKqysRJw4ocDZs7m/XKdOyXDggAJyuYghQzh6RERERET0JiZIRq54cRHt2mlKfi9ebJ2rfalUwNixtgA065vKlOHoERERERHRm5ggmYABAzQjPZs3KxAenvNL9r//WeHcOTkcHUWMGcPRIyIiIiKitzFBMgHVqqnRsWMqRFHAmDG2UKv138eTJ8DUqZoRqJEjk+HqytEjIiIiIqK3MUEyEd9+m4wCBUSEhcmxbp1+Fe1EEZgwwRaPH8tQpYoKffrwvkdERERERBlhgmQiXF1FjBiRDACYNMkG8fFCtl+7YoUV1q61gkwmYvr0ZFgZriAeEREREZFZYYJkQvr1S0XlyirExcnw8ce2SErK+jWnTskwdqwNAGDs2BTUqWPAO84SEREREZkZJkgmxNoaWLr0FZycRJw8qcCQIe9fjxQWJsPHH9shNVVAaGgqPv+chRmIiIiIiN6HCZKJ8fBQY/nyJFhZidiyxQq9e9siOjr9dDtRBP76S4F27ewRFyeDt7cKc+e+gpD9WXlERERERBZJv9X+ZBSCglSYN+8VBg+2xX//WeHQIQW6d09FuXJqvHwpYMMGBS5flgMAmjdPxcKFr+DgIHHQREREREQmgAmSierQQYkqVRIxYoQtTp+WY8mS9DeRtbERMXhwCkaOTIGM44RERERERNnCBMmEeXmpsXVrIv7+W4EzZ+S4d09ASoqAFi2UaN06FQULSh0hEREREZFpYYJk4mQyoH17Jdq3V0odChERERGRyePkKyIiIiIioteYIBEREREREb3GBImIiIiIiOg1JkhERERERESvMUEiIiIiIiJ6jQkSERERERHRa0yQiIiIiIiIXmOCRERERERE9BoTJCIiIiIioteYIBEREREREb3GBImIiIiIiOg1JkhERERERESvMUEiIiIiIiJ6jQkSERERERHRa0yQiIiIiIiIXmOCRERERERE9BoTJCIiIiIioteYIBEREREREb2mkDqAvCYIUkdA76O9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" - }, - "metadata": {}, - "output_type": "display_data", - "jetTransient": { - "display_id": null - } - } - ], - "execution_count": 7 - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "2533054dd18b57c7", - "metadata": { - "ExecuteTime": { - "end_time": "2025-07-08T16:02:00.928164Z", - "start_time": "2025-07-08T16:02:00.666031Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "import seaborn as sns\n", - "import numpy as np\n", - "from scipy.interpolate import make_interp_spline\n", - "\n", - "# Step 1: Count frequencies\n", - "word_counts = df[\"length\"].value_counts().sort_index()\n", - "x = word_counts.index.values # distinct word counts\n", - "y = word_counts.values # their frequencies\n", - "\n", - "# Step 2: Create smoother X values (interpolation)\n", - "x_smooth = np.linspace(x.min(), x.max(), 300)\n", - "spline = make_interp_spline(x, y, k=3) # cubic spline\n", - "y_smooth = spline(x_smooth)\n", - "\n", - "# Step 3: Plot\n", - "plt.figure(figsize=(10, 6))\n", - "plt.plot(x_smooth, y_smooth, color='blue', label='Smoothed Curve')\n", - "plt.scatter(x, y, color='black', zorder=5, label='Actual Counts')\n", - "plt.title(\"Smoothed Word Count Distribution\")\n", - "plt.xlabel(\"Number of Words in Name\")\n", - "plt.ylabel(\"Frequency\")\n", - "plt.grid(True)\n", - "plt.legend()\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "af313d893f31698f", - "metadata": { - "ExecuteTime": { - "end_time": "2025-07-08T16:08:48.468235Z", - "start_time": "2025-07-08T16:08:47.627659Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - ">> Using categorical units to plot a list of strings that are all parsable as floats or dates. If these strings should be plotted as numbers, cast to the appropriate data type before plotting.\n", - ">> Using categorical units to plot a list of strings that are all parsable as floats or dates. If these strings should be plotted as numbers, cast to the appropriate data type before plotting.\n" - ] - }, - { - "data": { - "image/png": "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jBihJUuWaNy4cXr33XfVvHnzbIOQ62G321WmTBmnvRIulhX2JCcnq0OHDgoKCtLkyZNVo0YNBQQEaPPmzXryySedJp2Ucv74AgAKNsIBAABuUmRkpObPn69ffvlFLVu2vOb4rG+ffX19FR4enis1VKlSRdKFb5cv/nb76NGjl31jXqNGDZ06dSrXtp2lW7du8vb21rvvvnvNb8lLly6twMBA7dmz57J1u3fvlpeXl+PsDll7PiQnJ6tYsWKOcVl7S9yInOzefym73a4///zTKTz5/fffJV04S0KWEiVKKDIyUkuWLFGfPn30448/XjbJ442oUaOGvvnmG7Vt2/aqH+jXrVunf/75R//973916623Opbv37//pmsAABRczDkAAMBNGjNmjAIDAzVgwAAlJiZetv7Sb6zLlCmjjh076vXXX9eRI0cuG3/pKQpzIjw8XL6+vnrllVectpfdh9J7771XGzdu1KpVqy5bl5ycrIyMjOveviRVqlRJDz/8sL7++mu98sorl6232+2aMWOGDh06JG9vb3Xt2lWfffaZ054ViYmJWrp0qdq1a+c4TKFGjRqS5DQXwunTp7V48eIbqlOSChcuLOlCv9djzpw5jv8bYzRnzhz5+vqqS5cuTuP69u2rXbt2afTo0fL29lbv3r1vuNYs9957rzIzMzVlypTL1mVkZDh6ydpz4uLnQXp6ul599dWbrgEAUHCx5wAAADepVq1aWrp0qe6//37dcsst6tOnjxo3bixjjPbv36+lS5fKy8tLFStWdFxn7ty5ateunRo2bKiHH35Y1atXV2JiojZu3KhDhw5p27Zt11VD6dKlNWrUKD333HPq3r277rjjDm3ZskUrVqxQqVKlnMaOHj1an3/+ubp37+44xd/p06cVFxenjz76SAcOHLjsOjk1Y8YM7du3T0OHDtV///tfde/eXcWLF1d8fLyWLVum3bt3Oz4oT506VatXr1a7du30+OOPy8fHR6+//rrS0tI0ffp0x2127dpVlStX1sCBAx0fthcsWKDSpUsrPj7+hups0qSJvL29NW3aNKWkpMjf31+dO3e+4vH8khQQEKCVK1cqKipKrVq10ooVK7R8+XKNGzfusvkbIiMjVbJkSS1btkzdunW76u3mVIcOHfToo4/queee09atW9W1a1f5+vpq7969WrZsmWbPnq27775bbdq0UfHixRUVFaWhQ4fKZrPpnXfeybPDKgAAHspt50kAAKCA+eOPP8ygQYNMzZo1TUBAgClUqJCpU6eOeeyxx8zWrVsvG79v3z7Tr18/U7ZsWePr62sqVKhgunfvbj766CPHmKzT9W3atMnput9+++1lp+LLzMw0kyZNMuXKlTOFChUyHTt2NDt27DBVqlRxOpWhMcacPHnSjB071tSsWdP4+fmZUqVKmTZt2pgXX3zRpKenG2P+dyrDF1544bruh4yMDDN//nzTvn17ExwcbHx9fU2VKlVM//79LzvN4ebNm01ERIQpUqSICQwMNJ06dTIbNmy47DZjY2NNq1atjJ+fn6lcubKZOXPmFU9lGBkZedn1O3ToYDp06OC07M033zTVq1c33t7e1zytYVRUlClcuLDZt2+f6dq1qwkMDDQhISFmwoQJJjMzM9vrPP7440aSWbp06RVv90qyHt9ly5Zdtu6NN94woaGhplChQqZo0aKmYcOGZsyYMebw4cOOMT/++KNp3bq1KVSokClfvrwZM2aMWbVq1WV9dujQwdSvX/+66wMAFDw2Y4iRAQAActuIESP01ltvKSEhQYGBge4uBwCAq2LOAQAAgFx27tw5vfvuu+rVqxfBAADAIzDnAAAAQC5JSkrSN998o48++kj//POPhg0b5u6SAADIEcIBAACAXLJr1y716dNHZcqU0csvv6wmTZq4uyQAAHKEOQcAAAAAALA45hwAAAAAAMDiCAcAAAAAALA45hzIQ3a7XYcPH1bRokVls9ncXQ4AAAAAoIAzxujkyZMqX768vLyuvH8A4UAeOnz4sCpVquTuMgAAAAAAFnPw4EFVrFjxiusJB/JQ0aJFJV14UIKCgtxcDQAAAACgoEtNTVWlSpUcn0evhHAgD2UdShAUFEQ4AAAAAADIM9c6tJ0JCQEAAAAAsDjCAQAAAAAALI5wAAAAAAAAi2POgXwoMzNT58+fd3cZecbPz++qp9QAAAAAALgW4UA+YoxRQkKCkpOT3V1KnvLy8lK1atXk5+fn7lIAAAAAwJIIB/KRrGCgTJkyCgwMvOZskgWB3W7X4cOHdeTIEVWuXNkSPQMAAABAfkM4kE9kZmY6goGSJUu6u5w8Vbp0aR0+fFgZGRny9fV1dzkAAAAAYDkc6J1PZM0xEBgY6OZK8l7W4QSZmZlurgQAAAAArIlwIJ+x4m71VuwZAAAAAPITwgEAAAAAACyOcAA51rFjRw0fPtzdZQAAAAAAchnhgIdJSEjQsGHDVLNmTQUEBCgkJERt27bVa6+9pjNnzri7PAAAAACAB+JsBR7kzz//VNu2bVWsWDE9++yzatiwofz9/RUXF6c33nhDFSpU0L/+9S93l3lFmZmZstls8vIikwIAAACA/IRPaR7k8ccfl4+Pj3799Vfde++9qlu3rqpXr65///vfWr58ue68805JUnJysh566CGVLl1aQUFB6ty5s7Zt2+a4nYkTJ6pJkyZ65513VLVqVQUHB6t37946efKkY8zp06fVr18/FSlSROXKldOMGTMuqyctLU2jRo1ShQoVVLhwYbVq1Urr1q1zrF+0aJGKFSumzz//XPXq1ZO/v7/i4+NddwcBAAAAAG4I4YCH+Oeff/T1118rOjpahQsXznZM1qz/99xzj5KSkrRixQrFxsaqWbNm6tKli44fP+4Yu2/fPn366af68ssv9eWXX2r9+vV6/vnnHetHjx6t9evX67PPPtPXX3+tdevWafPmzU7bGzx4sDZu3Kj3339f27dv1z333KPbb79de/fudYw5c+aMpk2bpvnz52vnzp0qU6ZMbt4tAAAAAIBcwGEFHuKPP/6QMUa33HKL0/JSpUrp3LlzkqTo6Gjdeeed+uWXX5SUlCR/f39J0osvvqhPP/1UH330kR555BFJkt1u16JFi1S0aFFJUt++fbVmzRr93//9n06dOqW33npL7777rrp06SJJWrx4sSpWrOjYbnx8vBYuXKj4+HiVL19ekjRq1CitXLlSCxcu1LPPPitJOn/+vF599VU1btzYhfcOAAAAAOBmEA54uF9++UV2u119+vRRWlqatm3bplOnTqlkyZJO486ePat9+/Y5LletWtURDEhSuXLllJSUJOnCXgXp6elq1aqVY32JEiWcgom4uDhlZmaqdu3aTttJS0tz2rafn58aNWqUO80CAAAAAFyCcMBD1KxZUzabTXv27HFaXr16dUlSoUKFJEmnTp1SuXLlnI79z1KsWDHH/319fZ3W2Ww22e32HNdz6tQpeXt7KzY2Vt7e3k7rihQp4vh/oUKFHIc7AAAAAADyJ8IBD1GyZEnddtttmjNnjoYMGXLFeQeaNWumhIQE+fj4qGrVqje0rRo1asjX11c///yzKleuLEk6ceKEfv/9d3Xo0EGS1LRpU2VmZiopKUnt27e/oe0AAAAAAPIHwgEP8uqrr6pt27Zq3ry5Jk6cqEaNGsnLy0ubNm3S7t27FRoaqvDwcIWFhalHjx6aPn26ateurcOHD2v58uW666671Lx582tup0iRIho4cKBGjx6tkiVLqkyZMnr66aedTkFYu3Zt9enTR/369dOMGTPUtGlTHT16VGvWrFGjRo0UGRnpyrsCAAAAADxK/OSGLt9G5Zi4G74u4YAHqVGjhrZs2aJnn31WY8eO1aFDh+Tv76969epp1KhRevzxx2Wz2fTVV1/p6aefVv/+/XX06FGVLVtWt956q0JCQnK8rRdeeEGnTp3SnXfeqaJFi+qJJ55QSkqK05iFCxdq6tSpeuKJJ/T333+rVKlSat26tbp3757brQMAAAAAXMhmjDHuLsIqUlNTFRwcrJSUFAUFBTmtO3funPbv369q1aopICDATRW6h5V7BwAAAGAN7tpz4GqfQy/mdcU1AAAAAADAEggHAAAAAACwOMIBAAAAAAAsjnAAAAAAAACLIxwAAAAAAMDiCAcAAAAAALA4wgEAAAAAACyOcAAAAAAAAIsjHAAAAAAAwOIIB3DTjDF65JFHVKJECdlsNm3dutXdJQEAAAAAroOPuwvA1YWOfjtPtxf7Qr/rvs7KlSu1aNEirVu3TtWrV1epUqVcUBkAAAAAwFUIB3DT9u3bp3LlyqlNmzbuLgUAAAAAcAMIB3BTHnzwQS1evFiSZLPZVKVKFR04cMC9RQEAAAAArgvhAG7K7NmzVaNGDb3xxhvatGmTvL293V0SAAAAAOA6EQ7gpgQHB6to0aLy9vZW2bJl3V0OAAAAAOAGcLYCAAAAAAAsjnAAAAAAAACLIxwAAAAAAMDiCAcAAAAAALA4JiTM52Jf6OfuEgAAAAAABRx7DuCmDR8+XAcOHHB3GQAAAACAG0Q4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHE+7i4AVxc/uWGebq9yTFyebg8AAAAA4H7sOQAAAAAAgMURDuCmdezYUUOGDNHw4cNVvHhxhYSE6M0339Tp06fVv39/FS1aVDVr1tSKFSvcXSoAAAAAIBuEA8gVixcvVqlSpfTLL79oyJAhGjRokO655x61adNGmzdvVteuXdW3b1+dOXPG3aUCAAAAAC5BOIBc0bhxY40fP161atXS2LFjFRAQoFKlSunhhx9WrVq1FBMTo3/++Ufbt293d6kAAAAAgEsQDiBXNGrUyPF/b29vlSxZUg0b/m8yxZCQEElSUlJSntcGAAAAALi6fBMOPP/887LZbBo+fLhj2blz5xQdHa2SJUuqSJEi6tWrlxITE52uFx8fr8jISAUGBqpMmTIaPXq0MjIynMasW7dOzZo1k7+/v2rWrKlFixZdtv25c+eqatWqCggIUKtWrfTLL784rc9JLVbm6+vrdNlmszkts9lskiS73Z6ndQEAAAAAri1fhAObNm3S66+/7vTtsySNGDFCX3zxhZYtW6b169fr8OHD6tmzp2N9ZmamIiMjlZ6erg0bNmjx4sVatGiRYmJiHGP279+vyMhIderUSVu3btXw4cP10EMPadWqVY4xH3zwgUaOHKkJEyZo8+bNaty4sSIiIpy+5b5WLQAAAAAAeCq3hwOnTp1Snz599Oabb6p48eKO5SkpKXrrrbc0c+ZMde7cWaGhoVq4cKE2bNign376SZL09ddfa9euXXr33XfVpEkTdevWTVOmTNHcuXOVnp4uSZo3b56qVaumGTNmqG7duho8eLDuvvtuvfTSS45tzZw5Uw8//LD69++vevXqad68eQoMDNSCBQtyXAsAAAAAAJ7Kx90FREdHKzIyUuHh4Zo6dapjeWxsrM6fP6/w8HDHsjp16qhy5crauHGjWrdurY0bN6phw4aO49klKSIiQoMGDdLOnTvVtGlTbdy40ek2ssZkHb6Qnp6u2NhYjR071rHey8tL4eHh2rhxY45ryU5aWprS0tIcl1NTU6/7/qkcE3fd1wEAAAAA4Hq4NRx4//33tXnzZm3atOmydQkJCfLz81OxYsWcloeEhCghIcEx5uJgIGt91rqrjUlNTdXZs2d14sQJZWZmZjtm9+7dOa4lO88995wmTZp0xfUFxbp16y5bduDAgcuWGWNcXwwAAAAA4Lq57bCCgwcPatiwYVqyZIkCAgLcVYZLjR07VikpKY6fgwcPurskAAAAAAAu47ZwIDY2VklJSWrWrJl8fHzk4+Oj9evX6+WXX5aPj49CQkKUnp6u5ORkp+slJiaqbNmykqSyZctedsaArMvXGhMUFKRChQqpVKlS8vb2znbMxbdxrVqy4+/vr6CgIKcfAAAAAADyG7eFA126dFFcXJy2bt3q+GnevLn69Onj+L+vr6/WrFnjuM6ePXsUHx+vsLAwSVJYWJji4uKcziqwevVqBQUFqV69eo4xF99G1pis2/Dz81NoaKjTGLvdrjVr1jjGhIaGXrMWAAAAAAA8ldvmHChatKgaNGjgtKxw4cIqWbKkY/nAgQM1cuRIlShRQkFBQRoyZIjCwsIcEwB27dpV9erVU9++fTV9+nQlJCRo/Pjxio6Olr+/vyTpscce05w5czRmzBgNGDBAa9eu1Ycffqjly5c7tjty5EhFRUWpefPmatmypWbNmqXTp0+rf//+kqTg4OBr1gIAAAAAgKdy+9kKruall16Sl5eXevXqpbS0NEVEROjVV191rPf29taXX36pQYMGKSwsTIULF1ZUVJQmT57sGFOtWjUtX75cI0aM0OzZs1WxYkXNnz9fERERjjH33Xefjh49qpiYGCUkJKhJkyZauXKl0ySF16olt1hx0j4r9gwAAAAA+YnN8Mksz6Smpio4OFgpKSmXzT+QmZmp33//XWXKlFHJkiXdVKF7pKSk6PDhw6pZs6Z8fX3dXQ4AAAAA5Lr4yQ1dvo3KMXGXLbva59CL5es9B6zE29tbxYoVc8yfEBgYKJvN5uaqXM9ut+vo0aMKDAyUjw9PRwAAAABwBz6N5SNZZz64eIJFK/Dy8lLlypUtEYYAAAAAQH5EOJCP2Gw2lStXTmXKlNH58+fdXU6e8fPzk5eX206cAQAAAACWRziQD3l7e8vb29vdZQAAAAAALIKvawEAAAAAsDjCAQAAAAAALI5wAAAAAAAAiyMcAAAAAADA4ggHAAAAAACwOMIBAAAAAAAsjnAAAAAAAACLIxwAAAAAAMDiCAcAAAAAALA4wgEAAAAAACyOcAAAAAAAAIsjHAAAAAAAwOIIBwAAAAAAsDjCAQAAAAAALI5wAAAAAAAAiyMcAAAAAADA4ggHAAAAAACwOMIBAAAAAAAsjnAAAAAAAACLIxwAAAAAAMDiCAcAAAAAALA4wgEAAAAAACyOcAAAAAAAAIsjHAAAAAAAwOIIBwAAAAAAsDjCAQAAAAAALI5wAAAAAAAAiyMcAAAAAADA4ggHAAAAAACwOMIBAAAAAAAsjnAAAAAAAACLIxwAAAAAAMDiCAcAAAAAALA4wgEAAAAAACyOcAAAAAAAAIvzcXcBAAAAAADriJ/c0OXbqBwT5/JtFDTsOQAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFufj7gIAAAAAAHCn0NFvu3wbnxR1+SZuCnsOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHE+7i4AAAAAwAXxkxu6fBuVY+Jcvg0Anoc9BwAAAAAAsDjCAQAAAAAALI5wAAAAAAAAiyMcAAAAAADA4ggHAAAAAACwOMIBAAAAAAAsjnAAAAAAAACLIxwAAAAAAMDiCAcAAAAAALA4t4YDr732mho1aqSgoCAFBQUpLCxMK1ascKw/d+6coqOjVbJkSRUpUkS9evVSYmKi023Ex8crMjJSgYGBKlOmjEaPHq2MjAynMevWrVOzZs3k7++vmjVratGiRZfVMnfuXFWtWlUBAQFq1aqVfvnlF6f1OakFAAAAAABP5NZwoGLFinr++ecVGxurX3/9VZ07d9a///1v7dy5U5I0YsQIffHFF1q2bJnWr1+vw4cPq2fPno7rZ2ZmKjIyUunp6dqwYYMWL16sRYsWKSYmxjFm//79ioyMVKdOnbR161YNHz5cDz30kFatWuUY88EHH2jkyJGaMGGCNm/erMaNGysiIkJJSUmOMdeqBQAAAAAAT2Uzxhh3F3GxEiVK6IUXXtDdd9+t0qVLa+nSpbr77rslSbt371bdunW1ceNGtW7dWitWrFD37t11+PBhhYSESJLmzZunJ598UkePHpWfn5+efPJJLV++XDt27HBso3fv3kpOTtbKlSslSa1atVKLFi00Z84cSZLdblelSpU0ZMgQPfXUU0pJSblmLTmRmpqq4OBgpaSkKCgoKNfuMwAAABQM8ZMbunwblWPiXL4N4Gry4/M8dPTbLqrkfz4p+oLLt5Fd3zn9HJpv5hzIzMzU+++/r9OnTyssLEyxsbE6f/68wsPDHWPq1KmjypUra+PGjZKkjRs3qmHDho5gQJIiIiKUmprq2Ptg48aNTreRNSbrNtLT0xUbG+s0xsvLS+Hh4Y4xOaklO2lpaUpNTXX6AQAAAAAgv3F7OBAXF6ciRYrI399fjz32mD755BPVq1dPCQkJ8vPzU7FixZzGh4SEKCEhQZKUkJDgFAxkrc9ad7UxqampOnv2rI4dO6bMzMxsx1x8G9eqJTvPPfecgoODHT+VKlXK2Z0CAAAAAEAecns4cMstt2jr1q36+eefNWjQIEVFRWnXrl3uLitXjB07VikpKY6fgwcPurskAAAAAAAu4+PuAvz8/FSzZk1JUmhoqDZt2qTZs2frvvvuU3p6upKTk52+sU9MTFTZsmUlSWXLlr3srAJZZxC4eMylZxVITExUUFCQChUqJG9vb3l7e2c75uLbuFYt2fH395e/v/913BsAAAAAAOQ9t+85cCm73a60tDSFhobK19dXa9ascazbs2eP4uPjFRYWJkkKCwtTXFyc01kFVq9eraCgINWrV88x5uLbyBqTdRt+fn4KDQ11GmO327VmzRrHmJzUAgAAAACAp3LrngNjx45Vt27dVLlyZZ08eVJLly7VunXrtGrVKgUHB2vgwIEaOXKkSpQooaCgIA0ZMkRhYWGOswN07dpV9erVU9++fTV9+nQlJCRo/Pjxio6Odnxj/9hjj2nOnDkaM2aMBgwYoLVr1+rDDz/U8uXLHXWMHDlSUVFRat68uVq2bKlZs2bp9OnT6t+/vyTlqBYAAAAAADyVW8OBpKQk9evXT0eOHFFwcLAaNWqkVatW6bbbbpMkvfTSS/Ly8lKvXr2UlpamiIgIvfrqq47re3t768svv9SgQYMUFhamwoULKyoqSpMnT3aMqVatmpYvX64RI0Zo9uzZqlixoubPn6+IiAjHmPvuu09Hjx5VTEyMEhIS1KRJE61cudJpksJr1QIAAAAAgKeyGWOMu4uwipyeXxIAAADWlB/P/w7ktvz4PA8d/baLKvmfT4q+4PJtZNd3Tj+H5rs5BwAAAAAAQN4iHAAAAAAAwOLcfipDAAAA4FL5cbdjACjI2HMAAAAAAACLIxwAAAAAAMDiCAcAAAAAALA4wgEAAAAAACyOcAAAAAAAAIsjHAAAAAAAwOIIBwAAAAAAsDjCAQAAAAAALI5wAAAAAAAAiyMcAAAAAADA4ggHAAAAAACwOMIBAAAAAAAsjnAAAAAAAACLIxwAAAAAAMDiCAcAAAAAALA4wgEAAAAAACyOcAAAAAAAAIvzcXcBAAAAAGBF8ZMbunwblWPiXL4NFAzsOQAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAW53MjV6pevbo2bdqkkiVLOi1PTk5Ws2bN9Oeff+ZKcQAAAACAvBM6+m2Xb+OToi7fBG7ADe05cODAAWVmZl62PC0tTX///fdNFwUAAAAAAPLOde058Pnnnzv+v2rVKgUHBzsuZ2Zmas2aNapatWquFQcAAAAAAFzvusKBHj16SJJsNpuioqKc1vn6+qpq1aqaMWNGrhUHAAAAAABc77rCAbvdLkmqVq2aNm3apFKlSrmkKAAAAAAAkHduaELC/fv353YdAAAAAADATW4oHJCkNWvWaM2aNUpKSnLsUZBlwYIFN10YAAAApPjJDV2+jcoxcS7fBgAgf7uhcGDSpEmaPHmymjdvrnLlyslms+V2XQAAAAAAII/cUDgwb948LVq0SH379s3tegAAAAAAQB7zupErpaenq02bNrldCwAAAAAAcIMbCgceeughLV26NLdrAQAAAAAAbnBDhxWcO3dOb7zxhr755hs1atRIvr6+TutnzpyZK8UBAAAAAADXu6FwYPv27WrSpIkkaceOHU7rmJwQAAAAAADPckPhwLfffpvbdQAAAAAAADe5oTkHAAAAAABAwXFDew506tTpqocPrF279oYLAgAAAAAAeeuGwoGs+QaynD9/Xlu3btWOHTsUFRWVG3UBAAAAAIA8ckPhwEsvvZTt8okTJ+rUqVM3VRAAAAAAAMhbuTrnwAMPPKAFCxbk5k0CAAAAAAAXy9VwYOPGjQoICMjNmwQAAAAAAC52Q4cV9OzZ0+myMUZHjhzRr7/+qmeeeSZXCgMAAAAAAHnjhsKB4OBgp8teXl665ZZbNHnyZHXt2jVXCgMAAAAAAHnjhsKBhQsX5nYdAAAAAADATW4oHMgSGxur3377TZJUv359NW3aNFeKAgAAAAAAeeeGwoGkpCT17t1b69atU7FixSRJycnJ6tSpk95//32VLl06N2sEAAAAAAAudEPhwJAhQ3Ty5Ent3LlTdevWlSTt2rVLUVFRGjp0qN57771cLRIAACB+ckOXb6NyTJzLtwEAQH50Q+HAypUr9c033ziCAUmqV6+e5s6dy4SEAAAAAAB4GK8buZLdbpevr+9ly319fWW322+6KAAAAAAAkHduKBzo3Lmzhg0bpsOHDzuW/f333xoxYoS6dOmSa8UBAAAAAADXu6FwYM6cOUpNTVXVqlVVo0YN1ahRQ9WqVVNqaqpeeeWV3K4RAAAAAAC40A3NOVCpUiVt3rxZ33zzjXbv3i1Jqlu3rsLDw3O1OAAAAAAA4HrXtefA2rVrVa9ePaWmpspms+m2227TkCFDNGTIELVo0UL169fX999/76paAQAAAACAC1xXODBr1iw9/PDDCgoKumxdcHCwHn30Uc2cOTPXigMAAAAAAK53XYcVbNu2TdOmTbvi+q5du+rFF1+86aIAAMCVxU9u6PJtVI6Jc/k2AABA/nFdew4kJiZmewrDLD4+Pjp69OhNFwUAAAAAAPLOdYUDFSpU0I4dO664fvv27SpXrtxNFwUAAAAAAPLOdYUDd9xxh5555hmdO3fusnVnz57VhAkT1L1791wrDgAAAAAAuN51zTkwfvx4/fe//1Xt2rU1ePBg3XLLLZKk3bt3a+7cucrMzNTTTz/tkkIBAAAAAIBrXFc4EBISog0bNmjQoEEaO3asjDGSJJvNpoiICM2dO1chISEuKRQAAAAAALjGdYUDklSlShV99dVXOnHihP744w8ZY1SrVi0VL17cFfUBAAAAAAAXu+5wIEvx4sXVokWL3KwFAAAAAAC4wQ2HAwCA/IPz3gMAAOBmXNfZCgAAAAAAQMFDOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBwTEgIoUJiYDwDgKqGj33b5Nj4p6vJNAEC23LrnwHPPPacWLVqoaNGiKlOmjHr06KE9e/Y4jTl37pyio6NVsmRJFSlSRL169VJiYqLTmPj4eEVGRiowMFBlypTR6NGjlZGR4TRm3bp1atasmfz9/VWzZk0tWrTosnrmzp2rqlWrKiAgQK1atdIvv/xy3bUAAAAAAOBp3BoOrF+/XtHR0frpp5+0evVqnT9/Xl27dtXp06cdY0aMGKEvvvhCy5Yt0/r163X48GH17NnTsT4zM1ORkZFKT0/Xhg0btHjxYi1atEgxMTGOMfv371dkZKQ6deqkrVu3avjw4XrooYe0atUqx5gPPvhAI0eO1IQJE7R582Y1btxYERERSkpKynEtAAAAAAB4IrceVrBy5Uqny4sWLVKZMmUUGxurW2+9VSkpKXrrrbe0dOlSde7cWZK0cOFC1a1bVz/99JNat26tr7/+Wrt27dI333yjkJAQNWnSRFOmTNGTTz6piRMnys/PT/PmzVO1atU0Y8YMSVLdunX1ww8/6KWXXlJERIQkaebMmXr44YfVv39/SdK8efO0fPlyLViwQE899VSOagEAAAAAwBPlqwkJU1JSJEklSpSQJMXGxur8+fMKDw93jKlTp44qV66sjRs3SpI2btyohg0bKiQkxDEmIiJCqamp2rlzp2PMxbeRNSbrNtLT0xUbG+s0xsvLS+Hh4Y4xOanlUmlpaUpNTXX6AQAAAAAgv8k34YDdbtfw4cPVtm1bNWjQQJKUkJAgPz8/FStWzGlsSEiIEhISHGMuDgay1metu9qY1NRUnT17VseOHVNmZma2Yy6+jWvVcqnnnntOwcHBjp9KlSrl8N4AAAAAACDv5JtwIDo6Wjt27ND777/v7lJyzdixY5WSkuL4OXjwoLtLAgAAAADgMvniVIaDBw/Wl19+qe+++04VK1Z0LC9btqzS09OVnJzs9I19YmKiypYt6xhz6VkFss4gcPGYS88qkJiYqKCgIBUqVEje3t7y9vbOdszFt3GtWi7l7+8vf3//67gnAAAAAADIe27dc8AYo8GDB+uTTz7R2rVrVa1aNaf1oaGh8vX11Zo1axzL9uzZo/j4eIWFhUmSwsLCFBcX53RWgdWrVysoKEj16tVzjLn4NrLGZN2Gn5+fQkNDncbY7XatWbPGMSYntQAAAAAA4IncuudAdHS0li5dqs8++0xFixZ1HLsfHBysQoUKKTg4WAMHDtTIkSNVokQJBQUFaciQIQoLC3OcHaBr166qV6+e+vbtq+nTpyshIUHjx49XdHS041v7xx57THPmzNGYMWM0YMAArV27Vh9++KGWL1/uqGXkyJGKiopS8+bN1bJlS82aNUunT592nL0gJ7UAAAAAAOCJ3BoOvPbaa5Kkjh07Oi1fuHChHnzwQUnSSy+9JC8vL/Xq1UtpaWmKiIjQq6++6hjr7e2tL7/8UoMGDVJYWJgKFy6sqKgoTZ482TGmWrVqWr58uUaMGKHZs2erYsWKmj9/vuM0hpJ033336ejRo4qJiVFCQoKaNGmilStXOk1SeK1aAAAAAADwRG4NB4wx1xwTEBCguXPnau7cuVccU6VKFX311VdXvZ2OHTtqy5YtVx0zePBgDR48+KZqAQAAAADA0+SLCQkBAADgOUJHv+3ybXxS1OWbAABcJN+cyhAAAAAAALgH4QAAAAAAABbHYQUAAAAAcAkOn4HVsOcAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMVxKkOggIqf3NDl26gcE+fybQAAAABwPfYcAAAAAADA4ggHAAAAAACwOMIBAAAAAAAsjnAAAAAAAACLIxwAAAAAAMDiCAcAAAAAALA4wgEAAAAAACyOcAAAAAAAAIsjHAAAAAAAwOIIBwAAAAAAsDjCAQAAAAAALI5wAAAAAAAAiyMcAAAAAADA4nzcXQAAADcqfnJDl2+jckycy7cBAADgbuw5AAAAAACAxREOAAAAAABgcYQDAAAAAABYHHMOoMDjmGQAAAAAuDr2HAAAAAAAwOIIBwAAAAAAsDjCAQAAAAAALI5wAAAAAAAAiyMcAAAAAADA4ggHAAAAAACwOMIBAAAAAAAszsfdBQAAAHiq0NFvu3wbnxR1+SYAAGDPAQAAAAAArI5wAAAAAAAAiyMcAAAAAADA4ggHAAAAAACwOMIBAAAAAAAsjnAAAAAAAACLIxwAAAAAAMDiCAcAAAAAALA4wgEAAAAAACyOcAAAAAAAAIsjHAAAAAAAwOIIBwAAAAAAsDjCAQAAAAAALM7H3QUAAADPFzr6bZdv45OiLt8EAACWxZ4DAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcT7uLgAAgIIkdPTbLt/GJ0VdvgkAAGAx7DkAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcT7uLgB5J35yQ5dvo3JMnMu3AQAAAADIXew5AAAAAACAxbl1z4HvvvtOL7zwgmJjY3XkyBF98skn6tGjh2O9MUYTJkzQm2++qeTkZLVt21avvfaaatWq5Rhz/PhxDRkyRF988YW8vLzUq1cvzZ49W0WKFHGM2b59u6Kjo7Vp0yaVLl1aQ4YM0ZgxY5xqWbZsmZ555hkdOHBAtWrV0rRp03THHXdcVy0AkJ3Q0W+7fBufFHX5JgAAAFCAuTUcOH36tBo3bqwBAwaoZ8+el62fPn26Xn75ZS1evFjVqlXTM888o4iICO3atUsBAQGSpD59+ujIkSNavXq1zp8/r/79++uRRx7R0qVLJUmpqanq2rWrwsPDNW/ePMXFxWnAgAEqVqyYHnnkEUnShg0bdP/99+u5555T9+7dtXTpUvXo0UObN29WgwYNclwLgKvjQzIAAACQP7k1HOjWrZu6deuW7TpjjGbNmqXx48fr3//+tyTp7bffVkhIiD799FP17t1bv/32m1auXKlNmzapefPmkqRXXnlFd9xxh1588UWVL19eS5YsUXp6uhYsWCA/Pz/Vr19fW7du1cyZMx3hwOzZs3X77bdr9OjRkqQpU6Zo9erVmjNnjubNm5ejWgAAAAAA8FT5ds6B/fv3KyEhQeHh4Y5lwcHBatWqlTZu3ChJ2rhxo4oVK+YIBiQpPDxcXl5e+vnnnx1jbr31Vvn5+TnGREREaM+ePTpx4oRjzMXbyRqTtZ2c1JKdtLQ0paamOv0AAAAAAJDf5NtwICEhQZIUEhLitDwkJMSxLiEhQWXKlHFa7+PjoxIlSjiNye42Lt7GlcZcvP5atWTnueeeU3BwsOOnUqVK1+gaAAAAAIC8l2/DgYJg7NixSklJcfwcPHjQ3SUBAAAAAHCZfBsOlC1bVpKUmJjotDwxMdGxrmzZskpKSnJan5GRoePHjzuNye42Lt7GlcZcvP5atWTH399fQUFBTj8AAAAAAOQ3+TYcqFatmsqWLas1a9Y4lqWmpurnn39WWFiYJCksLEzJycmKjY11jFm7dq3sdrtatWrlGPPdd9/p/PnzjjGrV6/WLbfcouLFizvGXLydrDFZ28lJLQAAAAAAeCq3hgOnTp3S1q1btXXrVkkXJv7bunWr4uPjZbPZNHz4cE2dOlWff/654uLi1K9fP5UvX149evSQJNWtW1e33367Hn74Yf3yyy/68ccfNXjwYPXu3Vvly5eXJP3nP/+Rn5+fBg4cqJ07d+qDDz7Q7NmzNXLkSEcdw4YN08qVKzVjxgzt3r1bEydO1K+//qrBgwdLUo5qAQAAAADAU7n1VIa//vqrOnXq5Lic9YE9KipKixYt0pgxY3T69Gk98sgjSk5OVrt27bRy5UoFBAQ4rrNkyRINHjxYXbp0kZeXl3r16qWXX37ZsT44OFhff/21oqOjFRoaqlKlSikmJsZxGkNJatOmjZYuXarx48dr3LhxqlWrlj799FM1aNDAMSYntQAAAAAA4IncGg507NhRxpgrrrfZbJo8ebImT558xTElSpTQ0qVLr7qdRo0a6fvvv7/qmHvuuUf33HPPTdUCAAAAAIAnyrdzDgAAAAAAgLxBOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWJxbJyQEABRcoaPfdvk2Pinq8k0AAABYAnsOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFMSEh4AZM1AYAAAAgP2HPAQAAAAAALI5wAAAAAAAAi+OwArgVu9cDAAAAgPux5wAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAW5+PuAnBB6Oi3Xb6NT4q6fBMAAAAAAA/EngMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AAAAAACAxREOAAAAAABgcYQDAAAAAABYHOEAAAAAAAAWRzgAAAAAAIDFEQ4AAAAAAGBxhAMAAAAAAFgc4QAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWJyPuwvwNHPnztULL7yghIQENW7cWK+88opatmzp7rIAAAAAjxU/uaHLt1E5Js7l2wA8GXsOXIcPPvhAI0eO1IQJE7R582Y1btxYERERSkpKcndpAAAAAADcMMKB6zBz5kw9/PDD6t+/v+rVq6d58+YpMDBQCxYscHdpAAAAAADcMA4ryKH09HTFxsZq7NixjmVeXl4KDw/Xxo0bs71OWlqa0tLSHJdTUlIkSampqZeNzUw7m8sVX+6kb6bLt5Fdb1dD365D365D3zlD365D365D3zlD366TH/u+dfx7Lqrkf5YUyX99W/Xxpm/XcVffWcuMMVe9rs1cawQkSYcPH1aFChW0YcMGhYWFOZaPGTNG69ev188//3zZdSZOnKhJkyblZZkAAAAAAFzm4MGDqlix4hXXs+eAC40dO1YjR450XLbb7Tp+/LhKliwpm82Wp7WkpqaqUqVKOnjwoIKCgvJ02+5E3/RtBfRN31ZA3/RtBfRN31ZA33nftzFGJ0+eVPny5a86jnAgh0qVKiVvb28lJiY6LU9MTFTZsmWzvY6/v7/8/f2dlhUrVsxVJeZIUFCQpX4Js9C3tdC3tdC3tdC3tdC3tdC3tdB33goODr7mGCYkzCE/Pz+FhoZqzZo1jmV2u11r1qxxOswAAAAAAABPw54D12HkyJGKiopS8+bN1bJlS82aNUunT59W//793V0aAAAAAAA3jHDgOtx33306evSoYmJilJCQoCZNmmjlypUKCQlxd2nX5O/vrwkTJlx2mENBR9/0bQX0Td9WQN/0bQX0Td9WQN/5t2/OVgAAAAAAgMUx5wAAAAAAABZHOAAAAAAAgMURDgAAAAAAYHGEAwAAAAAAWBzhAAAAAAAAFkc4AFgQJymBFfA8tw673e7uEtzi3LlzkqzbvxV/x63YM2AV+eH3m3DA4k6fPq309HSdOHFCEm8wCrrMzEyny1Z7vK3yOFtdenq6JCktLU2SdR73vXv3auvWre4uI8/t27dPc+bM0dGjR91dSp7atWuX6tSpo23btsnLyzpv51JTU3XixAklJCTIZrNZ5nUsIyND0v/+nlml70v/flvl7zmsJev9eX54fvu4uwC4z65duzR69GidOHFCGRkZevnll9W6dWt3l+Vye/bs0dKlS/XXX3+pefPm6tChgxo2bChjjGw2m7vLc5nffvtNr7zyig4fPqy6devq7rvvVmhoqLvLcrlDhw4pMTFRoaGhBfrxvdQff/yhDz/8UHv27FH79u0VHh6uqlWrurssl9u9e7emTZumw4cPq2zZsho9erQaNGjg7rJcbtu2bWratKnmzp2rJk2auLucPLN9+3Z17txZUVFROnbsmEqXLi273V7gPyxv3bpVXbp00YkTJ7R69Wo1btzYEn3v3LlTgwYN0qlTp3To0CG9++676tq1q7vLcrms1++jR4+qfPny6t27t8LCwtxdlsvt2bNHS5YsUXx8vNq1a6d27dqpTp06Bf65npiYqJSUFNWuXdvdpeSp/fv3a9WqVfr999/VrVs3NW3aVKVKlXJ3WS73+++/67XXXlN8fLwaN26svn37qlq1am6rp+D+ZuGqdu3apXbt2ql27drq2bOnqlatqgkTJujcuXP5IrVylR07digsLEyHDh1ScnKyli9frg4dOmjVqlUF+oPj7t271bp1a505c0Y+Pj6KjY1V27Zt9c4777i7NJfas2ePmjdvrkGDBumHH35wdzl5ZseOHWrTpo22bdumvXv36o033tC0adN0+vRpd5fmUnFxcWrTpo38/f1Vo0YNJSYmaubMmTp//nyB/ru2bds2tWnTRmPGjNGgQYPcXU6eOXLkiHr27KmoqCjNmDFDdevWlfS/PUYKqm3btiksLEzDhw/XsGHDNG/ePGVkZMjLy6tAP893796tDh06qHXr1ho9erTuuusuDR48WKmpqZLyxzdurrBz5061bdtWxhiVLl1aiYmJuvXWWzV//vwC/Td9165datWqlXbt2qW9e/dq/vz5uu2227RmzZoC/Vz/7bff1LJlSz3zzDPauXOnu8vJM3FxcWrXrp0+//xzffnllxoyZIgWLFggu91eYB9r6X/vW06cOCG73a4VK1bovffekzHGfX0bWM7Zs2fNXXfdZQYNGuRY9tZbb5k+ffqY9PR0c/ToUTdW5zqnTp0yERERZtSoUY5lsbGxpnjx4sbf3998+OGHxhhjMjMz3VWiyzz++OOmR48ejsuJiYlm/Pjxxtvb27z66qvGGGPsdru7ynOJI0eOmI4dO5q2bduabt26ma5du5rvvvvO3WW5XHx8vKlXr5556qmnHMvmzp1rqlevbv7++283VuZaf/75p6lRo4Z5+umnHcsmTpxoBgwYYIy58PtvTMH7/f7tt9+Mj4+P4/G22+3m448/Ns8++6x57733zJ49e9xcoeusXLnStGnTxhhz4XEdMmSIiYyMNC1atDBvv/22OXv2rJsrzH1btmwxPj4+ZuzYscYYY/bv328qVapkpk+f7ubKXOv8+fOmX79+pl+/fo5lq1evNj179jTHjx83Bw8edGN1rnPu3DnTq1cvM2TIEMeyw4cPmzp16hg/Pz8zY8YMY0zBe/3OyMgwDzzwgOnTp49j2ZYtW8zAgQONt7e3+fLLL40xBe/v+d9//23atGljGjdubFq2bGkGDhxo4uLi3F2Wyx04cMDUqlXLjBs3zqSnpxtjjHnqqadMzZo1C+Tf8Sz79u0zVapUcXrfMnDgQDN06FBjzIW/e+7AngMWlJ6ern379ql+/fqOZfv27dP333+vFi1aqEWLFlq0aJGkgpXEnzt3TgcPHnQcOmGMUbNmzdS5c2eFhYXpgQce0M8//1wgd1VLSEhQyZIlHZfLlCmjKVOmaMqUKYqOjtZXX30lm81WoB7vQ4cOydvbW9OnT9fQoUPl7e2tqVOn6vvvv3d3aS5jjNG3336r2rVr67HHHnMckzpw4EBJF76JKag2bdqktm3baujQoY5lqamp+vXXX9WqVSvdfvvtWrVqVYH7xmn9+vXKzMxUu3btZLfb1alTJz3//POaN2+enn32Wd1xxx3auHGju8t0iX/++Uc+PheOjuzYsaP27t2rxo0bq1WrVoqKitLzzz8vqeC8jp08eVLjx4/XqFGj9Oyzz0qSSpYsqSZNmujbb791c3WulZGRof3796t69eqOZT/88IO+/fZb3XrrrWrQoIEmTZpU4PYaOX/+vPbu3et4v5aRkaFy5cqpbdu2Cg8P16hRo7R8+fICt+ej3W7XwYMHValSJceyJk2a6LnnntMjjzyiu+++Wz/99FOBe7+2e/duFS1aVIsXL9bjjz+uLVu2aNasWdqxY4e7S3OZzMxMffbZZ2ratKmGDBnieEyHDx+u9PR07d27180VukZmZqZWr16tLl266IknnnC8ThUqVEg7duxQx44d1b9/f23YsCHvi3NLJAG3stvt5v777zcNGzY0H330kRk1apQJDAw0ixYtMsuXLzfPPvus8fLyKnDfsiYlJZmwsDAzdepURxL5559/mvLly5uPP/7Y3H777aZPnz4mIyOjwKXwEydONJUqVXJ8c5zVX3p6unnsscdM3bp1zZEjR9xZokts3brV8f/ly5c79iBYv369Y3nWNw8F5RuI5cuXm3nz5jku2+12c/LkSVOhQgWzbNkyN1bmWidOnDC7d+92XJ4+fboJCAgws2bNMvPmzTODBg0yfn5+Zvv27W6s0jUmTpxovL29TY0aNUyvXr3Mnj17TEZGhvnll1/MPffcY5o3b24SExPdXWauW7FihQkICDCLFy82PXv2dOrx7bffNjabzfzwww9urDD3XbwnSNbfrB9++MHYbDbz0UcfuausPDF06FBTtGhRM3fuXBMdHW0KFSpk3nvvPbNlyxazZMkSY7PZzH//+193l5mr0tPTzZ133mkGDhxoUlJSjDEXvmUtVaqU+frrr82DDz5o2rZta06fPu3mSnNfdHS0CQsLM8ePH3daHh8fb3r16mXuuOMOx31SUJw9e9Zs2LDBcXnBggWmWbNmZuDAgU6vXQXtPeqiRYvM7NmznZYlJiaaYsWKmW+//dY9ReWBP//80+zYscNxedKkSSYgIMA8++yzJiYmxtx3332mevXq5s8//8zTuggHLGrNmjXm3nvvNT169DA1a9Y0r7/+umNdWlqaqV+/vpkwYYL7CnSR4cOHm0aNGpn/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8ccfTXR0tAkKCvLo3+8//vjDVKxY0YwZM8YkJyebX3/91URFRZkBAwaYc+fOOcZNmjTJtG/f3thsNhMaGmrKli3r0Y/31fq+dN4ru91uMjIyzNChQ03x4sWdjlH3NNfT98mTJ03Tpk1Nx44dPf4Ljevp2xhj/vrrLzN69Gi3vX4TDhRgZ8+eNc2aNTPvv/++0/I9e/aYUqVKmX/961+OZcuXLzfTpk0z8+bN8+hvWoy5dt933XWX401GcnKyeeedd0zTpk09Oom12+1m2rRp5o477jBff/21mTBhgqlTp84V30gbc2Eegp07d3r0N6k56fvSD07bt283FSpU8OgXmuvt+/z586ZNmzYe/0HxevvesWOHI3m3Ut/bt283I0aMMA0bNvToQORG/q7t3bvXJCQkmH/++Sevy801N/J3zRhjUlJSzL59+/Ky1FyVk74v/uY8Li7OvPXWW+bjjz82f/31lztKzhXX+3hnZmaazz77zISFhXn073daWpoZOXKkuffee51+j9966y1TsmTJy/YKOHbsmFmxYoX54YcfPPrUldfbtzHG/PLLL8Zms3l0sH+9fScnJ5sqVaqYEiVKWOp5vmnTJvP444+bxo0bu61vwoEC7NSpU6ZChQrZvrBu27bNFC5cuEBOOpiTvqdMmeJYd+bMGY/e5TbLkSNHzKJFi4wxF2Z5zXqDMXHiRMcYT9/dNDs56fvSb9oKwgzH19v3ggULPHqX2yzX2/eOHTsKxEz919v3li1bPDr4y5KTvrP7ZtXTXe/j7a7zYec2Xsdy/jp26aGRnubs2bNm5syZ5s033zTG/O9397fffnM61LEgTbBpTM77vpSnv0+9kb6nTp1qfvvttzytM7fdSN/fffed0+HfeY1woICbMWOGqVixovniiy8cy7JeWKdOnWpatWpljh075vjjW1DeWOW074LSb3YOHz6c7RuMTz/9tMCckSE7V+s76zlQEB/3K/X98ccfu7Eq16Nv+jbmwu93QfsQcTH6du77k08+seTrWEHr++I9VbNel48cOWJq1qzpNCu9Jx9CkJ0b6bsgvG/Jad+evIdEdnLad37Zo5WzFRQgR44c0cGDB3XixAmFh4fL29tbPXv21E8//aTp06fLz89PXbt2la+vrySpVKlSSk1NVaFChRwzIHvi7MY307cn9pslu76lC7N0Z83M/sgjj0iS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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "gender_by_year = df.groupby(['year', 'sex']).size().reset_index(name='count')\n", - "\n", - "plt.figure(figsize=(12, 6))\n", - "sns.barplot(data=gender_by_year, x='year', y='count', hue='sex')\n", - "plt.title('Gender Count by Year')\n", - "plt.xlabel('Year')\n", - "plt.ylabel('Count')\n", - "plt.xticks(rotation=45)\n", - "plt.legend(title='Gender')\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "93232202305056a3", - "metadata": { - "ExecuteTime": { - "end_time": "2025-07-08T16:09:45.349954Z", - "start_time": "2025-07-08T16:09:45.086546Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnwAAAKSCAYAAABIowakAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAATZNJREFUeJzt3Xl4ZHWd7/HPqS2p7PueTq/0RjfgiGwqqDiICt4RRkFHoUdgriJexHFGQEdEdLzjsImODDoCgpcRcUYcBKWbfRXoptm6G3pfknT2vfaqc/+oJhC6O1VJquqcOvV+PU89nVQqVd+kK5VPfsv3Z5imaQoAAACO5bK6AAAAAGQXgQ8AAMDhCHwAAAAOR+ADAABwOAIfAACAwxH4AAAAHI7ABwAA4HAEPgAAAIcj8AEAADgcgQ8oUFdddZUMw8jJY51yyik65ZRTJt9/9NFHZRiG7rnnnpw8/vnnn6/58+fn5LFma3x8XBdccIGamppkGIYuvfRSq0sC4CAEPsABbrvtNhmGMXkpLi5WS0uLTjvtNP3oRz/S2NhYRh6nq6tLV111lTZu3JiR+8skO9eWju9///u67bbb9MUvflF33HGHPve5zx32tpFIRDfeeKOOOeYYVVRUqKqqSitXrtRFF12kLVu25LBqAPnCY3UBADLn6quv1oIFCxSNRrV//349+uijuvTSS3Xdddfp97//vVavXj15229+85v6xje+MaP77+rq0ne+8x3Nnz9fRx99dNqf9+CDD87ocWZjutp+9rOfKZFIZL2GuXj44Yd1/PHH69vf/nbK25511ll64IEHdO655+rCCy9UNBrVli1bdN999+nEE0/UsmXLclAxgHxC4AMc5PTTT9e73/3uyfcvv/xyPfzww/r4xz+uM888U5s3b5bf75ckeTweeTzZfQkIBAIqKSmRz+fL6uOk4vV6LX38dPT29mrFihUpb/f888/rvvvu0/e+9z1dccUVUz724x//WMPDw1mqEEA+Y0oXcLgPfvCD+ta3vqXdu3frzjvvnLz+UGv41q5dq/e+972qqqpSWVmZli5dOhkqHn30UR177LGSpDVr1kxOH992222Skuv0jjzySK1fv17vf//7VVJSMvm571zD96Z4PK4rrrhCTU1NKi0t1Zlnnqm9e/dOuc38+fN1/vnnH/S5b7/PVLUdag3fxMSEvva1r6m9vV1FRUVaunSp/vVf/1WmaU65nWEY+vKXv6zf/e53OvLII1VUVKSVK1fqj3/846G/4e/Q29urL3zhC2psbFRxcbGOOuoo3X777ZMff3M9486dO/WHP/xhsvZdu3Yd8v62b98uSTrppJMO+pjb7VZtbe2U6zo7O/W3f/u3amxsnKz9F7/4xeTHg8Ggli1bpmXLlikYDE5ePzg4qObmZp144omKx+Npfa0A7IvABxSAN9eDTTe1+tprr+njH/+4wuGwrr76al177bU688wz9dRTT0mSli9frquvvlqSdNFFF+mOO+7QHXfcofe///2T9zEwMKDTTz9dRx99tG644QZ94AMfmLau733ve/rDH/6gf/zHf9RXvvIVrV27VqeeeuqU4JGOdGp7O9M0deaZZ+r666/XRz7yEV133XVaunSpvv71r+uyyy476PZPPvmkvvSlL+mcc87Rv/zLvygUCumss87SwMDAtHUFg0GdcsopuuOOO/TZz35WP/zhD1VZWanzzz9fN95442Ttd9xxh+rq6nT00UdP1l5fX3/I++zo6JAk/epXv1IsFpv28Xt6enT88cdr3bp1+vKXv6wbb7xRixcv1he+8AXdcMMNkiS/36/bb79d27Zt05VXXjn5uRdffLFGRkZ02223ye12T/s4APKACSDv3XrrraYk8/nnnz/sbSorK81jjjlm8v1vf/vb5ttfAq6//npTktnX13fY+3j++edNSeatt9560MdOPvlkU5J58803H/JjJ5988uT7jzzyiCnJbG1tNUdHRyevv/vuu01J5o033jh5XUdHh3neeeelvM/pajvvvPPMjo6Oyfd/97vfmZLMa665Zsrtzj77bNMwDHPbtm2T10kyfT7flOteeuklU5J50003HfRYb3fDDTeYksw777xz8rpIJGKecMIJZllZ2ZSvvaOjw/zYxz427f2ZpmkmEonJ73VjY6N57rnnmj/5yU/M3bt3H3TbL3zhC2Zzc7PZ398/5fpzzjnHrKysNAOBwOR1l19+uelyuczHH3/c/M1vfmNKMm+44YaU9QDID4zwAQWirKxs2t26VVVVkqR777131hscioqKtGbNmrRv//nPf17l5eWT75999tlqbm7W/fffP6vHT9f9998vt9utr3zlK1Ou/9rXvibTNPXAAw9Muf7UU0/VokWLJt9fvXq1KioqtGPHjpSP09TUpHPPPXfyOq/Xq6985SsaHx/XY489NuPaDcPQn/70J11zzTWqrq7WXXfdpYsvvlgdHR369Kc/PbmGzzRN/fa3v9UZZ5wh0zTV398/eTnttNM0MjKiDRs2TN7vVVddpZUrV+q8887Tl770JZ188skHfX8A5C8CH1AgxsfHp4Srd/r0pz+tk046SRdccIEaGxt1zjnn6O67755R+GttbZ3RBo0lS5ZMed8wDC1evPiw69cyZffu3WppaTno+7F8+fLJj7/dvHnzDrqP6upqDQ0NpXycJUuWyOWa+lJ7uMdJV1FRka688kpt3rxZXV1duuuuu3T88cfr7rvv1pe//GVJUl9fn4aHh3XLLbeovr5+yuXNUN7b2zt5nz6fT7/4xS+0c+dOjY2N6dZbb81Zn0YA2ccuXaAA7Nu3TyMjI1q8ePFhb+P3+/X444/rkUce0R/+8Af98Y9/1K9//Wt98IMf1IMPPpjWOq43dwBn0uFCRzwez9nassM9jvmODR5WaG5u1jnnnKOzzjpLK1eu1N13363bbrttMqj/zd/8jc4777xDfu7b2/RI0p/+9CdJUigU0tatW7VgwYLsFg8gZwh8QAG44447JEmnnXbatLdzuVz60Ic+pA996EO67rrr9P3vf19XXnmlHnnkEZ166qkZH/HZunXrlPdN09S2bdumBJHq6upDthrZvXu3Fi5cOPn+TGrr6OjQunXrNDY2NmWU782mxW9ujJirjo4Ovfzyy0okElNG+TL9OFJyqnj16tXaunWr+vv7VV9fr/LycsXjcZ166qkpP//ll1/W1VdfrTVr1mjjxo264IIL9Morr6iysjJjNQKwDlO6gMM9/PDD+u53v6sFCxbos5/97GFvNzg4eNB1bzYwDofDkqTS0lJJylivt1/+8pdT1hXec8896u7u1umnnz553aJFi/Tss88qEolMXnffffcd1L5lJrV99KMfVTwe149//OMp119//fUyDGPK48/FRz/6Ue3fv1+//vWvJ6+LxWK66aabVFZWppNPPnnG97l161bt2bPnoOuHh4f1zDPPqLq6WvX19XK73TrrrLP029/+Vq+++upBt+/r65t8OxqN6vzzz1dLS4tuvPFG3Xbbberp6dFXv/rVGdcHwJ4Y4QMc5IEHHtCWLVsUi8XU09Ojhx9+WGvXrlVHR4d+//vfq7i4+LCfe/XV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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "sex_counts = df['sex'].value_counts()\n", - "\n", - "plt.figure(figsize=(8, 8))\n", - "plt.pie(sex_counts, labels=sex_counts.index, autopct='%1.1f%%', startangle=90, colors=['lightblue', 'lightpink'])\n", - "plt.title('Distribution of Sex')\n", - "plt.show()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "f7b8afb3bc565875", - "metadata": { - "ExecuteTime": { - "end_time": "2025-07-08T16:13:37.061494Z", - "start_time": "2025-07-08T16:13:36.764013Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA04AAAIjCAYAAAA0vUuxAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAARsdJREFUeJzt3XlcVdX+//H3QeAACijJ4IBKivOsqag5pEbq9UqDlVmoqd26mJrTI7u3zLQwzemmOZRKZV7LcuhnToSiOeZEOeWcmAJqqQgqIuzfHz0833sC3IDgQXg9H4/9yL322mt/9vGUvtt7LSyGYRgCAAAAAOTIydEFAAAAAEBRR3ACAAAAABMEJwAAAAAwQXACAAAAABMEJwAAAAAwQXACAAAAABMEJwAAAAAwQXACAAAAABMEJwAAAAAwQXACAAeqVq2a+vXr5+gyir3JkyfrwQcfVKlSpdS4cWNHl5Nnb7/9tiwWi6PLAIASjeAEAAUkKipKFotFu3fvzvZ4hw4dVL9+/bu+zurVq/X222/f9Tglxfr16zV69Gi1adNGCxcu1HvvvZdtv3/+859ycnLSH3/8Ydf+xx9/yMnJSVarVTdu3LA7dvLkSVksFr3xxhuFVn9+xMbG6oknnlBAQIBcXV3l5+enHj16aNmyZY4uTZJ07do1vf3224qNjXV0KQCQawQnAHCgI0eO6OOPP87TOatXr9a4ceMKqaLiZ8OGDXJyctL8+fMVHh6ubt26Zduvbdu2MgxDW7dutWvftm2bnJyclJ6eniUU3+7btm3bwik+H8aOHauOHTvqwIED+sc//qE5c+Zo1KhRSklJ0ZNPPqnFixc7ukRdu3ZN48aNIzgBuK84O7oAACjJrFaro0vIs9TUVJUuXdrRZeTa+fPn5e7uLldX1zv2ux1+tmzZoh49etjat27dqoYNG+r69evasmWLXUjasmWLnJyc1Lp167uq8datW8rMzDSt0czXX3+td955R0899ZQWL14sFxcX27FRo0Zp3bp1Sk9Pv6trAEBJxRMnAHCgv85xSk9P17hx4xQcHCw3Nzc98MADatu2raKjoyVJ/fr106xZsyRJFovFtt2WmpqqESNGKDAwUFarVbVq1dIHH3wgwzDsrnv9+nUNGTJE5cuXl6enp/7+97/r7Nmzslgsdq8B3p5bc+jQIT333HMqV66cLTj8/PPP6tevnx588EG5ubkpICBAL774on7//Xe7a90e4+jRo3r++efl7e0tX19fvfnmmzIMQ2fOnFHPnj3l5eWlgIAATZkyJVef3a1btzR+/HhVr15dVqtV1apV0xtvvKG0tDRbH4vFooULFyo1NdX2WUVFRWU7XpUqVRQYGJjlidPWrVvVpk0btW7dOttj9erVU9myZSX9GdIGDBggf39/ubm5qVGjRvr000/tzvn1119lsVj0wQcfaPr06bb6Dx06JOnPMPbQQw/Jzc1N1atX19y5c3P1eUjSm2++KR8fHy1YsMAuNN0WGhqqv/3tb7b93NQbGxsri8WS5enQ7fv438+zX79+KlOmjM6ePauwsDCVKVNGvr6+GjlypDIyMmzn+fr6SpLGjRtn+325/b1LTExU//79VblyZVmtVlWoUEE9e/bUr7/+muvPAQAKA0+cAKCAXblyRRcvXszSnpv/0//2228rMjJSAwcOVIsWLZScnKzdu3dr79696tKli/7xj3/o3Llzio6O1ueff253rmEY+vvf/66NGzdqwIABaty4sdatW6dRo0bp7NmzmjZtmq1vv3799NVXX+mFF15Qq1attGnTJnXv3j3Hunr16qXg4GC99957thAWHR2tkydPqn///goICNDBgwc1b948HTx4UDt27MiymMEzzzyjOnXqaOLEifruu+80YcIE+fj4aO7cuXrkkUf0/vvv64svvtDIkSP10EMPqV27dnf8rAYOHKhPP/1UTz31lEaMGKGdO3cqMjJShw8f1vLlyyVJn3/+uebNm6cff/xRn3zyiSTd8elQ27ZttWzZMqWlpclqtermzZvatWuXXnnlFV27dk2jR4+WYRiyWCy6dOmSDh06pJdfflnSn2G0Q4cOOn78uAYPHqygoCAtXbpU/fr10+XLlzV06FC7ay1cuFA3btzQSy+9JKvVKh8fH+3fv1+PPvqofH199fbbb+vWrVsaO3as/P397/hZSNKxY8f0yy+/6MUXX5Snp6dp/7zWm1sZGRkKDQ1Vy5Yt9cEHH+j777/XlClTVL16db3yyivy9fXV7Nmz9corr+jxxx/XE088IUlq2LChJOnJJ5/UwYMH9eqrr6patWo6f/68oqOjFR8fr2rVquWrJgAoEAYAoEAsXLjQkHTHrV69enbnVK1a1ejbt69tv1GjRkb37t3veJ2IiAgju/98r1ixwpBkTJgwwa79qaeeMiwWi3H8+HHDMAxjz549hiRj2LBhdv369etnSDLGjh1raxs7dqwhyejdu3eW6127di1L23//+19DkrF58+YsY7z00ku2tlu3bhmVK1c2LBaLMXHiRFv7pUuXDHd3d7vPJDtxcXGGJGPgwIF27SNHjjQkGRs2bLC19e3b1yhduvQdx7tt1qxZhiTjhx9+MAzDMLZv325IMk6fPm0cOnTIkGQcPHjQMAzDWLVqlSHJ+OKLLwzDMIzp06cbkoxFixbZxrt586YREhJilClTxkhOTjYMwzBOnTplSDK8vLyM8+fP210/LCzMcHNzM06fPm1rO3TokFGqVKlsf8//18qVKw1JxrRp03J1r7mtd+PGjYYkY+PGjXbn376PhQsX2tr69u1rSDLeeecdu75NmjQxmjVrZtu/cOFClu+aYfz5+y/JmDx5cq7uAQDuJV7VA4ACNmvWLEVHR2fZbv8f9TspW7asDh48qGPHjuX5uqtXr1apUqU0ZMgQu/YRI0bIMAytWbNGkrR27VpJf64i979effXVHMe+/VTlf7m7u9t+fePGDV28eFGtWrWSJO3duzdL/4EDB9p+XapUKTVv3lyGYWjAgAG29rJly6pWrVo6efJkjrVIf96rJA0fPtyufcSIEZKk77777o7n5+R/5zlJf76KV6lSJVWpUkW1a9eWj4+P7XW9vy4MsXr1agUEBKh379628VxcXDRkyBClpKRo06ZNdtd68sknba+sSX8+qVm3bp3CwsJUpUoVW3udOnUUGhpqWntycrIk5eppU37qzYu/fl8efvhh099TSba5aLGxsbp06VK+rw8AhaFEB6fNmzerR48eqlixoiwWi1asWJHnMQzD0AcffKCaNWvKarWqUqVKevfddwu+WAD3jRYtWqhz585ZtnLlypme+8477+jy5cuqWbOmGjRooFGjRunnn3/O1XVPnz6tihUrZvmLc506dWzHb//TyclJQUFBdv1q1KiR49h/7Sv9uUz30KFD5e/vL3d3d/n6+tr6XblyJUv//w0DkuTt7S03NzeVL18+S7vZX5pv38Nfaw4ICFDZsmVt95pX9evXV9myZe3CUZs2bST9OV8qJCTE7lhgYKDtvk6fPq3g4GA5Odn/0frXz/+2v36mFy5c0PXr1xUcHJylrlq1apnW7uXlJUm6evWqad/81Jtbbm5udoFQksqVK5erIGS1WvX+++9rzZo18vf3V7t27TRp0iQlJibmqxYAKEglOjilpqaqUaNGtonW+TF06FB98skn+uCDD/TLL7/o22+/VYsWLQqwSgAlSbt27XTixAktWLBA9evX1yeffKKmTZva5uc4yv8+Xbrt6aef1scff6yXX35Zy5Yt0/r1621PszIzM7P0L1WqVK7aJGVZzCInBf1DYZ2cnBQSEqJt27bZlib/3zlRrVu31pYtW2xzn+5mGfLsPtO7Ubt2bUnS/v37C3TcnD7j24s9/FVOv6e5NWzYMB09elSRkZFyc3PTm2++qTp16mjfvn13NS4A3K0SHZy6du2qCRMm6PHHH8/2eFpamkaOHKlKlSqpdOnSatmypd2qQocPH9bs2bO1cuVK/f3vf1dQUJCaNWumLl263KM7AFAc+fj4qH///vrvf/+rM2fOqGHDhnYr3eX0F9mqVavq3LlzWZ44/PLLL7bjt/+ZmZmpU6dO2fU7fvx4rmu8dOmSYmJi9Prrr2vcuHF6/PHH1aVLFz344IO5HuNu3L6Hv77SmJSUpMuXL9vuNT/atm2rP/74Q99++63Onz9ve+Ik/RmcTpw4odWrV+v69et2walq1ao6duxYltD4188/J76+vnJ3d8/2Nc0jR46Y1l2zZk3VqlVLK1euVEpKimn/3NZ7+0np5cuX7frl94mUZB54q1evrhEjRmj9+vU6cOCAbt68mevVFgGgsJTo4GRm8ODB2r59u5YsWaKff/5ZvXr10mOPPWb7Q+3//b//pwcffFCrVq1SUFCQqlWrpoEDB2b5qfMAkFt/Xcq7TJkyqlGjht0S27d/htJf/yLbrVs3ZWRkaObMmXbt06ZNk8ViUdeuXSXJNl/mo48+suv34Ycf5rrO208V/vpkaPr06bke427c/iG2f73e1KlTJemOKwSauR2G3n//fXl4eKhx48a2Yy1atJCzs7MmTZpk1/d2TYmJifryyy9tbbdu3dKHH36oMmXKqH379ne8bqlSpRQaGqoVK1YoPj7e1n748GGtW7cuV7WPGzdOv//+uwYOHKhbt25lOb5+/XqtWrUqT/VWrVpVpUqV0ubNm+3G+uv3Jy88PDwkZf0OX7t2TTdu3LBrq169ujw9Pe3+HQAAR2A58hzEx8dr4cKFio+PV8WKFSVJI0eO1Nq1a7Vw4UK99957OnnypE6fPq2lS5fqs88+U0ZGhl577TU99dRT2rBhg4PvAMD9qG7duurQoYOaNWsmHx8f7d69W19//bUGDx5s69OsWTNJ0pAhQxQaGqpSpUrp2WefVY8ePdSxY0f961//0q+//qpGjRpp/fr1WrlypYYNG6bq1avbzn/yySc1ffp0/f7777blyI8ePSopd6+/eXl52eafpKenq1KlSlq/fn2Wp1iFpVGjRurbt6/mzZuny5cvq3379vrxxx/16aefKiwsTB07dsz32C1atJCrq6u2b9+uDh06yNn5//6o9PDwUKNGjbR9+3aVLVtW9evXtx176aWXNHfuXPXr10979uxRtWrV9PXXX2vr1q2aPn16rhZtGDdunNauXauHH35Y//znP21Bpl69erma6/bMM89o//79evfdd7Vv3z717t1bVatW1e+//661a9cqJiZGixcvzlO93t7e6tWrlz788ENZLBZVr15dq1at0vnz5/P60dq4u7urbt26+vLLL1WzZk35+Piofv36unXrljp16qSnn35adevWlbOzs5YvX66kpCQ9++yz+b4eABQIRy7pV5RIMpYvX27bv73MbOnSpe02Z2dn4+mnnzYMwzAGDRpkSDKOHDliO+/2Mr+//PLLvb4FAA52eznyXbt2ZXu8ffv2psuRT5gwwWjRooVRtmxZw93d3ahdu7bx7rvvGjdv3rT1uXXrlvHqq68avr6+hsVisVum+urVq8Zrr71mVKxY0XBxcTGCg4ONyZMnG5mZmXbXTU1NNSIiIgwfHx+jTJkyRlhYmHHkyBFDkt3y4LeXEr9w4UKW+/ntt9+Mxx9/3Chbtqzh7e1t9OrVyzh37lyOS5r/dYyclgnP7nPKTnp6ujFu3DgjKCjIcHFxMQIDA40xY8YYN27cyNV17iQkJMSQZLzxxhtZjg0ZMsSQZHTt2jXLsaSkJKN///5G+fLlDVdXV6NBgwZ2y3Ubxv8t453TktubNm0ymjVrZri6uhoPPvigMWfOHNtnmFsxMTFGz549DT8/P8PZ2dnw9fU1evToYaxcuTLP9RrGn8uHP/nkk4aHh4dRrlw54x//+Idx4MCBbJcjz+6zzq7+bdu22e7z9nfm4sWLRkREhFG7dm2jdOnShre3t9GyZUvjq6++yvW9A0BhsRhGLmfgFnMWi0XLly9XWFiYJOnLL79Unz59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oMDAQL355ps6dOiQ1qxZo8OHD2v27NkqX758nq4LACh4BCcAQIHp2LGjtm7dqlu3bunq1avat2+f2rdvr3bt2tmeRG3fvl1paWnq2LGjUlNTNXv2bE2ePFldu3ZV3bp19fHHH8vd3V3z58+3G/udd95Rly5dVL16dbm6umr+/Pn64IMP1KlTJzVo0ECffvqp3fyq7Bw7dky1a9e+Y5+81GQmMzNTUVFRql+/vh5++GG98MILiomJkSR5e3vL1dVVHh4eCggIUEBAgEqVKqX4+Hg1adJEzZs3V7Vq1dS5c2f16NEjT9cFABQ8ghMAoMB06NBBqamp2rVrl3744QfVrFlTvr6+at++vW2eU2xsrB588EFVqVJFJ06cUHp6utq0aWMbw8XFRS1atNDhw4ftxm7evLnt1ydOnNDNmzfVsmVLW5uPj49q1ap1x/oMwzC9h7zUZKZatWry9PS07VeoUEHnz5+/4zmvvPKKlixZosaNG2v06NHatm1bnq4JACgcBCcAQIGpUaOGKleurI0bN2rjxo1q3769JKlixYoKDAzUtm3btHHjRj3yyCN5Hvv2a3R3o2bNmvrll1/uehwnJ6csISy7FflcXFzs9i0WizIzM+84dteuXXX69Gm99tprOnfunDp16qSRI0fedc0AgLtDcAIAFKiOHTsqNjZWsbGxdsuQt2vXTmvWrNGPP/5om990+7W7rVu32vqlp6dr165dqlu3bo7XqF69ulxcXLRz505b26VLl3T06NE71vbcc8/p+++/1759+7IcS09PV2pqaq5q8vX11dWrV5WammrrExcXd8drZ8fV1VUZGRlZ2n19fdW3b18tWrRI06dP17x58/I8NgCgYBGcAAAFqmPHjtqyZYvi4uJsT5wkqX379po7d65u3rxpC06lS5fWK6+8olGjRmnt2rU6dOiQBg0apGvXrmnAgAE5XqNMmTIaMGCARo0apQ0bNujAgQPq16+fnJzu/MfasGHD1KZNG3Xq1EmzZs3STz/9pJMnT+qrr75Sq1atdOzYsVzV1LJlS3l4eOiNN97QiRMntHjxYkVFReX5s6pWrZp27typX3/9VRcvXlRmZqbeeustrVy5UsePH9fBgwe1atUq1alTJ89jAwAKFj/HCQBQoDp27Kjr16+rdu3a8vf3t7W3b99eV69etS1bftvEiROVmZmpF154QVevXlXz5s21bt06lStX7o7XmTx5slJSUtSjRw95enpqxIgRunLlyh3PsVqtio6O1rRp0zR37lyNHDlSHh4eqlOnjoYMGaL69evnqiYfHx8tWrRIo0aN0scff6xOnTrp7bff1ksvvZSnz2rkyJHq27ev6tatq+vXr+vUqVNydXXVmDFj9Ouvv8rd3V0PP/ywlixZkqdxAQAFz2LkZqYsAAAAAJRgvKoHAAAAACYITgAAAABgguAEAAAAACYITgAAAABgguAEAAAAACYITgAAAABgguAEAAAAACYITgAAAABgguAEAAAAACYITgAAAABgguAEAAAAACb+P3XBtmhRM6pKAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(10, 6))\n", - "plt.hist(df['words'], bins=30, color='skyblue', edgecolor='black')\n", - "plt.title('Histogram of Word Counts')\n", - "plt.xlabel('Word Counts')\n", - "plt.ylabel('Frequency')\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "f5c322d32b2d60fa", - "metadata": { - "ExecuteTime": { - "end_time": "2025-07-08T16:13:42.022402Z", - "start_time": "2025-07-08T16:13:41.781236Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "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5uZme67w7//+AEBRuKVnnK4lKSlJc+fOVVJSkqpXry5JGjVqlFavXq25c+dqwoQJOnDggA4fPqylS5dqwYIFysnJ0XPPPaeHH35Y3377rYvfAYDiqnHjxrrvvvsUHBysSpUqacuWLfr88881bNgwW5/g4GBJ0rPPPqvQ0FC5u7vrscceU/fu3dWhQwe98sorOnTokIKCgrR27Vp9+eWXGjlypG3WIjg4WP/5z380ffp0/fXXX7blyPfu3SupYL/9r1Chgu699169+eabunjxomrUqKG1a9fq4MGDRfCp5BUUFKTw8HC9//77OnPmjNq3b6/Nmzdr/vz56tmzpzp06OC0c7m7u+uVV15RREREnn0PPvigli1bpl69eqlbt246ePCgYmNj1bhxY7uwcL0qVKigWbNmqX///rrjjjv02GOPqUqVKkpKStLKlSvVtm3bPIE5P1988YVtBvLvwsPD9cILL+irr77Sgw8+qIEDByo4OFgZGRnasWOHPv/8cx06dCjP82hmJkyYoB49eqht27aKiIjQ6dOn9e6776pJkyZ2n4+3t7caN26sJUuWKDAwUJUqVVKTJk3UpEmTAp/ryi8nO3bsqJo1a+rw4cN655131Lx5c7tZSQAoCgSnq9ixY4dycnLy3O+dlZWlypUrS7p8r3hWVpYWLFhg6/fRRx8pODhYe/bssd2+BwB/9+yzz+qrr77S2rVrlZWVpdq1a2v8+PF64YUXbH0eeughDR8+XIsXL9Ynn3wiwzD02GOPyc3NTV999ZVGjx6tJUuWaO7cuQoICNDkyZNtq81dsWDBAvn5+WnRokVavny5QkJCtGTJEjVs2FBeXl4FqnXhwoUaPny4Zs6cKcMw1LlzZ61atcr2C6Wi9uGHH6pu3bqaN2+eli9fLj8/P0VFRTn9Njnp8qzT+PHj8zy3NHDgQCUnJ2v27Nlas2aNGjdurE8++URLly5VfHy8U2vo27evqlevrokTJ2ry5MnKyspSjRo11K5du3xDXX4WL16cb/t9990nf39/bdy4URMmTLD90q9ChQoKDAzU2LFj7VYDLKju3btr0aJFGjNmjF5++WU1aNBA8+bN0/z58/N8ce+HH36o4cOH67nnnlN2draio6MLFZzCwsL0/vvv67333tOZM2fk5+en3r17a8yYMXJz4yYaAEXLYhTFE54lkMVi0fLly20P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AAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACYITAAAAAJggOAEAAACACZcHp5kzZyogIEBeXl5q3bq1Nm/efM3+06dPV8OGDeXt7S1/f38999xzunDhwg2qFgAAAMCtyKXBacmSJYqMjFR0dLS2bt2qoKAghYaG6sSJE/n2X7hwoV5++WVFR0crMTFRH330kZYsWaL//ve/N7hyAAAAALcSlwanadOmaciQIYqIiFDjxo0VGxurMmXKaM6cOfn2//HHH9W2bVv17dtXAQEB6ty5s/r06WM6SwUAAAAA18NlwSk7O1sJCQkKCQn5v2Lc3BQSEqJNmzble8zdd9+thIQEW1A6cOCAvvnmG3Xt2vWq58nKylJaWprdBgAAAACFUcpVJ05NTVVOTo6sVqtdu9Vq1e7du/M9pm/fvkpNTdU999wjwzB06dIlPfXUU9e8VS8mJkZjx451au0AAAAAbi0OzTgdOHDA2XUUSHx8vCZMmKD33ntPW7du1bJly7Ry5UqNGzfuqsdERUXp7Nmztu3IkSM3sGIAAAAANwOHZpzq16+v9u3ba9CgQXr44Yfl5eVV6DF8fX3l7u6ulJQUu/aUlBT5+fnle8xrr72m/v37a/DgwZKkpk2bKiMjQ0888YReeeUVubnlzYGenp7y9PQsdH0AAAAAcIVDM05bt25Vs2bNFBkZKT8/Pz355JOFXqDBw8NDwcHBiouLs7Xl5uYqLi5Obdq0yfeY8+fP5wlH7u7ukiTDMAr5LgAAAACgYBwKTs2bN9eMGTN07NgxzZkzR8ePH9c999yjJk2aaNq0aTp58mSBxomMjNQHH3yg+fPnKzExUU8//bQyMjIUEREhSRowYICioqJs/bt3765Zs2Zp8eLFOnjwoNatW6fXXntN3bt3twUoAAAAAHC261ocolSpUnrooYfUrVs3vffee4qKitKoUaP03//+V48++qgmTZqkatWqXfX43r176+TJkxo9erSSk5PVvHlzrV692rZgRFJSkt0M06uvviqLxaJXX31VR48eVZUqVdS9e3e98cYb1/M2AAAAAOCaris4bdmyRXPmzNHixYtVtmxZjRo1SoMGDdKff/6psWPHqkePHqa38A0bNkzDhg3Ld198fLx9saVKKTo6WtHR0ddTNgAAAAAUikPBadq0aZo7d6727Nmjrl27asGCBeratattdqhOnTqaN2+eAgICnFkrAAAAALiEQ8Fp1qxZevzxxzVw4MCr3opXtWpVffTRR9dVHAAAAAAUBw4Fp3379pn28fDwUHh4uCPDAwAAAECx4tCqenPnztXSpUvztC9dulTz58+/7qIAAAAAoDhxKDjFxMTI19c3T3vVqlU1YcKE6y4KAAAAAIoTh4JTUlKS6tSpk6e9du3aSkpKuu6iAAAAAKA4cSg4Va1aVdu3b8/T/ttvv6ly5crXXRQAAAAAFCcOBac+ffro2Wef1YYNG5STk6OcnBx9++23GjFihB577DFn1wgAAAAALuXQqnrjxo3ToUOH1KlTJ5UqdXmI3NxcDRgwgGecAAAAANx0HApOHh4eWrJkicaNG6fffvtN3t7eatq0qWrXru3s+gAAAADA5RwKTlcEBgYqMDDQWbUAAAAAQLHkUHDKycnRvHnzFBcXpxMnTig3N9du/7fffuuU4gAAAACgOHAoOI0YMULz5s1Tt27d1KRJE1ksFmfXBQAAAADFhkPBafHixfrss8/UtWtXZ9cDAAAAAMWOQ8uRe3h4qH79+s6uBQAAAACKJYeC0/PPP68ZM2bIMAxn1wMAAAAAxY5Dt+p9//332rBhg1atWqV//etfKl26tN3+ZcuWOaU4AAAAACgOHApOFStWVK9evZxdCwAAAAAUSw4Fp7lz5zq7DgAAAAAothx6xkmSLl26pPXr12v27Nk6d+6cJOnYsWNKT093WnEAAAAAUBw4NON0+PBhPfDAA0pKSlJWVpbuv/9+lS9fXpMmTVJWVpZiY2OdXScAAAAAuIxDM04jRoxQy5Ytdfr0aXl7e9vae/Xqpbi4OKcVBwAAAADFgUMzTv/v//0//fjjj/Lw8LBrDwgI0NGjR51SGAAAAAAUFw7NOOXm5ionJydP+59//qny5ctfd1EAAAAAUJw4FJw6d+6s6dOn215bLBalp6crOjpaXbt2dVZtAAAAAFAsOHSr3tSpUxUaGqrGjRvrwoUL6tu3r/bt2ydfX18tWrTI2TUCAAAAgEs5FJxq1qyp3377TYsXL9b27duVnp6uQYMGqV+/fnaLRQAAAADAzcCh4CRJpUqVUlhYmDNrAQAAAIBiyaHgtGDBgmvuHzBggEPFAAAAAEBx5FBwGjFihN3rixcv6vz58/Lw8FCZMmUITgAAAABuKg6tqnf69Gm7LT09XXv27NE999zD4hAAAAAAbjoOBaf8NGjQQBMnTswzGwUAAAAAJZ3TgpN0ecGIY8eOOXNIAAAAAHA5h55x+uqrr+xeG4ah48eP691331Xbtm2dUhgAAAAAFBcOBaeePXvavbZYLKpSpYo6duyoqVOnOqMuAAAAACg2HApOubm5zq4DAAAAAIotpz7jBAAAAAA3I4dmnCIjIwvcd9q0aY6cAgAAAACKDYeC06+//qpff/1VFy9eVMOGDSVJe/fulbu7u+644w5bP4vF4pwqAQAAAMCFHApO3bt3V/ny5TV//nzddtttki5/KW5ERITatWun559/3qlFAgAAAIArOfSM09SpUxUTE2MLTZJ02223afz48ayqBwAAAOCm41BwSktL08mTJ/O0nzx5UufOnbvuogAAAACgOHEoOPXq1UsRERFatmyZ/vzzT/3555/64osvNGjQID300EPOrhEAAAAAXMqhZ5xiY2M1atQo9e3bVxcvXrw8UKlSGjRokCZPnuzUAgEAAADA1RwKTmXKlNF7772nyZMn648//pAk1atXT2XLlnVqcQAAAABQHFzXF+AeP35cx48fV4MGDVS2bFkZhuGsugAAAACg2HAoOP3111/q1KmTAgMD1bVrVx0/flySNGjQIJYiBwAAAHDTcSg4PffccypdurSSkpJUpkwZW3vv3r21evVqpxUHAAAAAMWBQ884rV27VmvWrFHNmjXt2hs0aKDDhw87pTAAAAAAKC4cmnHKyMiwm2m64tSpU/L09LzuogAAAACgOHEoOLVr104LFiywvbZYLMrNzdWbb76pDh06OK04AAAAACgO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X/THH39ozZo1ioiIMA0lO3bs0LZt22zbb7/9psDAQPXr108DBgzQsmXLdPDgQW3evFkxMTFauXJlgesaPny4YmJi9OWXX2rPnj0aMWKETp8+bffdVgEBAfr555916NAhpaamFug2vszMTA0bNkzx8fE6fPiwfvjhB/3yyy9q1KhRgWsDADiOGScAgNO8/vrrWrJkiV3bq6++qgMHDig0NFRlypTRE088oZ49e+rs2bPXda7q1avrhx9+0EsvvaTOnTsrKytLtWvX1gMPPCA3t2v/XvDKbNAV7u7uunTpkubOnavx48fr+eef19GjR+Xr66u77rpLDz74YIHreumll5ScnKwBAwbI3d1dTzzxhEJDQ+1u/xs1apTCw8PVuHFjZWZm6uDBg6bjuru766+//tKAAQOUkpIiX19fPfTQQxo7dmyBawMAOM5iOPPGbAAAYCc3N1eNGjXSo48+qnHjxrm6HACAg5hxAgDAiQ4fPqy1a9eqffv2ysrK0rvvvquDBw+qb9++ri4NAHAdeMYJAAAncnNz07x583TnnXeqbdu22rFjh9avX8+zSABQwnGrHgAAAACYYMYJAAAAAEwQnAAAAADABMEJAAAAAEwQnAAAAADABMEJAAAAAEwQnAAAAADABMEJAAAAAEwQnAAAAADAxP8HMC3D6eylx5oAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(10, 6))\n", - "plt.hist(df['length'], bins=30, color='lightgreen', edgecolor='black')\n", - "plt.title('Histogram of Name Lengths')\n", - "plt.xlabel('Name Lengths')\n", - "plt.ylabel('Frequency')\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "cc849ca9d9d43ae3", - "metadata": { - "ExecuteTime": { - "end_time": "2025-07-08T16:14:08.587040Z", - "start_time": "2025-07-08T16:13:47.209322Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "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801t375dmzdvloeHh2bNmqV3331Xn3zyid588035+voqMjLygsfs3Lmzvv76a+3fv1/NmjWTdC6cjhgxQjfddJPi4+N18uRJ1atXT4ZhaMuWLYqKipKrq2uZfi/FffXVV1q6dKkeffRRNWzYUM2aNVNmZqZiYmJ09uxZPf3006pbt67mzZsnHx+fSz4fp0+f1vr16xUdHa3w8PBLji9vveUxePBgNW/eXNOmTdO3336rt99+W40aNTKXKbz33nvmczpy5EhJUkREhCTpkUce0UcffaRHH31Ubdu21bFjx7Rp0yb98MMP+vOf/3zBn7l9+3Zt2bJF9913nxo3bqz9+/frzTffVNeuXbV7927VqVPHYfzYsWNVv359xcfHa//+/Zo1a5YeffRRffjhh+aY5557TlOnTlWfPn3Up08fffvtt+rZs6cKCgrK9XxMmjRJ0dHRevPNNy8667p27Vr98ssvGj58uEJCQpSWlqZ58+YpLS1NW7dulYuLi8P4e++9V23atNELL7yglStXaurUqQoMDNTcuXPVrVs3TZ8+XYmJifr73/+uG2+8UdHR0ZLOzfDfeeed2rRpk0aOHKk2bdrov//9r1555RX9+OOPFbKE46uvvlLv3r3Vvn17xcfHy9XVVQsXLlS3bt309ddf66abbnIYf6nXjHTuH9lLly7Vgw8+qFtuuUUbN25U3759HY5zzz336Mcff9QHH3ygV155RQ0bNpR07h+udps2bdLHH3+s0aNHy8/PT6+99poGDBigAwcOqEGDBpIu/3UISJIMoIZbuHChIanEzcvLy1i0aJHD2E8//dSQZEydOtWhfeDAgYaLi4uxb98+s+2ZZ54xXF1djeTkZGPZsmWGJGPWrFkO3zd06FBDkjF27FizzWazGX379jU8PT2NI0eOmO2SjPj4ePP+XXfdZXh6eho///yz2ZaRkWH4+fkZ0dHRZpv9ZyclJTn87E8++cSQZGzfvr3sT5ZhGIcPHzY8PT2Nnj17GkVFRWb7G2+8YUgyFixYYLbFx8cbkhwex4WsXLnSkGS89957hmEYxqFDhwxJxsaNG43c3FzDzc3NWLlypWEYhrFr1y5DkvH8888bhlG+34skw9XV1UhLS3MYO378eEOSsW3bNofHGhAQYEgy0tPTL1j7f/7zH0OSMW7cuEs+zvLUm56ebkgyFi5cWOIY578e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yZN19913q0ePHiU+CakIEREROn78uG677TbzE57it7LM8F/q+NK5TwFKO3737t3l4eFRrmM2bdpUNputxEVA9u3bV2Lspd5vyupyXoeARHBFLVZYWKgvv/xSnp6e5ke4ffr0UVFRkd544w2Hsa+88opcXFzM2YDCwkINGzZMYWFhevXVV7Vo0SJlZWXp8ccfL/VnFT+eYRh644035OHhodtuu63U8W5uburZs6eWL1/usJwgKytL77//vjp37mx+fF23bl1JJcPPiRMnSsyo2GdoLrZcoHv37vL09NRrr73m8P3z589XdnZ2iTONy8MeRl9++WUVFhY6zLg2a9ZMoaGhmjFjhsNYqey/l4vp06ePtm7dqm+++cZsO3LkiBITE8tUe3x8vAzD0IMPPmj+Q6e4nTt36p133ilXvf7+/mrYsKGSk5Mdxs2ePbtMNV1I3bp1S7weioqKSvzDqlGjRgoLC7vk8hE3N7cSr6XXX3/9sq8UZg9Xr7/+usNxZ82adVnHs7OvdT3/Cm72WcDzH8OV/rzSDB48WL///rveeuutEn1//PGHTp06dUXHb9++vSIiIvTSSy+V+jo8f9uxsujVq5ekkq+7119/vcTYC73flNWVvA4BiaUCqEVWr15tzngdPnxY77//vn766Sc9/fTTZgi84447FBMTowkTJmj//v267rrr9OWXX2r58uUaP368OdsxdepUff/991q/fr38/PwUGRmp5557ThMnTtTAgQPVp08f8+d6e3trzZo1Gjp0qG6++WatXr1aK1eu1LPPPuuwjcz5pk6dqrVr16pz584aPXq03N3dNXfuXOXn55vhTjoXRt3c3DR9+nRlZ2fLy8tL3bp10/vvv6/Zs2fr7rvvVkREhHJzc/XWW2/J39/fob7zBQUF6ZlnntHkyZN1++23684779TevXs1e/Zs3XjjjQ7bh5VXeHi4mjRpopSUFDVr1kxhYWEO/R07dtS///1vubi4OMzGlvX3cjFPPfWU3nvvPd1+++0aN26cuR1W06ZNlZqaesnv79ixoxISEjR69Gi1bt1aDz74oK6++mrl5uZqw4YN+uyzzzR16tRy1ztixAi98MILGjFihDp06KDk5GRzRv5ytW/fXuvWrdPLL7+ssLAwNW/eXK1atVLjxo01cOBAXXfddfL19dW6deu0ffv2UvciLa5fv3567733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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(8, 6))\n", - "sns.boxplot(data=df[['words', 'length']])\n", - "plt.title('Boxplots of Word Counts and Name Lengths')\n", - "plt.ylabel('Values')\n", - "plt.xticks(ticks=[0, 1], labels=['Words', 'Length'])\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "f27c59dd8b8eaf4b", - "metadata": { - "ExecuteTime": { - "end_time": "2025-07-08T18:18:51.166573Z", - "start_time": "2025-07-08T18:18:42.805191Z" - } - }, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0kAAAIjCAYAAADWYVDIAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAZHRJREFUeJzt3Xl8VOXZ//Fv9n2yQYDsIWyiIMomi7IKgqXuqFhlEfVXQUHLo2IrAi6gWHF9WrUt2FrqvrRVFFTQsoisgrIoawggIetAEkJIzu8PnkxPmCyTWXIS8nm/Xrw058x17mvuuefMXHPOuY+fYRiGAAAAAACSJH+rEwAAAACApoQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQC8zM/PT7Nnz7Y6DTQhgwcP1gUXXGB1Gs1Oenq6JkyYYHUaAFogiiQAbtu2bZuuv/56paWlKTQ0VElJSbr88sv14osv+qzNJUuW6LnnnnNafvjwYc2ePVtbtmzxWdu+tn37ds2ePVv79+/3aDuDBw+Wn5+fxowZ47Ru//798vPz0zPPPONRG1ZYvHix/Pz8tGHDBqtTqVFzHIMVFRWy2Wy66qqrnNYtXLhQfn5+Gj9+vNO6WbNmyc/PTz/++GNjpOmSkydPauHCherbt6+io6MVGhqqTp06aerUqU0mzzVr1mj27NkqLCy0OhUA9aBIAuCWNWvWqFevXvruu+90xx136KWXXtLkyZPl7++v559/3mft1lUkzZkzp1l9QT3b9u3bNWfOHI+LpCr//ve/tXHjRq9sC/VrjmMwICBAl1xyidasWeO0bvXq1QoMDNTq1atrXJeQkKBOnTo1Rpr1ys3N1cCBA3X//fcrISFBc+fO1csvv6yrr75a//znP5vMUbw1a9Zozpw5FElAMxBodQIAmqcnnnhC0dHRWr9+vWJiYqqty8nJsSYpHyguLlZERITVaTRYamqqjh8/rjlz5uif//yn1emgCRs4cKCWL1+uHTt26LzzznMsX716tcaOHaslS5bo559/Vtu2bSVJp0+f1rp16zRixAiP2/bW+2vChAnavHmz3n33XV133XXV1j322GP67W9/63EbAFoWjiQBcMuePXt0/vnnOxVIkpSQkOC07I033lCfPn0UHh6u2NhYXXbZZVq2bJlj/UcffaQrr7xSiYmJCgkJUWZmph577DFVVFQ4HjN48GB9/PHHOnDggPz8/OTn56f09HStXLlSvXv3liRNnDjRsW7x4sWO2HXr1umKK65QdHS0wsPDNWjQIKdfyGfPni0/Pz9t375d48aNU2xsrAYOHCjpzJewyMhI7d27VyNHjlRERIQSExM1d+5cGYZRb39t3rxZo0aNks1mU2RkpIYNG6ZvvvnGsX7x4sW64YYbJElDhgxxPIeVK1dKkoqKirRz504VFRXV25YkRUVF6b777tO//vUvbdq0qc7H5ufna8aMGerWrZsiIyNls9k0atQofffdd9Uet3LlSvn5+entt9/WnDlzlJSUpKioKF1//fUqKipSWVmZpk+froSEBEVGRmrixIkqKytzau+NN95Qz549FRYWpri4ON100006ePCgS8/LFYcOHdKkSZPUpk0bhYSE6Pzzz9df/vKXWp/LE088oeTkZIWGhmrYsGHavXu30zZffvlltW/fXmFhYerTp4/+85//aPDgwRo8eLBje/WNQenM0cIhQ4YoPDxcSUlJevrpp+t9PhdccIGGDBnitLyyslJJSUm6/vrrHcvefPNN9ezZU1FRUbLZbOrWrVu9R3arxrj5/bB37179/PPPmjp1qkJDQ6ut27Jli4qLix1xkvTll1/q0ksvVUREhGJiYnTVVVdpx44d1dqp6/1lGIYef/xxJScnKzw8XEOGDNEPP/xQb99IZ97bH3/8sW6//XanAkmSQkJCnE4vdSXfCRMmKD093Wl7Vc/DzM/PT1OnTtWHH36oCy64wDHuPv3002px//M//yNJysjIcIyRqiPHy5cv18CBAxUTE6PIyEh17txZDz/8sEt9AMD7OJIEwC1paWlau3atvv/++3pPZZkzZ45mz56t/v37a+7cuQoODta6dev05ZdfOn6NXrx4sSIjI3X//fcrMjJSX375pWbNmiW73a4FCxZIkn7729+qqKhI2dnZWrhwoSQpMjJS5513nubOnatZs2bpzjvv1KWXXipJ6t+/v6QzX4hGjRqlnj176tFHH5W/v78WLVqkoUOH6j//+Y/69OlTLd8bbrhBHTt21JNPPlmtAKqoqNAVV1yhSy65RE8//bQ+/fRTPfroozp9+rTmzp1b6/P/4YcfdOmll8pms+mBBx5QUFCQXnnlFQ0ePFhfffWV+vbtq8suu0z33nuvXnjhBT388MOOX/Sr/vvBBx9o4sSJWrRokcsXsk+bNk0LFy7U7Nmz6zyatHfvXn344Ye64YYblJGRoaNHj+qVV17RoEGDtH37diUmJlZ7/Lx58xQWFqaHHnpIu3fv1osvvqigoCD5+/uroKBAs2fP1jfffKPFixcrIyNDs2bNcsQ+8cQTeuSRRzR27FhNnjxZx44d04svvqjLLrtMmzdvrrHoboijR4/qkksucXxpbd26tZYuXarbb79ddrtd06dPr/b4+fPny9/fXzNmzFBRUZGefvpp3XLLLVq3bp3jMX/4wx80depUXXrppbrvvvu0f/9+XX311YqNjVVycrIk1TsGJamgoEBXXHGFrr32Wo0dO1bvvvuuHnzwQXXr1k2jRo2q9TndeOONmj17drWjOZK0atUqHT58WDfddJOkM1+yb775Zg0bNkxPPfWUJGnHjh1avXq1pk2bVuv2L7nkEgUGBmrVqlWaPHmypDMFU0REhHr37q1evXpp9erVjgKkqmCqKnA+//xzjRo1Su3bt9fs2bNVWlqqF198UQMGDNCmTZucCo2a3l+zZs3S448/rtGjR2v06NHatGmTRowYoVOnTtWad5WqsX3rrbfW+1h38nXVqlWr9P777+vuu+9WVFSUXnjhBV133XXKyspSfHy8rr32Wv3444/6xz/+oYULF6pVq1aSpNatW+uHH37QL37xC3Xv3l1z585VSEiIdu/eXeOpjgAaiQEAbli2bJkREBBgBAQEGP369TMeeOAB47PPPjNOnTpV7XE//fST4e/vb1xzzTVGRUVFtXWVlZWO/y8pKXFq46677jLCw8ONkydPOpZdeeWVRlpamtNj169fb0gyFi1a5NRGx44djZEjRzq1l5GRYVx++eWOZY8++qghybj55pudtj9+/HhDknHPPfdU2/aVV15pBAcHG8eOHXMsl2Q8+uijjr+vvvpqIzg42NizZ49j2eHDh42oqCjjsssucyx75513DEnGihUrnNpftGhRjc+vJoMGDTLOP/98wzAMY86cOYYkY+PGjYZhGMa+ffsMScaCBQscjz958qTTa7Nv3z4jJCTEmDt3rmPZihUrDEnGBRdcUO11vvnmmw0/Pz9j1KhR1bbRr1+/aq/V/v37jYCAAOOJJ56o9rht27YZgYGBTstr64P169fX+pjb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aWlpkqTdu3dXm2Hu9OnT2r9/f7Wiy1evn3Tm6EufPn301ltvaerUqXr//fd19dVXKyQkpNrjgoODNWbMGI0ZM0aVlZW6++679corr+iRRx5xOhpmlpCQ4CiEIiIi1LVr12qTaPTv31+rV69Wdna2AgICHAVUVf/UNr5btWpV7xTfVdv46aefqh2pPXbsmEtHYcaMGaN58+bpjTfeqLdIaki+sbGxNd7PqOpolDvqGiP+/v4aNmyYhg0bpmeffVZPPvmkfvvb32rFihVeG88AXMfpdgDcsmLFihp/Ia06p7/qdJarr75a/v7+mjt3rtNRiar4ql9Jzds7deqU/vd//9dp+xERETWeAlb1xebsLzU9e/ZUZmamnnnmGZ04ccIp7tixY7U+x5q89NJL1fJ/6aWXFBQUpGHDhtX4+ICAAI0YMUIfffRRtVPyjh49qiVLlmjgwIGO04Vqew5Sw6cAP9v06dMVExNT4yx8AQEBTq/lO++84zi1y1uuvfZaBQQEaM6cOU7tGYahvLw8j7YfEBCg6667Tu+9956+//57p/UNfa2lM0V/fHy8XnvtNce1VZL097//3ekLfF2vnzfceOON+uabb/SXv/xFubm51U61k+TUf/7+/o4irqap2M82cOBAbdmyRcuWLas2K590pkhau3at/vOf/6h79+6O63/atWunHj166PXXX6/2vL///nstW7ZMo0ePrrfd4cOHKygoSC+++GK1cVHTUc+a9OvXT1dccYX+9Kc/6cMPP3Raf+rUKc2YMaPB+WZmZqqoqEhbt251LDty5Ig++OADl/KqSW1jJD8/3+mxVT8qufLaAfA+jiQBcMs999yjkpISXXPNNerSpYtOnTqlNWvW6K233lJ6errjGpAOHTrot7/9rR577DFdeumluvbaaxUSEqL169crMTFR8+bNU//+/RUbG6vx48fr3nvvlZ+fn/72t7/VWIT17NlTb731lu6//3717t1bkZGRGjNmjDIzMxUTE6M//vGPioqKUkREhPr27auMjAz96U9/0qhRo3T++edr4sSJSkpK0qFDh7RixQrZbDb961//cuk5h4aG6tNPP9X48ePVt29fLV26VB9//LEefvhhtW7duta4xx9/3HEPlLvvvluBgYF65ZVXVFZWVu0+OT169FBAQICeeuopFRUVKSQkREOHDlVCQoJbU4CbRUdHa9q0aTVO4PCLX/xCc+fO1cSJE9W/f39t27ZNf//7352uv/JUZmamHn/8cc2cOdMxjXZUVJT27dunDz74QHfeeafjy2xd/vKXv9R4rc20adM0f/58rVixQn379tUdd9yhrl27Kj8/X5s2bdLnn39e45fRugQHB2v27Nm65557NHToUI0dO1b79+/X4sWLlZmZWe3IQF1j0BvGjh2rGTNmaMaMGYqLi3M6ujB58mTl5+dr6NChSk5O1oEDB/Tiiy+qR48e1W4SW5uBAwdq0aJFWr9+vaZMmVJtXf/+/VVUVKSioiLdc8891dYtWLBAo0aNUr9+/XT77bc7ptSOjo7W7Nmz6223devWmjFjhubNm6df/OIXGj16tDZv3qylS5e6fCTzr3/9q0aMGKFrr71WY8aM0bBhwxQREaGffvpJb775po4cOeK4V5Kr+d5000168MEHdc011+jee+9VSUmJ/vCHP6hTp0713nusNj179pR05nYGN910k4KCgjRmzBjNnTtXX3/9ta688kqlpaUpJydH//u//6vk5GSPTm0E4IFGnk0PwDli6dKlxqRJk4wuXboYkZGRRnBwsNGhQwfjnnvuMY4ePer0+L/85S/GRRddZISEhBixsbHGoEGDjOXLlzvWr1692rjkkkuMsLAwIzEx0TGluM6aEvvEiRPGuHHjjJiYGENStSl6P/roI6Nr165GYGCg01TMmzdvNq699lojPj7eCAkJMdLS0oyxY8caX3zxheMxVVP71jQN7/jx442IiAhjz549xogRI4zw8HCjTZs2xqOPPuo0fbbOmgLcMAxj06ZNxsiRI43IyEgjPDzcGDJkiLFmzRqndl577TWjffv2RkBAQLXn7u4U4GYFBQVGdHR0jVOA/+Y3vzHatWtnhIWFGQMGDDDWrl1rDBo0qNoU11XTZr/zzjvVtlvb1Ny19ed7771nDBw40IiIiDAiIiKMLl26GFOmTDF27dpV5/Oqaqe2fwcPHjQMwzCOHj1qTJkyxUhJSTGCgoKMtm3bGsOGDTNeffXVep9L1RTpZ/fzCy+8YKSlpRkhISFGnz59jNWrVxs9e/Y0rrjiimqPq20M1vaa1DbNdG0GDBhgSDImT57stO7dd981RowYYSQkJBjBwcFGamqqcddddxlHjhxxadtVU41LMn788cdq6yorKx3vubfeessp9vPPPzcGDBhghIWFGTabzRgzZoyxffv2ao+p6/1VUVFhzJkzxzEGBw8ebHz//fdGWlpavVOAVykpKTGeeeYZo3fv3o59UseOHY177rmn2tTcruZrGGdudXDBBRcYwcHBRufOnY033nij1inAp0yZ4hRfU/6PPfaYkZSUZPj7+zumA//iiy+Mq666ykhMTDSCg4ONxMRE4+abb3Z6HQA0Hj/D8MHVqQBwjpkwYYLefffdGk/ZQ8tTWVmp1q1b69prr9Vrr71mdToAAC/jmiQAAOpw8uRJp1M///rXvyo/P1+DBw+2JikAgE9xTRIAAHX45ptvdN999+mGG25QfHy8Nm3apD//+c+64IILdMMNN1idHgDAByiSAACoQ3p6ulJSUvTCCy8oPz9fcXFxuu222zR//nwFBwdbnR4AwAe4JgkAAAAATLgmCQAAAABMKJIAAAAAwOScvyapsrJShw8fVlRUVLWb/gEAAABoWQzD0PHjx5WYmCh//9qPF53zRdLhw4eVkpJidRoAAAAAmoiDBw8qOTm51vXnfJEUFRUl6UxH2Gw2j7dXXl6uZcuWacSIEQoKCvJ4e2i5GEvwFsYSvIWxBG9hLMEbfDGO7Ha7UlJSHDVCbc75IqnqFDubzea1Iik8PFw2m403PTzCWIK3MJbgLYwleAtjCd7gy3FU32U4TNwAAAAAACYUSQAAAABgQpEEAAAAACYUSQAAAABgQpEEAAAAACYUSQAAAABgQpEEAAAAACYUSQAAAABgQpEEAAAAACYUSQAAAABgQpEEAAAAACYUSQAAAABgQpEEAAAAACYUSQAAAABgYmmR9PXXX2vMmDFKTEyUn5+fPvzww2rrDcPQrFmz1K5dO4WFhWn48OH66aefrEkWAACghbCXlmv74SKt25un7YeLZC8tb1Dszp/tkqSdP9tdjvWkTSt42kdWxMJ1gVY2XlxcrAsvvFCTJk3Stdde67T+6aef1gsvvKDXX39dGRkZeuSRRzRy5Eht375doaGhFmQMAABwbsvKK9ai1fuVlV/iWJYWH64J/dOVGh/hUuzh/BMaHSu99MVuJcVH1hvrSZtW8EYfNXYsGsbSI0mjRo3S448/rmuuucZpnWEYeu655/S73/1OV111lbp3766//vWvOnz4sNMRJwAAAHjOXlru9CVckg7klWjxmv11HrVwN9aTNq1gRR95GouGs/RIUl327dunn3/+WcOHD3csi46OVt++fbV27VrddNNNNcaVlZWprKzM8bfdfuZwb3l5ucrLPR88VdvwxrbQsjGW4C2MJXgLYwkHcu06nH+ixi+Ih/JO6ECuXV3a2uqNDVSlZPpvXbGetGkFb/VRY8Y2V77YJ7m6LT/DMAyvteoBPz8/ffDBB7r66qslSWvWrNGAAQN0+PBhtWvXzvG4sWPHys/PT2+99VaN25k9e7bmzJnjtHzJkiUKDw/3Se4AAAAAmr6SkhKNGzdORUVFstlqLyqb7JEkd82cOVP333+/42+73a6UlBSNGDGizo5wVXl5uZYvX67LL79cQUFBHm8PLRdjCd7CWIK3MJaw82e7Xvpid63rpw7rUOvRCnNsoCo1IjZHywoSdPr/ru6oLdaTNq3grT5qzNjmyhf7pKqzzOrTZIuktm3bSpKOHj1a7UjS0aNH1aNHj1rjQkJCFBIS4rQ8KCjIqzt8b28PLRdjCd7CWIK3MJZarrRWNiXFR+pAXonzuvhwpbWy1To2aoo9LX+dln+dsZ60aQVv91FjxDZ33twnubqdJnufpIyMDLVt21ZffPGFY5ndbte6devUr18/CzMDAAA4N9nCgjShf7rS4qtfolA1g5otrPYvmO7GetKmFazoI09j0XCWHkk6ceKEdu/+72HDffv2acuWLYqLi1NqaqqmT5+uxx9/XB07dnRMAZ6YmOi4bgkAAADelRofoenDOym7oETHT55WVGigkmPDXfoSXhV7INeuvZt+1tRhHZTWylZvrCdtWsEbfdTYsWgYS4ukDRs2aMiQIY6/q64lGj9+vBYvXqwHHnhAxcXFuvPOO1VYWKiBAwfq008/5R5JAAAAPmQLC1LXsGi3Y7u0tWmvpC5tXT8FzJM2reBpH1kRC9dZWiQNHjxYdU2u5+fnp7lz52ru3LmNmBUAAACAlqzJXpMEAAAAAFagSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADAJtDoBAOc2e2m5sgtKdPzkaUWFBio5Nly2sCCr0wKAZsOK/Whz23fn2E9qb26xikrLFRMWpIxWEUqwhTbZNq3oXyv6qDmjSALgM1l5xVq0er+y8kscy9LiwzWhf7pS4yMszAwAmgcr9qPNbd+9/XCRFny2S9uyixzLuqdEa8aIzuqaGN3k2rSif63oo+aO0+0A+IS9tNzpQ0CSDuSVaPGa/bKXlluUGQA0D1bsR5vbvjvHftLpy78kbT1YpGeW7VKO/WSTatOK/rWij84FFEkAfCK7oMTpQ6DKgbwSZRfUvA4AcIYV+9Hmtu/em1vs9OW/ytaDRdqbW9yk2rSif63oo3MBRRIAnzh+8rRH6wGgpbNiP9rc9t1F9Rx5qW99Y7dpRf9a0UfnAookAD4RFVr3JY/1rQeAls6K/Whz23dH1zPZQX3rG7tNK/rXij46F1AkAfCJ5NhwpcWH17guLT5cybE1rwMAnGHFfrS57bvbt4pQ95SaJx7onhKt9q28PxGCJ21a0b9W9NG5gCIJgE/YwoI0oX+604dB1Qw+TXkqWQBoCqzYjza3fXeCLVQzRnR2KgKqZm7zxRTXnrRpRf9a0UfngqZ1zBTAOSU1PkLTh3dqVvfaAICmxIr9aHPbd3dNjNb8a7s77gEUHRak9j6+B5AnbVrRv1b0UXNHkQTAp2xhQeoaxj0YAMBdVuxHm9u+O8EW2uhf+D1p04r+taKPmjNOtwMAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAk0CrE6hLRUWFZs+erTfeeEM///yzEhMTNWHCBP3ud7+Tn5+f1ekBspeWK7ugRMdPnlZUaKCSY8NlCws659rMsZ/U3txiFZWWKyYsSBmtIpRgC/Vpm56060m+VvQvgHMf+xbfon99qyX2b5Mukp566in94Q9/0Ouvv67zzz9fGzZs0MSJExUdHa17773X6vTQwmXlFWvR6v3Kyi9xLEuLD9eE/ulKjY84Z9rcfrhICz7bpW3ZRY5l3VOiNWNEZ3VNjPZJm56060m+VvQvgHMf+xbfon99q6X2b5M+3W7NmjW66qqrdOWVVyo9PV3XX3+9RowYoW+//dbq1NDC2UvLnXYYknQgr0SL1+yXvbT8nGgzx37SqeCQpK0Hi/TMsl3KsZ/0epuetOtJvlb0L4BzH/sW36J/fasl92+TPpLUv39/vfrqq/rxxx/VqVMnfffdd1q1apWeffbZWmPKyspUVlbm+Ntut0uSysvLVV7u+QtZtQ1vbAvN14Fcuw7nn6jxDXQo74QO5NrVpa2tzm00dCx5o82G2n20SLsOFyq4hp9Tdh4q1O6jRYoNC/Bqm56060m+VvSvt7BfgrcwlryvOe9bPNFYY6ml9m9jsbp/fTGOXN2Wn2EYhtda9bLKyko9/PDDevrppxUQEKCKigo98cQTmjlzZq0xs2fP1pw5c5yWL1myROHh4b5MFwAAAEATVlJSonHjxqmoqEg2W+0FXpMukt588039z//8jxYsWKDzzz9fW7Zs0fTp0/Xss89q/PjxNcbUdCQpJSVFubm5dXaEq8rLy7V8+XJdfvnlCgo6ty9YQ+12/mzXS1/srnX91GEdXDqS1JCx5I02G2r9/nzNePu7Wtc/M/ZC9U6P82qbnrTrSb5W9K+3sF+CtzCWvK8571s80VhjqaX2b2Oxun99MY7sdrtatWpVb5HUpE+3+5//+R899NBDuummmyRJ3bp104EDBzRv3rxai6SQkBCFhIQ4LQ8KCvLqm9Tb20PzktbKpqT4SB3IK3FeFx+utFY2l8eHq2PJm226qkObaHVJitHWg0VO67qnRKtDm2ifvA/cbdeTfK3oX29jvwRvYSx5z7mwb/GEr8dSS+9fX2sq/evNceTqdpr0xA0lJSXy96+eYkBAgCorKy3KCDjDFhakCf3TlRZf/RTOqtlefDEtphVtJthCNWNEZ3VPqT4rXNVscb6aBtzddj3J14r+BXDuY9/iW/Svb7Xk/m3SR5LGjBmjJ554QqmpqTr//PO1efNmPfvss5o0aZLVqQFKjY/Q9OGdGvW+AVa02TUxWvOv7e6471B0WJDaN8J9ktxt15N8rehfAOc+9i2+Rf/6Vkvt3yZdJL344ot65JFHdPfddysnJ0eJiYm66667NGvWLKtTAySd+YWla5jv7hXUVNpMsIU2ys1jvdWuJ/la0b8Azn3sW3yL/vWtlti/TbpIioqK0nPPPafnnnvO6lQAAAAAtBBN+pokAAAAAGhsFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYEKRBAAAAAAmFEkAAAAAYBJodQJAc2YvLVd2QYmOnzytqNBAJceGyxYW5FLcgVy7JGnnz3altbK5FCdJOfaT2ptbrKLScsWEBSmjVYQSbKE+jd137IQOFpTKXlqu6LAgJceGKaN1pEtt7sk5oUOF/41NjAlTZoJrse6260mbnsS6Ox486d8c+0ntPlokSdqwP1+ZbaJdHg/utnsgt1hZ+SUq+r+41LhwpbWKcKnNvTknlG3q36SYMLX38WvjSZvZ+SXan/ff90xafISS48JdinX3/ebuOAKApqi57tMokgA3ZeUVa9Hq/crKL3EsS4sP14T+6UqNr/0LY1Xc4fwTGh0rvfTFbiXFR9YbJ0nbDxdpwWe7tC27yLGse0q0ZozorK6J0T6J3ZxVoPlLd2rdvnzHsr4ZcXpoVBddlBpbZ5tWxFqVr7vjwZM2q17TXYcL9eAF0m/e/k5dkmJcGg/utrvlYIHmfbJT354dN7qLeqScW+Nha3ah5i/dofX7CxzLeqfH6qFR56l7ckydse6+39wdRwDQFDXnfRqn2wFusJeWO73pJelAXokWr9kve2m5V+OkM79Kn/2lS5K2HizSM8t2Kcd+0uux+46dcPqCKUnr9uVr/tKd2nfsRK1t7smpO3ZPTu2x7rbrSZuexLr7unrSv56MB3fbPZBb7FQgOeI+2akDucW1trm3nv7d64PXxpM2s/NLnAokSVq/v0Dzl+5Q9lmvtZm7r40n+wcAaGqa+z6NIglwQ3ZBidObvsqBvBJlF9S8zt04SdqbW+z0pavK1oNF2lvXF1Q3Yw8WlDp9wayybl++DhaU1trmocK6Yw8V1h7rbruetOlJrLuvqyf968l4cLfdrPwSpwLJHFdbH0hSdj39m+2D18aTNvfnFTsVSFXW7y/Q/jzvv9882T8AQFPT3PdpFEmAG46fPO3WenfjJKmonl9c6lrvbmx9v/LUtd6KWKvydfd19aRNT8aDu+1a0aYnsVb1r7uxnuwfAKCpae77NIokwA1RoXVfzlfbenfjJCm6nosc61rvbmx9F1bWtd6KWKvydfd19aRNT8aDu+1a0aYnsVb1r7uxnuwfAKCpae77NIokwA3JseFKi695hqu0+HAlx9a8zt04SWrfKkLdU2q+4Lt7SrTa1zG7mLuxKbFh6psRV+O6vhlxSokNq7XNpJi6Y5Niao91t11P2vQk1t3X1ZP+9WQ8uNtualx4nXGpdcz6llxP/yb74LXxpM30+Aj1Tq95Yofe6bFKr+OCY3dfG0/2DwDQ1DT3fRpFEuAGW1iQJvRPd3rzV83YUtcv2+7ESVKCLVQzRnR2+vJVNWNWXVMLuxub0TpSD43q4vRFs29GnGaO7lLndNGZCXXH1jV1s7vtetKmJ7Huvq6e9K8n48HddtNaReih0TXHPTS6S53TgLevp3/rmpLb3dfGkzaT48L10KjznAqlqtnt6poG3N3XxpP9AwA0Nc19n+ZnGIZhdRK+ZLfbFR0draKiItlsNo+3V15erk8++USjR49WUFDTfnHhe57eJ2nvplVqf/FAt++TFB0WpPZu3iepIbHm++nYwoKU4uZ9kmz/d48ad+6T1JB2PWnTk1hv3Cepof1bdZ+kY9u/Ueuul6iDm/dJaki73rpPki0sSMlu3iepIa+NJ22a75MUHRakdDfvk9SQ95uV9xThMw7ewlhCFU/2ab4YR67WBk37ZECgibOFBalrWN33o6ktrktbm/ZK6tLW1qA3foIt1OUvwd6KzWgd6fKX9rNlJkS6XGR4q11P2vQk1t3x4En/JthCFRsWoE+2S73T4xo0ltxtN61VhMtF0dnaJ0S6XKCczd3XxpM2k+PCXS6Kzubu+83dcQQATVFz3adxuh0AAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIBJg4uk119/XR9//LHj7wceeEAxMTHq37+/Dhw44NXkAAAAAKCxNbhIevLJJxUWFiZJWrt2rV5++WU9/fTTatWqle677z6vJwgAAAAAjSmwoQEHDx5Uhw4dJEkffvihrrvuOt15550aMGCABg8e7O38AAAAAKBRNfhIUmRkpPLy8iRJy5Yt0+WXXy5JCg0NVWlpqXezAwAAAIBG1uAjSZdffrkmT56siy66SD/++KNGjx4tSfrhhx+Unp7u7fwAAAAAoFE1+EjSyy+/rH79+unYsWN67733FB8fL0nauHGjbr75Zq8nCAAAAACNqcFHkux2u1544QX5+1evr2bPnq2DBw96LTEAAAAAsEKDjyRlZGQoNzfXaXl+fr4yMjK8khQAAAAAWKXBRZJhGDUuP3HihEJDQz1OCAAAAACs5PLpdvfff78kyc/PT7NmzVJ4eLhjXUVFhdatW6cePXp4PUEAAAAAaEwuF0mbN2+WdOZI0rZt2xQcHOxYFxwcrAsvvFAzZszwfoYAAAAA0IhcLpJWrFghSZo4caKef/552Ww2nyUFAAAAAFZp8Ox2ixYt8kUeAAAAANAkNLhIKi4u1vz58/XFF18oJydHlZWV1dbv3bvXa8kBAAAAQGNrcJE0efJkffXVV7r11lvVrl07+fn5+SIvh0OHDunBBx/U0qVLVVJSog4dOmjRokXq1auXT9sFfMleWq4DuXZJ0s6f7UprZZMtLMil2Oz8Eu3PK1ZRabliwoKUFh+h5Ljw+gMl7ck5oUOFpbKXlis6LEiJMWHKTIj0WZxVsS0t3+y845KktbtzlRQf1eTzbW7929ixOfaT2pv73/d4RqsIJdhcmz3WXlqu7IISHT95WlGhgUqODXd53wIA+K8GF0lLly7Vxx9/rAEDBvgin2oKCgo0YMAADRkyREuXLlXr1q31008/KTY21udtA76SlVesRav363D+CY2OlV76YreS4iM1oX+6UuMj6ozdml2o+Ut3aP3+Asey3umxemjUeeqeHFNn7OasAs1fulPr9uU7lvXNiNNDo7rootTa31PuxlkV2xLz3ZKVp6f7SHe8sVE9UuObfL7NrX8bM3b74SIt+GyXtmUXOZZ1T4nWjBGd1TUxus42q/YtWfkljmVp8eEu7VsAANU1+D5JsbGxiouL80UuTp566imlpKRo0aJF6tOnjzIyMjRixAhlZmY2SvuAt9lLy52+xEjSgbwSLV6zX/bS8lpjs/NLnAokSVq/v0Dzl+5Q9lnbNNuTc8LpC5skrduXr/lLd2pPzgmvxlkVS77ka3WbnsTm2E86FUiStPVgkZ5Ztks59pO1tunJvgUA4KzBR5Iee+wxzZo1S6+//nq1eyX5wj//+U+NHDlSN9xwg7766islJSXp7rvv1h133FFrTFlZmcrKyhx/2+1nTmkqLy9XebnnHxJV2/DGttDyHMi163D+CQVKCtSZ6/mq/nso74QO5NrVpW3NM0fuzSnS1qx8hdTw08bWrHztzSlSm6iaT6vJzjuuLVl5CglwXrclK0/ZeceVGhvitTirYltqviH+Z27yXfXfpp5vY8U2t3x3Hy3SrsOFCq7hPb7zUKF2Hy1SbFgNG1X1fcvZ6tu3mPEZB29hLMEbfDGOXN2Wn2EYRkM2fNFFF2nPnj0yDEPp6ekKCqr+pWzTpk0N2VydQkPPnIN9//3364YbbtD69es1bdo0/fGPf9T48eNrjJk9e7bmzJnjtHzJkiU+L+oAAAAANF0lJSUaN26cioqK6rylUYOLpJoKELNHH320IZurU3BwsHr16qU1a9Y4lt17771av3691q5dW2NMTUeSUlJSlJub65V7O5WXl2v58uW6/PLLnQpEoD47f7brpS92SzpzBGlEbI6WFSTo9P+d+Tp1WIdaf+1duydXd/+99h8h/veWi9Uvs1WN69bsztWdb2ysNfbVX/VU/w7Ose7GWRXbUvMN8Tf0WK9KPbLBX2WVfk0+38aKbW75rt+frxlvf1dr3DNjL1Tv9JpPdzfvW2pS177FjM84eAtjCd7gi3Fkt9vVqlWreoukBp9u580iqD7t2rVT165dqy0777zz9N5779UaExISopAQ59MYgoKCvPom9fb20DKktbIpKT5SB/L+e93AafnrtPyVFh+utFa2WsdV+4RodU+Nc7omSTozeUP7hOhaY5Pjo9QjNd7pGgnpzMXkyfFRNca6G2dVbEvPt6zST2UVfs0mX1/HNrd8O7SJVpekGG09WOS0rntKtDq0qf09XtO+xbGunn1LTfiMg7cwluAN3hxHrm6nwRM3NKYBAwZo165d1Zb9+OOPSktLsygjwDO2sCBN6J+utPjqp35WzUBV11S9yXHhemjUeeqdXn1mrKrZ7eqaBjwzIVIPjeqivhnVf4XumxGnmaO71DotsbtxVsWSL/la3aYnsQm2UM0Y0VndU6rPYlc1u11d04B7sm8BADhr8Ol2/v7+dd4bqaKiwuOkqqxfv179+/fXnDlzNHbsWH377be644479Oqrr+qWW25xaRt2u13R0dH1HlJzVXl5uT755BONHj2aX0bgtqr7JO3dtErtLx7o9n2SosOClO7mfZJsYUFKcuM+Mw2Jsyq2peWbnXdchT9+q5hOfZTs5n2S6N+mE2u+T1J0WJDaN+J9kviMg7cwluANvhhHrtYGDT7d7oMPPqj2d3l5uTZv3qzXX3+93uuVGqp379764IMPNHPmTM2dO1cZGRl67rnnXC6QgKbKFhakLm1t2iupS9uGnQaTHBfuclF0tsyESJe/4HkjzqrYlpZvamyIPvlR6t+hVYPGEv3bNGMTbKEuF0Vns4UFqWtY3fdTAgDUr8FF0lVXXeW07Prrr9f555+vt956S7fffrtXEqvyi1/8Qr/4xS+8uk0AAAAAqI3Xrkm65JJL9MUXX3hrcwAAAABgCa8USaWlpXrhhReUlJTkjc0BAAAAgGUafLpdbGxstYkbDMPQ8ePHFR4erjfeeMOryQEAAABAY2twkfTcc89V+9vf31+tW7dW3759FRsbW3MQAAAAADQTDS6Sxo8f74s8AAAAAKBJaHCRJEmFhYX685//rB07dkiSzj//fE2aNEnR0Uw7CgAAAKB5a/DEDRs2bFBmZqYWLlyo/Px85efn69lnn1VmZqY2bdrkixwBAAAAoNE0+EjSfffdp1/+8pd67bXXFBh4Jvz06dOaPHmypk+frq+//trrSQIAAABAY2lwkbRhw4ZqBZIkBQYG6oEHHlCvXr28mhwAAAAANLYGn25ns9mUlZXltPzgwYOKiorySlIAAAAAYJUGF0k33nijbr/9dr311ls6ePCgDh48qDfffFOTJ0/WzTff7IscAQAAAKDRNPh0u2eeeUZ+fn667bbbdPr0aUlSUFCQfv3rX2v+/PleTxAAAAAAGlODi6Tg4GA9//zzmjdvnvbs2SNJyszMVHh4uNeTAwAAAIDG5vLpdhUVFdq6datKS0slSeHh4erWrZu6desmPz8/bd26VZWVlT5LFAAAAAAag8tF0t/+9jdNmjRJwcHBTuuCgoI0adIkLVmyxKvJAQAAAEBjc7lI+vOf/6wZM2YoICDAaV3VFOCvvvqqV5MDAAAAgMbmcpG0a9cuXXLJJbWu7927t3bs2OGVpAAAAADAKi4XScXFxbLb7bWuP378uEpKSrySFAAAAABYxeUiqWPHjlqzZk2t61etWqWOHTt6JSkAAAAAsIrLRdK4ceP0u9/9Tlu3bnVa991332nWrFkaN26cV5MDAAAAgMbm8n2S7rvvPi1dulQ9e/bU8OHD1aVLF0nSzp079fnnn2vAgAG67777fJYoAAAAADQGl4ukoKAgLVu2TAsXLtSSJUv09ddfyzAMderUSU888YSmT5+uoKAgX+YKAAAAAD7ncpEknSmUHnjgAT3wwAO+ygcAAAAALOXyNUkAAAAA0BJQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJi4NLvd/fff7/IGn332WbeTAQAAAACruVQkbd68udrfmzZt0unTp9W5c2dJ0o8//qiAgAD17NnT+xkCAAAAQCNyqUhasWKF4/+fffZZRUVF6fXXX1dsbKwkqaCgQBMnTtSll17qmywBAAAAoJE0+Jqk3//+95o3b56jQJKk2NhYPf744/r973/v1eQAAAAAoLE1uEiy2+06duyY0/Jjx47p+PHjXkkKAAAAAKzS4CLpmmuu0cSJE/X+++8rOztb2dnZeu+993T77bfr2muv9UWOAAAAANBoXLomyeyPf/yjZsyYoXHjxqm8vPzMRgIDdfvtt2vBggVeTxAAAAAAGlODiqSKigpt2LBBTzzxhBYsWKA9e/ZIkjIzMxUREeGTBAEAAACgMTWoSAoICNCIESO0Y8cOZWRkqHv37r7KC2g0B3KLlZVfoqLSckWHBSk1LlxprVwr+u2l5couKNHxk6cVFRqo5Nhw2cKC6o3bk3NC2XlnruFbuztXSfFRykyIdKnNPTkndKiwVPb/yzcxJsznsVa0Sb6ut9nYY6ml9W9LyddeWq4DuXZJ0s6f7UprZXNpf4amy93PKABunG53wQUXaO/evcrIyPBFPkCj2nKwQPM+2alv9+U7lvXNiNNDo7uoR0psHZFSVl6xFq3er6z8EseytPhwTeifrtT42ouszVkFmr90p7Zk5enpPtIdb2xUj9R4PTSqiy5KrbvNqth1Z+frw1gr2iTfhrXZmGOpJfZvS8i3an92OP+ERsdKL32xW0nxkfXuz9B0ufsZBeCMBk/c8Pjjj2vGjBn697//rSNHjshut1f7BzQXB3KLnQokSVq3L1/zP9mpA7nFtcbaS8udPnwk6UBeiRav2S97aXmNcXtyTjh9iXG0uXSn9uScqLVNK2LJl3ytbpN8fZ+vu/szNF28poDnGlwkjR49Wt99951++ctfKjk5WbGxsYqNjVVMTEy1eycBTV1WfolTgVRl3b58pw8Xs+yCklrXH8grUXZBzesOFZY6fYkxt3mosLTWNq2IJV/ytbpN8vV9vu7uz9B08ZoCnmvw6XYrVqzwRR5Aoyuq55e0utYfP3m6ztja1tf3611d662IJV/fxpKvb2PJ17X17u7P0HTxmgKea3CRNGjQIF/kATS66HouXq1rfVRo3W+d2tbXd8FsXeutiCVf38aSr29jyde19e7uz9B08ZoCnmvw6XaSVFhYqN///veaPHmyJk+erIULF6qoqMjbuQE+lRoXrr4ZcTWu65sRp9S48Fpjk2PDlRZf8/q0+HAlx9a8LikmrM42k2LCam3TiljyJV+r2yRf3+fr7v4MTRevKeC5BhdJGzZsUGZmphYuXKj8/Hzl5+fr2WefVWZmpjZt2uSLHAGfSGsVoYdGd3H6YlE1u11d04DbwoI0oX+604dQ1cxBtf1qm5kQqYdG1dzmzNFd6pyq14pY8iVfq9skX9/n6+7+DE0XryngOT/DMIyGBFx66aXq0KGDXnvtNQUGnjlce/r0aU2ePFl79+7V119/7ZNE3WW32xUdHa2ioiLZbDaPt1deXq5PPvlEo0ePVlAQO5lzgZX3SSr88VvFdOqjZDfvbWMLC1KSm/dQaUisFW2Sb8Puk9SYY6ml9W9LybfqPkl7N61S+4sHcp+kc4CV90ni+xK8wRfjyNXaoMFFUlhYmDZv3qwuXbpUW759+3b16tVLJSVNa8YUiiQ0VYwleAtjCd7CWIK3MJbgDVYWSQ0+3c5msykrK8tp+cGDBxUVFdXQzQEAAABAk9LgIunGG2/U7bffrrfeeksHDx7UwYMH9eabb2ry5Mm6+eabfZEjAAAAADSaBs8B+cwzz8jPz0+33XabTp8+M89+UFCQfv3rX2v+/PleTxAAAAAAGpPLRdK+ffuUkZGh4OBgPf/885o3b5727NkjScrMzFR4ONNJAgAAAGj+XC6SMjMzlZaWpiFDhmjo0KEaMmSIunXr5svcAAAAAKDRuVwkffnll1q5cqVWrlypf/zjHzp16pTat2/vKJiGDBmiNm3a+DJXAAAAAPA5l4ukwYMHa/DgwZKkkydPas2aNY6i6fXXX1d5ebm6dOmiH374wVe5AgAAAIDPNXjiBkkKDQ3V0KFDNXDgQA0ZMkRLly7VK6+8op07d3o7PwAAAABoVA0qkk6dOqVvvvlGK1as0MqVK7Vu3TqlpKTosssu00svvaRBgwb5Kk8AAAAAaBQuF0lDhw7VunXrlJGRoUGDBumuu+7SkiVL1K5dO1/mBwAAAACNyuUi6T//+Y/atWunoUOHavDgwRo0aJDi4+N9mRsAAAAANDp/Vx9YWFioV199VeHh4XrqqaeUmJiobt26aerUqXr33Xd17NgxX+YJAAAAAI3C5SNJERERuuKKK3TFFVdIko4fP65Vq1ZpxYoVevrpp3XLLbeoY8eO+v77732WLAAAAAD4mstHks4WERGhuLg4xcXFKTY2VoGBgdqxY4c3cwMAAACARufykaTKykpt2LBBK1eu1IoVK7R69WoVFxcrKSlJQ4YM0csvv6whQ4b4MlcAAAAA8DmXi6SYmBgVFxerbdu2GjJkiBYuXKjBgwcrMzPTl/kBAAAAQKNyuUhasGCBhgwZok6dOvkyHwAAAACwlMtF0l133eXLPAAAAACgSXB74gYAAAAAOBdRJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJgEWp1AQ8yfP18zZ87UtGnT9Nxzz1mdDnzAXlqu7IISHT95WlGhgUqODZctLMinbe7JOaFDhaWyl5YrOixIiTFhykyIdCk2O79E+/OKVVRarpiwIKXFRyg5LtylNrPzjkuS1u7OVVJ8lMttepKvu7FWtEm+rrfZ2GOppfVvS8k3O79Ee3OKJEnf7MlVRkK0S/szK/bbAOBrzaZIWr9+vV555RV1797d6lTgI1l5xVq0er+y8kscy9LiwzWhf7pS4yN80ubmrALNX7pT6/blO5b1zYjTQ6O66KLU2Dpjt2YXav7SHVq/v8CxrHd6rB4adZ66J8fU2+aWrDw93Ue6442N6pEa71KbnuTrbqwVbZJvw9pszLHUEvu3JeRbtT/bmpWvJ3pJv/77JnVPjat3f2bFfhsAGkOzON3uxIkTuuWWW/Taa68pNrbuHT2aJ3tpudMHrSQdyCvR4jX7ZS8t93qbe3JOOH2hkKR1+/I1f+lO7ck5UWtsdn6JU4EkSev3F2j+0h3KPut5eKNNK2LJl3ytbpN8fZ+vu/szK/bbANBYmsWRpClTpujKK6/U8OHD9fjjj9f52LKyMpWVlTn+ttvtkqTy8nKVl3u+w67ahje2hf86kGvX4fwTNQ7IQ3kndCDXri5tbV5tMzvvuLZk5SkkwHndlqw8ZecdV2psSI2xe3OKtDUrXyE1/MywNStfe3OK1CbK+XQTc5sh/oak//63vjY9ydfdWCvaJN+Gt9lYY6ml9u+5nq95f3b2WKprf2bFfhvNB9+X4A2+GEeubsvPMAzDa636wJtvvqknnnhC69evV2hoqAYPHqwePXrUek3S7NmzNWfOHKflS5YsUXh4/edWAwAAADg3lZSUaNy4cSoqKpLNVvsPOU26SDp48KB69eql5cuXO65Fqq9IqulIUkpKinJzc+vsCFeVl5dr+fLluvzyyxUUxIWp3rLzZ7te+mJ3reunDuvg9V8k1+zO1Z1vbKx1/au/6qn+HVrVuG7tnlzd/fdNtcb+7y0Xq1+mc6y5zRB/Q4/1qtQjG/xVVulXb5ue5OturBVtkm/D22yssdRS+/dcz9e8PwvxNzTr4grN3RTgGEu17c+s2G+j+eD7ErzBF+PIbrerVatW9RZJTfp0u40bNyonJ0cXX3yxY1lFRYW+/vprvfTSSyorK1NAQPVzC0JCQhQS4nxKQVBQkFffpN7eXkuX1sqmpPhIHchzPvc9LT5caa1sXu/v5Pgo9UiNdzqHXzpzsXNyfFStbbZPiFb31Dinc/ilM5M3tE+IrjG2pjbLKv1UVuFXb5ue5OturBVtkq/7bfp6LLX0/j1X861pf1ZW6aeySr8692dW7LfR/PB9Cd7gzXHk6naa9MQNw4YN07Zt27RlyxbHv169eumWW27Rli1bnAokNF+2sCBN6J+utPjqp0RWzZLki+lkMxMi9dCoLuqbEVdted+MOM0c3aXOaXOT48L10Kjz1Du9+kQiVbPb1TZtridtWhFLvuRrdZvk6/t83d2fWbHfBoDG0qRPt6tJfafbnc1utys6OrreQ2quKi8v1yeffKLRo0fzy4gPWH2fJFtYkJLcvE9SdFiQ0ht4n6TCH79VTKc+Snbz3jYNzdfdWCvaJN+G3SepMcdSS+vflpJv1X2SCnZ9q9jOfdSe+yTBA3xfgjf4Yhy5WhtQJDUQb3p4C2MJ3sJYgrcwluAtjCV4g5VFUpO+JqkmK1eutDoFAAAAAOewJn1NEgAAAAA0NookAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAE4okAAAAADChSAIAAAAAk0CrE8C5x15aruyCEh0/eVpRoYFKjg2XLSzIp7F7ck7oUGGp7KXlig4LUmJMmDITIl1q04rYPTknlJ13XJK0dneukuKjmny+za1/W1K+jT2WWlr/tqR83RlLe3NOKNvUZlJMmNq72KYnnxcA4EsUSfCqrLxiLVq9X1n5JY5lafHhmtA/XanxET6J3ZxVoPlLd2rdvnzHsr4ZcXpoVBddlBpbZ5tWxFbFbcnK09N9pDve2KgeqfFNPt/m1r8tKd/GHEstsX9bUr4NHUuetOnJ5wUA+Bqn28Fr7KXlTh94knQgr0SL1+yXvbTc67F7ck44fUBL0rp9+Zq/dKf25JyotU0rYsmXfK1uk3zJ11uxe+uJ21tHm558XgBAY6BIgtdkF5Q4feBVOZBXouyCmtd5EnuosNTpA7rKun35OlRYWmubVsSSL/la3Sb5kq+3YrPricuuo01PPi8AoDFQJMFrjp887fZ6d2Pr+7WxvqNXjR1Lvr6NJV/fxpKvb2NbUr6efF4AQGOgSILXRIXWfYlbXevdja3vAt+61lsRS76+jSVf38aSr29jW1K+nnxeAEBjoEiC1yTHhistPrzGdWnx4UqOrXmdJ7FJMWHqmxFX47q+GXFKigmrtU0rYsmXfK1uk3zJ11uxyfXEJdfRpiefFwDQGCiS4DW2sCBN6J/u9MFXNVtRfb9kuhObmRCph0Z1cfqg7psRp5mju9Q5fa0VseRLvla3Sb7k663Y9vXE1TUNuCefFwDQGPwMwzCsTsKX7Ha7oqOjVVRUJJvN5vH2ysvL9cknn2j06NEKCmInXhOr75Nk+7/7dLhzX5HGiq26H0nhj98qplMfJbt5b5vGzLe59W9Lyrexx1JL69+WlK87Y8l8nyRbWJCSuU8SxPcleIcvxpGrtQFFUgPxpoe3MJbgLYwleAtjCd7CWII3WFkkcbodAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJhQJAEAAACACUUSAAAAAJgEWp1AXebNm6f3339fO3fuVFhYmPr376+nnnpKnTt3tjq1ZsFeWq7sghIdP3laUaGBSo4Nly0syOft7s05oezCUtlLyxUdFqSkmDC1T4h0KXZPzgkdMsUmxoQp04VYd+Osit2Tc0LZecclSWt35yopPqrJ59vc+rcl5dvYY6ml9W9zyjfHflJ7c4tVVFqumLAgZbSKUIIt1KVYAMB/Neki6auvvtKUKVPUu3dvnT59Wg8//LBGjBih7du3KyIiwur0mrSsvGItWr1fWfkljmVp8eGa0D9dqfG+67vNWQWav3Sn1u3LdyzrmxGnh0Z10UWpsT6JtaJNb+S7JStPT/eR7nhjo3qkxjf5fJtb/7akfBtzLLXE/m0u+W4/XKQFn+3Stuwix7LuKdGaMaKzuiZG1xkLAKiuSZ9u9+mnn2rChAk6//zzdeGFF2rx4sXKysrSxo0brU6tSbOXljsVSJJ0IK9Ei9fsl7203Cft7s054fThLknr9uVr/tKd2ptzotbYPfXE7qkl1t04q2LJl3ytbpN8z818c+wnnQokSdp6sEjPLNulHPvJWmMBAM6a9JGksxUVndn5x8XF1fqYsrIylZWVOf622+2SpPLycpWXe14cVG3DG9vylQO5dh3OP1Hji3so74QO5NrVpa3N6+0ezDuuLVl5CglwXrclK08H844rJTakxtjsemKz844rtYZYd+OsijXHhfgbkv7736aeb2O1Sb4Nb7OxxlJL7d/mkO/uo0XadbhQwTX89LnzUKF2Hy1SbFgNGz5Lc/iMQ/PAWII3+GIcubotP8MwDK+16kOVlZX65S9/qcLCQq1atarWx82ePVtz5sxxWr5kyRKFh4f7MkUAAAAATVhJSYnGjRunoqIi2Wy1HzRoNkXSr3/9ay1dulSrVq1ScnJyrY+r6UhSSkqKcnNz6+wIV5WXl2v58uW6/PLLFRTk+0kQ3LHzZ7te+mJ3reunDuvgkyNJa3bn6s43aj8V8tVf9VT/Dq28GmtFm97KN8Tf0GO9KvXIBn+VVfo1+Xwbq03ybXibjTWWWmr/Nod81+/P14y3v6s19pmxF6p3eu1nYVRpDp9xaB4YS/AGX4wju92uVq1a1VskNYvT7aZOnap///vf+vrrr+sskCQpJCREISHOpyMEBQV59U3q7e15U1orm5LiI3Ugr8R5XXy40lrZfJJ7SnyUeqTGO51PL5258DglPqrWdpPriU2uJdbdOKtia4orq/RTWYVfs8nX122Sr/tt+nostfT+bcr5dmgTrS5JMdp6sMhpXfeUaHVoE92g/X5T/oxD88JYgjd4cxy5up0mPXGDYRiaOnWqPvjgA3355ZfKyMiwOqVmwRYWpAn905UWX/30wqrZ7Xw1DXj7hEg9NKqL+mZU/7Wyb0acZo7uUuc04Jn1xNY2/a27cVbFki/5Wt0m+Z6b+SbYQjVjRGd1T6k+i13V7HZMAw4ADdOkT7e7++67tWTJEn300UfV7o0UHR2tsLAwl7Zht9sVHR1d7yE1V5WXl+uTTz7R6NGjm/wvI03hPkm2sCAlu3mfJNv/3WOpofcVaUicVbFV97Yp/PFbxXTqo2Q3723TmPk2t/5tSfk29lhqaf3bnPI13ycpOixI7Rt4n6Tm9BmHpo2xBG/wxThytTZo0kWSn59fjcsXLVqkCRMmuLSNllwkoWljLMFbGEvwFsYSvIWxBG+wskhq0tckNeH6DQAAAMA5qklfkwQAAAAAjY0iCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMAq1OoKXYk3NChwpLZS8tV3RYkBJjwpSZEOnTWCvatCq2OeabnXdckrR2d66S4qOafL7NrX9bUr6NPZaaW//m2E9qb26xikrLFRMWpIxWEUqwhbrUZnZ+ifbn/Tc2LT5CyXHhLsXaS8uVXVCi4ydPKyo0UMmx4bKFBbkUCwCwFkVSI9icVaD5S3dq3b58x7K+GXF6aFQXXZQa65NYK9q0Kra55rslK09P95HueGOjeqTGN/l8m1v/tqR8G3MsNbf+3X64SAs+26Vt2UWOZd1TojVjRGd1TYyus82t2YWav3SH1u8vcCzrnR6rh0adp+7JMXXGZuUVa9Hq/crKL3EsS4sP14T+6UqNj6gzFgBgPU6387E9OSecPtglad2+fM1fulN7ck54PdaKNq2KJV/ytbpN8m26+ebYTzoVSJK09WCRnlm2Szn2k7W2mZ1f4lQgSdL6/QWav3SHsk3Fz9nspeVOBZIkHcgr0eI1+2UvLa81FgDQNFAk+dihwlKnD/Yq6/bl61BhqddjrWjTqljyJV+r2yTfppvv3txipwKpytaDRdqbW1xrm/vzip0KpCrr9xdof17tsdkFJU4FUpUDeSXKLqi9wAIANA0UST5W3y+Gda13N9aKNq2KJV/fxpKvb2PJ17exRfXE1bXek9jjJ0/XGVvfegCA9SiSfKy+i3TrWu9urBVtWhVLvr6NJV/fxpKvb2Oj64mra70nsVGhdV/uW996AID1KJJ8LCkmTH0z4mpc1zcjTkkxYV6PtaJNq2LJl3ytbpN8m26+7VtFqHtKzZMzdE+JVvtWtU+gkB4fod7pNU8I0Ts9Vul1TL6QHBuutPiaZ8BLiw9Xcqxrs+MBAKxDkeRjmQmRemhUF6cP+L4ZcZo5ukud09e6G2tFm1bFki/5Wt0m+TbdfBNsoZoxorNToVQ1u11d04Anx4XroVHnORVKVbPb1TUNuC0sSBP6pzsVSlWz2zENOAA0fX6GYRhWJ+FLdrtd0dHRKioqks1m83h75eXl+uSTTzR69GgFBbn+QWe+v4ctLEhJbt4bpCGxVrRpVWxzzDc777gKf/xWMZ36KNnNe9vQv02nTSvzbeyx1Nz613yfpOiwILV38z5J0WFBSj/H75Pk7mcccDbGErzBF+PI1dqAIqmBeNPDWxhL8BbGEryFsQRvYSzBG6wskjjdDgAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwIQiCQAAAABMKJIAAAAAwCTQ6gR8zTAMSZLdbvfK9srLy1VSUiK73a6goCCvbBMtE2MJ3sJYgrcwluAtjCV4gy/GUVVNUFUj1OacL5KOHz8uSUpJSbE4EwAAAABNwfHjxxUdHV3rej+jvjKqmausrNThw4cVFRUlPz8/j7dnt9uVkpKigwcPymazeSFDtFSMJXgLYwnewliCtzCW4A2+GEeGYej48eNKTEyUv3/tVx6d80eS/P39lZyc7PXt2mw23vTwCsYSvIWxBG9hLMFbGEvwBm+Po7qOIFVh4gYAAAAAMKFIAgAAAAATiqQGCgkJ0aOPPqqQkBCrU0Ezx1iCtzCW4C2MJXgLYwneYOU4OucnbgAAAACAhuBIEgAAAACYUCQBAAAAgAlFEgAAAACYUCQBAAAAgAlFUgO9/PLLSk9PV2hoqPr27atvv/3W6pTQxH399dcaM2aMEhMT5efnpw8//LDaesMwNGvWLLVr105hYWEaPny4fvrpJ2uSRZM1b9489e7dW1FRUUpISNDVV1+tXbt2VXvMyZMnNWXKFMXHxysyMlLXXXedjh49alHGaKr+8Ic/qHv37o6bM/br109Lly51rGccwV3z58+Xn5+fpk+f7ljGeIIrZs+eLT8/v2r/unTp4lhvxTiiSGqAt956S/fff78effRRbdq0SRdeeKFGjhypnJwcq1NDE1ZcXKwLL7xQL7/8co3rn376ab3wwgv64x//qHXr1ikiIkIjR47UyZMnGzlTNGVfffWVpkyZom+++UbLly9XeXm5RowYoeLiYsdj7rvvPv3rX//SO++8o6+++kqHDx/Wtddea2HWaIqSk5M1f/58bdy4URs2bNDQoUN11VVX6YcffpDEOIJ71q9fr1deeUXdu3evtpzxBFedf/75OnLkiOPfqlWrHOssGUcGXNanTx9jypQpjr8rKiqMxMREY968eRZmheZEkvHBBx84/q6srDTatm1rLFiwwLGssLDQCAkJMf7xj39YkCGai5ycHEOS8dVXXxmGcWbcBAUFGe+8847jMTt27DAkGWvXrrUqTTQTsbGxxp/+9CfGEdxy/Phxo2PHjsby5cuNQYMGGdOmTTMMg/0SXPfoo48aF154YY3rrBpHHEly0alTp7Rx40YNHz7csczf31/Dhw/X2rVrLcwMzdm+ffv0888/VxtX0dHR6tu3L+MKdSoqKpIkxcXFSZI2btyo8vLyamOpS5cuSk1NZSyhVhUVFXrzzTdVXFysfv36MY7glilTpujKK6+sNm4k9ktomJ9++kmJiYlq3769brnlFmVlZUmybhwF+mzL55jc3FxVVFSoTZs21Za3adNGO3futCgrNHc///yzJNU4rqrWAWerrKzU9OnTNWDAAF1wwQWSzoyl4OBgxcTEVHssYwk12bZtm/r166eTJ08qMjJSH3zwgbp27aotW7YwjtAgb775pjZt2qT169c7rWO/BFf17dtXixcvVufOnXXkyBHNmTNHl156qb7//nvLxhFFEgA0M1OmTNH3339f7XxtoCE6d+6sLVu2qKioSO+++67Gjx+vr776yuq00MwcPHhQ06ZN0/LlyxUaGmp1OmjGRo0a5fj/7t27q2/fvkpLS9Pbb7+tsLAwS3LidDsXtWrVSgEBAU4zaRw9elRt27a1KCs0d1Vjh3EFV02dOlX//ve/tWLFCiUnJzuWt23bVqdOnVJhYWG1xzOWUJPg4GB16NBBPXv21Lx583ThhRfq+eefZxyhQTZu3KicnBxdfPHFCgwMVGBgoL766iu98MILCgwMVJs2bRhPcEtMTIw6deqk3bt3W7ZfokhyUXBwsHr27KkvvvjCsayyslJffPGF+vXrZ2FmaM4yMjLUtm3bauPKbrdr3bp1jCtUYxiGpk6dqg8++EBffvmlMjIyqq3v2bOngoKCqo2lXbt2KSsri7GEelVWVqqsrIxxhAYZNmyYtm3bpi1btjj+9erVS7fccovj/xlPcMeJEye0Z88etWvXzrL9EqfbNcD999+v8ePHq1evXurTp4+ee+45FRcXa+LEiVanhibsxIkT2r17t+Pvffv2acuWLYqLi1NqaqqmT5+uxx9/XB07dlRGRoYeeeQRJSYm6uqrr7YuaTQ5U6ZM0ZIlS/TRRx8pKirKcR52dHS0wsLCFB0drdtvv13333+/4uLiZLPZdM8996hfv3665JJLLM4eTcnMmTM1atQopaam6vjx41qyZIlWrlypzz77jHGEBomKinJcF1klIiJC8fHxjuWMJ7hixowZGjNmjNLS0nT48GE9+uijCggI0M0332zdfsln8+ado1588UUjNTXVCA4ONvr06WN88803VqeEJm7FihWGJKd/48ePNwzjzDTgjzzyiNGmTRsjJCTEGDZsmLFr1y5rk0aTU9MYkmQsWrTI8ZjS0lLj7rvvNmJjY43w8HDjmmuuMY4cOWJd0miSJk2aZKSlpRnBwcFG69atjWHDhhnLli1zrGccwRPmKcANg/EE19x4441Gu3btjODgYCMpKcm48cYbjd27dzvWWzGO/AzDMHxXggEAAABA88I1SQAAAABgQpEEAAAAACYUSQAAAABgQpEEAAAAACYUSQAAAABgQpEEAAAAACYUSQAAAABgQpEEAAAAACYUSQAAWGzlypXy8/NTYWGh1akAAESRBABww4QJE+Tn56f58+dXW/7hhx/Kz8/Poqzq1lQKkcGDB2v69OmW5gAAqBtFEgDALaGhoXrqqadUUFBgdSoAAHgVRRIAwC3Dhw9X27ZtNW/evFofk5eXp5tvvllJSUkKDw9Xt27d9I9//KPaYwYPHqx77rlH06dPV2xsrNq0aaPXXntNxcXFmjhxoqKiotShQwctXbq0Wtz333+vUaNGKTIyUm3atNGtt96q3Nxct59PWVmZZsyYoaSkJEVERKhv375auXKlY/3ixYsVExOjzz77TOedd54iIyN1xRVX6MiRI47HnD59Wvfee69iYmIUHx+vBx98UOPHj9fVV18t6cwRuK+++krPP/+8/Pz85Ofnp/379zviN27cqF69eik8PFz9+/fXrl273H4+AAD3USQBANwSEBCgJ598Ui+++KKys7NrfMzJkyfVs2dPffzxx/r+++9155136tZbb9W3335b7XGvv/66WrVqpW+//Vb33HOPfv3rX+uGG25Q//79tWnTJo0YMUK33nqrSkpKJEmFhYUaOnSoLrroIm3YsEGffvqpjh49qrFjx7r9fKZOnaq1a9fqzTff1NatW3XDDTfoiiuu0E8//eR4TElJiZ555hn97W9/09dff62srCzNmDHDsf6pp57S3//+dy1atEirV6+W3W7Xhx9+6Fj//PPPq1+/frrjjjt05MgRHTlyRCkpKY71v/3tb/X73/9eGzZsUGBgoCZNmuT28wEAeMAAAKCBxo8fb1x11VWGYRjGJZdcYkyaNMkwDMP44IMPjPo+Wq688krjN7/5jePvQYMGGQMHDnT8ffr0aSMiIsK49dZbHcuOHDliSDLWrl1rGIZhPPbYY8aIESOqbffgwYOGJGPXrl01trtixQpDklFQUOC07sCBA0ZAQIBx6NChasuHDRtmzJw50zAMw1i0aJEhydi9e7dj/csvv2y0adPG8XebNm2MBQsWVHsuqampjr6qer7Tpk2rMbfPP//csezjjz82JBmlpaU1Ph8AgO8EWlifAQDOAU899ZSGDh1a7YhKlYqKCj355JN6++23dejQIZ06dUplZWUKDw+v9rju3bs7/j8gIEDx8fHq1q2bY1mbNm0kSTk5OZKk7777TitWrFBkZKRTm3v27FGnTp0a9By2bdumiooKp7iysjLFx8c7/g4PD1dmZqbj73bt2jlyKioq0tGjR9WnT59qz6Vnz56qrKx0KQ9zP7Rr107SmeecmpraoOcDAPAMRRIAwCOXXXaZRo4cqZkzZ2rChAnV1i1YsEDPP/+8nnvuOXXr1k0RERGaPn26Tp06Ve1xQUFB1f728/OrtqxqxryqYuPEiRMaM2aMnnrqKad8qoqLhjhx4oQCAgK0ceNGBQQEVFtnLsRqytMwjAa3V5u6njMAoPFQJAEAPDZ//nz16NFDnTt3rrZ89erVuuqqq/SrX/1K0pkv/D/++KO6du3qUXsXX3yx3nvvPaWnpysw0POPsosuukgVFRXKycnRpZde6tY2oqOj1aZNG61fv16XXXaZpDNH0jZt2qQePXo4HhccHKyKigqPcwYA+A4TNwAAPNatWzfdcssteuGFF6ot79ixo5YvX641a9Zox44duuuuu3T06FGP25syZYry8/N18803a/369dqzZ48+++wzTZw4sd4CZNu2bdqyZYvj33fffadOnTrplltu0W233ab3339f+/bt07fffqt58+bp448/djmve+65R/PmzdNHH32kXbt2adq0aSooKKh276j09HStW7dO+/fvV25uLkeKAKAJokgCAHjF3Llznb7w/+53v9PFF1+skSNHavDgwWrbtq1jOmxPJCYmavXq1aqoqNCIESPUrVs3TZ8+XTExMfL3r/uj7bLLLtNFF13k+NezZ09J0qJFi3TbbbfpN7/5jTp37qyrr75a69evb9D1QA8++KBuvvlm3XbbberXr58iIyM1cuRIhYaGOh4zY8YMBQQEqGvXrmrdurWysrLc6wQAgM/4Gd48mRoAADhUVlbqvPPO09ixY/XYY49ZnQ4AwEVckwQAgJccOHBAy5Yt06BBg1RWVqaXXnpJ+/bt07hx46xODQDQAJxuBwCAl/j7+2vx4sXq3bu3BgwYoG3btunzzz/XeeedZ3VqAIAG4HQ7AAAAADDhSBIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIAJRRIAAAAAmFAkAQAAAIDJ/wczC/aM60yRaQAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.figure(figsize=(10, 6))\n", - "sns.scatterplot(data=df, x='length', y='words', alpha=0.7)\n", - "plt.title('Scatterplot: Name Length vs Word Counts')\n", - "plt.xlabel('Name Length')\n", - "plt.ylabel('Word Counts')\n", - "plt.grid(True)\n", - "plt.show()" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": ".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.11.11" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b339851 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,41 @@ +[project] +name = "ners" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.11" +dependencies = [ + "geopandas>=1.1.1", + "joblib>=1.5.2", + "lightgbm>=4.6.0", + "matplotlib>=3.10.6", + "numpy>=2.3.3", + "ollama>=0.6.0", + "pandas>=2.3.3", + "plotly>=6.3.1", + "psutil>=7.1.0", + "pydantic>=2.11.10", + "pyyaml>=6.0.3", + "scikit-learn>=1.7.2", + "seaborn>=0.13.2", + "spacy>=3.8.7", + "streamlit>=1.50.0", + "tqdm>=4.67.1", + "typer>=0.19.2", + "xgboost>=3.0.5", +] + +[project.scripts] +ners = "ners.cli:app" + +[build-system] +requires = ["uv_build>=0.8.12,<0.9.0"] +build-backend = "uv_build" + +[dependency-groups] +dev = [ + "ruff>=0.13.3", +] + +[tool.uv] +required-environments = ["sys_platform == 'linux' and platform_machine == 'x86_64'"] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 3037ffc..0000000 --- a/requirements.txt +++ /dev/null @@ -1,170 +0,0 @@ -absl-py==2.3.0 -altair==5.1.2 -annotated-types==0.7.0 -anyio==4.9.0 -appnope==0.1.4 -argon2-cffi==25.1.0 -argon2-cffi-bindings==21.2.0 -arrow==1.3.0 -asttokens==3.0.0 -astunparse==1.6.3 -async-lru==2.0.5 -attrs==25.3.0 -babel==2.17.0 -beautifulsoup4==4.13.4 -black==25.1.0 -bleach==6.2.0 -blinker==1.9.0 -cachetools==6.1.0 -certifi==2025.6.15 -cffi==1.17.1 -charset-normalizer==3.4.2 -click==8.2.1 -comm==0.2.2 -contourpy==1.3.2 -cycler==0.12.1 -debugpy==1.8.14 -decorator==5.2.1 -defusedxml==0.7.1 -executing==2.2.0 -fastjsonschema==2.21.1 -flake8==7.3.0 -flatbuffers==25.2.10 -fonttools==4.58.4 -fqdn==1.5.1 -gast==0.6.0 -gitdb==4.0.12 -GitPython==3.1.45 -google-pasta==0.2.0 -grpcio==1.73.0 -h11==0.16.0 -h5py==3.14.0 -httpcore==1.0.9 -httpx==0.28.1 -idna==3.10 -imbalanced-learn==0.13.0 -ipykernel==6.29.5 -ipython>=8.0,<9.0 -ipython_pygments_lexers==1.1.1 -isoduration==20.11.0 -jedi==0.19.2 -Jinja2==3.1.6 -joblib==1.5.1 -json5==0.12.0 -jsonpointer==3.0.0 -jsonschema==4.24.0 -jsonschema-specifications==2025.4.1 -jupyter-events==0.12.0 -jupyter-lsp==2.2.5 -jupyter_client==8.6.3 -jupyter_core==5.8.1 -jupyter_server==2.16.0 -jupyter_server_terminals==0.5.3 -jupyterlab==4.4.4 -jupyterlab_pygments==0.3.0 -jupyterlab_server==2.27.3 -keras==3.10.0 -kiwisolver==1.4.8 -libclang==18.1.1 -lightgbm~=4.6.0 -Markdown==3.8.2 -markdown-it-py==3.0.0 -MarkupSafe==3.0.2 -matplotlib==3.10.3 -matplotlib-inline==0.1.7 -mccabe==0.7.0 -mdurl==0.1.2 -mistune==3.1.3 -ml-dtypes==0.3.2 -mypy==1.17.0 -mypy_extensions==1.1.0 -namex==0.1.0 -narwhals==2.0.1 -nbclient==0.10.2 -nbconvert==7.16.6 -nbformat==5.10.4 -nest-asyncio==1.6.0 -nltk==3.9.1 -notebook==7.4.4 -notebook_shim==0.2.4 -numpy==1.26.4 -ollama~=0.5.1 -opt_einsum==3.4.0 -optree==0.16.0 -overrides==7.7.0 -packaging==25.0 -pandas==2.3.0 -pandocfilters==1.5.1 -parso==0.8.4 -pathspec==0.12.1 -pexpect==4.9.0 -pillow==11.2.1 -platformdirs==4.3.8 -plotly~=6.2.0 -prometheus_client==0.22.1 -prompt_toolkit==3.0.51 -protobuf==4.25.8 -psutil==7.0.0 -ptyprocess==0.7.0 -pure_eval==0.2.3 -pyarrow==21.0.0 -pycodestyle==2.14.0 -pycparser==2.22 -pydantic~=2.11.7 -pydantic_core==2.33.2 -pydeck==0.9.1 -pyflakes==3.4.0 -Pygments==2.19.1 -pyparsing==3.2.3 -python-dateutil==2.9.0.post0 -python-json-logger==3.3.0 -pytz==2025.2 -PyYAML~=6.0.2 -pyzmq==27.0.0 -referencing==0.36.2 -regex==2024.11.6 -requests==2.32.4 -rfc3339-validator==0.1.4 -rfc3986-validator==0.1.1 -rich==14.0.0 -rpds-py==0.26.0 -scikit-learn~=1.6.1 -scipy==1.15.3 -seaborn==0.13.2 -Send2Trash==1.8.3 -six==1.17.0 -sklearn-compat==0.1.3 -smmap==5.0.2 -sniffio==1.3.1 -soupsieve==2.7 -spacy~=3.8.7 -stack-data==0.6.3 -streamlit~=1.47.1 -tenacity==9.1.2 -tensorboard==2.16.2 -tensorboard-data-server==0.7.2 -tensorflow==2.16.2 -tensorflow-io-gcs-filesystem==0.37.1 -termcolor==3.1.0 -terminado==0.18.1 -threadpoolctl==3.6.0 -tinycss2==1.4.0 -toml==0.10.2 -toolz==1.0.0 -tornado==6.5.1 -tqdm==4.67.1 -traitlets==5.14.3 -types-python-dateutil==2.9.0.20250516 -types-PyYAML==6.0.12.20250516 -typing-inspection==0.4.1 -typing_extensions==4.14.0 -tzdata==2025.2 -uri-template==1.3.0 -urllib3==2.5.0 -wcwidth==0.2.13 -webcolors==24.11.1 -webencodings==0.5.1 -websocket-client==1.8.0 -Werkzeug==3.1.3 -wrapt==1.17.2 -xgboost~=3.0.3 \ No newline at end of file diff --git a/src/ners/__init__.py b/src/ners/__init__.py new file mode 100644 index 0000000..c9a6010 --- /dev/null +++ b/src/ners/__init__.py @@ -0,0 +1,3 @@ +"""DRC NERS NLP package.""" + +__all__: list[str] = [] diff --git a/src/ners/cli.py b/src/ners/cli.py new file mode 100644 index 0000000..d30cab3 --- /dev/null +++ b/src/ners/cli.py @@ -0,0 +1,226 @@ +from __future__ import annotations + +import os +import subprocess +import sys +from pathlib import Path +from typing import Optional + +import typer + +from ners.core.config import setup_config, PipelineConfig + +app = typer.Typer(help="DRC NERS command-line interface", no_args_is_help=True) + + +# ------------------------- +# Pipeline commands +# ------------------------- +pipeline_app = typer.Typer(help="Data processing pipeline") +app.add_typer(pipeline_app, name="pipeline") + + +@pipeline_app.command("run") +def pipeline_run( + config: Optional[Path] = typer.Option(None, help="Path to configuration file"), + env: str = typer.Option("development", help="Environment name"), +) -> None: + """Run the full processing pipeline.""" + from ners.main import run_pipeline as _run_pipeline + + cfg = setup_config(config_path=config, env=env) + code = _run_pipeline(cfg) + raise typer.Exit(code) + + +# ------------------------- +# NER commands +# ------------------------- +ner_app = typer.Typer(help="NER dataset and model") +app.add_typer(ner_app, name="ner") + + +def _load_config(config: Optional[Path], env: str) -> PipelineConfig: + return setup_config(config_path=config, env=env) + + +@ner_app.command("feature") +def ner_feature( + config: Optional[Path] = typer.Option(None, help="Path to configuration file"), + env: str = typer.Option("development", help="Environment name"), +) -> None: + from ners.ner import feature as _feature + + cfg = _load_config(config, env) + _feature(cfg) + + +@ner_app.command("build") +def ner_build( + config: Optional[Path] = typer.Option(None, help="Path to configuration file"), + env: str = typer.Option("development", help="Environment name"), +) -> None: + from ners.ner import build as _build + + cfg = _load_config(config, env) + _build(cfg) + + +@ner_app.command("train") +def ner_train( + config: Optional[Path] = typer.Option(None, help="Path to configuration file"), + env: str = typer.Option("development", help="Environment name"), +) -> None: + from ners.ner import train as _train + + cfg = _load_config(config, env) + _train(cfg) + + +@ner_app.command("run") +def ner_run( + config: Optional[Path] = typer.Option(None, help="Path to configuration file"), + env: str = typer.Option("development", help="Environment name"), + reset: bool = typer.Option( + False, help="Reset intermediate outputs and rerun all steps" + ), +) -> None: + from ners.ner import run_pipeline as _ner_pipeline + + cfg = _load_config(config, env) + code = _ner_pipeline(cfg, reset) + raise typer.Exit(code) + + +# ------------------------- +# Research commands +# ------------------------- +research_app = typer.Typer(help="Research experiments and training") +app.add_typer(research_app, name="research") + + +@research_app.command("train") +def research_train( + name: str = typer.Option(..., "--name", help="Model name to train"), + type: str = typer.Option(..., "--type", help="Experiment type"), + templates: str = typer.Option( + "research_templates.yaml", help="Templates file path" + ), + config: Optional[Path] = typer.Option(None, help="Path to configuration file"), + env: str = typer.Option("development", help="Environment name"), +) -> None: + from ners.research.experiment.experiment_builder import ExperimentBuilder + from ners.research.model_trainer import ModelTrainer + + cfg = _load_config(config, env) + exp_builder = ExperimentBuilder(cfg) + tmpl = exp_builder.load_templates(templates) + exp_cfg = exp_builder.find_template(tmpl, name, type) + + trainer = ModelTrainer(cfg) + trainer.train_single_model( + model_name=exp_cfg.get("name"), + model_type=exp_cfg.get("model_type"), + features=exp_cfg.get("features"), + model_params=exp_cfg.get("model_params", {}), + tags=exp_cfg.get("tags", []), + ) + + +# ------------------------- +# Monitor commands +# ------------------------- +monitor_app = typer.Typer(help="Monitor pipeline checkpoints") +app.add_typer(monitor_app, name="monitor") + + +@monitor_app.command("status") +def monitor_status( + config: Optional[Path] = typer.Option(None, help="Path to configuration file"), + env: str = typer.Option("development", help="Environment name"), + detailed: bool = typer.Option( + False, help="Show detailed status (failed batch IDs)" + ), +) -> None: + _ = _load_config(config, env) + from ners.processing.monitoring.pipeline_monitor import PipelineMonitor + + PipelineMonitor().print_status(detailed=detailed) + + +@monitor_app.command("clean") +def monitor_clean( + step: Optional[str] = typer.Option(None, help="Step to clean; default all"), + keep_last: int = typer.Option(1, help="Number of latest checkpoint files to keep"), + force: bool = typer.Option(False, help="Do not ask for confirmation"), + config: Optional[Path] = typer.Option(None, help="Path to configuration file"), + env: str = typer.Option("development", help="Environment name"), +) -> None: + _ = _load_config(config, env) + from ners.processing.monitoring.pipeline_monitor import PipelineMonitor + + mon = PipelineMonitor() + if not force: + typer.confirm("Clean checkpoints?", abort=True) + + if step: + mon.clean_step_checkpoints(step, keep_last) + else: + for s in mon.steps: + mon.clean_step_checkpoints(s, keep_last) + + +@monitor_app.command("reset") +def monitor_reset( + step: Optional[str] = typer.Option(None, help="Step to reset; default all"), + force: bool = typer.Option(False, help="Do not ask for confirmation"), + config: Optional[Path] = typer.Option(None, help="Path to configuration file"), + env: str = typer.Option("development", help="Environment name"), +) -> None: + _ = _load_config(config, env) + from ners.processing.monitoring.pipeline_monitor import PipelineMonitor + + mon = PipelineMonitor() + if not force: + msg = f"Reset {step or 'all steps'}? This deletes checkpoints." + typer.confirm(msg, abort=True) + + if step: + mon.reset_step(step) + else: + for s in mon.steps: + mon.reset_step(s) + + +# ------------------------- +# Web commands +# ------------------------- +web_app = typer.Typer(help="Web UI wrapper") +app.add_typer(web_app, name="web") + + +@web_app.command("run") +def web_run( + config: Optional[Path] = typer.Option(None, help="Path to configuration file"), + env: str = typer.Option("development", help="Environment name"), +) -> None: + """Launch the Streamlit web app via subprocess.""" + app_path = Path(__file__).parent / "web" / "app.py" + cmd = [ + sys.executable, + "-m", + "streamlit", + "run", + str(app_path), + ] + # Pass configuration via environment variables to avoid argparse in Streamlit + env_vars = os.environ.copy() + if config is not None: + env_vars["NERS_CONFIG"] = str(config) + env_vars["NERS_ENV"] = env + + raise typer.Exit(subprocess.call(cmd, env=env_vars)) + + +if __name__ == "__main__": # pragma: no cover + app() diff --git a/core/__init__.py b/src/ners/core/__init__.py similarity index 100% rename from core/__init__.py rename to src/ners/core/__init__.py diff --git a/core/config/__init__.py b/src/ners/core/config/__init__.py similarity index 88% rename from core/config/__init__.py rename to src/ners/core/config/__init__.py index 322aded..4169761 100644 --- a/core/config/__init__.py +++ b/src/ners/core/config/__init__.py @@ -2,10 +2,10 @@ import logging from pathlib import Path from typing import Optional, Union -from core.utils import ensure_directories -from .config_manager import ConfigManager -from .logging_config import LoggingConfig -from .pipeline_config import PipelineConfig +from ners.core.utils import ensure_directories +from ners.core.config.config_manager import ConfigManager +from ners.core.config.logging_config import LoggingConfig +from ners.core.config.pipeline_config import PipelineConfig config_manager = ConfigManager() @@ -22,7 +22,9 @@ def load_config(config_path: Optional[Union[str, Path]] = None) -> PipelineConfi return config_manager.get_config() -def setup_config(config_path: Optional[Path] = None, env: str = "development") -> PipelineConfig: +def setup_config( + config_path: Optional[Path] = None, env: str = "development" +) -> PipelineConfig: """ Unified configuration loading and logging setup for all entrypoint scripts. diff --git a/core/config/annotation_config.py b/src/ners/core/config/annotation_config.py similarity index 100% rename from core/config/annotation_config.py rename to src/ners/core/config/annotation_config.py diff --git a/core/config/config_manager.py b/src/ners/core/config/config_manager.py similarity index 91% rename from core/config/config_manager.py rename to src/ners/core/config/config_manager.py index 3939405..8e6c650 100644 --- a/core/config/config_manager.py +++ b/src/ners/core/config/config_manager.py @@ -5,8 +5,8 @@ from typing import Optional, Union, Dict, Any import yaml -from core.config.pipeline_config import PipelineConfig -from core.config.project_paths import ProjectPaths +from ners.core.config.pipeline_config import PipelineConfig +from ners.core.config.project_paths import ProjectPaths class ConfigManager: @@ -36,7 +36,7 @@ class ConfigManager: def _setup_default_paths(self): """Setup default project paths""" - root_dir = Path(__file__).parent.parent.parent + root_dir = Path(__file__).parent.parent.parent.parent.parent self.default_paths = ProjectPaths( root_dir=root_dir, configs_dir=root_dir / "config", @@ -53,7 +53,9 @@ class ConfigManager: self.config_path = config_path if not self.config_path.exists(): - logging.warning(f"Config file not found: {self.config_path}. Using defaults.") + logging.warning( + f"Config file not found: {self.config_path}. Using defaults." + ) return self._create_default_config() try: @@ -122,7 +124,11 @@ class ConfigManager: def _deep_update(self, base_dict: Dict, update_dict: Dict): """Recursively update nested dictionaries""" for key, value in update_dict.items(): - if key in base_dict and isinstance(base_dict[key], dict) and isinstance(value, dict): + if ( + key in base_dict + and isinstance(base_dict[key], dict) + and isinstance(value, dict) + ): self._deep_update(base_dict[key], value) else: base_dict[key] = value diff --git a/core/config/data_config.py b/src/ners/core/config/data_config.py similarity index 100% rename from core/config/data_config.py rename to src/ners/core/config/data_config.py diff --git a/core/config/logging_config.py b/src/ners/core/config/logging_config.py similarity index 100% rename from core/config/logging_config.py rename to src/ners/core/config/logging_config.py diff --git a/core/config/pipeline_config.py b/src/ners/core/config/pipeline_config.py similarity index 68% rename from core/config/pipeline_config.py rename to src/ners/core/config/pipeline_config.py index 43bf1a8..d20ac36 100644 --- a/core/config/pipeline_config.py +++ b/src/ners/core/config/pipeline_config.py @@ -1,10 +1,10 @@ from pydantic import BaseModel -from core.config.annotation_config import AnnotationConfig -from core.config.data_config import DataConfig -from core.config.logging_config import LoggingConfig -from core.config.processing_config import ProcessingConfig -from core.config.project_paths import ProjectPaths +from ners.core.config.annotation_config import AnnotationConfig +from ners.core.config.data_config import DataConfig +from ners.core.config.logging_config import LoggingConfig +from ners.core.config.processing_config import ProcessingConfig +from ners.core.config.project_paths import ProjectPaths class PipelineConfig(BaseModel): diff --git a/core/config/processing_config.py b/src/ners/core/config/processing_config.py similarity index 75% rename from core/config/processing_config.py rename to src/ners/core/config/processing_config.py index 5d1d705..4bf6034 100644 --- a/core/config/processing_config.py +++ b/src/ners/core/config/processing_config.py @@ -10,6 +10,8 @@ class ProcessingConfig(BaseModel): max_workers: int = 4 checkpoint_interval: int = 5 use_multiprocessing: bool = False - encoding_options: list = field(default_factory=lambda: ["utf-8", "utf-16", "latin1"]) + encoding_options: list = field( + default_factory=lambda: ["utf-8", "utf-16", "latin1"] + ) chunk_size: int = 100_000 epochs: int = 2 diff --git a/core/config/project_paths.py b/src/ners/core/config/project_paths.py similarity index 100% rename from core/config/project_paths.py rename to src/ners/core/config/project_paths.py diff --git a/core/utils/__init__.py b/src/ners/core/utils/__init__.py similarity index 92% rename from core/utils/__init__.py rename to src/ners/core/utils/__init__.py index b452b86..65e387a 100644 --- a/core/utils/__init__.py +++ b/src/ners/core/utils/__init__.py @@ -4,13 +4,13 @@ from pathlib import Path from typing import TYPE_CHECKING if TYPE_CHECKING: - from core.config import PipelineConfig + from ners.core.config import PipelineConfig @contextmanager def temporary_config_override(**overrides): """Context manager for temporarily overriding configuration""" - from core.config import get_config + from ners.core.config import get_config config = get_config() original_values = {} diff --git a/core/utils/data_loader.py b/src/ners/core/utils/data_loader.py similarity index 91% rename from core/utils/data_loader.py rename to src/ners/core/utils/data_loader.py index d429e88..6f64ade 100644 --- a/core/utils/data_loader.py +++ b/src/ners/core/utils/data_loader.py @@ -5,7 +5,7 @@ from typing import Optional, Union, Iterator, Dict import pandas as pd -from core.config.pipeline_config import PipelineConfig +from ners.core.config.pipeline_config import PipelineConfig OPTIMIZED_DTYPES = { # Numeric columns with appropriate bit-width @@ -113,7 +113,9 @@ class DataLoader: sex_values = df["sex"].dropna().unique() if len(sex_values) == 0: - logging.warning(f"No valid values found in sex column 'sex', using random sampling") + logging.warning( + "No valid values found in sex column 'sex', using random sampling" + ) return df.sample(n=max_size, random_state=self.config.data.random_seed) # Calculate samples per sex category @@ -140,18 +142,22 @@ class DataLoader: logging.info(f"Sampled {current_samples} records for sex '{sex}'") if not balanced_samples: - logging.warning("No balanced samples could be created, using random sampling") + logging.warning( + "No balanced samples could be created, using random sampling" + ) return df.sample(n=max_size, random_state=self.config.data.random_seed) # Create result using iloc with indices (no copying until final step) result = df.iloc[balanced_samples].copy() # Shuffle the final result - result = result.sample(frac=1, random_state=self.config.data.random_seed).reset_index( - drop=True - ) + result = result.sample( + frac=1, random_state=self.config.data.random_seed + ).reset_index(drop=True) - logging.info(f"Created balanced dataset with {len(result)} records from {len(df)} total") + logging.info( + f"Created balanced dataset with {len(result)} records from {len(df)} total" + ) return result @classmethod diff --git a/core/utils/prompt_manager.py b/src/ners/core/utils/prompt_manager.py similarity index 93% rename from core/utils/prompt_manager.py rename to src/ners/core/utils/prompt_manager.py index fecd8c5..fecee35 100644 --- a/core/utils/prompt_manager.py +++ b/src/ners/core/utils/prompt_manager.py @@ -1,4 +1,4 @@ -from core.config.pipeline_config import PipelineConfig +from ners.core.config.pipeline_config import PipelineConfig class PromptManager: diff --git a/core/utils/rate_limiter.py b/src/ners/core/utils/rate_limiter.py similarity index 100% rename from core/utils/rate_limiter.py rename to src/ners/core/utils/rate_limiter.py diff --git a/core/utils/region_mapper.py b/src/ners/core/utils/region_mapper.py similarity index 100% rename from core/utils/region_mapper.py rename to src/ners/core/utils/region_mapper.py diff --git a/core/utils/state_manager.py b/src/ners/core/utils/state_manager.py similarity index 95% rename from core/utils/state_manager.py rename to src/ners/core/utils/state_manager.py index f650d12..1397d96 100644 --- a/core/utils/state_manager.py +++ b/src/ners/core/utils/state_manager.py @@ -2,7 +2,7 @@ import json import logging from typing import Dict, Any -from core.config.pipeline_config import PipelineConfig +from ners.core.config.pipeline_config import PipelineConfig class StateManager: diff --git a/core/utils/text_cleaner.py b/src/ners/core/utils/text_cleaner.py similarity index 100% rename from core/utils/text_cleaner.py rename to src/ners/core/utils/text_cleaner.py diff --git a/main.py b/src/ners/main.py similarity index 60% rename from main.py rename to src/ners/main.py index 2b53c6e..3939ed2 100755 --- a/main.py +++ b/src/ners/main.py @@ -1,21 +1,17 @@ #!.venv/bin/python3 -import argparse import logging -import sys -import traceback - -from core.config import setup_config -from core.utils.data_loader import DataLoader -from processing.batch.batch_config import BatchConfig -from processing.pipeline import Pipeline -from processing.steps.data_cleaning_step import DataCleaningStep -from processing.steps.data_selection_step import DataSelectionStep -from processing.steps.data_splitting_step import DataSplittingStep -from processing.steps.feature_extraction_step import FeatureExtractionStep +from ners.core.utils.data_loader import DataLoader +from ners.processing.batch.batch_config import BatchConfig +from ners.processing.pipeline import Pipeline +from ners.processing.steps.data_cleaning_step import DataCleaningStep +from ners.processing.steps.data_selection_step import DataSelectionStep +from ners.processing.steps.data_splitting_step import DataSplittingStep +from ners.processing.steps.llm_annotation_step import LLMAnnotationStep +from ners.processing.steps.ner_annotation_step import NERAnnotationStep +from ners.processing.steps.feature_extraction_step import FeatureExtractionStep def create_pipeline(config) -> Pipeline: - """Create pipeline from configuration""" batch_config = BatchConfig( batch_size=config.processing.batch_size, max_workers=config.processing.max_workers, @@ -23,14 +19,13 @@ def create_pipeline(config) -> Pipeline: use_multiprocessing=config.processing.use_multiprocessing, ) - # Add steps based on configuration pipeline = Pipeline(batch_config) steps = [ DataCleaningStep(config), FeatureExtractionStep(config), DataSelectionStep(config), - # NERAnnotationStep(config), - # LLMAnnotationStep(config), + NERAnnotationStep(config), + LLMAnnotationStep(config), ] for stage in config.stages: @@ -42,7 +37,6 @@ def create_pipeline(config) -> Pipeline: def run_pipeline(config) -> int: - """Run the complete pipeline""" try: logging.info(f"Starting pipeline: {config.name} v{config.version}") @@ -79,27 +73,3 @@ def run_pipeline(config) -> int: except Exception as e: logging.error(f"Pipeline failed: {e}", exc_info=True) return 1 - - -def main(): - """Main entry point with unified configuration loading""" - parser = argparse.ArgumentParser( - description="DRC NERS Processing Pipeline", - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - parser.add_argument("--config", type=str, help="Path to configuration file") - parser.add_argument("--env", type=str, default="development", help="Environment name") - args = parser.parse_args() - - try: - config = setup_config(config_path=args.config, env=args.env) - return run_pipeline(config) - - except Exception as e: - print(f"Pipeline failed: {e}") - traceback.print_exc() - return 1 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/src/ners/monitor.py b/src/ners/monitor.py new file mode 100755 index 0000000..e207a10 --- /dev/null +++ b/src/ners/monitor.py @@ -0,0 +1,14 @@ +#!.venv/bin/python3 +from ners.processing.monitoring.pipeline_monitor import PipelineMonitor + + +def status(*, detailed: bool = False) -> None: + PipelineMonitor().print_status(detailed=detailed) + + +def clean_step(step: str, *, keep_last: int = 1) -> None: + PipelineMonitor().clean_step_checkpoints(step, keep_last) + + +def reset_step(step: str) -> None: + PipelineMonitor().reset_step(step) diff --git a/ner.py b/src/ners/ner.py similarity index 62% rename from ner.py rename to src/ners/ner.py index d671c35..fe83d57 100755 --- a/ner.py +++ b/src/ners/ner.py @@ -1,29 +1,24 @@ #!/usr/bin/env python3 -import argparse import logging import os -import sys import traceback from pathlib import Path -from core.config import setup_config, PipelineConfig -from processing.ner.name_builder import NameBuilder -from processing.ner.name_engineering import NameEngineering -from processing.ner.name_model import NameModel +from ners.core.config import PipelineConfig +from ners.processing.ner.name_builder import NameBuilder +from ners.processing.ner.name_engineering import NameEngineering +from ners.processing.ner.name_model import NameModel def feature(config: PipelineConfig): - """Apply feature engineering to create position-independent NER dataset.""" NameEngineering(config).compute() def build(config: PipelineConfig): - """Build NER dataset using NERDataBuilder.""" NameBuilder(config).build() def train(config: PipelineConfig): - """Train the NER model.""" name_model = NameModel(config) data_path = Path(config.paths.data_dir) / config.data.output_files["ner_data"] @@ -37,7 +32,9 @@ def train(config: PipelineConfig): split_idx = int(len(data) * 0.9) train_data, eval_data = data[:split_idx], data[split_idx:] - logging.info(f"Training with {len(train_data)} examples, evaluating on {len(eval_data)}") + logging.info( + f"Training with {len(train_data)} examples, evaluating on {len(eval_data)}" + ) name_model.train( data=train_data, epochs=config.processing.epochs, @@ -75,21 +72,9 @@ def run_pipeline(config: PipelineConfig, reset: bool = False): def main(): - parser = argparse.ArgumentParser(description="NER model management for DRC names") - parser.add_argument("--config", type=str, help="Path to configuration file") - parser.add_argument("--env", type=str, default="development", help="Environment name") - parser.add_argument("--reset", action="store_true", help="Reset all steps") - args = parser.parse_args() - try: - config = setup_config(config_path=args.config, env=args.env) - return run_pipeline(config, args.reset) - - except Exception as e: - print(f"Pipeline failed: {e}") + logging.error("This module is no longer a CLI. Use 'ners ner ...' instead.") + return 1 + except Exception: traceback.print_exc() return 1 - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/processing/__init__.py b/src/ners/processing/__init__.py similarity index 100% rename from processing/__init__.py rename to src/ners/processing/__init__.py diff --git a/processing/batch/__init__.py b/src/ners/processing/batch/__init__.py similarity index 100% rename from processing/batch/__init__.py rename to src/ners/processing/batch/__init__.py diff --git a/processing/batch/batch_config.py b/src/ners/processing/batch/batch_config.py similarity index 67% rename from processing/batch/batch_config.py rename to src/ners/processing/batch/batch_config.py index df60987..036320d 100644 --- a/processing/batch/batch_config.py +++ b/src/ners/processing/batch/batch_config.py @@ -8,4 +8,6 @@ class BatchConfig: batch_size: int = 1000 max_workers: int = 4 checkpoint_interval: int = 5 # Save checkpoint every N batches - use_multiprocessing: bool = False # Use ProcessPoolExecutor instead of ThreadPoolExecutor + use_multiprocessing: bool = ( + False # Use ProcessPoolExecutor instead of ThreadPoolExecutor + ) diff --git a/processing/batch/batch_processor.py b/src/ners/processing/batch/batch_processor.py similarity index 88% rename from processing/batch/batch_processor.py rename to src/ners/processing/batch/batch_processor.py index e6773ed..43f886e 100644 --- a/processing/batch/batch_processor.py +++ b/src/ners/processing/batch/batch_processor.py @@ -4,9 +4,9 @@ from typing import Iterator import pandas as pd -from processing.batch.batch_config import BatchConfig -from processing.batch.memory_monitor import MemoryMonitor -from processing.steps import PipelineStep +from ners.processing.batch.batch_config import BatchConfig +from ners.processing.batch.memory_monitor import MemoryMonitor +from ners.processing.steps import PipelineStep class BatchProcessor: @@ -33,7 +33,9 @@ class BatchProcessor: for batch_num, (batch, batch_id) in enumerate(self.create_batches(df)): if step.batch_exists(batch_id): - logging.info(f"Batch {batch_id} already processed, loading from checkpoint") + logging.info( + f"Batch {batch_id} already processed, loading from checkpoint" + ) processed_batch = step.load_batch(batch_id) else: try: @@ -80,7 +82,9 @@ class BatchProcessor: def process_concurrent(self, step: PipelineStep, df: pd.DataFrame) -> pd.DataFrame: """Memory-optimized concurrent processing""" executor_class = ( - ProcessPoolExecutor if self.config.use_multiprocessing else ThreadPoolExecutor + ProcessPoolExecutor + if self.config.use_multiprocessing + else ThreadPoolExecutor ) results = {} @@ -89,7 +93,9 @@ class BatchProcessor: future_to_batch = {} for batch, batch_id in self.create_batches(df): if step.batch_exists(batch_id): - logging.info(f"Batch {batch_id} already processed, loading from checkpoint") + logging.info( + f"Batch {batch_id} already processed, loading from checkpoint" + ) results[batch_id] = step.load_batch(batch_id) else: # Only copy if necessary for concurrent processing @@ -121,7 +127,9 @@ class BatchProcessor: del results self.memory_monitor.cleanup_memory() - result = self._safe_concat(ordered_results) if ordered_results else pd.DataFrame() + result = ( + self._safe_concat(ordered_results) if ordered_results else pd.DataFrame() + ) # Final cleanup del ordered_results @@ -131,7 +139,9 @@ class BatchProcessor: def process(self, step: PipelineStep, df: pd.DataFrame) -> pd.DataFrame: """Process data using the configured strategy""" - step.state.total_batches = (len(df) + self.config.batch_size - 1) // self.config.batch_size + step.state.total_batches = ( + len(df) + self.config.batch_size - 1 + ) // self.config.batch_size step.load_state() logging.info(f"Starting {step.name} with {step.state.total_batches} batches") diff --git a/processing/batch/memory_monitor.py b/src/ners/processing/batch/memory_monitor.py similarity index 100% rename from processing/batch/memory_monitor.py rename to src/ners/processing/batch/memory_monitor.py diff --git a/processing/monitoring/__init__.py b/src/ners/processing/monitoring/__init__.py similarity index 100% rename from processing/monitoring/__init__.py rename to src/ners/processing/monitoring/__init__.py diff --git a/processing/monitoring/pipeline_monitor.py b/src/ners/processing/monitoring/pipeline_monitor.py similarity index 90% rename from processing/monitoring/pipeline_monitor.py rename to src/ners/processing/monitoring/pipeline_monitor.py index 1c17da3..0e5d5d1 100644 --- a/processing/monitoring/pipeline_monitor.py +++ b/src/ners/processing/monitoring/pipeline_monitor.py @@ -4,8 +4,8 @@ import shutil from datetime import datetime from typing import Optional, Dict -from core.config.config_manager import ConfigManager -from core.config.project_paths import ProjectPaths +from ners.core.config.config_manager import ConfigManager +from ners.core.config.project_paths import ProjectPaths class PipelineMonitor: @@ -97,7 +97,10 @@ class PipelineMonitor: avg_completion = total_completion / len(self.steps) - if avg_completion >= 100 and overall_status not in ["error", "completed_with_errors"]: + if avg_completion >= 100 and overall_status not in [ + "error", + "completed_with_errors", + ]: overall_status = "completed" return { @@ -121,7 +124,9 @@ class PipelineMonitor: print(f"{step_name.replace('_', ' ').title()}:") print(f" Status: {step_status['status']}") print(f" Progress: {step_status['completion_percentage']:.1f}%") - print(f" Batches: {step_status['processed_batches']}/{step_status['total_batches']}") + print( + f" Batches: {step_status['processed_batches']}/{step_status['total_batches']}" + ) if step_status["failed_batches"] > 0: print(f" Failed Batches: {step_status['failed_batches']}") @@ -141,7 +146,10 @@ class PipelineMonitor: if step_dir.exists(): csv_files = list(step_dir.glob("*.csv")) step_size = sum(f.stat().st_size for f in csv_files) - counts[step] = {"files": len(csv_files), "size_mb": step_size / (1024 * 1024)} + counts[step] = { + "files": len(csv_files), + "size_mb": step_size / (1024 * 1024), + } total_size += step_size else: counts[step] = {"files": 0, "size_mb": 0} @@ -160,7 +168,9 @@ class PipelineMonitor: csv_files = sorted(step_dir.glob("batch_*.csv")) if len(csv_files) <= keep_last: - logging.info(f"Only {len(csv_files)} checkpoint files for {step_name}, keeping all") + logging.info( + f"Only {len(csv_files)} checkpoint files for {step_name}, keeping all" + ) return files_to_delete = csv_files[:-keep_last] if keep_last > 0 else csv_files diff --git a/processing/ner/__init__.py b/src/ners/processing/ner/__init__.py similarity index 100% rename from processing/ner/__init__.py rename to src/ners/processing/ner/__init__.py diff --git a/processing/ner/formats/__init__.py b/src/ners/processing/ner/formats/__init__.py similarity index 85% rename from processing/ner/formats/__init__.py rename to src/ners/processing/ner/formats/__init__.py index d2a39e8..94fa2c7 100644 --- a/processing/ner/formats/__init__.py +++ b/src/ners/processing/ner/formats/__init__.py @@ -3,7 +3,7 @@ from typing import List, Tuple, Dict import pandas as pd -from processing.steps.feature_extraction_step import NameCategory +from ners.processing.steps.feature_extraction_step import NameCategory class BaseNameFormatter(ABC): @@ -12,7 +12,9 @@ class BaseNameFormatter(ABC): Contains common logic for NER tagging and attribute computation. """ - def __init__(self, connectors: List[str] = None, additional_surnames: List[str] = None): + def __init__( + self, connectors: List[str] = None, additional_surnames: List[str] = None + ): self.connectors = connectors or ["wa", "ya", "ka", "ba"] self.additional_surnames = additional_surnames or [ "jean", @@ -46,7 +48,9 @@ class BaseNameFormatter(ABC): end_pos = current_pos + len(word) # Determine tag based on word content - if word in native_parts or any(connector in word for connector in self.connectors): + if word in native_parts or any( + connector in word for connector in self.connectors + ): tag = "NATIVE" elif word == surname or word in self.additional_surnames: tag = "SURNAME" @@ -72,7 +76,9 @@ class BaseNameFormatter(ABC): "words": words_count, "length": length, "identified_category": ( - NameCategory.SIMPLE.value if words_count == 3 else NameCategory.COMPOSE.value + NameCategory.SIMPLE.value + if words_count == 3 + else NameCategory.COMPOSE.value ), } diff --git a/processing/ner/formats/connectors_format.py b/src/ners/processing/ner/formats/connectors_format.py similarity index 95% rename from processing/ner/formats/connectors_format.py rename to src/ners/processing/ner/formats/connectors_format.py index 66a6795..4bf192d 100644 --- a/processing/ner/formats/connectors_format.py +++ b/src/ners/processing/ner/formats/connectors_format.py @@ -3,7 +3,7 @@ from typing import Dict import pandas as pd -from processing.ner.formats import BaseNameFormatter +from ners.processing.ner.formats import BaseNameFormatter class ConnectorFormatter(BaseNameFormatter): diff --git a/processing/ner/formats/extended_surname_format.py b/src/ners/processing/ner/formats/extended_surname_format.py similarity index 76% rename from processing/ner/formats/extended_surname_format.py rename to src/ners/processing/ner/formats/extended_surname_format.py index cc94388..a4c4df7 100644 --- a/processing/ner/formats/extended_surname_format.py +++ b/src/ners/processing/ner/formats/extended_surname_format.py @@ -3,13 +3,15 @@ from typing import Dict import pandas as pd -from processing.ner.formats import BaseNameFormatter +from ners.processing.ner.formats import BaseNameFormatter class ExtendedSurnameFormatter(BaseNameFormatter): def transform(self, row: pd.Series) -> Dict: native_parts = self.parse_native_components(row["probable_native"]) - original_surname = row["probable_surname"] if pd.notna(row["probable_surname"]) else "" + original_surname = ( + row["probable_surname"] if pd.notna(row["probable_surname"]) else "" + ) # Add random additional surname additional_surname = random.choice(self.additional_surnames) @@ -22,7 +24,9 @@ class ExtendedSurnameFormatter(BaseNameFormatter): "identified_name": row["probable_native"], "probable_surname": combined_surname, "identified_surname": combined_surname, - "ner_entities": str(self.create_ner_tags(full_name, native_parts, combined_surname)), + "ner_entities": str( + self.create_ner_tags(full_name, native_parts, combined_surname) + ), "transformation_type": self.transformation_type, **self.compute_numeric_features(full_name), } diff --git a/processing/ner/formats/native_only_format.py b/src/ners/processing/ner/formats/native_only_format.py similarity index 93% rename from processing/ner/formats/native_only_format.py rename to src/ners/processing/ner/formats/native_only_format.py index 8e98163..8f0f82c 100644 --- a/processing/ner/formats/native_only_format.py +++ b/src/ners/processing/ner/formats/native_only_format.py @@ -2,7 +2,7 @@ from typing import Dict import pandas as pd -from processing.ner.formats import BaseNameFormatter +from ners.processing.ner.formats import BaseNameFormatter class NativeOnlyFormatter(BaseNameFormatter): diff --git a/processing/ner/formats/original_format.py b/src/ners/processing/ner/formats/original_format.py similarity index 94% rename from processing/ner/formats/original_format.py rename to src/ners/processing/ner/formats/original_format.py index ffcced9..5985d01 100644 --- a/processing/ner/formats/original_format.py +++ b/src/ners/processing/ner/formats/original_format.py @@ -2,7 +2,7 @@ from typing import Dict import pandas as pd -from processing.ner.formats import BaseNameFormatter +from ners.processing.ner.formats import BaseNameFormatter class OriginalFormatter(BaseNameFormatter): diff --git a/processing/ner/formats/position_flipped_format.py b/src/ners/processing/ner/formats/position_flipped_format.py similarity index 94% rename from processing/ner/formats/position_flipped_format.py rename to src/ners/processing/ner/formats/position_flipped_format.py index 9702640..ad53ead 100644 --- a/processing/ner/formats/position_flipped_format.py +++ b/src/ners/processing/ner/formats/position_flipped_format.py @@ -2,7 +2,7 @@ from typing import Dict import pandas as pd -from processing.ner.formats import BaseNameFormatter +from ners.processing.ner.formats import BaseNameFormatter class PositionFlippedFormatter(BaseNameFormatter): diff --git a/processing/ner/formats/reduced_native_format.py b/src/ners/processing/ner/formats/reduced_native_format.py similarity index 74% rename from processing/ner/formats/reduced_native_format.py rename to src/ners/processing/ner/formats/reduced_native_format.py index 2f992f1..3bd1b50 100644 --- a/processing/ner/formats/reduced_native_format.py +++ b/src/ners/processing/ner/formats/reduced_native_format.py @@ -2,7 +2,7 @@ from typing import Dict import pandas as pd -from processing.ner.formats import BaseNameFormatter +from ners.processing.ner.formats import BaseNameFormatter class ReducedNativeFormatter(BaseNameFormatter): @@ -11,7 +11,9 @@ class ReducedNativeFormatter(BaseNameFormatter): surname = row["probable_surname"] if pd.notna(row["probable_surname"]) else "" # Keep only first native component + surname - reduced_native = native_parts[0] if len(native_parts) > 1 else row["probable_native"] + reduced_native = ( + native_parts[0] if len(native_parts) > 1 else row["probable_native"] + ) full_name = f"{reduced_native} {surname}".strip() return { @@ -20,7 +22,9 @@ class ReducedNativeFormatter(BaseNameFormatter): "identified_name": reduced_native, "probable_surname": surname, "identified_surname": surname, - "ner_entities": str(self.create_ner_tags(full_name, [reduced_native], surname)), + "ner_entities": str( + self.create_ner_tags(full_name, [reduced_native], surname) + ), "transformation_type": self.transformation_type, **self.compute_numeric_features(full_name), } diff --git a/processing/ner/name_builder.py b/src/ners/processing/ner/name_builder.py similarity index 66% rename from processing/ner/name_builder.py rename to src/ners/processing/ner/name_builder.py index f724b3f..a2e1783 100644 --- a/processing/ner/name_builder.py +++ b/src/ners/processing/ner/name_builder.py @@ -4,8 +4,8 @@ import logging import spacy from spacy.tokens import DocBin -from core.config import PipelineConfig -from core.utils.data_loader import DataLoader +from ners.core.config import PipelineConfig +from ners.core.utils.data_loader import DataLoader from .name_tagger import NameTagger @@ -20,7 +20,9 @@ class NameBuilder: self.tagger = NameTagger() def build(self) -> int: - filepath = self.config.paths.get_data_path(self.config.data.output_files["engineered"]) + filepath = self.config.paths.get_data_path( + self.config.data.output_files["engineered"] + ) df = self.data_loader.load_csv_complete(filepath) df = df[["name", "ner_tagged", "ner_entities"]] @@ -38,7 +40,9 @@ class NameBuilder: # Use NERNameTagger for parsing and validation parsed_entities = self.tagger.parse_entities(ner_df["ner_entities"]) - validated_entities = self.tagger.validate_entities(ner_df["name"], parsed_entities) + validated_entities = self.tagger.validate_entities( + ner_df["name"], parsed_entities + ) # Drop rows with no valid entities mask = validated_entities.map(bool) @@ -51,22 +55,33 @@ class NameBuilder: # Prepare training data training_data = list( - zip(ner_df["name"].tolist(), [{"entities": ents} for ents in validated_entities]) + zip( + ner_df["name"].tolist(), + [{"entities": ents} for ents in validated_entities], + ) ) # Use NERNameTagger to create spaCy DocBin - docs = self.tagger.create_docs(nlp, ner_df["name"].tolist(), validated_entities.tolist()) + docs = self.tagger.create_docs( + nlp, ner_df["name"].tolist(), validated_entities.tolist() + ) doc_bin = DocBin(docs=docs) # Save - json_path = self.config.paths.get_data_path(self.config.data.output_files["ner_data"]) - spacy_path = self.config.paths.get_data_path(self.config.data.output_files["ner_spacy"]) + json_path = self.config.paths.get_data_path( + self.config.data.output_files["ner_data"] + ) + spacy_path = self.config.paths.get_data_path( + self.config.data.output_files["ner_spacy"] + ) with open(json_path, "w", encoding="utf-8") as f: json.dump(training_data, f, ensure_ascii=False, separators=(",", ":")) doc_bin.to_disk(spacy_path) - logging.info(f"Processed: {len(training_data)}, Skipped: {total_rows - len(training_data)}") + logging.info( + f"Processed: {len(training_data)}, Skipped: {total_rows - len(training_data)}" + ) logging.info(f"Saved NER JSON to {json_path}") logging.info(f"Saved NER spacy to {spacy_path}") return 0 diff --git a/processing/ner/name_engineering.py b/src/ners/processing/ner/name_engineering.py similarity index 62% rename from processing/ner/name_engineering.py rename to src/ners/processing/ner/name_engineering.py index 0b300f6..e78c3e6 100644 --- a/processing/ner/name_engineering.py +++ b/src/ners/processing/ner/name_engineering.py @@ -6,14 +6,14 @@ import numpy as np import pandas as pd from tqdm import tqdm -from core.config import PipelineConfig -from core.utils.data_loader import DataLoader -from processing.ner.formats.connectors_format import ConnectorFormatter -from processing.ner.formats.extended_surname_format import ExtendedSurnameFormatter -from processing.ner.formats.native_only_format import NativeOnlyFormatter -from processing.ner.formats.original_format import OriginalFormatter -from processing.ner.formats.position_flipped_format import PositionFlippedFormatter -from processing.ner.formats.reduced_native_format import ReducedNativeFormatter +from ners.core.config import PipelineConfig +from ners.core.utils.data_loader import DataLoader +from ners.processing.ner.formats.connectors_format import ConnectorFormatter +from ners.processing.ner.formats.extended_surname_format import ExtendedSurnameFormatter +from ners.processing.ner.formats.native_only_format import NativeOnlyFormatter +from ners.processing.ner.formats.original_format import OriginalFormatter +from ners.processing.ner.formats.position_flipped_format import PositionFlippedFormatter +from ners.processing.ner.formats.reduced_native_format import ReducedNativeFormatter class NameEngineering: @@ -44,42 +44,60 @@ class NameEngineering: # Initialize format classes self.formatters = { "original": OriginalFormatter(self.connectors, self.additional_surnames), - "native_only": NativeOnlyFormatter(self.connectors, self.additional_surnames), - "position_flipped": PositionFlippedFormatter(self.connectors, self.additional_surnames), - "reduced_native": ReducedNativeFormatter(self.connectors, self.additional_surnames), - "connector_added": ConnectorFormatter(self.connectors, self.additional_surnames), - "extended_surname": ExtendedSurnameFormatter(self.connectors, self.additional_surnames), + "native_only": NativeOnlyFormatter( + self.connectors, self.additional_surnames + ), + "position_flipped": PositionFlippedFormatter( + self.connectors, self.additional_surnames + ), + "reduced_native": ReducedNativeFormatter( + self.connectors, self.additional_surnames + ), + "connector_added": ConnectorFormatter( + self.connectors, self.additional_surnames + ), + "extended_surname": ExtendedSurnameFormatter( + self.connectors, self.additional_surnames + ), } def load_data(self) -> pd.DataFrame: """Load and filter NER-tagged data from CSV file""" - filepath = self.config.paths.get_data_path(self.config.data.output_files["featured"]) + filepath = self.config.paths.get_data_path( + self.config.data.output_files["featured"] + ) df = self.data_loader.load_csv_complete(filepath) # Filter only NER-tagged rows ner_data = df[df["ner_tagged"] == 1].copy() - logging.info(f"Loaded {len(ner_data)} NER-tagged records from {len(df)} total records") + logging.info( + f"Loaded {len(ner_data)} NER-tagged records from {len(df)} total records" + ) return ner_data def compute(self) -> None: logging.info("Applying feature engineering transformations...") - input_filepath = self.config.paths.get_data_path(self.config.data.output_files["featured"]) + input_filepath = self.config.paths.get_data_path( + self.config.data.output_files["featured"] + ) output_filepath = self.config.paths.get_data_path( self.config.data.output_files["engineered"] ) df = self.data_loader.load_csv_complete(input_filepath) ner_df = df[df["ner_tagged"] == 1].copy() - logging.info(f"Loaded {len(ner_df)} NER-tagged records from {len(df)} total records") + logging.info( + f"Loaded {len(ner_df)} NER-tagged records from {len(df)} total records" + ) del df # No need to keep in memory gc.collect() - ner_df = ner_df.sample(frac=1, random_state=self.config.data.random_seed).reset_index( - drop=True - ) + ner_df = ner_df.sample( + frac=1, random_state=self.config.data.random_seed + ).reset_index(drop=True) total_rows = len(ner_df) # Calculate split points @@ -94,7 +112,11 @@ class NameEngineering: (0, split_25_1, "original"), # First 25%: original format (split_25_1, split_25_2, "native_only"), # Second 25%: remove surname (split_25_2, split_25_3, "position_flipped"), # Third 25%: flip positions - (split_25_3, split_10_1, "reduced_native"), # Fourth 10%: reduce native components + ( + split_25_3, + split_10_1, + "reduced_native", + ), # Fourth 10%: reduce native components (split_10_1, split_10_2, "connector_added"), # Fifth 10%: add connectors (split_10_2, total_rows, "extended_surname"), # Last 5%: extend surnames ] diff --git a/processing/ner/name_model.py b/src/ners/processing/ner/name_model.py similarity index 87% rename from processing/ner/name_model.py rename to src/ners/processing/ner/name_model.py index bc4901e..b47beb2 100644 --- a/processing/ner/name_model.py +++ b/src/ners/processing/ner/name_model.py @@ -11,7 +11,7 @@ from spacy.training import Example from spacy.util import minibatch from tqdm import tqdm -from core.config.pipeline_config import PipelineConfig +from ners.core.config.pipeline_config import PipelineConfig class NameModel: @@ -87,7 +87,9 @@ class NameModel: # Handle different annotation formats from NERNameTagger if not isinstance(annotations, dict) or "entities" not in annotations: - logging.warning(f"Skipping invalid annotations at index {i}: {annotations}") + logging.warning( + f"Skipping invalid annotations at index {i}: {annotations}" + ) skipped_count += 1 continue @@ -124,7 +126,9 @@ class NameModel: valid_entities = [] for entity in entities: if not isinstance(entity, (list, tuple)) or len(entity) != 3: - logging.warning(f"Skipping invalid entity format in '{text}': {entity}") + logging.warning( + f"Skipping invalid entity format in '{text}': {entity}" + ) continue start, end, label = entity @@ -138,21 +142,30 @@ class NameModel: or start < 0 or end > len(text) ): - logging.warning(f"Skipping invalid entity bounds in '{text}': {entity}") + logging.warning( + f"Skipping invalid entity bounds in '{text}': {entity}" + ) continue # Check for overlaps with already validated entities has_overlap = any( - start < v_end and end > v_start for v_start, v_end, _ in valid_entities + start < v_end and end > v_start + for v_start, v_end, _ in valid_entities ) if has_overlap: - logging.warning(f"Skipping overlapping entity in '{text}': {entity}") + logging.warning( + f"Skipping overlapping entity in '{text}': {entity}" + ) continue # Validate that the span doesn't contain spaces (matching tagger validation) span_text = text[start:end] - if not span_text or span_text != span_text.strip() or " " in span_text: + if ( + not span_text + or span_text != span_text.strip() + or " " in span_text + ): logging.warning( f"Skipping entity with spaces in '{text}': {entity} -> '{span_text}'" ) @@ -161,7 +174,9 @@ class NameModel: valid_entities.append((start, end, label)) if not valid_entities: - logging.warning(f"Skipping training example with no valid entities: '{text}'") + logging.warning( + f"Skipping training example with no valid entities: '{text}'" + ) skipped_count += 1 continue @@ -219,7 +234,9 @@ class NameModel: batches = minibatch(examples, size=batch_size) for batch in batches: batch_losses = {} - self.nlp.update(batch, losses=batch_losses, drop=dropout_rate, sgd=optimizer) + self.nlp.update( + batch, losses=batch_losses, drop=dropout_rate, sgd=optimizer + ) logging.info( f"Training batch with {len(batch)} examples, current losses: {batch_losses}" ) @@ -230,7 +247,7 @@ class NameModel: del batches # free memory losses_history.append(losses.get("ner", 0)) - logging.info(f"Epoch {epoch+1}/{epochs}, Total Loss: {losses['ner']:.4f}") + logging.info(f"Epoch {epoch + 1}/{epochs}, Total Loss: {losses['ner']:.4f}") # Store training statistics self.training_stats = { @@ -242,7 +259,9 @@ class NameModel: "dropout_rate": dropout_rate, } - logging.info(f"Training completed. Final loss: {self.training_stats['final_loss']:.4f}") + logging.info( + f"Training completed. Final loss: {self.training_stats['final_loss']:.4f}" + ) def evaluate(self, test_data: List[Tuple[str, Dict]]) -> Dict[str, Any]: """Evaluate the trained model on test data""" @@ -291,10 +310,14 @@ class NameModel: entity_stats[label]["fp"] += 1 # Calculate overall metrics - precision = correct_entities / predicted_entities if predicted_entities > 0 else 0 + precision = ( + correct_entities / predicted_entities if predicted_entities > 0 else 0 + ) recall = correct_entities / actual_entities if actual_entities > 0 else 0 f1_score = ( - 2 * (precision * recall) / (precision + recall) if (precision + recall) > 0 else 0 + 2 * (precision * recall) / (precision + recall) + if (precision + recall) > 0 + else 0 ) # Calculate per-label metrics @@ -304,7 +327,11 @@ class NameModel: label_precision = tp / (tp + fp) if (tp + fp) > 0 else 0 label_recall = tp / (tp + fn) if (tp + fn) > 0 else 0 label_f1 = ( - (2 * (label_precision * label_recall) / (label_precision + label_recall)) + ( + 2 + * (label_precision * label_recall) + / (label_precision + label_recall) + ) if (label_precision + label_recall) > 0 else 0 ) @@ -394,7 +421,9 @@ class NameModel: "label": ent.label_, "start": ent.start_char, "end": ent.end_char, - "confidence": getattr(ent, "score", None), # If confidence scores are available + "confidence": getattr( + ent, "score", None + ), # If confidence scores are available } ) diff --git a/processing/ner/name_tagger.py b/src/ners/processing/ner/name_tagger.py similarity index 91% rename from processing/ner/name_tagger.py rename to src/ners/processing/ner/name_tagger.py index 6251ac0..7ab7280 100644 --- a/processing/ner/name_tagger.py +++ b/src/ners/processing/ner/name_tagger.py @@ -48,7 +48,9 @@ class NameTagger: # Find the first occurrence of this native word that doesn't overlap start_pos = 0 while True: - pos = name_lower.find(native_word_lower, start_pos) # Case-insensitive search + pos = name_lower.find( + native_word_lower, start_pos + ) # Case-insensitive search if pos == -1: break @@ -78,7 +80,9 @@ class NameTagger: # Find the first occurrence that doesn't overlap start_pos = 0 while True: - pos = name_lower.find(surname_lower, start_pos) # Case-insensitive search + pos = name_lower.find( + surname_lower, start_pos + ) # Case-insensitive search if pos == -1: break @@ -120,8 +124,13 @@ class NameTagger: continue # Check for overlaps with already validated entities - if any(start < v_end and end > v_start for v_start, v_end, _ in validated_entities): - logging.warning(f"Overlapping span ({start}, {end}, '{label}') in '{name}'") + if any( + start < v_end and end > v_start + for v_start, v_end, _ in validated_entities + ): + logging.warning( + f"Overlapping span ({start}, {end}, '{label}') in '{name}'" + ) continue # CRITICAL VALIDATION: Check that the span contains only the expected word (no spaces) @@ -200,10 +209,16 @@ class NameTagger: elif entities_str.startswith("[[") and entities_str.endswith("]]"): return [tuple(e) for e in ast.literal_eval(entities_str)] elif entities_str.startswith("[{") and entities_str.endswith("}]"): - return [(e["start"], e["end"], e["label"]) for e in json.loads(entities_str)] + return [ + (e["start"], e["end"], e["label"]) for e in json.loads(entities_str) + ] else: parsed = ast.literal_eval(entities_str) - return [tuple(e) for e in parsed if isinstance(e, (list, tuple)) and len(e) == 3] + return [ + tuple(e) + for e in parsed + if isinstance(e, (list, tuple)) and len(e) == 3 + ] except (ValueError, SyntaxError, json.JSONDecodeError): return [] @@ -251,7 +266,9 @@ class NameTagger: last_end = e return filtered - def validate_entities(self, texts: pd.Series, entities_series: pd.Series) -> pd.Series: + def validate_entities( + self, texts: pd.Series, entities_series: pd.Series + ) -> pd.Series: """Vectorized entity validation.""" return pd.Series(map(self.validate, texts, entities_series), index=texts.index) diff --git a/processing/pipeline.py b/src/ners/processing/pipeline.py similarity index 90% rename from processing/pipeline.py rename to src/ners/processing/pipeline.py index e93c54e..4d4bd5b 100644 --- a/processing/pipeline.py +++ b/src/ners/processing/pipeline.py @@ -4,9 +4,9 @@ from typing import Dict, Any import pandas as pd -from processing.batch.batch_config import BatchConfig -from processing.batch.batch_processor import BatchProcessor -from processing.steps import PipelineStep +from ners.processing.batch.batch_config import BatchConfig +from ners.processing.batch.batch_processor import BatchProcessor +from ners.processing.steps import PipelineStep class Pipeline: diff --git a/processing/steps/__init__.py b/src/ners/processing/steps/__init__.py similarity index 93% rename from processing/steps/__init__.py rename to src/ners/processing/steps/__init__.py index c8483c1..8873645 100644 --- a/processing/steps/__init__.py +++ b/src/ners/processing/steps/__init__.py @@ -8,9 +8,9 @@ from typing import List, Optional import pandas as pd from pydantic import BaseModel -from core.config.pipeline_config import PipelineConfig -from core.utils.data_loader import DataLoader -from processing.batch.batch_config import BatchConfig +from ners.core.config.pipeline_config import PipelineConfig +from ners.core.utils.data_loader import DataLoader +from ners.processing.batch.batch_config import BatchConfig @dataclass @@ -38,7 +38,10 @@ class PipelineStep(ABC): """Abstract base class for pipeline steps""" def __init__( - self, name: str, pipeline_config: PipelineConfig, batch_config: Optional[BatchConfig] = None + self, + name: str, + pipeline_config: PipelineConfig, + batch_config: Optional[BatchConfig] = None, ): self.name = name self.pipeline_config = pipeline_config diff --git a/processing/steps/data_cleaning_step.py b/src/ners/processing/steps/data_cleaning_step.py similarity index 84% rename from processing/steps/data_cleaning_step.py rename to src/ners/processing/steps/data_cleaning_step.py index 1443984..6284f78 100644 --- a/processing/steps/data_cleaning_step.py +++ b/src/ners/processing/steps/data_cleaning_step.py @@ -2,9 +2,9 @@ import logging import pandas as pd -from core.config.pipeline_config import PipelineConfig -from core.utils.text_cleaner import TextCleaner -from processing.steps import PipelineStep +from ners.core.config.pipeline_config import PipelineConfig +from ners.core.utils.text_cleaner import TextCleaner +from ners.processing.steps import PipelineStep class DataCleaningStep(PipelineStep): diff --git a/processing/steps/data_selection_step.py b/src/ners/processing/steps/data_selection_step.py similarity index 85% rename from processing/steps/data_selection_step.py rename to src/ners/processing/steps/data_selection_step.py index 5b07104..8ae202d 100644 --- a/processing/steps/data_selection_step.py +++ b/src/ners/processing/steps/data_selection_step.py @@ -2,8 +2,8 @@ import logging import pandas as pd -from core.config.pipeline_config import PipelineConfig -from processing.steps import PipelineStep +from ners.core.config.pipeline_config import PipelineConfig +from ners.processing.steps import PipelineStep class DataSelectionStep(PipelineStep): @@ -31,8 +31,12 @@ class DataSelectionStep(PipelineStep): ) # Check which columns exist in the batch - available_columns = [col for col in self.selected_columns if col in batch.columns] - missing_columns = [col for col in self.selected_columns if col not in batch.columns] + available_columns = [ + col for col in self.selected_columns if col in batch.columns + ] + missing_columns = [ + col for col in self.selected_columns if col not in batch.columns + ] if missing_columns: logging.warning(f"Missing columns in batch {batch_id}: {missing_columns}") diff --git a/processing/steps/data_splitting_step.py b/src/ners/processing/steps/data_splitting_step.py similarity index 77% rename from processing/steps/data_splitting_step.py rename to src/ners/processing/steps/data_splitting_step.py index 953e72a..27b97fd 100644 --- a/processing/steps/data_splitting_step.py +++ b/src/ners/processing/steps/data_splitting_step.py @@ -1,11 +1,11 @@ import numpy as np import pandas as pd -from core.config.pipeline_config import PipelineConfig -from core.utils.region_mapper import RegionMapper -from processing.batch.batch_config import BatchConfig -from processing.steps import PipelineStep -from processing.steps.feature_extraction_step import Gender +from ners.core.config.pipeline_config import PipelineConfig +from ners.core.utils.region_mapper import RegionMapper +from ners.processing.batch.batch_config import BatchConfig +from ners.processing.steps import PipelineStep +from ners.processing.steps.feature_extraction_step import Gender class DataSplittingStep(PipelineStep): @@ -26,7 +26,9 @@ class DataSplittingStep(PipelineStep): if self.eval_indices is None: np.random.seed(self.pipeline_config.data.random_seed) eval_size = int(total_size * self.pipeline_config.data.evaluation_fraction) - self.eval_indices = set(np.random.choice(total_size, size=eval_size, replace=False)) + self.eval_indices = set( + np.random.choice(total_size, size=eval_size, replace=False) + ) return self.eval_indices def process_batch(self, batch: pd.DataFrame, batch_id: int) -> pd.DataFrame: @@ -45,7 +47,9 @@ class DataSplittingStep(PipelineStep): df_evaluation = df[eval_mask] df_featured = df[~eval_mask] - self.data_loader.save_csv(df_evaluation, data_dir / output_files["evaluation"]) + self.data_loader.save_csv( + df_evaluation, data_dir / output_files["evaluation"] + ) self.data_loader.save_csv(df_featured, data_dir / output_files["featured"]) else: self.data_loader.save_csv(df, data_dir / output_files["featured"]) @@ -53,7 +57,9 @@ class DataSplittingStep(PipelineStep): if self.pipeline_config.data.split_by_province: for province in RegionMapper.get_provinces(): df_region = df[df.province == province] - self.data_loader.save_csv(df_region, data_dir / "provinces" / f"{province}.csv") + self.data_loader.save_csv( + df_region, data_dir / "provinces" / f"{province}.csv" + ) if self.pipeline_config.data.split_by_gender: df_males = df[df.sex == Gender.MALE.value] diff --git a/processing/steps/feature_extraction_step.py b/src/ners/processing/steps/feature_extraction_step.py similarity index 95% rename from processing/steps/feature_extraction_step.py rename to src/ners/processing/steps/feature_extraction_step.py index 5ed8aa3..30192ed 100644 --- a/processing/steps/feature_extraction_step.py +++ b/src/ners/processing/steps/feature_extraction_step.py @@ -5,10 +5,10 @@ from typing import Dict, Any import pandas as pd -from core.config.pipeline_config import PipelineConfig -from core.utils.region_mapper import RegionMapper -from processing.ner.name_tagger import NameTagger -from processing.steps import PipelineStep +from ners.core.config.pipeline_config import PipelineConfig +from ners.core.utils.region_mapper import RegionMapper +from ners.processing.ner.name_tagger import NameTagger +from ners.processing.steps import PipelineStep class Gender(Enum): @@ -64,10 +64,14 @@ class FeatureExtractionStep(PipelineStep): self._assign_probable_names(result) self._process_simple_names(result) - result["identified_category"] = self._assign_identified_category(result["words"]) + result["identified_category"] = self._assign_identified_category( + result["words"] + ) if "year" in result.columns: - result["year"] = pd.to_numeric(result["year"], errors="coerce").astype("Int16") + result["year"] = pd.to_numeric(result["year"], errors="coerce").astype( + "Int16" + ) if "region" in result.columns: result["province"] = self.region_mapper.map(result["region"]).str.lower() diff --git a/processing/steps/llm_annotation_step.py b/src/ners/processing/steps/llm_annotation_step.py similarity index 88% rename from processing/steps/llm_annotation_step.py rename to src/ners/processing/steps/llm_annotation_step.py index 357df1f..c819a19 100644 --- a/processing/steps/llm_annotation_step.py +++ b/src/ners/processing/steps/llm_annotation_step.py @@ -7,12 +7,12 @@ import ollama import pandas as pd from pydantic import ValidationError -from core.config.pipeline_config import PipelineConfig -from core.utils.prompt_manager import PromptManager -from core.utils.rate_limiter import RateLimitConfig -from core.utils.rate_limiter import RateLimiter -from processing.batch.batch_config import BatchConfig -from processing.steps import PipelineStep, NameAnnotation +from ners.core.config.pipeline_config import PipelineConfig +from ners.core.utils.prompt_manager import PromptManager +from ners.core.utils.rate_limiter import RateLimitConfig +from ners.core.utils.rate_limiter import RateLimiter +from ners.processing.batch.batch_config import BatchConfig +from ners.processing.steps import PipelineStep, NameAnnotation class LLMAnnotationStep(PipelineStep): @@ -24,7 +24,8 @@ class LLMAnnotationStep(PipelineStep): batch_config = BatchConfig( batch_size=pipeline_config.processing.batch_size, max_workers=min( - self.llm_config.max_concurrent_requests, pipeline_config.processing.max_workers + self.llm_config.max_concurrent_requests, + pipeline_config.processing.max_workers, ), checkpoint_interval=pipeline_config.processing.checkpoint_interval, use_multiprocessing=pipeline_config.processing.use_multiprocessing, @@ -33,7 +34,9 @@ class LLMAnnotationStep(PipelineStep): self.prompt = PromptManager(pipeline_config).load_prompt() self.rate_limiter = ( - self._create_rate_limiter() if self.llm_config.enable_rate_limiting else None + self._create_rate_limiter() + if self.llm_config.enable_rate_limiting + else None ) # Statistics @@ -76,7 +79,9 @@ class LLMAnnotationStep(PipelineStep): f"Request took {elapsed_time:.2f}s, exceeding {self.llm_config.timeout_seconds}s timeout" ) - annotation = NameAnnotation.model_validate_json(response.message.content) + annotation = NameAnnotation.model_validate_json( + response.message.content + ) result = { **annotation.model_dump(), "annotated": 1, @@ -119,7 +124,9 @@ class LLMAnnotationStep(PipelineStep): logging.info(f"Batch {batch_id}: No entries to annotate") return batch - logging.info(f"Batch {batch_id}: Annotating {len(unannotated_entries)} entries with LLM") + logging.info( + f"Batch {batch_id}: Annotating {len(unannotated_entries)} entries with LLM" + ) batch = batch.copy() client = ollama.Client() diff --git a/processing/steps/ner_annotation_step.py b/src/ners/processing/steps/ner_annotation_step.py similarity index 91% rename from processing/steps/ner_annotation_step.py rename to src/ners/processing/steps/ner_annotation_step.py index f2c92c3..9f71a8b 100644 --- a/processing/steps/ner_annotation_step.py +++ b/src/ners/processing/steps/ner_annotation_step.py @@ -5,9 +5,9 @@ from typing import Dict import pandas as pd -from core.config.pipeline_config import PipelineConfig -from processing.ner.name_model import NameModel -from processing.steps import PipelineStep, NameAnnotation +from ners.core.config.pipeline_config import PipelineConfig +from ners.processing.ner.name_model import NameModel +from ners.processing.steps import PipelineStep, NameAnnotation class NERAnnotationStep(PipelineStep): @@ -39,7 +39,9 @@ class NERAnnotationStep(PipelineStep): logging.info("NER model loaded successfully") else: logging.warning(f"NER model not found at {self.model_path}") - logging.warning("NER annotation will be skipped. Train the model first.") + logging.warning( + "NER annotation will be skipped. Train the model first." + ) self.name_model.nlp = None except Exception as e: logging.error(f"Failed to load NER model: {e}") @@ -80,7 +82,9 @@ class NERAnnotationStep(PipelineStep): # Create annotation result in same format as LLM step annotation = NameAnnotation( identified_name=" ".join(native_parts) if native_parts else None, - identified_surname=" ".join(surname_parts) if surname_parts else None, + identified_surname=" ".join(surname_parts) + if surname_parts + else None, ) result = { @@ -124,7 +128,9 @@ class NERAnnotationStep(PipelineStep): logging.info(f"Batch {batch_id}: No entries to annotate") return batch - logging.info(f"Batch {batch_id}: Annotating {len(unannotated_entries)} entries with NER") + logging.info( + f"Batch {batch_id}: Annotating {len(unannotated_entries)} entries with NER" + ) batch = batch.copy() diff --git a/research/__init__.py b/src/ners/research/__init__.py similarity index 100% rename from research/__init__.py rename to src/ners/research/__init__.py diff --git a/research/base_model.py b/src/ners/research/base_model.py similarity index 91% rename from research/base_model.py rename to src/ners/research/base_model.py index 8fff57d..35cb599 100644 --- a/research/base_model.py +++ b/src/ners/research/base_model.py @@ -7,7 +7,7 @@ import matplotlib.pyplot as plt import numpy as np import pandas as pd -from research.experiment import ExperimentConfig +from ners.research.experiment import ExperimentConfig class BaseModel(ABC): @@ -103,16 +103,25 @@ class BaseModel(ABC): feature_names = self._get_feature_names() return dict(zip(feature_names, coefficients)) - elif hasattr(self.model, "named_steps") and "classifier" in self.model.named_steps: + elif ( + hasattr(self.model, "named_steps") + and "classifier" in self.model.named_steps + ): # For sklearn pipelines (like LogisticRegression with vectorizer) classifier = self.model.named_steps["classifier"] if hasattr(classifier, "coef_"): coefficients = np.abs(classifier.coef_[0]) - if hasattr(self.model.named_steps["vectorizer"], "get_feature_names_out"): - feature_names = self.model.named_steps["vectorizer"].get_feature_names_out() + if hasattr( + self.model.named_steps["vectorizer"], "get_feature_names_out" + ): + feature_names = self.model.named_steps[ + "vectorizer" + ].get_feature_names_out() # Take top features to avoid too many n-grams top_indices = np.argsort(coefficients)[-20:] - return dict(zip(feature_names[top_indices], coefficients[top_indices])) + return dict( + zip(feature_names[top_indices], coefficients[top_indices]) + ) return None @@ -143,7 +152,7 @@ class BaseModel(ABC): model_data = joblib.load(path) # Recreate the model instance - from research.experiment import ExperimentConfig + from ners.research.experiment import ExperimentConfig config = ExperimentConfig.from_dict(model_data["config"]) instance = cls(config) @@ -221,7 +230,9 @@ class BaseModel(ABC): if "accuracy" in self.training_history: axes[0].plot(self.training_history["accuracy"], label="Training Accuracy") if "val_accuracy" in self.training_history: - axes[0].plot(self.training_history["val_accuracy"], label="Validation Accuracy") + axes[0].plot( + self.training_history["val_accuracy"], label="Validation Accuracy" + ) axes[0].set_title("Model Accuracy") axes[0].set_xlabel("Epoch") axes[0].set_ylabel("Accuracy") diff --git a/research/experiment/__init__.py b/src/ners/research/experiment/__init__.py similarity index 88% rename from research/experiment/__init__.py rename to src/ners/research/experiment/__init__.py index b948a9c..2cbd36d 100644 --- a/research/experiment/__init__.py +++ b/src/ners/research/experiment/__init__.py @@ -18,7 +18,9 @@ class ExperimentConfig: tags: List[str] = field(default_factory=list) # Model configuration - model_type: str = "logistic_regression" # logistic_regression, lstm, transformer, etc. + model_type: str = ( + "logistic_regression" # logistic_regression, lstm, transformer, etc. + ) model_params: Dict[str, Any] = field(default_factory=dict) # Feature configuration @@ -26,7 +28,9 @@ class ExperimentConfig: feature_params: Dict[str, Any] = field(default_factory=dict) # Data configuration - train_data_filter: Optional[Dict[str, Any]] = None # Filter criteria for training data + train_data_filter: Optional[Dict[str, Any]] = ( + None # Filter criteria for training data + ) test_data_filter: Optional[Dict[str, Any]] = None target_column: str = "sex" @@ -36,7 +40,9 @@ class ExperimentConfig: cross_validation_folds: int = 5 # Evaluation configuration - metrics: List[str] = field(default_factory=lambda: ["accuracy", "precision", "recall", "f1"]) + metrics: List[str] = field( + default_factory=lambda: ["accuracy", "precision", "recall", "f1"] + ) def to_dict(self) -> Dict[str, Any]: """Convert to dictionary for serialization""" diff --git a/research/experiment/experiement_result.py b/src/ners/research/experiment/experiement_result.py similarity index 90% rename from research/experiment/experiement_result.py rename to src/ners/research/experiment/experiement_result.py index 0e47654..4db6e26 100644 --- a/research/experiment/experiement_result.py +++ b/src/ners/research/experiment/experiement_result.py @@ -2,7 +2,7 @@ from dataclasses import dataclass, field, asdict from datetime import datetime from typing import Optional, Dict, List, Any -from research.experiment import ExperimentConfig, ExperimentStatus +from ners.research.experiment import ExperimentConfig, ExperimentStatus @dataclass @@ -51,6 +51,8 @@ class ExperimentResult: """Create from dictionary""" data["config"] = ExperimentConfig.from_dict(data["config"]) data["start_time"] = datetime.fromisoformat(data["start_time"]) - data["end_time"] = datetime.fromisoformat(data["end_time"]) if data["end_time"] else None + data["end_time"] = ( + datetime.fromisoformat(data["end_time"]) if data["end_time"] else None + ) data["status"] = ExperimentStatus(data["status"]) return cls(**data) diff --git a/research/experiment/experiment_builder.py b/src/ners/research/experiment/experiment_builder.py similarity index 93% rename from research/experiment/experiment_builder.py rename to src/ners/research/experiment/experiment_builder.py index fb09956..e9efe0c 100644 --- a/research/experiment/experiment_builder.py +++ b/src/ners/research/experiment/experiment_builder.py @@ -3,9 +3,9 @@ from typing import List, Dict import yaml -from core.config.pipeline_config import PipelineConfig -from research.experiment import ExperimentConfig -from research.experiment.feature_extractor import FeatureType +from ners.core.config.pipeline_config import PipelineConfig +from ners.research.experiment import ExperimentConfig +from ners.research.experiment.feature_extractor import FeatureType class ExperimentBuilder: @@ -27,7 +27,9 @@ class ExperimentBuilder: raise @classmethod - def find_template(cls, templates: dict, name: str, experiment_type: str = "baseline") -> dict: + def find_template( + cls, templates: dict, name: str, experiment_type: str = "baseline" + ) -> dict: """Find experiment configuration by name and type""" # Map type to section in templates diff --git a/research/experiment/experiment_runner.py b/src/ners/research/experiment/experiment_runner.py similarity index 85% rename from research/experiment/experiment_runner.py rename to src/ners/research/experiment/experiment_runner.py index 7cc3201..293a3a4 100644 --- a/research/experiment/experiment_runner.py +++ b/src/ners/research/experiment/experiment_runner.py @@ -9,12 +9,16 @@ import pandas as pd from sklearn.metrics import confusion_matrix from sklearn.model_selection import train_test_split -from core.config import PipelineConfig -from core.utils.data_loader import DataLoader -from research.base_model import BaseModel -from research.experiment import ExperimentConfig, ExperimentStatus, calculate_metrics -from research.experiment.experiment_tracker import ExperimentTracker -from research.model_registry import create_model +from ners.core.config import PipelineConfig +from ners.core.utils.data_loader import DataLoader +from ners.research.base_model import BaseModel +from ners.research.experiment import ( + ExperimentConfig, + ExperimentStatus, + calculate_metrics, +) +from ners.research.experiment.experiment_tracker import ExperimentTracker +from ners.research.model_registry import create_model class ExperimentRunner: @@ -32,10 +36,14 @@ class ExperimentRunner: try: logging.info(f"Starting experiment: {experiment_id}") - self.tracker.update_experiment(experiment_id, status=ExperimentStatus.RUNNING) + self.tracker.update_experiment( + experiment_id, status=ExperimentStatus.RUNNING + ) # Load data - filepath = self.config.paths.get_data_path(self.config.data.output_files["featured"]) + filepath = self.config.paths.get_data_path( + self.config.data.output_files["featured"] + ) df = self.data_loader.load_csv_complete(filepath) # Apply data filters if specified @@ -63,8 +71,12 @@ class ExperimentRunner: test_pred = model.predict(X_test) # Calculate metrics - train_metrics = calculate_metrics(y_train, train_pred, experiment_config.metrics) - test_metrics = calculate_metrics(y_test, test_pred, experiment_config.metrics) + train_metrics = calculate_metrics( + y_train, train_pred, experiment_config.metrics + ) + test_metrics = calculate_metrics( + y_test, test_pred, experiment_config.metrics + ) # Cross-validation if requested cv_metrics = {} @@ -125,7 +137,9 @@ class ExperimentRunner: experiment_ids = [] for i, config in enumerate(experiments): - logging.info(f"Running experiment {i + 1}/{len(experiments)}: {config.name}") + logging.info( + f"Running experiment {i + 1}/{len(experiments)}: {config.name}" + ) try: exp_id = self.run_experiment(config) experiment_ids.append(exp_id) @@ -136,7 +150,9 @@ class ExperimentRunner: return experiment_ids @classmethod - def _apply_data_filters(cls, df: pd.DataFrame, config: ExperimentConfig) -> pd.DataFrame: + def _apply_data_filters( + cls, df: pd.DataFrame, config: ExperimentConfig + ) -> pd.DataFrame: """Apply data filters specified in experiment config""" filtered_df = df.copy() @@ -148,9 +164,13 @@ class ExperimentRunner: filtered_df = filtered_df[filtered_df[column].isin(criteria)] elif isinstance(criteria, dict): if "min" in criteria: - filtered_df = filtered_df[filtered_df[column] >= criteria["min"]] + filtered_df = filtered_df[ + filtered_df[column] >= criteria["min"] + ] if "max" in criteria: - filtered_df = filtered_df[filtered_df[column] <= criteria["max"]] + filtered_df = filtered_df[ + filtered_df[column] <= criteria["max"] + ] else: filtered_df = filtered_df[filtered_df[column] == criteria] @@ -231,7 +251,9 @@ class ExperimentRunner: return model except Exception as e: - logging.error(f"Failed to load model for experiment {experiment_id}: {e}") + logging.error( + f"Failed to load model for experiment {experiment_id}: {e}" + ) return None return None diff --git a/research/experiment/experiment_tracker.py b/src/ners/research/experiment/experiment_tracker.py similarity index 91% rename from research/experiment/experiment_tracker.py rename to src/ners/research/experiment/experiment_tracker.py index cbdab93..8e50177 100644 --- a/research/experiment/experiment_tracker.py +++ b/src/ners/research/experiment/experiment_tracker.py @@ -6,9 +6,9 @@ from typing import Optional, Dict, List import pandas as pd -from core.config import PipelineConfig, get_config -from research.experiment import ExperimentConfig, ExperimentStatus -from research.experiment.experiement_result import ExperimentResult +from ners.core.config import PipelineConfig, get_config +from ners.research.experiment import ExperimentConfig, ExperimentStatus +from ners.research.experiment.experiement_result import ExperimentResult class ExperimentTracker: @@ -97,7 +97,10 @@ class ExperimentTracker: return sorted(results, key=lambda x: x.start_time, reverse=True) def get_best_experiment( - self, metric: str = "accuracy", dataset: str = "test", filters: Optional[Dict] = None + self, + metric: str = "accuracy", + dataset: str = "test", + filters: Optional[Dict] = None, ) -> Optional[ExperimentResult]: """Get the best experiment based on a metric""" experiments = self.list_experiments() @@ -106,7 +109,9 @@ class ExperimentTracker: # Apply additional filters if "model_type" in filters: experiments = [ - e for e in experiments if e.config.model_type == filters["model_type"] + e + for e in experiments + if e.config.model_type == filters["model_type"] ] if "features" in filters: experiments = [ @@ -118,7 +123,9 @@ class ExperimentTracker: valid_experiments = [] for exp in experiments: if exp.status == ExperimentStatus.COMPLETED: - metrics_dict = exp.test_metrics if dataset == "test" else exp.train_metrics + metrics_dict = ( + exp.test_metrics if dataset == "test" else exp.train_metrics + ) if metric in metrics_dict: valid_experiments.append((exp, metrics_dict[metric])) diff --git a/research/experiment/feature_extractor.py b/src/ners/research/experiment/feature_extractor.py similarity index 96% rename from research/experiment/feature_extractor.py rename to src/ners/research/experiment/feature_extractor.py index 916c69d..cff71e2 100644 --- a/research/experiment/feature_extractor.py +++ b/src/ners/research/experiment/feature_extractor.py @@ -24,7 +24,9 @@ class FeatureType(Enum): class FeatureExtractor: """Extract different types of features from name data""" - def __init__(self, feature_types: List[FeatureType], feature_params: Dict[str, Any] = None): + def __init__( + self, feature_types: List[FeatureType], feature_params: Dict[str, Any] = None + ): self.feature_types = feature_types self.feature_params = feature_params or {} diff --git a/research/model_registry.py b/src/ners/research/model_registry.py similarity index 50% rename from research/model_registry.py rename to src/ners/research/model_registry.py index 4e1bb49..8ca2948 100644 --- a/research/model_registry.py +++ b/src/ners/research/model_registry.py @@ -1,18 +1,18 @@ from typing import List -from research.base_model import BaseModel -from research.experiment import ExperimentConfig -from research.models.bigru_model import BiGRUModel -from research.models.cnn_model import CNNModel -from research.models.ensemble_model import EnsembleModel -from research.models.lightgbm_model import LightGBMModel -from research.models.logistic_regression_model import LogisticRegressionModel -from research.models.lstm_model import LSTMModel -from research.models.naive_bayes_model import NaiveBayesModel -from research.models.random_forest_model import RandomForestModel -from research.models.svm_model import SVMModel -from research.models.transformer_model import TransformerModel -from research.models.xgboost_model import XGBoostModel +from ners.research.base_model import BaseModel +from ners.research.experiment import ExperimentConfig +from ners.research.models.bigru_model import BiGRUModel +from ners.research.models.cnn_model import CNNModel +from ners.research.models.ensemble_model import EnsembleModel +from ners.research.models.lightgbm_model import LightGBMModel +from ners.research.models.logistic_regression_model import LogisticRegressionModel +from ners.research.models.lstm_model import LSTMModel +from ners.research.models.naive_bayes_model import NaiveBayesModel +from ners.research.models.random_forest_model import RandomForestModel +from ners.research.models.svm_model import SVMModel +from ners.research.models.transformer_model import TransformerModel +from ners.research.models.xgboost_model import XGBoostModel MODEL_REGISTRY = { "bigru": BiGRUModel, diff --git a/research/model_trainer.py b/src/ners/research/model_trainer.py similarity index 86% rename from research/model_trainer.py rename to src/ners/research/model_trainer.py index 5d908ee..ad77c61 100644 --- a/research/model_trainer.py +++ b/src/ners/research/model_trainer.py @@ -5,12 +5,12 @@ from typing import List, Dict, Any import pandas as pd -from core.config import get_config -from core.utils.data_loader import DataLoader -from research.experiment import FeatureType, ExperimentConfig -from research.experiment.experiment_runner import ExperimentRunner -from research.experiment.experiment_tracker import ExperimentTracker -from research.model_registry import MODEL_REGISTRY +from ners.core.config import get_config +from ners.core.utils.data_loader import DataLoader +from ners.research.experiment import FeatureType, ExperimentConfig +from ners.research.experiment.experiment_runner import ExperimentRunner +from ners.research.experiment.experiment_tracker import ExperimentTracker +from ners.research.model_registry import MODEL_REGISTRY class ModelTrainer: @@ -66,7 +66,9 @@ class ModelTrainer: if experiment and experiment.test_metrics: logging.info("Training completed successfully!") logging.info(f"Experiment ID: {experiment_id}") - logging.info(f"Test Accuracy: {experiment.test_metrics.get('accuracy', 0):.4f}") + logging.info( + f"Test Accuracy: {experiment.test_metrics.get('accuracy', 0):.4f}" + ) logging.info(f"Test F1-Score: {experiment.test_metrics.get('f1', 0):.4f}") if save_artifacts: @@ -144,13 +146,17 @@ class ModelTrainer: try: # Load data for learning curve generation - data_path = self.config.paths.get_data_path(self.config.data.output_files["featured"]) + data_path = self.config.paths.get_data_path( + self.config.data.output_files["featured"] + ) if data_path.exists(): df = self.data_loader.load_csv_complete(data_path) # Generate learning curve logging.info("Generating learning curve...") - trained_model.generate_learning_curve(df, df[experiment.config.target_column]) + trained_model.generate_learning_curve( + df, df[experiment.config.target_column] + ) # Plot and save learning curve learning_curve_path = model_dir / "learning_curve.png" @@ -187,8 +193,12 @@ class ModelTrainer: "model_path": str(model_path), "config_path": str(config_path), "results_path": str(results_path), - "learning_curve_plot": str(learning_curve_path) if learning_curve_path else None, - "training_history_plot": str(training_history_path) if training_history_path else None, + "learning_curve_plot": str(learning_curve_path) + if learning_curve_path + else None, + "training_history_plot": str(training_history_path) + if training_history_path + else None, "has_learning_curve": bool(trained_model.learning_curve_data), "has_training_history": bool(trained_model.training_history), } @@ -215,8 +225,12 @@ class ModelTrainer: "config_path": str(config_path), "results_path": str(results_path), "metadata_path": str(metadata_path), - "learning_curve_plot": str(learning_curve_path) if learning_curve_path else None, - "training_history_plot": str(training_history_path) if training_history_path else None, + "learning_curve_plot": str(learning_curve_path) + if learning_curve_path + else None, + "training_history_plot": str(training_history_path) + if training_history_path + else None, } def load_trained_model(self, experiment_id: str): @@ -227,7 +241,9 @@ class ModelTrainer: model_path = model_dir / "complete_model.joblib" if not model_path.exists(): - raise FileNotFoundError(f"Model artifacts not found for experiment {experiment_id}") + raise FileNotFoundError( + f"Model artifacts not found for experiment {experiment_id}" + ) # Load the model class dynamically metadata_path = model_dir / "metadata.json" @@ -261,7 +277,9 @@ class ModelTrainer: metadata = json.load(f) models_data.append(metadata) except Exception as e: - logging.warning(f"Could not read metadata for {model_dir.name}: {e}") + logging.warning( + f"Could not read metadata for {model_dir.name}: {e}" + ) if not models_data: logging.info("No saved models found.") diff --git a/research/models/__init__.py b/src/ners/research/models/__init__.py similarity index 100% rename from research/models/__init__.py rename to src/ners/research/models/__init__.py diff --git a/research/models/bigru_model.py b/src/ners/research/models/bigru_model.py similarity index 93% rename from research/models/bigru_model.py rename to src/ners/research/models/bigru_model.py index 5c9c347..daabfcf 100644 --- a/research/models/bigru_model.py +++ b/src/ners/research/models/bigru_model.py @@ -7,7 +7,7 @@ from tensorflow.keras.models import Sequential from tensorflow.keras.preprocessing.sequence import pad_sequences from tensorflow.keras.preprocessing.text import Tokenizer -from research.neural_network_model import NeuralNetworkModel +from ners.research.neural_network_model import NeuralNetworkModel class BiGRUModel(NeuralNetworkModel): @@ -53,7 +53,9 @@ class BiGRUModel(NeuralNetworkModel): ) model.compile( - loss="sparse_categorical_crossentropy", optimizer="adam", metrics=["accuracy"] + loss="sparse_categorical_crossentropy", + optimizer="adam", + metrics=["accuracy"], ) return model diff --git a/research/models/cnn_model.py b/src/ners/research/models/cnn_model.py similarity index 87% rename from research/models/cnn_model.py rename to src/ners/research/models/cnn_model.py index d1b1257..c7097a2 100644 --- a/research/models/cnn_model.py +++ b/src/ners/research/models/cnn_model.py @@ -15,7 +15,7 @@ from tensorflow.keras.models import Sequential from tensorflow.keras.preprocessing.text import Tokenizer from tensorflow.keras.preprocessing.sequence import pad_sequences -from research.neural_network_model import NeuralNetworkModel +from ners.research.neural_network_model import NeuralNetworkModel class CNNModel(NeuralNetworkModel): @@ -29,7 +29,9 @@ class CNNModel(NeuralNetworkModel): [ # Learn char/subword embeddings; spatial dropout regularizes across channels # to make the model robust to noisy characters and transliteration. - Embedding(input_dim=vocab_size, output_dim=params.get("embedding_dim", 64)), + Embedding( + input_dim=vocab_size, output_dim=params.get("embedding_dim", 64) + ), SpatialDropout1D(rate=params.get("embedding_dropout", 0.1)), # Small kernels capture short n-gram like patterns; padding='same' keeps # sequence length stable for simpler pooling behavior. @@ -59,7 +61,9 @@ class CNNModel(NeuralNetworkModel): ) model.compile( - loss="sparse_categorical_crossentropy", optimizer="adam", metrics=["accuracy"] + loss="sparse_categorical_crossentropy", + optimizer="adam", + metrics=["accuracy"], ) return model @@ -75,6 +79,8 @@ class CNNModel(NeuralNetworkModel): self.tokenizer.fit_on_texts(text_data) sequences = self.tokenizer.texts_to_sequences(text_data) - max_len = self.config.model_params.get("max_len", 20) # Longer for character level + max_len = self.config.model_params.get( + "max_len", 20 + ) # Longer for character level return pad_sequences(sequences, maxlen=max_len, padding="post") diff --git a/research/models/ensemble_model.py b/src/ners/research/models/ensemble_model.py similarity index 77% rename from research/models/ensemble_model.py rename to src/ners/research/models/ensemble_model.py index 7ccf801..4f758b3 100644 --- a/research/models/ensemble_model.py +++ b/src/ners/research/models/ensemble_model.py @@ -8,8 +8,8 @@ from sklearn.linear_model import LogisticRegression from sklearn.naive_bayes import MultinomialNB from sklearn.pipeline import Pipeline -from research.experiment import ExperimentConfig -from research.traditional_model import TraditionalModel +from ners.research.experiment import ExperimentConfig +from ners.research.traditional_model import TraditionalModel class EnsembleModel(TraditionalModel): @@ -40,22 +40,28 @@ class EnsembleModel(TraditionalModel): [ ( "vectorizer", - CountVectorizer(analyzer="char", ngram_range=(2, 4), max_features=5000), + CountVectorizer( + analyzer="char", ngram_range=(2, 4), max_features=5000 + ), ), ( "classifier", - LogisticRegression(max_iter=1000, random_state=self.config.random_seed), + LogisticRegression( + max_iter=1000, random_state=self.config.random_seed + ), ), ] ) - estimators.append((f"logistic_regression", model)) + estimators.append(("logistic_regression", model)) elif model_type == "random_forest": model = Pipeline( [ ( "vectorizer", - TfidfVectorizer(analyzer="char", ngram_range=(2, 3), max_features=3000), + TfidfVectorizer( + analyzer="char", ngram_range=(2, 3), max_features=3000 + ), ), ( "classifier", @@ -65,19 +71,21 @@ class EnsembleModel(TraditionalModel): ), ] ) - estimators.append((f"rf", model)) + estimators.append(("rf", model)) elif model_type == "naive_bayes": model = Pipeline( [ ( "vectorizer", - CountVectorizer(analyzer="char", ngram_range=(1, 3), max_features=4000), + CountVectorizer( + analyzer="char", ngram_range=(1, 3), max_features=4000 + ), ), ("classifier", MultinomialNB()), ] ) - estimators.append((f"nb", model)) + estimators.append(("nb", model)) # Soft voting averages probabilities (preferred when members are calibrated); # hard voting uses majority class. Parallelize member predictions. diff --git a/research/models/lightgbm_model.py b/src/ners/research/models/lightgbm_model.py similarity index 97% rename from research/models/lightgbm_model.py rename to src/ners/research/models/lightgbm_model.py index deb895f..1da50b0 100644 --- a/research/models/lightgbm_model.py +++ b/src/ners/research/models/lightgbm_model.py @@ -5,7 +5,7 @@ from sklearn.base import BaseEstimator from sklearn.feature_extraction.text import CountVectorizer from sklearn.preprocessing import LabelEncoder -from research.traditional_model import TraditionalModel +from ners.research.traditional_model import TraditionalModel class LightGBMModel(TraditionalModel): @@ -106,7 +106,9 @@ class LightGBMModel(TraditionalModel): lambda x: x if x in known_classes else default_class ) - encoded = self.label_encoders[feature_key].transform(column_mapped) + encoded = self.label_encoders[feature_key].transform( + column_mapped + ) features.append(encoded.reshape(-1, 1)) diff --git a/research/models/logistic_regression_model.py b/src/ners/research/models/logistic_regression_model.py similarity index 97% rename from research/models/logistic_regression_model.py rename to src/ners/research/models/logistic_regression_model.py index dc2e54b..452397a 100644 --- a/research/models/logistic_regression_model.py +++ b/src/ners/research/models/logistic_regression_model.py @@ -5,7 +5,7 @@ from sklearn.feature_extraction.text import CountVectorizer from sklearn.linear_model import LogisticRegression from sklearn.pipeline import Pipeline -from research.traditional_model import TraditionalModel +from ners.research.traditional_model import TraditionalModel class LogisticRegressionModel(TraditionalModel): diff --git a/research/models/lstm_model.py b/src/ners/research/models/lstm_model.py similarity index 93% rename from research/models/lstm_model.py rename to src/ners/research/models/lstm_model.py index 1e65aa1..792c7a4 100644 --- a/research/models/lstm_model.py +++ b/src/ners/research/models/lstm_model.py @@ -7,7 +7,7 @@ from tensorflow.keras.models import Sequential from tensorflow.keras.preprocessing.sequence import pad_sequences from tensorflow.keras.preprocessing.text import Tokenizer -from research.neural_network_model import NeuralNetworkModel +from ners.research.neural_network_model import NeuralNetworkModel class LSTMModel(NeuralNetworkModel): @@ -50,7 +50,9 @@ class LSTMModel(NeuralNetworkModel): ) model.compile( - loss="sparse_categorical_crossentropy", optimizer="adam", metrics=["accuracy"] + loss="sparse_categorical_crossentropy", + optimizer="adam", + metrics=["accuracy"], ) return model diff --git a/research/models/naive_bayes_model.py b/src/ners/research/models/naive_bayes_model.py similarity index 96% rename from research/models/naive_bayes_model.py rename to src/ners/research/models/naive_bayes_model.py index d377d7f..cf8f027 100644 --- a/research/models/naive_bayes_model.py +++ b/src/ners/research/models/naive_bayes_model.py @@ -5,7 +5,7 @@ from sklearn.feature_extraction.text import CountVectorizer from sklearn.naive_bayes import MultinomialNB from sklearn.pipeline import Pipeline -from research.traditional_model import TraditionalModel +from ners.research.traditional_model import TraditionalModel class NaiveBayesModel(TraditionalModel): diff --git a/research/models/random_forest_model.py b/src/ners/research/models/random_forest_model.py similarity index 87% rename from research/models/random_forest_model.py rename to src/ners/research/models/random_forest_model.py index 14ef0bc..7d6f5a1 100644 --- a/research/models/random_forest_model.py +++ b/src/ners/research/models/random_forest_model.py @@ -6,7 +6,7 @@ from sklearn.base import BaseEstimator from sklearn.ensemble import RandomForestClassifier from sklearn.preprocessing import LabelEncoder -from research.traditional_model import TraditionalModel +from ners.research.traditional_model import TraditionalModel class RandomForestModel(TraditionalModel): @@ -18,7 +18,6 @@ class RandomForestModel(TraditionalModel): self.label_encoders: Dict[str, LabelEncoder] = {} def build_model(self) -> BaseEstimator: - params = self.config.model_params # Tree ensemble is robust to mixed numeric/categorical encodings; parallelize @@ -56,10 +55,14 @@ class RandomForestModel(TraditionalModel): column_clean = column.fillna("unknown").astype(str) known_classes = set(encoder.classes_) default_class = ( - "unknown" if "unknown" in known_classes else encoder.classes_[0] + "unknown" + if "unknown" in known_classes + else encoder.classes_[0] ) column_mapped = column_clean.apply( - lambda value: value if value in known_classes else default_class + lambda value: value + if value in known_classes + else default_class ) encoded = encoder.transform(column_mapped) diff --git a/research/models/svm_model.py b/src/ners/research/models/svm_model.py similarity index 96% rename from research/models/svm_model.py rename to src/ners/research/models/svm_model.py index b980f36..2d56a9e 100644 --- a/research/models/svm_model.py +++ b/src/ners/research/models/svm_model.py @@ -5,7 +5,7 @@ from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.pipeline import Pipeline from sklearn.svm import SVC -from research.traditional_model import TraditionalModel +from ners.research.traditional_model import TraditionalModel class SVMModel(TraditionalModel): diff --git a/research/models/transformer_model.py b/src/ners/research/models/transformer_model.py similarity index 82% rename from research/models/transformer_model.py rename to src/ners/research/models/transformer_model.py index f5bdcbe..2fc460f 100644 --- a/research/models/transformer_model.py +++ b/src/ners/research/models/transformer_model.py @@ -16,7 +16,7 @@ from tensorflow.keras.models import Model from tensorflow.keras.preprocessing.sequence import pad_sequences from tensorflow.keras.preprocessing.text import Tokenizer -from research.neural_network_model import NeuralNetworkModel +from ners.research.neural_network_model import NeuralNetworkModel class TransformerModel(NeuralNetworkModel): @@ -37,7 +37,8 @@ class TransformerModel(NeuralNetworkModel): # Add positional encoding positions = tf.range(start=0, limit=params.get("max_len", 8), delta=1) pos_embedding = Embedding( - input_dim=params.get("max_len", 8), output_dim=params.get("embedding_dim", 64) + input_dim=params.get("max_len", 8), + output_dim=params.get("embedding_dim", 64), )(positions) x = x + pos_embedding @@ -49,7 +50,9 @@ class TransformerModel(NeuralNetworkModel): model = Model(inputs, outputs) model.compile( - optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"] + optimizer="adam", + loss="sparse_categorical_crossentropy", + metrics=["accuracy"], ) return model @@ -62,11 +65,15 @@ class TransformerModel(NeuralNetworkModel): key_dim=cfg_params.get("transformer_head_size", 64), dropout=cfg_params.get("attn_dropout", 0.1), )(x, x) - x = LayerNormalization(epsilon=1e-6)(x + Dropout(cfg_params.get("dropout", 0.1))(attn)) + x = LayerNormalization(epsilon=1e-6)( + x + Dropout(cfg_params.get("dropout", 0.1))(attn) + ) ff = Dense(cfg_params.get("transformer_ff_dim", 128), activation="relu")(x) ff = Dense(x.shape[-1])(ff) - return LayerNormalization(epsilon=1e-6)(x + Dropout(cfg_params.get("dropout", 0.1))(ff)) + return LayerNormalization(epsilon=1e-6)( + x + Dropout(cfg_params.get("dropout", 0.1))(ff) + ) def prepare_features(self, X: pd.DataFrame) -> np.ndarray: text_data = self._collect_text_corpus(X) diff --git a/research/models/xgboost_model.py b/src/ners/research/models/xgboost_model.py similarity index 97% rename from research/models/xgboost_model.py rename to src/ners/research/models/xgboost_model.py index c642203..eaf34e1 100644 --- a/research/models/xgboost_model.py +++ b/src/ners/research/models/xgboost_model.py @@ -5,7 +5,7 @@ from sklearn.base import BaseEstimator from sklearn.feature_extraction.text import CountVectorizer from sklearn.preprocessing import LabelEncoder -from research.traditional_model import TraditionalModel +from ners.research.traditional_model import TraditionalModel class XGBoostModel(TraditionalModel): @@ -106,7 +106,9 @@ class XGBoostModel(TraditionalModel): lambda x: x if x in known_classes else default_class ) - encoded = self.label_encoders[feature_key].transform(column_mapped) + encoded = self.label_encoders[feature_key].transform( + column_mapped + ) features.append(encoded.reshape(-1, 1)) diff --git a/research/neural_network_model.py b/src/ners/research/neural_network_model.py similarity index 91% rename from research/neural_network_model.py rename to src/ners/research/neural_network_model.py index 64f6445..6181367 100644 --- a/research/neural_network_model.py +++ b/src/ners/research/neural_network_model.py @@ -10,8 +10,10 @@ from sklearn.model_selection import StratifiedKFold from sklearn.model_selection import train_test_split from sklearn.preprocessing import LabelEncoder -from research.base_model import BaseModel -from research.experiment.feature_extractor import FeatureExtractor +import tensorflow as tf + +from ners.research.base_model import BaseModel +from ners.research.experiment.feature_extractor import FeatureExtractor class NeuralNetworkModel(BaseModel): @@ -34,8 +36,6 @@ class NeuralNetworkModel(BaseModel): # - Enables memory growth to avoid pre-allocating all VRAM # - Optionally enables mixed precision if requested via model params try: - import tensorflow as tf # Imported lazily to avoid dependency for non-NN runs - requested_gpu = bool(self.config.model_params.get("use_gpu", False)) enable_mixed = bool(self.config.model_params.get("mixed_precision", False)) @@ -49,15 +49,15 @@ class NeuralNetworkModel(BaseModel): if enable_mixed: try: - from tensorflow.keras import mixed_precision - - mixed_precision.set_global_policy("mixed_float16") + tf.keras.mixed_precision.set_global_policy("mixed_float16") logging.info("Enabled TensorFlow mixed precision (float16)") except Exception as e: logging.warning(f"Could not enable mixed precision: {e}") else: if requested_gpu: - logging.warning("Requested GPU but no TensorFlow GPU device is available.") + logging.warning( + "Requested GPU but no TensorFlow GPU device is available." + ) except Exception as e: # Keep silent in non-TF environments / non-NN workflows logging.debug(f"TensorFlow GPU setup skipped: {e}") @@ -86,7 +86,9 @@ class NeuralNetworkModel(BaseModel): logging.info(f"Vocabulary size: {vocab_size}") # Get additional model parameters - self.model = self.build_model_with_vocab(vocab_size=vocab_size, **self.config.model_params) + self.model = self.build_model_with_vocab( + vocab_size=vocab_size, **self.config.model_params + ) # Train the neural network logging.info( @@ -143,7 +145,7 @@ class NeuralNetworkModel(BaseModel): # Keep zeros (padding) untouched; clamp negatives and > max_idx to OOV invalid_mask = (arr < 0) | (arr > max_idx) # Avoid turning zeros into OOV - invalid_mask &= (arr != 0) + invalid_mask &= arr != 0 if invalid_mask.any(): arr[invalid_mask] = oov_index @@ -157,10 +159,14 @@ class NeuralNetworkModel(BaseModel): """Combine configured textual features into one string per record.""" column_names = [ - feature.value for feature in self.config.features if feature.value in X.columns + feature.value + for feature in self.config.features + if feature.value in X.columns ] if not column_names: - raise ValueError("No configured text features found in the provided DataFrame.") + raise ValueError( + "No configured text features found in the provided DataFrame." + ) text_frame = X[column_names].fillna("").astype(str) @@ -193,9 +199,7 @@ class NeuralNetworkModel(BaseModel): pass if enable_mixed: try: - from tensorflow.keras import mixed_precision - - mixed_precision.set_global_policy("mixed_float16") + tf.keras.mixed_precision.set_global_policy("mixed_float16") except Exception: pass else: @@ -208,7 +212,9 @@ class NeuralNetworkModel(BaseModel): X_prepared = self._sanitize_sequences(X_prepared) y_encoded = self.label_encoder.transform(y) - cv = StratifiedKFold(n_splits=cv_folds, shuffle=True, random_state=self.config.random_seed) + cv = StratifiedKFold( + n_splits=cv_folds, shuffle=True, random_state=self.config.random_seed + ) accuracies = [] precisions = [] @@ -280,14 +286,14 @@ class NeuralNetworkModel(BaseModel): pass if enable_mixed: try: - from tensorflow.keras import mixed_precision - - mixed_precision.set_global_policy("mixed_float16") + tf.keras.mixed_precision.set_global_policy("mixed_float16") except Exception: pass else: if requested_gpu: - logging.warning("Requested GPU for learning curve but none is available.") + logging.warning( + "Requested GPU for learning curve but none is available." + ) except Exception: pass @@ -342,7 +348,7 @@ class NeuralNetworkModel(BaseModel): # Train model if hasattr(model, "fit"): - history = model.fit( + model.fit( X_train_subset, y_train_subset, epochs=self.config.model_params.get("epochs", 10), diff --git a/research/statistics/__init__.py b/src/ners/research/statistics/__init__.py similarity index 100% rename from research/statistics/__init__.py rename to src/ners/research/statistics/__init__.py diff --git a/research/statistics/plots.py b/src/ners/research/statistics/plots.py similarity index 73% rename from research/statistics/plots.py rename to src/ners/research/statistics/plots.py index 051feb1..86014ff 100644 --- a/research/statistics/plots.py +++ b/src/ners/research/statistics/plots.py @@ -3,12 +3,16 @@ import pandas as pd import matplotlib.pyplot as plt import seaborn as sns -from research.statistics.utils import LETTERS, build_letter_frequencies +from ners.research.statistics.utils import LETTERS, build_letter_frequencies def plot_transition_matrix(ax, df_probs, title=""): hm = sns.heatmap( - df_probs.loc[list(LETTERS), list(LETTERS)], cmap="Reds", annot=False, cbar=False, ax=ax + df_probs.loc[list(LETTERS), list(LETTERS)], + cmap="Reds", + annot=False, + cbar=False, + ax=ax, ) ax.set_title(title, fontsize=12) return hm @@ -31,8 +35,12 @@ def plot_letter_frequencies(males, females, sort_values=False, title=None): x = np.arange(len(df_plot)) w = 0.4 fig, ax = plt.subplots(figsize=(16, 6)) - ax.bar(x - w / 2, df_plot["Male"], width=w, label="Male", color="steelblue", alpha=0.8) - ax.bar(x + w / 2, df_plot["Female"], width=w, label="Female", color="salmon", alpha=0.8) + ax.bar( + x - w / 2, df_plot["Male"], width=w, label="Male", color="steelblue", alpha=0.8 + ) + ax.bar( + x + w / 2, df_plot["Female"], width=w, label="Female", color="salmon", alpha=0.8 + ) ax.set_xticks(x) ax.set_xticklabels(df_plot["letter"]) diff --git a/research/statistics/utils.py b/src/ners/research/statistics/utils.py similarity index 92% rename from research/statistics/utils.py rename to src/ners/research/statistics/utils.py index 25f2248..b27c135 100644 --- a/research/statistics/utils.py +++ b/src/ners/research/statistics/utils.py @@ -5,8 +5,6 @@ import numpy as np import pandas as pd from scipy.spatial.distance import euclidean from scipy.stats import entropy -from scipy.spatial.distance import euclidean -from scipy.stats import entropy from typing import Dict, Any LETTERS = "abcdefghijklmnopqrstuvwxyz" @@ -49,7 +47,12 @@ def build_words_token(df: pd.DataFrame, source: str, target: str) -> pd.DataFram def build_letter_frequencies(series: pd.Series) -> pd.DataFrame: # Normalize: lowercase, remove non-letters, concatenate all into one string - s = series.astype(str).str.lower().str.replace(r"[^a-z]", "", regex=True).str.cat(sep="") + s = ( + series.astype(str) + .str.lower() + .str.replace(r"[^a-z]", "", regex=True) + .str.cat(sep="") + ) # Convert string into Series of characters chars = pd.Series(list(s)) @@ -150,8 +153,12 @@ def build_transition_comparisons( kl_names_mf = entropy(prepared_names["m"] + 1e-12, prepared_names["f"] + 1e-12) kl_names_fm = entropy(prepared_names["f"] + 1e-12, prepared_names["m"] + 1e-12) - kl_surnames_mf = entropy(prepared_surnames["m"] + 1e-12, prepared_surnames["f"] + 1e-12) - kl_surnames_fm = entropy(prepared_surnames["f"] + 1e-12, prepared_surnames["m"] + 1e-12) + kl_surnames_mf = entropy( + prepared_surnames["m"] + 1e-12, prepared_surnames["f"] + 1e-12 + ) + kl_surnames_fm = entropy( + prepared_surnames["f"] + 1e-12, prepared_surnames["m"] + 1e-12 + ) jsd_names = 0.5 * (kl_names_mf + kl_names_fm) jsd_surnames = 0.5 * (kl_surnames_mf + kl_surnames_fm) @@ -163,7 +170,9 @@ def build_transition_comparisons( P_f = transitions["f"]["probs"].flatten() # Calculate the observed JSD (our test statistic) - observed_jsd = 0.5 * (entropy(P_m + 1e-12, P_f + 1e-12) + entropy(P_f + 1e-12, P_m + 1e-12)) + observed_jsd = 0.5 * ( + entropy(P_m + 1e-12, P_f + 1e-12) + entropy(P_f + 1e-12, P_m + 1e-12) + ) # Concatenate male and female counts counts_m = transitions["m"]["counts"] @@ -194,10 +203,12 @@ def build_transition_comparisons( permuted_jsd = 0.5 * ( entropy( - permuted_probs_m.mean(axis=1) + 1e-12, permuted_probs_f.mean(axis=1) + 1e-12 + permuted_probs_m.mean(axis=1) + 1e-12, + permuted_probs_f.mean(axis=1) + 1e-12, ) + entropy( - permuted_probs_f.mean(axis=1) + 1e-12, permuted_probs_m.mean(axis=1) + 1e-12 + permuted_probs_f.mean(axis=1) + 1e-12, + permuted_probs_m.mean(axis=1) + 1e-12, ) ) permuted_jsds.append(permuted_jsd) diff --git a/research/traditional_model.py b/src/ners/research/traditional_model.py similarity index 88% rename from research/traditional_model.py rename to src/ners/research/traditional_model.py index 8f97c0a..bce368c 100644 --- a/research/traditional_model.py +++ b/src/ners/research/traditional_model.py @@ -8,8 +8,8 @@ from sklearn.model_selection import StratifiedKFold, cross_val_score from sklearn.model_selection import learning_curve from sklearn.preprocessing import LabelEncoder -from research.base_model import BaseModel -from research.experiment.feature_extractor import FeatureExtractor +from ners.research.base_model import BaseModel +from ners.research.experiment.feature_extractor import FeatureExtractor class TraditionalModel(BaseModel): @@ -52,7 +52,9 @@ class TraditionalModel(BaseModel): # Train model if len(X_prepared.shape) == 1: # For text-based features (like LogisticRegression with vectorization) - logging.info(f"Fitting model with {X_prepared.shape[0]} samples (text features)") + logging.info( + f"Fitting model with {X_prepared.shape[0]} samples (text features)" + ) else: # For numerical features logging.info( @@ -74,12 +76,16 @@ class TraditionalModel(BaseModel): return self - def cross_validate(self, X: pd.DataFrame, y: pd.Series, cv_folds: int = 5) -> Dict[str, float]: + def cross_validate( + self, X: pd.DataFrame, y: pd.Series, cv_folds: int = 5 + ) -> Dict[str, float]: features_df = self.feature_extractor.extract_features(X) X_prepared = self.prepare_features(features_df) y_encoded = self.label_encoder.transform(y) - cv = StratifiedKFold(n_splits=cv_folds, shuffle=True, random_state=self.config.random_seed) + cv = StratifiedKFold( + n_splits=cv_folds, shuffle=True, random_state=self.config.random_seed + ) # Calculate different metrics results = {} @@ -95,7 +101,11 @@ class TraditionalModel(BaseModel): for metric in ["precision", "recall", "f1"]: if metric in self.config.metrics: scores = cross_val_score( - self.model, X_prepared, y_encoded, cv=cv, scoring=f"{metric}_weighted" + self.model, + X_prepared, + y_encoded, + cv=cv, + scoring=f"{metric}_weighted", ) results[metric] = scores.mean() results[f"{metric}_std"] = scores.std() diff --git a/src/ners/train.py b/src/ners/train.py new file mode 100755 index 0000000..eee5c18 --- /dev/null +++ b/src/ners/train.py @@ -0,0 +1,46 @@ +#!.venv/bin/python3 +import logging +import traceback + +from ners.core.config import setup_config +from ners.research.experiment.experiment_builder import ExperimentBuilder +from ners.research.model_trainer import ModelTrainer + + +def train_from_template( + name: str, + type: str, + *, + templates: str = "research_templates.yaml", + config: str | None = None, + env: str = "development", +) -> int: + try: + cfg = setup_config(config_path=config, env=env) + experiment_builder = ExperimentBuilder(cfg) + + logging.info(f"Loading research templates from: {templates}") + tmpl = experiment_builder.load_templates(templates) + + logging.info(f"Looking for experiment: name='{name}', type='{type}'") + experiment_config = experiment_builder.find_template(tmpl, name, type) + + logging.info(f"Found experiment: {experiment_config.get('name')}") + logging.info(f"Description: {experiment_config.get('description')}") + logging.info(f"Features: {experiment_config.get('features')}") + + trainer = ModelTrainer(cfg) + trainer.train_single_model( + model_name=experiment_config.get("name"), + model_type=experiment_config.get("model_type"), + features=experiment_config.get("features"), + model_params=experiment_config.get("model_params", {}), + tags=experiment_config.get("tags", []), + ) + + logging.info("Training completed successfully!") + return 0 + except Exception as e: + logging.error(f"Training failed: {e}") + traceback.print_exc() + return 1 diff --git a/core/utils/log_reader.py b/src/ners/web/__init__.py similarity index 100% rename from core/utils/log_reader.py rename to src/ners/web/__init__.py diff --git a/web/app.py b/src/ners/web/app.py similarity index 66% rename from web/app.py rename to src/ners/web/app.py index 7cde28b..8488c7d 100644 --- a/web/app.py +++ b/src/ners/web/app.py @@ -1,19 +1,13 @@ #!.venv/bin/python3 -import argparse -import sys -from pathlib import Path +import os import streamlit as st -# Add parent directory to Python path to access core modules -parent_dir = Path(__file__).parent.parent -sys.path.insert(0, str(parent_dir)) - -from core.config import setup_config, PipelineConfig -from core.utils.data_loader import DataLoader -from processing.monitoring.pipeline_monitor import PipelineMonitor -from research.experiment.experiment_runner import ExperimentRunner -from research.experiment.experiment_tracker import ExperimentTracker +from ners.core.config import setup_config, PipelineConfig +from ners.core.utils.data_loader import DataLoader +from ners.processing.monitoring.pipeline_monitor import PipelineMonitor +from ners.research.experiment.experiment_runner import ExperimentRunner +from ners.research.experiment.experiment_tracker import ExperimentTracker # Page configuration st.set_page_config( @@ -65,19 +59,9 @@ class StreamlitApp: ) -def main(): - parser = argparse.ArgumentParser( - description="DRC NERS Platform", - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - parser.add_argument("--config", type=str, help="Path to configuration file") - parser.add_argument("--env", type=str, default="development", help="Environment name") - args = parser.parse_args() - - config = setup_config(args.config, env=args.env) - app = StreamlitApp(config) - app.run() - - -if __name__ == "__main__": - main() +# Initialize app using environment variables when launched via Typer +_config_path = os.environ.get("NERS_CONFIG") +_env = os.environ.get("NERS_ENV", "development") +_cfg = setup_config(_config_path, env=_env) +_app = StreamlitApp(_cfg) +_app.run() diff --git a/web/interfaces/__init__.py b/src/ners/web/interfaces/__init__.py similarity index 100% rename from web/interfaces/__init__.py rename to src/ners/web/interfaces/__init__.py diff --git a/web/interfaces/configuration.py b/src/ners/web/interfaces/configuration.py similarity index 100% rename from web/interfaces/configuration.py rename to src/ners/web/interfaces/configuration.py diff --git a/web/interfaces/dashboard.py b/src/ners/web/interfaces/dashboard.py similarity index 81% rename from web/interfaces/dashboard.py rename to src/ners/web/interfaces/dashboard.py index 435db1c..371dd5b 100644 --- a/web/interfaces/dashboard.py +++ b/src/ners/web/interfaces/dashboard.py @@ -1,7 +1,7 @@ import pandas as pd import streamlit as st -from core.utils.data_loader import OPTIMIZED_DTYPES +from ners.core.utils.data_loader import OPTIMIZED_DTYPES @st.cache_data @@ -25,7 +25,9 @@ class Dashboard: # Load basic statistics try: - data_path = self.config.paths.get_data_path(self.config.data.output_files["featured"]) + data_path = self.config.paths.get_data_path( + self.config.data.output_files["featured"] + ) if data_path.exists(): df = load_dataset(str(data_path)) @@ -37,13 +39,17 @@ class Dashboard: st.metric("Annotated Names", f"{annotated:,}") with col3: - provinces = df["province"].nunique() if "province" in df.columns else 0 + provinces = ( + df["province"].nunique() if "province" in df.columns else 0 + ) st.metric("Provinces", provinces) with col4: if "sex" in df.columns: gender_dist = df["sex"].value_counts() - ratio = gender_dist.get("f", 0) / max(gender_dist.get("m", 1), 1) + ratio = gender_dist.get("f", 0) / max( + gender_dist.get("m", 1), 1 + ) st.metric("F/M Rate", f"{ratio:.2%}") with col5: if "annotated" in df.columns: @@ -79,4 +85,6 @@ class Dashboard: st.dataframe(pd.DataFrame(exp_data), use_container_width=True) else: - st.info("No experiments found. Create your first experiment in the Experiments tab!") + st.info( + "No experiments found. Create your first experiment in the Experiments tab!" + ) diff --git a/src/ners/web/interfaces/data_overview.py b/src/ners/web/interfaces/data_overview.py new file mode 100644 index 0000000..8cac3b8 --- /dev/null +++ b/src/ners/web/interfaces/data_overview.py @@ -0,0 +1,52 @@ +from datetime import datetime + +import pandas as pd +import streamlit as st + +from ners.core.utils.data_loader import OPTIMIZED_DTYPES + + +@st.cache_data +def load_dataset(file_path: str) -> pd.DataFrame: + try: + return pd.read_csv(file_path, dtype=OPTIMIZED_DTYPES) + except Exception as e: + st.error(f"Error loading dataset: {e}") + return pd.DataFrame() + + +class DataOverview: + def __init__(self, config): + self.config = config + + def index(self): + st.title("Data Overview") + data_files = { + "Names": self.config.data.input_file, + "Featured Dataset": self.config.data.output_files["featured"], + "Evaluation Dataset": self.config.data.output_files["evaluation"], + "Male Names": self.config.data.output_files["males"], + "Female Names": self.config.data.output_files["females"], + } + + st.write("Available Data Files:") + for name, rel_path in data_files.items(): + file_path = self.config.paths.get_data_path(rel_path) + exists = file_path.exists() + size = file_path.stat().st_size if exists else 0 + stats = ( + f"Size: {size / (1024 * 1024):.1f} MB, Last Modified: {datetime.fromtimestamp(file_path.stat().st_mtime)}" + if exists + else "Not found" + ) + st.write(f"- {name}: {file_path} ({stats})") + + # Preview featured dataset if available + data_path = self.config.paths.get_data_path( + self.config.data.output_files["featured"] + ) + if data_path.exists(): + df = load_dataset(str(data_path)) + st.subheader("Featured Dataset Preview") + st.dataframe(df.head(), use_container_width=True) + st.write(f"Rows: {len(df):,}") diff --git a/web/interfaces/data_processing.py b/src/ners/web/interfaces/data_processing.py similarity index 89% rename from web/interfaces/data_processing.py rename to src/ners/web/interfaces/data_processing.py index 1f82d53..0b738ad 100644 --- a/web/interfaces/data_processing.py +++ b/src/ners/web/interfaces/data_processing.py @@ -2,8 +2,8 @@ import pandas as pd import plotly.express as px import streamlit as st -from core.utils.data_loader import OPTIMIZED_DTYPES -from web.interfaces.log_reader import LogReader +from ners.core.utils.data_loader import OPTIMIZED_DTYPES +from ners.web.interfaces.log_reader import LogReader @st.cache_data @@ -31,7 +31,9 @@ class DataProcessing: # Step details for step_name, step_status in status["steps"].items(): - with st.expander(f"{step_name.replace('_', ' ').title()} - {step_status['status']}"): + with st.expander( + f"{step_name.replace('_', ' ').title()} - {step_status['status']}" + ): col1, col2, col3 = st.columns(3) with col1: @@ -63,14 +65,20 @@ class DataProcessing: with col2: num_entries = st.number_input( - "Number of entries", min_value=5, max_value=50, value=10, key="num_log_entries" + "Number of entries", + min_value=5, + max_value=50, + value=10, + key="num_log_entries", ) # Get log entries based on filter if log_level_filter == "All": log_entries = log_reader.read_last_entries(num_entries) else: - log_entries = log_reader.read_entries_by_level(log_level_filter, num_entries) + log_entries = log_reader.read_entries_by_level( + log_level_filter, num_entries + ) if log_entries: for entry in log_entries: diff --git a/web/interfaces/experiments.py b/src/ners/web/interfaces/experiments.py similarity index 79% rename from web/interfaces/experiments.py rename to src/ners/web/interfaces/experiments.py index 968f29f..e9550fa 100644 --- a/web/interfaces/experiments.py +++ b/src/ners/web/interfaces/experiments.py @@ -2,13 +2,13 @@ from typing import List, Dict import streamlit as st -from core.config.pipeline_config import PipelineConfig -from research.experiment import ExperimentConfig, ExperimentStatus -from research.experiment.experiment_builder import ExperimentBuilder -from research.experiment.experiment_runner import ExperimentRunner -from research.experiment.experiment_tracker import ExperimentTracker -from research.experiment.feature_extractor import FeatureType -from research.model_registry import list_available_models +from ners.core.config.pipeline_config import PipelineConfig +from ners.research.experiment import ExperimentConfig, ExperimentStatus +from ners.research.experiment.experiment_builder import ExperimentBuilder +from ners.research.experiment.experiment_runner import ExperimentRunner +from ners.research.experiment.experiment_tracker import ExperimentTracker +from ners.research.experiment.feature_extractor import FeatureType +from ners.research.model_registry import list_available_models class Experiments: @@ -46,13 +46,19 @@ class Experiments: available_experiments = self.experiment_builder.get_templates() # Create tabs for different experiment types - exp_tabs = st.tabs(["Baseline", "Advanced", "Feature Studies", "Hyperparameter Tuning"]) + exp_tabs = st.tabs( + ["Baseline", "Advanced", "Feature Studies", "Hyperparameter Tuning"] + ) with exp_tabs[0]: - self._show_experiments_by_type(available_experiments["baseline"], "baseline") + self._show_experiments_by_type( + available_experiments["baseline"], "baseline" + ) with exp_tabs[1]: - self._show_experiments_by_type(available_experiments["advanced"], "advanced") + self._show_experiments_by_type( + available_experiments["advanced"], "advanced" + ) with exp_tabs[2]: self._show_experiments_by_type( @@ -60,7 +66,9 @@ class Experiments: ) with exp_tabs[3]: - self._show_experiments_by_type(available_experiments["tuning"], "tuning") + self._show_experiments_by_type( + available_experiments["tuning"], "tuning" + ) except Exception as e: st.error(f"Error loading experiment templates: {e}") @@ -79,7 +87,9 @@ class Experiments: # Show available experiments for i, exp_template in enumerate(experiments): exp_name = exp_template.get("name", f"Experiment {i + 1}") - exp_description = exp_template.get("description", "No description available") + exp_description = exp_template.get( + "description", "No description available" + ) with st.expander(f"📊 {exp_name} - {exp_description}"): col1, col2 = st.columns([2, 1]) @@ -88,7 +98,7 @@ class Experiments: st.json(exp_template) with col2: - if st.button(f"🚀 Run Experiment", key=f"run_{experiment_type}_{i}"): + if st.button("🚀 Run Experiment", key=f"run_{experiment_type}_{i}"): self._run_template_experiment(exp_template) def _run_template_experiment(self, exp_template: Dict): @@ -100,7 +110,9 @@ class Experiments: # Run the experiment experiment_id = self.experiment_runner.run_experiment(experiment_config) - st.success(f"Experiment '{experiment_config.name}' completed successfully!") + st.success( + f"Experiment '{experiment_config.name}' completed successfully!" + ) st.info(f"Experiment ID: `{experiment_id}`") # Show results @@ -130,13 +142,17 @@ class Experiments: ) with col2: - model_filter = st.selectbox("Filter by Model", ["All"] + list_available_models()) + model_filter = st.selectbox( + "Filter by Model", ["All"] + list_available_models() + ) with col3: tag_filter = st.text_input("Filter by Tags (comma-separated)") # Get and filter experiments - experiments = self._get_filtered_experiments(status_filter, model_filter, tag_filter) + experiments = self._get_filtered_experiments( + status_filter, model_filter, tag_filter + ) if not experiments: st.info("No experiments found matching the filters.") @@ -149,20 +165,28 @@ class Experiments: ): self._display_experiment_details(exp, i) - def _get_filtered_experiments(self, status_filter: str, model_filter: str, tag_filter: str): + def _get_filtered_experiments( + self, status_filter: str, model_filter: str, tag_filter: str + ): """Get experiments with applied filters""" experiments = self.experiment_tracker.list_experiments() # Apply filters if status_filter != "All": - experiments = [e for e in experiments if e.status == ExperimentStatus(status_filter)] + experiments = [ + e for e in experiments if e.status == ExperimentStatus(status_filter) + ] if model_filter != "All": - experiments = [e for e in experiments if e.config.model_type == model_filter] + experiments = [ + e for e in experiments if e.config.model_type == model_filter + ] if tag_filter: tags = [tag.strip() for tag in tag_filter.split(",")] - experiments = [e for e in experiments if any(tag in e.config.tags for tag in tags)] + experiments = [ + e for e in experiments if any(tag in e.config.tags for tag in tags) + ] return experiments @@ -173,7 +197,9 @@ class Experiments: with col1: st.write(f"**Model:** {exp.config.model_type}") - st.write(f"**Features:** {', '.join([f.value for f in exp.config.features])}") + st.write( + f"**Features:** {', '.join([f.value for f in exp.config.features])}" + ) st.write(f"**Tags:** {', '.join(exp.config.tags)}") with col2: @@ -185,7 +211,7 @@ class Experiments: st.write(f"**Train Size:** {exp.train_size:,}") st.write(f"**Test Size:** {exp.test_size:,}") - if st.button(f"View Details", key=f"details_{index}"): + if st.button("View Details", key=f"details_{index}"): st.session_state.selected_experiment = exp.experiment_id st.rerun() @@ -198,7 +224,9 @@ class Experiments: st.write("Run multiple experiments with different parameter combinations.") # Add option to run template batch experiments - batch_type = st.radio("Batch Type", ["Template Batch", "Custom Parameter Sweep"]) + batch_type = st.radio( + "Batch Type", ["Template Batch", "Custom Parameter Sweep"] + ) if batch_type == "Template Batch": self._show_template_batch_experiments() @@ -227,10 +255,13 @@ class Experiments: if experiments: st.write(f"**{exp_type.title()} Experiments:**") exp_names = [ - exp.get("name", f"Exp {i}") for i, exp in enumerate(experiments) + exp.get("name", f"Exp {i}") + for i, exp in enumerate(experiments) ] selected_names = st.multiselect( - f"Select {exp_type} experiments", exp_names, key=f"select_{exp_type}" + f"Select {exp_type} experiments", + exp_names, + key=f"select_{exp_type}", ) for name in selected_names: @@ -258,13 +289,17 @@ class Experiments: experiment_configs.append(config) # Run batch experiments - experiment_ids = self.experiment_runner.run_experiment_batch(experiment_configs) + experiment_ids = self.experiment_runner.run_experiment_batch( + experiment_configs + ) st.success(f"Completed {len(experiment_ids)} template experiments!") # Show summary if experiment_ids: - comparison = self.experiment_runner.compare_experiments(experiment_ids) + comparison = self.experiment_runner.compare_experiments( + experiment_ids + ) st.write("**Template Batch Results:**") st.dataframe( comparison[["name", "model_type", "test_accuracy"]], @@ -285,7 +320,9 @@ class Experiments: with col1: base_name = st.text_input("Base Experiment Name", "parameter_sweep") model_types = st.multiselect( - "Model Types", list_available_models(), default=["logistic_regression"] + "Model Types", + list_available_models(), + default=["logistic_regression"], ) # N-gram ranges for logistic regression @@ -301,13 +338,20 @@ class Experiments: default=["full_name", "native_name", "surname"], ) - test_sizes = st.text_input("Test Sizes (comma-separated)", "0.15,0.2,0.25") + test_sizes = st.text_input( + "Test Sizes (comma-separated)", "0.15,0.2,0.25" + ) tags = st.text_input("Common Tags", "parameter_sweep,batch") if st.form_submit_button("🚀 Run Parameter Sweep"): self.run_batch_experiments( - base_name, model_types, ngram_ranges, feature_combinations, test_sizes, tags + base_name, + model_types, + ngram_ranges, + feature_combinations, + test_sizes, + tags, ) def run_batch_experiments( @@ -369,13 +413,17 @@ class Experiments: exp_count += 1 # Run experiments - experiment_ids = self.experiment_runner.run_experiment_batch(experiments) + experiment_ids = self.experiment_runner.run_experiment_batch( + experiments + ) st.success(f"Completed {len(experiment_ids)} batch experiments") # Show summary if experiment_ids: - comparison = self.experiment_runner.compare_experiments(experiment_ids) + comparison = self.experiment_runner.compare_experiments( + experiment_ids + ) st.write("**Batch Results Summary:**") st.dataframe( comparison[["name", "model_type", "test_accuracy"]], diff --git a/src/ners/web/interfaces/log_reader.py b/src/ners/web/interfaces/log_reader.py new file mode 100644 index 0000000..dffc7bf --- /dev/null +++ b/src/ners/web/interfaces/log_reader.py @@ -0,0 +1,80 @@ +from __future__ import annotations + +from dataclasses import dataclass +from datetime import datetime +from pathlib import Path +from typing import List + + +@dataclass +class LogEntry: + timestamp: datetime + level: str + message: str + + +class LogReader: + def __init__(self, log_file_path: Path): + self.log_file_path = Path(log_file_path) + + def read_last_entries(self, num_entries: int = 20) -> List[LogEntry]: + entries = [] + if not self.log_file_path.exists(): + return entries + + with open(self.log_file_path, "r") as f: + lines = f.readlines()[-num_entries:] + + for line in lines: + entry = self._parse_log_line(line) + if entry: + entries.append(entry) + + return entries + + def read_entries_by_level( + self, level: str, num_entries: int = 20 + ) -> List[LogEntry]: + entries = [] + if not self.log_file_path.exists(): + return entries + + with open(self.log_file_path, "r") as f: + for line in reversed(f.readlines()): + entry = self._parse_log_line(line) + if entry and entry.level == level: + entries.append(entry) + if len(entries) >= num_entries: + break + + return list(reversed(entries)) + + def get_log_stats(self) -> dict: + if not self.log_file_path.exists(): + return {} + + stats = {"total_lines": 0} + with open(self.log_file_path, "r") as f: + for line in f: + stats["total_lines"] += 1 + entry = self._parse_log_line(line) + if entry: + stats[entry.level] = stats.get(entry.level, 0) + 1 + + return stats + + @staticmethod + def _parse_log_line(line: str) -> LogEntry | None: + try: + # Expected format from logging config: [timestamp] - LEVEL - message + parts = line.strip().split(" - ") + if len(parts) >= 3: + timestamp_str = parts[0].strip("[]") + timestamp = datetime.fromisoformat(timestamp_str) + level = parts[1].strip() + message = " - ".join(parts[2:]) + return LogEntry(timestamp, level, message) + except Exception: + return None + + return None diff --git a/web/interfaces/ner_testing.py b/src/ners/web/interfaces/ner_testing.py similarity index 83% rename from web/interfaces/ner_testing.py rename to src/ners/web/interfaces/ner_testing.py index f4984c2..102e68c 100644 --- a/web/interfaces/ner_testing.py +++ b/src/ners/web/interfaces/ner_testing.py @@ -1,10 +1,8 @@ -from pathlib import Path - import streamlit as st from spacy import displacy -from core.config import PipelineConfig -from processing.ner.name_model import NameModel +from ners.core.config import PipelineConfig +from ners.processing.ner.name_model import NameModel class NERTesting: @@ -56,12 +54,15 @@ class NERTesting: with col1: st.metric( - "Training Examples", f"{self.training_stats.get('training_examples', 0):,}" + "Training Examples", + f"{self.training_stats.get('training_examples', 0):,}", ) with col2: st.metric("Epochs", self.training_stats.get("epochs", 0)) with col3: - st.metric("Final Loss", f"{self.training_stats.get('final_loss', 0):.2f}") + st.metric( + "Final Loss", f"{self.training_stats.get('final_loss', 0):.2f}" + ) with col4: st.metric("Batch Size", f"{self.training_stats.get('batch_size', 0):,}") @@ -99,9 +100,11 @@ class NERTesting: if names_input.strip(): if st.button("Analyze All Names", type="primary"): - names = [name.strip() for name in names_input.split("\n") if name.strip()] + names = [ + name.strip() for name in names_input.split("\n") if name.strip() + ] for i, name in enumerate(names): - st.markdown(f"**Name {i+1}: {name}**") + st.markdown(f"**Name {i + 1}: {name}**") self.analyze_and_display(name) if i < len(names) - 1: st.markdown("---") @@ -127,7 +130,9 @@ class NERTesting: else: st.warning("No entities detected in the input text.") - st.info("Try using traditional Congolese names or ensure the spelling is correct.") + st.info( + "Try using traditional Congolese names or ensure the spelling is correct." + ) except Exception as e: st.error(f"Error analyzing text: {e}") @@ -139,14 +144,21 @@ class NERTesting: ents = [] for entity in entities: ents.append( - {"start": entity["start"], "end": entity["end"], "label": entity["label"]} + { + "start": entity["start"], + "end": entity["end"], + "label": entity["label"], + } ) # Create doc-like structure for displacy doc_data = {"text": text, "ents": ents, "title": None} # Custom colors for our labels - colors = {"NATIVE": "#74C0FC", "SURNAME": "#69DB7C"} # Light blue # Light green + colors = { + "NATIVE": "#74C0FC", + "SURNAME": "#69DB7C", + } # Light blue # Light green options = {"colors": colors, "distance": 90} diff --git a/src/ners/web/interfaces/predictions.py b/src/ners/web/interfaces/predictions.py new file mode 100644 index 0000000..685f59d --- /dev/null +++ b/src/ners/web/interfaces/predictions.py @@ -0,0 +1,215 @@ +from typing import Optional + +import numpy as np +import pandas as pd +import streamlit as st + +from ners.core.utils.data_loader import OPTIMIZED_DTYPES +from ners.research.experiment.experiment_runner import ExperimentRunner +from ners.research.experiment.experiment_tracker import ExperimentTracker + + +class Predictions: + def __init__( + self, + config, + experiment_tracker: ExperimentTracker, + experiment_runner: ExperimentRunner, + ): + self.config = config + self.experiment_tracker = experiment_tracker + self.experiment_runner = experiment_runner + + def index(self): + st.title("Predictions") + + # Load available models + experiments = self.experiment_tracker.list_experiments() + completed_experiments = [ + e for e in experiments if e.status.value == "completed" and e.model_path + ] + + if not completed_experiments: + st.warning( + "No trained models available. Please run some experiments first." + ) + return + + # Model selection + model_options = { + f"{exp.config.name} (Acc: {exp.test_metrics.get('accuracy', 0):.3f})": exp + for exp in completed_experiments + if exp.test_metrics + } + + selected_model_name = st.selectbox("Select Model", list(model_options.keys())) + + if not selected_model_name: + return + + selected_experiment = model_options[selected_model_name] + + # Prediction modes + prediction_mode = st.radio( + "Prediction Mode", ["Single Name", "Batch Upload", "Dataset Prediction"] + ) + + if prediction_mode == "Single Name": + self.show_single_prediction(selected_experiment) + elif prediction_mode == "Batch Upload": + self.show_batch_prediction(selected_experiment) + elif prediction_mode == "Dataset Prediction": + self.show_dataset_prediction(selected_experiment) + + def show_single_prediction(self, experiment): + """Show single name prediction interface""" + name_input = st.text_input( + "Enter a name:", placeholder="e.g., Jean Baptiste Mukendi" + ) + if name_input and st.button("Predict Gender"): + try: + # Load the model + model = self.experiment_runner.load_experiment_model( + experiment.experiment_id + ) + + if model is None: + st.error("Failed to load model") + return + + # Create a DataFrame with the input + input_df = self._prepare_single_input(name_input) + + # Make prediction + prediction = model.predict(input_df)[0] + + # Get prediction probability if available + confidence = self._get_prediction_confidence(model, input_df) + + # Display results + self._display_single_prediction_results( + prediction, confidence, experiment, name_input + ) + + except Exception as e: + st.error(f"Error making prediction: {e}") + + def _prepare_single_input(self, name_input: str) -> pd.DataFrame: + """Prepare single name input for prediction""" + return pd.DataFrame( + { + "name": [name_input], + "words": [len(name_input.split())], + "length": [len(name_input.replace(" ", ""))], + "province": ["unknown"], # Default values + "identified_name": [None], + "identified_surname": [None], + "probable_native": [None], + "probable_surname": [None], + } + ) + + def _get_prediction_confidence( + self, model, input_df: pd.DataFrame + ) -> Optional[float]: + """Get prediction confidence if available""" + try: + probabilities = model.predict_proba(input_df)[0] + return max(probabilities) + except: + return None + + def _display_single_prediction_results( + self, prediction: str, confidence: Optional[float], experiment, name_input: str + ): + """Display single prediction results""" + col1, col2 = st.columns(2) + + with col1: + gender_label = "Female" if prediction == "f" else "Male" + st.success(f"**Predicted Gender:** {gender_label}") + + with col2: + if confidence: + st.metric("Confidence", f"{confidence:.2%}") + + # Additional info + st.info(f"Model used: {experiment.config.name}") + st.info( + f"Features used: {', '.join([f.value for f in experiment.config.features])}" + ) + + def show_batch_prediction(self, experiment): + uploaded_file = st.file_uploader("Upload CSV file with names", type="csv") + if uploaded_file is not None: + try: + df = pd.read_csv(uploaded_file, dtype=OPTIMIZED_DTYPES) + + st.write("**Uploaded Data Preview:**") + st.dataframe(df.head(), use_container_width=True) + + # Column selection + df = self._prepare_batch_data(df) + + if st.button("Run Batch Prediction"): + self._run_batch_prediction(df, experiment) + + except Exception as e: + st.error(f"Error processing file: {e}") + + def _prepare_batch_data(self, df: pd.DataFrame) -> pd.DataFrame: + """Prepare batch data for prediction""" + # Column selection + if "name" not in df.columns: + name_column = st.selectbox("Select the name column:", df.columns) + df = df.rename(columns={name_column: "name"}) + + # Add missing columns with defaults + required_columns = [ + "words", + "length", + "province", + "identified_name", + "identified_surname", + "probable_native", + "probable_surname", + ] + + for col in required_columns: + if col not in df.columns: + if col == "words": + df[col] = df["name"].str.split().str.len() + elif col == "length": + df[col] = df["name"].str.replace(" ", "").str.len() + else: + df[col] = None + + return df + + def _run_batch_prediction(self, df: pd.DataFrame, experiment): + """Run batch prediction and display results""" + with st.spinner("Making predictions..."): + # Load model + model = self.experiment_runner.load_experiment_model( + experiment.experiment_id + ) + + if model is None: + st.error("Failed to load model") + return + + # Make predictions + predictions = model.predict(df) + df["predicted_gender"] = predictions + df["gender_label"] = df["predicted_gender"].map( + {"f": "Female", "m": "Male"} + ) + + # Try to get probabilities + try: + probabilities = model.predict_proba(df) + df["confidence"] = np.max(probabilities, axis=1) + except: + df["confidence"] = None + + st.success("Predictions completed!") diff --git a/web/interfaces/results_analysis.py b/src/ners/web/interfaces/results_analysis.py similarity index 57% rename from web/interfaces/results_analysis.py rename to src/ners/web/interfaces/results_analysis.py index aa3d52c..19bb2ec 100644 --- a/web/interfaces/results_analysis.py +++ b/src/ners/web/interfaces/results_analysis.py @@ -1,18 +1,20 @@ from typing import List -import numpy as np import pandas as pd import plotly.express as px import plotly.graph_objects as go import streamlit as st -from research.experiment.experiment_runner import ExperimentRunner -from research.experiment.experiment_tracker import ExperimentTracker +from ners.research.experiment.experiment_runner import ExperimentRunner +from ners.research.experiment.experiment_tracker import ExperimentTracker class ResultsAnalysis: def __init__( - self, config, experiment_tracker: ExperimentTracker, experiment_runner: ExperimentRunner + self, + config, + experiment_tracker: ExperimentTracker, + experiment_runner: ExperimentRunner, ): self.config = config self.experiment_tracker = experiment_tracker @@ -38,7 +40,9 @@ class ResultsAnalysis: st.subheader("Compare Experiments") experiments = self.experiment_tracker.list_experiments() - completed_experiments = [e for e in experiments if e.status.value == "completed"] + completed_experiments = [ + e for e in experiments if e.status.value == "completed" + ] if not completed_experiments: st.warning("No completed experiments found.") @@ -78,10 +82,14 @@ class ResultsAnalysis: # Select columns to display metric_columns = [ - col for col in comparison_df.columns if col.startswith("test_") or col.startswith("cv_") + col + for col in comparison_df.columns + if col.startswith("test_") or col.startswith("cv_") ] display_columns = ["name", "model_type", "features"] + metric_columns - available_columns = [col for col in display_columns if col in comparison_df.columns] + available_columns = [ + col for col in display_columns if col in comparison_df.columns + ] st.dataframe(comparison_df[available_columns], use_container_width=True) @@ -102,11 +110,15 @@ class ResultsAnalysis: # Metric comparison across multiple metrics metric_columns = [ - col for col in comparison_df.columns if col.startswith("test_") or col.startswith("cv_") + col + for col in comparison_df.columns + if col.startswith("test_") or col.startswith("cv_") ] if len(metric_columns) > 1: - metric_to_plot = st.selectbox("Select Metric for Detailed Comparison", metric_columns) + metric_to_plot = st.selectbox( + "Select Metric for Detailed Comparison", metric_columns + ) if metric_to_plot in comparison_df.columns: fig = px.bar( @@ -163,7 +175,10 @@ class ResultsAnalysis: with col1: # Accuracy vs Training Size - if "accuracy" in analysis_df.columns and "train_size" in analysis_df.columns: + if ( + "accuracy" in analysis_df.columns + and "train_size" in analysis_df.columns + ): fig = px.scatter( analysis_df, x="train_size", @@ -176,7 +191,10 @@ class ResultsAnalysis: with col2: # Feature Count vs Performance - if "accuracy" in analysis_df.columns and "feature_count" in analysis_df.columns: + if ( + "accuracy" in analysis_df.columns + and "feature_count" in analysis_df.columns + ): fig = px.scatter( analysis_df, x="feature_count", @@ -201,133 +219,65 @@ class ResultsAnalysis: go.Bar( x=model_performance["model_type"], y=model_performance["mean"], - error_y=dict(type="data", array=model_performance["std"]), - name="Average Accuracy", + error_y=dict(type="data", array=model_performance["std"].fillna(0)), + name="Accuracy", ) ) - fig.update_layout(title="Average Accuracy by Model Type", yaxis_title="Accuracy") + st.plotly_chart(fig, use_container_width=True) def _display_top_experiments(self, analysis_df: pd.DataFrame): - """Display top performing experiments""" - st.subheader("Top Performing Experiments") - + """Display top-performing experiments""" if "accuracy" in analysis_df.columns: - display_columns = ["name", "model_type", "features", "accuracy"] + top_n = st.slider("Select Top N Experiments", 3, 20, 5) + top_experiments = analysis_df.nlargest(top_n, "accuracy") - # Add other metrics if available - for metric in ["precision", "recall", "f1"]: - if metric in analysis_df.columns: - display_columns.append(metric) - - top_experiments = analysis_df.nlargest(5, "accuracy")[display_columns] - st.dataframe(top_experiments, use_container_width=True) + st.write("**Top Performing Experiments:**") + st.dataframe( + top_experiments[ + [ + "name", + "model_type", + "features", + "train_size", + "test_size", + "accuracy", + ] + ], + use_container_width=True, + ) def show_model_analysis(self): - """Show detailed model analysis""" + """Show detailed model analysis interface""" st.subheader("Model Analysis") experiments = self.experiment_tracker.list_experiments() - completed_experiments = [e for e in experiments if e.status.value == "completed"] + completed_experiments = [ + e for e in experiments if e.status.value == "completed" + ] if not completed_experiments: - st.warning("No completed experiments found.") + st.warning("No completed experiments found for analysis.") return - # Select experiment for detailed analysis + # Model selection exp_options = { - f"{exp.config.name} ({exp.experiment_id[:8]})": exp for exp in completed_experiments + f"{exp.config.name} ({exp.experiment_id[:8]})": exp.experiment_id + for exp in completed_experiments } - selected_exp_name = st.selectbox( - "Select Experiment for Detailed Analysis", list(exp_options.keys()) + "Select Model for Analysis", list(exp_options.keys()) ) - if not selected_exp_name: return - selected_exp = exp_options[selected_exp_name] + exp_id = exp_options[selected_exp_name] + experiment = self.experiment_tracker.get_experiment(exp_id) - self._display_experiment_details(selected_exp) - self._display_confusion_matrix(selected_exp) - self._display_feature_importance(selected_exp) - self._display_prediction_examples(selected_exp) + if not experiment or not experiment.test_metrics: + st.warning("Selected experiment has no evaluation metrics.") + return - def _display_experiment_details(self, experiment): - """Display experiment configuration and metrics""" - col1, col2 = st.columns(2) - - with col1: - st.write("**Experiment Configuration**") - st.json( - { - "name": experiment.config.name, - "model_type": experiment.config.model_type, - "features": [f.value for f in experiment.config.features], - "model_params": experiment.config.model_params, - } - ) - - with col2: - st.write("**Performance Metrics**") - if experiment.test_metrics: - for metric, value in experiment.test_metrics.items(): - st.metric(metric.title(), f"{value:.4f}") - - def _display_confusion_matrix(self, experiment): - """Display confusion matrix if available""" - if experiment.confusion_matrix: - st.write("**Confusion Matrix**") - cm = np.array(experiment.confusion_matrix) - - fig = px.imshow(cm, text_auto=True, aspect="auto", title="Confusion Matrix") - st.plotly_chart(fig, use_container_width=True) - - def _display_feature_importance(self, experiment): - """Display feature importance if available""" - if experiment.feature_importance: - st.write("**Feature Importance**") - - importance_data = sorted( - experiment.feature_importance.items(), key=lambda x: x[1], reverse=True - )[:20] - - features, importances = zip(*importance_data) - - fig = px.bar( - x=list(importances), - y=list(features), - orientation="h", - title="Top 20 Feature Importances", - ) - fig.update_layout(height=600) - st.plotly_chart(fig, use_container_width=True) - - def _display_prediction_examples(self, experiment): - """Display prediction examples if available""" - if experiment.prediction_examples: - st.write("**Prediction Examples**") - - examples_df = pd.DataFrame(experiment.prediction_examples) - - # Separate correct and incorrect predictions - correct_examples = examples_df[examples_df["correct"] == True] - incorrect_examples = examples_df[examples_df["correct"] == False] - - col1, col2 = st.columns(2) - - with col1: - st.write("**Correct Predictions**") - if not correct_examples.empty: - st.dataframe( - correct_examples[["name", "true_label", "predicted_label"]], - use_container_width=True, - ) - - with col2: - st.write("**Incorrect Predictions**") - if not incorrect_examples.empty: - st.dataframe( - incorrect_examples[["name", "true_label", "predicted_label"]], - use_container_width=True, - ) + # Display detailed metrics + st.write("**Detailed Metrics:**") + st.json(experiment.test_metrics) diff --git a/web/pages/1_📊_Dashboard.py b/src/ners/web/pages/1_📊_Dashboard.py similarity index 67% rename from web/pages/1_📊_Dashboard.py rename to src/ners/web/pages/1_📊_Dashboard.py index f3b3f34..b256f03 100644 --- a/web/pages/1_📊_Dashboard.py +++ b/src/ners/web/pages/1_📊_Dashboard.py @@ -1,13 +1,6 @@ -import sys -from pathlib import Path - import streamlit as st -# Add parent directory to Python path to access core modules -parent_dir = Path(__file__).parent.parent.parent -sys.path.insert(0, str(parent_dir)) - -from web.interfaces.dashboard import Dashboard +from ners.web.interfaces.dashboard import Dashboard st.set_page_config(page_title="Dashboard", page_icon="📊", layout="wide") diff --git a/web/pages/2_📋_Data_Overview.py b/src/ners/web/pages/2_📋_Data_Overview.py similarity index 61% rename from web/pages/2_📋_Data_Overview.py rename to src/ners/web/pages/2_📋_Data_Overview.py index aae723c..12c00a7 100644 --- a/web/pages/2_📋_Data_Overview.py +++ b/src/ners/web/pages/2_📋_Data_Overview.py @@ -1,13 +1,6 @@ -import sys -from pathlib import Path - import streamlit as st -# Add parent directory to Python path to access core modules -parent_dir = Path(__file__).parent.parent.parent -sys.path.insert(0, str(parent_dir)) - -from web.interfaces.data_overview import DataOverview +from ners.web.interfaces.data_overview import DataOverview st.set_page_config(page_title="Data Overview", page_icon="📋", layout="wide") diff --git a/src/ners/web/pages/3_⚙️_Data_Processing.py b/src/ners/web/pages/3_⚙️_Data_Processing.py new file mode 100644 index 0000000..6fa4d34 --- /dev/null +++ b/src/ners/web/pages/3_⚙️_Data_Processing.py @@ -0,0 +1,14 @@ +import streamlit as st + +from ners.web.interfaces.data_processing import DataProcessing + +st.set_page_config(page_title="Data Processing", page_icon="⚙️", layout="wide") + +if "config" in st.session_state: + data_processing = DataProcessing( + st.session_state.config, st.session_state.pipeline_monitor + ) + data_processing.index() +else: + st.error("Please run the main app first to initialize the configuration.") + st.markdown("Go back to the [main page](/) to start the application.") diff --git a/web/pages/4_🧪_Experiments.py b/src/ners/web/pages/4_🧪_Experiments.py similarity index 67% rename from web/pages/4_🧪_Experiments.py rename to src/ners/web/pages/4_🧪_Experiments.py index 29bb680..de5df32 100644 --- a/web/pages/4_🧪_Experiments.py +++ b/src/ners/web/pages/4_🧪_Experiments.py @@ -1,13 +1,6 @@ -import sys -from pathlib import Path - import streamlit as st -# Add parent directory to Python path to access core modules -parent_dir = Path(__file__).parent.parent.parent -sys.path.insert(0, str(parent_dir)) - -from web.interfaces.experiments import Experiments +from ners.web.interfaces.experiments import Experiments st.set_page_config(page_title="Experiments", page_icon="🧪", layout="wide") diff --git a/web/pages/5_📈_Results_Analysis.py b/src/ners/web/pages/5_📈_Results_Analysis.py similarity index 67% rename from web/pages/5_📈_Results_Analysis.py rename to src/ners/web/pages/5_📈_Results_Analysis.py index 04525ee..5febe8b 100644 --- a/web/pages/5_📈_Results_Analysis.py +++ b/src/ners/web/pages/5_📈_Results_Analysis.py @@ -1,13 +1,6 @@ -import sys -from pathlib import Path - import streamlit as st -# Add parent directory to Python path to access core modules -parent_dir = Path(__file__).parent.parent.parent -sys.path.insert(0, str(parent_dir)) - -from web.interfaces.results_analysis import ResultsAnalysis +from ners.web.interfaces.results_analysis import ResultsAnalysis st.set_page_config(page_title="Results & Analysis", page_icon="📈", layout="wide") diff --git a/web/pages/6_🔮_Predictions.py b/src/ners/web/pages/6_🔮_Predictions.py similarity index 67% rename from web/pages/6_🔮_Predictions.py rename to src/ners/web/pages/6_🔮_Predictions.py index b414613..636c535 100644 --- a/web/pages/6_🔮_Predictions.py +++ b/src/ners/web/pages/6_🔮_Predictions.py @@ -1,13 +1,6 @@ -import sys -from pathlib import Path - import streamlit as st -# Add parent directory to Python path to access core modules -parent_dir = Path(__file__).parent.parent.parent -sys.path.insert(0, str(parent_dir)) - -from web.interfaces.predictions import Predictions +from ners.web.interfaces.predictions import Predictions st.set_page_config(page_title="Predictions", page_icon="🔮", layout="wide") diff --git a/web/pages/7_⚙️_Configuration.py b/src/ners/web/pages/7_⚙️_Configuration.py similarity index 61% rename from web/pages/7_⚙️_Configuration.py rename to src/ners/web/pages/7_⚙️_Configuration.py index c5e0e47..ff2c249 100644 --- a/web/pages/7_⚙️_Configuration.py +++ b/src/ners/web/pages/7_⚙️_Configuration.py @@ -1,13 +1,6 @@ -import sys -from pathlib import Path - import streamlit as st -# Add parent directory to Python path to access core modules -parent_dir = Path(__file__).parent.parent.parent -sys.path.insert(0, str(parent_dir)) - -from web.interfaces.configuration import Configuration +from ners.web.interfaces.configuration import Configuration st.set_page_config(page_title="Configuration", page_icon="⚙️", layout="wide") diff --git a/web/pages/8_🏷️_NER_Testing.py b/src/ners/web/pages/8_🏷️_NER_Testing.py similarity index 61% rename from web/pages/8_🏷️_NER_Testing.py rename to src/ners/web/pages/8_🏷️_NER_Testing.py index 1f9eab0..1430879 100644 --- a/web/pages/8_🏷️_NER_Testing.py +++ b/src/ners/web/pages/8_🏷️_NER_Testing.py @@ -1,13 +1,6 @@ -import sys -from pathlib import Path - import streamlit as st -# Add parent directory to Python path to access core modules -parent_dir = Path(__file__).parent.parent.parent -sys.path.insert(0, str(parent_dir)) - -from web.interfaces.ner_testing import NERTesting +from ners.web.interfaces.ner_testing import NERTesting st.set_page_config(page_title="NER Testing", page_icon="🏷️", layout="wide") diff --git a/notebooks/eda.ipynb b/src/notebooks/eda.ipynb similarity index 99% rename from notebooks/eda.ipynb rename to src/notebooks/eda.ipynb index cd049c8..9f7e652 100644 --- a/notebooks/eda.ipynb +++ b/src/notebooks/eda.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "id": "c93a55c8", "metadata": { "ExecuteTime": { @@ -20,8 +20,8 @@ "import os\n", "\n", "sys.path.append(os.path.abspath(\"..\"))\n", - "from core.utils.data_loader import DataLoader\n", - "from core.config.pipeline_config import PipelineConfig" + "from ners.core.utils.data_loader import DataLoader\n", + "from ners.core.config.pipeline_config import PipelineConfig" ] }, { @@ -44,7 +44,7 @@ " \"outputs_dir\": \"../data/processed\",\n", " \"logs_dir\": \"../logs\",\n", " \"configs_dir\": \"../configs\",\n", - " \"checkpoints_dir\": \"../checkpoints\"\n", + " \"checkpoints_dir\": \"../checkpoints\",\n", " }\n", ")\n", "\n", @@ -65,7 +65,7 @@ "source": [ "gdf = gpd.read_file(\"../osm/provinces.shp\")\n", "gdf_proj = gdf.to_crs(epsg=32732)\n", - "gdf['centroid'] = gdf_proj.geometry.centroid.to_crs(gdf.crs)\n", + "gdf[\"centroid\"] = gdf_proj.geometry.centroid.to_crs(gdf.crs)\n", "\n", "df = loader.load_csv_complete(config.paths.data_dir / \"names_featured.csv\")" ] @@ -92,25 +92,31 @@ "source": [ "import unicodedata\n", "\n", + "\n", "# Helper function for cleaning province names\n", "def clean_province(s):\n", " return (\n", " s.str.upper()\n", " .str.strip()\n", - " .apply(lambda x: unicodedata.normalize(\"NFKD\", x)\n", - " .encode(\"ascii\", errors=\"ignore\")\n", - " .decode(\"utf-8\") if isinstance(x, str) else x)\n", + " .apply(\n", + " lambda x: unicodedata.normalize(\"NFKD\", x)\n", + " .encode(\"ascii\", errors=\"ignore\")\n", + " .decode(\"utf-8\")\n", + " if isinstance(x, str)\n", + " else x\n", + " )\n", " )\n", "\n", + "\n", "# Apply to both DataFrames\n", - "df['province'] = clean_province(df['province'])\n", - "gdf['province'] = clean_province(gdf['name'])\n", + "df[\"province\"] = clean_province(df[\"province\"])\n", + "gdf[\"province\"] = clean_province(gdf[\"name\"])\n", "\n", "# Group and merge\n", - "counts = df['province'].value_counts().reset_index()\n", - "counts.columns = ['province', 'count']\n", + "counts = df[\"province\"].value_counts().reset_index()\n", + "counts.columns = [\"province\", \"count\"]\n", "\n", - "gdf = gdf.merge(counts, left_on='province', right_on='province', how='left')\n" + "gdf = gdf.merge(counts, left_on=\"province\", right_on=\"province\", how=\"left\")" ] }, { @@ -325,9 +331,6 @@ "
" ] }, - "jetTransient": { - "display_id": null - }, "metadata": {}, "output_type": "display_data" } @@ -335,18 +338,20 @@ "source": [ "fig, ax = plt.subplots(figsize=(10, 10))\n", "\n", - "gdf.plot(column='count', cmap='Blues', edgecolor='black', legend=True, ax=ax)\n", - "labels = gdf.loc[gdf['count'].notna(), ['province', 'centroid']]\n", + "gdf.plot(column=\"count\", cmap=\"Blues\", edgecolor=\"black\", legend=True, ax=ax)\n", + "labels = gdf.loc[gdf[\"count\"].notna(), [\"province\", \"centroid\"]]\n", "\n", "for _, row in labels.iterrows():\n", " ax.annotate(\n", - " text=row['province'],\n", - " xy=(row['centroid'].x, row['centroid'].y),\n", - " ha='center', va='center',\n", - " fontsize=8, color='black'\n", + " text=row[\"province\"],\n", + " xy=(row[\"centroid\"].x, row[\"centroid\"].y),\n", + " ha=\"center\",\n", + " va=\"center\",\n", + " fontsize=8,\n", + " color=\"black\",\n", " )\n", "\n", - "ax.axis('off')\n", + "ax.axis(\"off\")\n", "plt.show()" ] }, @@ -376,18 +381,15 @@ "
" ] }, - "jetTransient": { - "display_id": null - }, "metadata": {}, "output_type": "display_data" } ], "source": [ - "provinces = df['province'].value_counts()\n", + "provinces = df[\"province\"].value_counts()\n", "plt.figure(figsize=(7, 7))\n", - "plt.pie(provinces, labels=provinces.index, autopct='%1.1f%%', startangle=140)\n", - "plt.axis('equal')\n", + "plt.pie(provinces, labels=provinces.index, autopct=\"%1.1f%%\", startangle=140)\n", + "plt.axis(\"equal\")\n", "plt.show()" ] }, @@ -409,16 +411,13 @@ "
" ] }, - "jetTransient": { - "display_id": null - }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.figure(figsize=(10, 5))\n", - "provinces.plot(kind='bar', color='skyblue')\n", + "provinces.plot(kind=\"bar\", color=\"skyblue\")\n", "plt.xlabel(\"Province\")\n", "plt.ylabel(\"Count\")\n", "plt.xticks(rotation=45)\n", @@ -444,20 +443,17 @@ "
" ] }, - "jetTransient": { - "display_id": null - }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.show()\n", - "data = df.groupby(['province', 'sex'], observed=False).size().reset_index(name='count')\n", - "data = data.sort_values('count', ascending=False).drop_duplicates(['province', 'sex'])\n", + "data = df.groupby([\"province\", \"sex\"], observed=False).size().reset_index(name=\"count\")\n", + "data = data.sort_values(\"count\", ascending=False).drop_duplicates([\"province\", \"sex\"])\n", "\n", "plt.figure(figsize=(12, 6))\n", - "sns.barplot(data=data, x='province', y='count', hue='sex')\n", + "sns.barplot(data=data, x=\"province\", y=\"count\", hue=\"sex\")\n", "\n", "plt.xlabel(\"Region\")\n", "plt.ylabel(\"Count\")\n", @@ -485,18 +481,15 @@ "
" ] }, - "jetTransient": { - "display_id": null - }, "metadata": {}, "output_type": "display_data" } ], "source": [ - "sex = df['sex'].value_counts()\n", + "sex = df[\"sex\"].value_counts()\n", "plt.figure(figsize=(7, 7))\n", - "plt.pie(sex, labels=sex.index, autopct='%1.1f%%', startangle=140)\n", - "plt.axis('equal')\n", + "plt.pie(sex, labels=sex.index, autopct=\"%1.1f%%\", startangle=140)\n", + "plt.axis(\"equal\")\n", "plt.show()" ] }, @@ -518,26 +511,25 @@ "
" ] }, - "jetTransient": { - "display_id": null - }, "metadata": {}, "output_type": "display_data" } ], "source": [ - "df_provinces_sex_counts = df.groupby(['province', 'sex'], observed=False).size().reset_index(name='count')\n", - "provinces = df_provinces_sex_counts['province'].unique()\n", + "df_provinces_sex_counts = (\n", + " df.groupby([\"province\", \"sex\"], observed=False).size().reset_index(name=\"count\")\n", + ")\n", + "provinces = df_provinces_sex_counts[\"province\"].unique()\n", "cols = 3\n", "rows = (len(provinces) + cols - 1) // cols\n", "\n", "plt.figure(figsize=(cols * 5, rows * 5))\n", "for i, province in enumerate(provinces, 1):\n", - " data = df_provinces_sex_counts[df_provinces_sex_counts['province'] == province]\n", + " data = df_provinces_sex_counts[df_provinces_sex_counts[\"province\"] == province]\n", " plt.subplot(rows, cols, i)\n", - " plt.pie(data['count'], labels=data['sex'], autopct='%1.1f%%')\n", + " plt.pie(data[\"count\"], labels=data[\"sex\"], autopct=\"%1.1f%%\")\n", " plt.title(province)\n", - " plt.axis('equal')\n", + " plt.axis(\"equal\")\n", "\n", "plt.tight_layout()\n", "plt.show()" @@ -644,16 +636,18 @@ } ], "source": [ - "#breakdown of names into surname, middle name and first name\n", - "#retrieve all rows whose name is identified as simple, and delete rows whose identified_name is null or empty\n", + "# breakdown of names into surname, middle name and first name\n", + "# retrieve all rows whose name is identified as simple, and delete rows whose identified_name is null or empty\n", "\n", - "df_simple = df[df['identified_category'] == 'simple'].copy()\n", - "df_simple['surname'] = df_simple['identified_name'].str.split().str[0]\n", - "df_simple['middle_name'] = df_simple['identified_name'].str.split().str[1]\n", - "df_simple['first_name'] = df_simple['identified_surname']\n", - "df_simple = df_simple[df_simple['first_name'].notna() & (df_simple['first_name'].str.strip() != '')]\n", + "df_simple = df[df[\"identified_category\"] == \"simple\"].copy()\n", + "df_simple[\"surname\"] = df_simple[\"identified_name\"].str.split().str[0]\n", + "df_simple[\"middle_name\"] = df_simple[\"identified_name\"].str.split().str[1]\n", + "df_simple[\"first_name\"] = df_simple[\"identified_surname\"]\n", + "df_simple = df_simple[\n", + " df_simple[\"first_name\"].notna() & (df_simple[\"first_name\"].str.strip() != \"\")\n", + "]\n", "\n", - "df_simple[['name', 'surname', 'middle_name', 'first_name']].head()" + "df_simple[[\"name\", \"surname\", \"middle_name\", \"first_name\"]].head()" ] }, { @@ -680,7 +674,10 @@ ], "source": [ "# Simple distribution of first names (display of the 10 most popular first names)\n", - "sns.countplot(y=df_simple['first_name'], order=df_simple['first_name'].value_counts().iloc[:10].index)\n", + "sns.countplot(\n", + " y=df_simple[\"first_name\"],\n", + " order=df_simple[\"first_name\"].value_counts().iloc[:10].index,\n", + ")\n", "plt.title(\"Top 10 first names (simple names only)\")\n", "plt.xlabel(\"Count\")\n", "plt.ylabel(\"First name\")\n", @@ -799,9 +796,9 @@ } ], "source": [ - "firstnames = df_simple['first_name'].value_counts()\n", + "firstnames = df_simple[\"first_name\"].value_counts()\n", "df_firstnames = firstnames.reset_index()\n", - "df_firstnames.columns = ['First name', 'quantity']\n", + "df_firstnames.columns = [\"First name\", \"quantity\"]\n", "df_firstnames.head(10)" ] }, @@ -823,26 +820,37 @@ } ], "source": [ - "#Most common first name by province\n", - "top_names = df_simple.groupby(['province_clean', 'first_name']).size().reset_index(name='count')\n", - "top_names = top_names.sort_values(['province_clean', 'count'], ascending=[True, False])\n", - "top_names = top_names.drop_duplicates(subset='province_clean', keep='first')\n", - "gdf_named = gdf_merged.merge(top_names[['province_clean', 'first_name']], \n", - " left_on='province_upper', right_on='province_clean', \n", - " how='left')\n", + "# Most common first name by province\n", + "top_names = (\n", + " df_simple.groupby([\"province_clean\", \"first_name\"]).size().reset_index(name=\"count\")\n", + ")\n", + "top_names = top_names.sort_values([\"province_clean\", \"count\"], ascending=[True, False])\n", + "top_names = top_names.drop_duplicates(subset=\"province_clean\", keep=\"first\")\n", + "gdf_named = gdf_merged.merge(\n", + " top_names[[\"province_clean\", \"first_name\"]],\n", + " left_on=\"province_upper\",\n", + " right_on=\"province_clean\",\n", + " how=\"left\",\n", + ")\n", "\n", "fig, ax = plt.subplots(figsize=(12, 12))\n", - "gdf_named.plot(column='count', cmap='Blues', edgecolor='black', legend=True, ax=ax)\n", + "gdf_named.plot(column=\"count\", cmap=\"Blues\", edgecolor=\"black\", legend=True, ax=ax)\n", "\n", "for idx, row in gdf_named.iterrows():\n", - " if pd.notna(row['first_name']):\n", - " centroid = row['geometry'].centroid\n", + " if pd.notna(row[\"first_name\"]):\n", + " centroid = row[\"geometry\"].centroid\n", " label = f\"{row['first_name']}\"\n", - " plt.text(centroid.x, centroid.y, label, \n", - " horizontalalignment='center', fontsize=8, color='black')\n", + " plt.text(\n", + " centroid.x,\n", + " centroid.y,\n", + " label,\n", + " horizontalalignment=\"center\",\n", + " fontsize=8,\n", + " color=\"black\",\n", + " )\n", "\n", "plt.title(\"Most common first name by province\")\n", - "plt.axis('off')\n", + "plt.axis(\"off\")\n", "plt.show()" ] }, @@ -870,17 +878,25 @@ ], "source": [ "# Total number of distinct first names\n", - "total_firstnames = df_simple['first_name'].notna().sum()\n", + "total_firstnames = df_simple[\"first_name\"].notna().sum()\n", "print(f\">> Total number of first names registered : {total_firstnames}\")\n", "\n", "# categorization of first names\n", - "firstnames_by_sex = df_simple.groupby(['first_name', 'sex']).size().unstack(fill_value=0)\n", - "male_firstnames = firstnames_by_sex[(firstnames_by_sex['m'] > 0) & (firstnames_by_sex['f'] == 0)]\n", + "firstnames_by_sex = (\n", + " df_simple.groupby([\"first_name\", \"sex\"]).size().unstack(fill_value=0)\n", + ")\n", + "male_firstnames = firstnames_by_sex[\n", + " (firstnames_by_sex[\"m\"] > 0) & (firstnames_by_sex[\"f\"] == 0)\n", + "]\n", "print(f\">> Number of all-male first names : {len(male_firstnames)}\")\n", - "female_firstnames = firstnames_by_sex[(firstnames_by_sex['f'] > 0) & (firstnames_by_sex['m'] == 0)]\n", + "female_firstnames = firstnames_by_sex[\n", + " (firstnames_by_sex[\"f\"] > 0) & (firstnames_by_sex[\"m\"] == 0)\n", + "]\n", "print(f\">> Number of all-female first names : {len(female_firstnames)}\")\n", - "neutral_firstnames = firstnames_by_sex[(firstnames_by_sex['m'] > 0) & (firstnames_by_sex['f'] > 0)]\n", - "print(f\">> Number of all-neutral first names : {len(neutral_firstnames)}\")\n" + "neutral_firstnames = firstnames_by_sex[\n", + " (firstnames_by_sex[\"m\"] > 0) & (firstnames_by_sex[\"f\"] > 0)\n", + "]\n", + "print(f\">> Number of all-neutral first names : {len(neutral_firstnames)}\")" ] }, { @@ -906,15 +922,21 @@ } ], "source": [ - "# data for graphic interpretation \n", - "labels = ['Male', 'Female', 'Neutral']\n", + "# data for graphic interpretation\n", + "labels = [\"Male\", \"Female\", \"Neutral\"]\n", "values = [len(male_firstnames), len(female_firstnames), len(neutral_firstnames)]\n", "\n", "# circular\n", - "plt.figure(figsize=(6,6))\n", - "plt.pie(values, labels=labels, autopct='%1.1f%%', startangle=140, colors=['skyblue', 'lightgreen', 'lightgray'])\n", + "plt.figure(figsize=(6, 6))\n", + "plt.pie(\n", + " values,\n", + " labels=labels,\n", + " autopct=\"%1.1f%%\",\n", + " startangle=140,\n", + " colors=[\"skyblue\", \"lightgreen\", \"lightgray\"],\n", + ")\n", "plt.title(\"Distribution of first names by sex\")\n", - "plt.axis('equal')\n", + "plt.axis(\"equal\")\n", "plt.show()" ] }, @@ -937,31 +959,42 @@ ], "source": [ "# Assign first name sex category\n", - "df_simple['first_name_sex_category'] = df_simple['first_name'].map(\n", - " lambda x: 'Male' if x in male_firstnames else (\n", - " 'Female' if x in female_firstnames else (\n", - " 'Neutral' if x in neutral_firstnames else None\n", - " )\n", + "df_simple[\"first_name_sex_category\"] = df_simple[\"first_name\"].map(\n", + " lambda x: \"Male\"\n", + " if x in male_firstnames\n", + " else (\n", + " \"Female\"\n", + " if x in female_firstnames\n", + " else (\"Neutral\" if x in neutral_firstnames else None)\n", " )\n", ")\n", "\n", - "df_cat = df_simple.dropna(subset=['first_name_sex_category'])\n", - "category_counts = df_cat.groupby(['province_clean', 'first_name_sex_category']).size().unstack(fill_value=0)\n", - "category_counts['dominant_category'] = category_counts.idxmax(axis=1)\n", - "map_df = gdf.set_index('province_upper').join(category_counts['dominant_category'])\n", + "df_cat = df_simple.dropna(subset=[\"first_name_sex_category\"])\n", + "category_counts = (\n", + " df_cat.groupby([\"province_clean\", \"first_name_sex_category\"])\n", + " .size()\n", + " .unstack(fill_value=0)\n", + ")\n", + "category_counts[\"dominant_category\"] = category_counts.idxmax(axis=1)\n", + "map_df = gdf.set_index(\"province_upper\").join(category_counts[\"dominant_category\"])\n", "\n", - "color_map = {'Male': 'skyblue', 'Female': 'lightgreen', 'Neutral': 'lightgray'}\n", - "map_df['color'] = map_df['dominant_category'].map(color_map)\n", + "color_map = {\"Male\": \"skyblue\", \"Female\": \"lightgreen\", \"Neutral\": \"lightgray\"}\n", + "map_df[\"color\"] = map_df[\"dominant_category\"].map(color_map)\n", "\n", "fig, ax = plt.subplots(1, 1, figsize=(10, 8))\n", - "map_df.plot(color=map_df['color'], edgecolor='black', ax=ax)\n", + "map_df.plot(color=map_df[\"color\"], edgecolor=\"black\", ax=ax)\n", "for idx, row in map_df.iterrows():\n", - " plt.annotate(text=row['dominant_category'], xy=(row.geometry.centroid.x, row.geometry.centroid.y),\n", - " horizontalalignment='center', fontsize=8, color='black')\n", + " plt.annotate(\n", + " text=row[\"dominant_category\"],\n", + " xy=(row.geometry.centroid.x, row.geometry.centroid.y),\n", + " horizontalalignment=\"center\",\n", + " fontsize=8,\n", + " color=\"black\",\n", + " )\n", "\n", "plt.title(\"Dominant first name category by province\")\n", - "plt.axis('off')\n", - "plt.show()\n" + "plt.axis(\"off\")\n", + "plt.show()" ] }, { @@ -983,8 +1016,8 @@ ], "source": [ "# Histogram\n", - "plt.figure(figsize=(6,4))\n", - "plt.bar(labels, values, color=['skyblue', 'lightpink', 'lightgray'])\n", + "plt.figure(figsize=(6, 4))\n", + "plt.bar(labels, values, color=[\"skyblue\", \"lightpink\", \"lightgray\"])\n", "plt.title(\"Distribution of first names by sex\")\n", "plt.ylabel(\"Number of first names\")\n", "plt.show()" @@ -1117,14 +1150,16 @@ ], "source": [ "# Count of unique first names per region (province)\n", - "distinct_regions = df_simple['province'].nunique()\n", + "distinct_regions = df_simple[\"province\"].nunique()\n", "print(f\">> Number of distinct regions: {distinct_regions}\")\n", - "firstnames_by_region = df_simple.groupby('province')['first_name'].nunique().sort_values(ascending=False)\n", + "firstnames_by_region = (\n", + " df_simple.groupby(\"province\")[\"first_name\"].nunique().sort_values(ascending=False)\n", + ")\n", "\n", "print(\"Number of unique first names per region\")\n", "df_firstnames_region = firstnames_by_region.reset_index()\n", - "df_firstnames_region.columns = ['Region', 'Unique first names']\n", - "df_firstnames_region.head(12)\n" + "df_firstnames_region.columns = [\"Region\", \"Unique first names\"]\n", + "df_firstnames_region.head(12)" ] }, { @@ -1145,21 +1180,43 @@ } ], "source": [ - "unique_first_names = df_simple.groupby('province')['first_name'].nunique().reset_index(name='unique_count')\n", - "unique_first_names['province_clean'] = unique_first_names['province'].str.upper().str.strip() \\\n", - " .str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8')\n", - "gdf_diversity = gdf_merged.merge(unique_first_names[['province_clean', 'unique_count']], on='province_clean', how='left')\n", + "unique_first_names = (\n", + " df_simple.groupby(\"province\")[\"first_name\"]\n", + " .nunique()\n", + " .reset_index(name=\"unique_count\")\n", + ")\n", + "unique_first_names[\"province_clean\"] = (\n", + " unique_first_names[\"province\"]\n", + " .str.upper()\n", + " .str.strip()\n", + " .str.normalize(\"NFKD\")\n", + " .str.encode(\"ascii\", errors=\"ignore\")\n", + " .str.decode(\"utf-8\")\n", + ")\n", + "gdf_diversity = gdf_merged.merge(\n", + " unique_first_names[[\"province_clean\", \"unique_count\"]],\n", + " on=\"province_clean\",\n", + " how=\"left\",\n", + ")\n", "\n", "fig, ax = plt.subplots(figsize=(10, 10))\n", - "gdf_diversity.plot(column='unique_count', cmap='viridis', edgecolor='black', legend=True, ax=ax)\n", + "gdf_diversity.plot(\n", + " column=\"unique_count\", cmap=\"viridis\", edgecolor=\"black\", legend=True, ax=ax\n", + ")\n", "\n", "for idx, row in gdf_diversity.iterrows():\n", - " centroid = row['geometry'].centroid\n", - " plt.text(centroid.x, centroid.y, row['province_upper'], \n", - " horizontalalignment='center', fontsize=8, color='black')\n", + " centroid = row[\"geometry\"].centroid\n", + " plt.text(\n", + " centroid.x,\n", + " centroid.y,\n", + " row[\"province_upper\"],\n", + " horizontalalignment=\"center\",\n", + " fontsize=8,\n", + " color=\"black\",\n", + " )\n", "\n", "plt.title(\"First name diversity by province\")\n", - "plt.axis('off')\n", + "plt.axis(\"off\")\n", "plt.show()" ] }, @@ -1238,15 +1295,15 @@ ], "source": [ "# top 3 most popular first names by region\n", - "grouped = df_simple.groupby(['province', 'first_name']).size().reset_index(name='count')\n", - "grouped = grouped.sort_values(['province', 'count'], ascending=[True, False])\n", - "top3_by_region = grouped.groupby('province').head(3)\n", + "grouped = df_simple.groupby([\"province\", \"first_name\"]).size().reset_index(name=\"count\")\n", + "grouped = grouped.sort_values([\"province\", \"count\"], ascending=[True, False])\n", + "top3_by_region = grouped.groupby(\"province\").head(3)\n", "\n", - "for province, group in top3_by_region.groupby('province'):\n", + "for province, group in top3_by_region.groupby(\"province\"):\n", " print(f\"{province.upper()}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['first_name']:<15} {row['count']}\")\n", - " print()\n" + " print()" ] }, { @@ -1430,20 +1487,27 @@ } ], "source": [ - "#Group by region, gender and first name, then count\n", + "# Group by region, gender and first name, then count\n", "def determine_sex_category(row):\n", - " if row['first_name'] in neutral_firstnames:\n", - " return 'Neutral'\n", - " return row['sex']\n", + " if row[\"first_name\"] in neutral_firstnames:\n", + " return \"Neutral\"\n", + " return row[\"sex\"]\n", "\n", - "df_simple['sex_category'] = df_simple.apply(determine_sex_category, axis=1)\n", + "\n", + "df_simple[\"sex_category\"] = df_simple.apply(determine_sex_category, axis=1)\n", "\n", "# Groupement\n", - "grouped = df_simple.groupby(['province', 'sex_category', 'first_name']).size().reset_index(name='count')\n", - "grouped = grouped.sort_values(['province', 'sex_category', 'count'], ascending=[True, True, False])\n", - "top3_by_region_sex = grouped.groupby(['province', 'sex_category']).head(3)\n", + "grouped = (\n", + " df_simple.groupby([\"province\", \"sex_category\", \"first_name\"])\n", + " .size()\n", + " .reset_index(name=\"count\")\n", + ")\n", + "grouped = grouped.sort_values(\n", + " [\"province\", \"sex_category\", \"count\"], ascending=[True, True, False]\n", + ")\n", + "top3_by_region_sex = grouped.groupby([\"province\", \"sex_category\"]).head(3)\n", "\n", - "for (province, sex), group in top3_by_region_sex.groupby(['province', 'sex_category']):\n", + "for (province, sex), group in top3_by_region_sex.groupby([\"province\", \"sex_category\"]):\n", " print(f\"{province.upper()} - {sex}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['first_name']:<15} {row['count']}\")\n", @@ -1489,11 +1553,11 @@ ], "source": [ "# Grouping surnames by sex\n", - "surnames_by_sex = df_simple.groupby(['surname', 'sex']).size().reset_index(name='count')\n", - "surnames_by_sex = surnames_by_sex.sort_values(['sex', 'count'], ascending=[True, False])\n", - "top10_per_sex = surnames_by_sex.groupby('sex').head(10)\n", + "surnames_by_sex = df_simple.groupby([\"surname\", \"sex\"]).size().reset_index(name=\"count\")\n", + "surnames_by_sex = surnames_by_sex.sort_values([\"sex\", \"count\"], ascending=[True, False])\n", + "top10_per_sex = surnames_by_sex.groupby(\"sex\").head(10)\n", "\n", - "for sex, group in top10_per_sex.groupby('sex'):\n", + "for sex, group in top10_per_sex.groupby(\"sex\"):\n", " print(f\"Top 10 surnames for sex: {sex}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['surname']:<15} {row['count']}\")\n", @@ -1575,11 +1639,15 @@ ], "source": [ "# Grouping surnames by region\n", - "surnames_by_region = df_simple.groupby(['province', 'surname']).size().reset_index(name='count')\n", - "surnames_by_region = surnames_by_region.sort_values(['province', 'count'], ascending=[True, False])\n", - "top3_surnames_per_region = surnames_by_region.groupby('province').head(3)\n", + "surnames_by_region = (\n", + " df_simple.groupby([\"province\", \"surname\"]).size().reset_index(name=\"count\")\n", + ")\n", + "surnames_by_region = surnames_by_region.sort_values(\n", + " [\"province\", \"count\"], ascending=[True, False]\n", + ")\n", + "top3_surnames_per_region = surnames_by_region.groupby(\"province\").head(3)\n", "\n", - "for province, group in top3_surnames_per_region.groupby('province'):\n", + "for province, group in top3_surnames_per_region.groupby(\"province\"):\n", " print(f\"{province.upper()}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['surname']:<15} {row['count']}\")\n", @@ -1721,11 +1789,15 @@ ], "source": [ "# Grouping surnames by region and sex\n", - "grouped = df_simple.groupby(['province', 'sex', 'surname']).size().reset_index(name='count')\n", - "grouped = grouped.sort_values(['province', 'sex', 'count'], ascending=[True, True, False])\n", - "top3_surnames_by_region_sex = grouped.groupby(['province', 'sex']).head(3)\n", + "grouped = (\n", + " df_simple.groupby([\"province\", \"sex\", \"surname\"]).size().reset_index(name=\"count\")\n", + ")\n", + "grouped = grouped.sort_values(\n", + " [\"province\", \"sex\", \"count\"], ascending=[True, True, False]\n", + ")\n", + "top3_surnames_by_region_sex = grouped.groupby([\"province\", \"sex\"]).head(3)\n", "\n", - "for (province, sex), group in top3_surnames_by_region_sex.groupby(['province', 'sex']):\n", + "for (province, sex), group in top3_surnames_by_region_sex.groupby([\"province\", \"sex\"]):\n", " print(f\"{province.upper()} - {sex}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['surname']:<15} {row['count']}\")\n", @@ -1760,15 +1832,23 @@ "source": [ "# Find surnames common to both sexes per region - the most popular per region\n", "\n", - "common_surnames = df_simple.groupby(['province', 'surname', 'sex']).size().unstack(fill_value=0)\n", - "common_surnames = common_surnames[(common_surnames.get('m', 0) > 0) & (common_surnames.get('f', 0) > 0)]\n", - "common_surnames['total'] = common_surnames['m'] + common_surnames['f']\n", + "common_surnames = (\n", + " df_simple.groupby([\"province\", \"surname\", \"sex\"]).size().unstack(fill_value=0)\n", + ")\n", + "common_surnames = common_surnames[\n", + " (common_surnames.get(\"m\", 0) > 0) & (common_surnames.get(\"f\", 0) > 0)\n", + "]\n", + "common_surnames[\"total\"] = common_surnames[\"m\"] + common_surnames[\"f\"]\n", "common_surnames = common_surnames.reset_index()\n", - "top_common_surnames = common_surnames.sort_values(['province', 'total'], ascending=[True, False])\n", - "top_common_surnames = top_common_surnames.groupby('province').first().reset_index()\n", + "top_common_surnames = common_surnames.sort_values(\n", + " [\"province\", \"total\"], ascending=[True, False]\n", + ")\n", + "top_common_surnames = top_common_surnames.groupby(\"province\").first().reset_index()\n", "\n", "for _, row in top_common_surnames.iterrows():\n", - " print(f\"{row['province'].upper()} → {row['surname']} ({row['m']} M / {row['f']} F) - Total: {row['total']}\")" + " print(\n", + " f\"{row['province'].upper()} → {row['surname']} ({row['m']} M / {row['f']} F) - Total: {row['total']}\"\n", + " )" ] }, { @@ -1810,15 +1890,19 @@ ], "source": [ "# Grouping middle names by sex\n", - "middlenames_by_sex = df_simple.groupby(['middle_name', 'sex']).size().reset_index(name='count')\n", - "middlenames_by_sex = middlenames_by_sex.sort_values(['sex', 'count'], ascending=[True, False])\n", - "top10_middlenames_per_sex = middlenames_by_sex.groupby('sex').head(10)\n", + "middlenames_by_sex = (\n", + " df_simple.groupby([\"middle_name\", \"sex\"]).size().reset_index(name=\"count\")\n", + ")\n", + "middlenames_by_sex = middlenames_by_sex.sort_values(\n", + " [\"sex\", \"count\"], ascending=[True, False]\n", + ")\n", + "top10_middlenames_per_sex = middlenames_by_sex.groupby(\"sex\").head(10)\n", "\n", - "for sex, group in top10_middlenames_per_sex.groupby('sex'):\n", + "for sex, group in top10_middlenames_per_sex.groupby(\"sex\"):\n", " print(f\"Top 10 middle names for sex: {sex}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['middle_name']:<15} {row['count']}\")\n", - " print()\n" + " print()" ] }, { @@ -1896,15 +1980,19 @@ ], "source": [ "# Grouping middle names by region\n", - "middlenames_by_region = df_simple.groupby(['province', 'middle_name']).size().reset_index(name='count')\n", - "middlenames_by_region = middlenames_by_region.sort_values(['province', 'count'], ascending=[True, False])\n", - "top3_middlenames_per_region = middlenames_by_region.groupby('province').head(3)\n", + "middlenames_by_region = (\n", + " df_simple.groupby([\"province\", \"middle_name\"]).size().reset_index(name=\"count\")\n", + ")\n", + "middlenames_by_region = middlenames_by_region.sort_values(\n", + " [\"province\", \"count\"], ascending=[True, False]\n", + ")\n", + "top3_middlenames_per_region = middlenames_by_region.groupby(\"province\").head(3)\n", "\n", - "for province, group in top3_middlenames_per_region.groupby('province'):\n", + "for province, group in top3_middlenames_per_region.groupby(\"province\"):\n", " print(f\"{province.upper()}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['middle_name']:<20} {row['count']}\")\n", - " print() " + " print()" ] }, { @@ -2042,11 +2130,21 @@ ], "source": [ "# Grouping middle names by province and sex\n", - "middlenames_by_province_sex = df_simple.groupby(['province', 'sex', 'middle_name']).size().reset_index(name='count')\n", - "middlenames_by_province_sex = middlenames_by_province_sex.sort_values(['province', 'sex', 'count'], ascending=[True, True, False])\n", - "top3_middlenames_by_province_sex = middlenames_by_province_sex.groupby(['province', 'sex']).head(3)\n", + "middlenames_by_province_sex = (\n", + " df_simple.groupby([\"province\", \"sex\", \"middle_name\"])\n", + " .size()\n", + " .reset_index(name=\"count\")\n", + ")\n", + "middlenames_by_province_sex = middlenames_by_province_sex.sort_values(\n", + " [\"province\", \"sex\", \"count\"], ascending=[True, True, False]\n", + ")\n", + "top3_middlenames_by_province_sex = middlenames_by_province_sex.groupby(\n", + " [\"province\", \"sex\"]\n", + ").head(3)\n", "\n", - "for (province, sex), group in top3_middlenames_by_province_sex.groupby(['province', 'sex']):\n", + "for (province, sex), group in top3_middlenames_by_province_sex.groupby(\n", + " [\"province\", \"sex\"]\n", + "):\n", " print(f\"{province.upper()} - {sex}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['middle_name']:<20} {row['count']}\")\n", @@ -2128,14 +2226,20 @@ ], "source": [ "# Find middle names common to both sexes per region\n", - "common_middlenames = df_simple.groupby(['province', 'middle_name', 'sex']).size().unstack(fill_value=0)\n", - "common_middlenames = common_middlenames[(common_middlenames.get('m', 0) > 0) & (common_middlenames.get('f', 0) > 0)]\n", - "common_middlenames['total'] = common_middlenames['m'] + common_middlenames['f']\n", + "common_middlenames = (\n", + " df_simple.groupby([\"province\", \"middle_name\", \"sex\"]).size().unstack(fill_value=0)\n", + ")\n", + "common_middlenames = common_middlenames[\n", + " (common_middlenames.get(\"m\", 0) > 0) & (common_middlenames.get(\"f\", 0) > 0)\n", + "]\n", + "common_middlenames[\"total\"] = common_middlenames[\"m\"] + common_middlenames[\"f\"]\n", "common_middlenames = common_middlenames.reset_index()\n", - "common_middlenames = common_middlenames.sort_values(['province', 'total'], ascending=[True, False])\n", - "top3_common_middlenames = common_middlenames.groupby('province').head(3)\n", + "common_middlenames = common_middlenames.sort_values(\n", + " [\"province\", \"total\"], ascending=[True, False]\n", + ")\n", + "top3_common_middlenames = common_middlenames.groupby(\"province\").head(3)\n", "\n", - "for province, group in top3_common_middlenames.groupby('province'):\n", + "for province, group in top3_common_middlenames.groupby(\"province\"):\n", " print(f\"{province.upper()}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['middle_name']:<20} {row['total']}\")\n", @@ -2166,10 +2270,10 @@ ], "source": [ "# Pie chart of surnames by sex\n", - "sex = df['sex'].value_counts()\n", + "sex = df[\"sex\"].value_counts()\n", "plt.figure(figsize=(7, 7))\n", - "plt.pie(sex, labels=sex.index, autopct='%1.1f%%', startangle=140)\n", - "plt.axis('equal')\n", + "plt.pie(sex, labels=sex.index, autopct=\"%1.1f%%\", startangle=140)\n", + "plt.axis(\"equal\")\n", "plt.show()" ] }, @@ -2218,7 +2322,7 @@ ], "source": [ "table = df.groupby([\"year\", \"sex\"]).size().unstack(fill_value=0)\n", - "print(table)\n" + "print(table)" ] }, { @@ -2253,19 +2357,13 @@ ], "source": [ "plt.show()\n", - "#Bar chart middle name by region and sex\n", - "data = df.groupby(['province', 'sex']).size().reset_index(name='count')\n", - "dataa = data.sort_values('count', ascending=False).drop_duplicates(\n", - " ['province', 'sex'])\n", + "# Bar chart middle name by region and sex\n", + "data = df.groupby([\"province\", \"sex\"]).size().reset_index(name=\"count\")\n", + "dataa = data.sort_values(\"count\", ascending=False).drop_duplicates([\"province\", \"sex\"])\n", "\n", "# Bar chart\n", "plt.figure(figsize=(12, 6))\n", - "sns.barplot(\n", - " data=dataa,\n", - " x='province',\n", - " y='count',\n", - " hue='sex'\n", - ")\n", + "sns.barplot(data=dataa, x=\"province\", y=\"count\", hue=\"sex\")\n", "plt.xlabel(\"Region\")\n", "plt.ylabel(\"Count\")\n", "plt.xticks(rotation=45)\n", @@ -2293,18 +2391,25 @@ ], "source": [ "# Pie chart of surnames by sex and region\n", - "prov_sex_counts = df_simple.groupby(['province', 'sex']).size().reset_index(name='count')\n", - "provinces = prov_sex_counts['province'].unique()\n", + "prov_sex_counts = (\n", + " df_simple.groupby([\"province\", \"sex\"]).size().reset_index(name=\"count\")\n", + ")\n", + "provinces = prov_sex_counts[\"province\"].unique()\n", "cols = 3\n", "rows = (len(provinces) + cols - 1) // cols\n", "\n", "plt.figure(figsize=(cols * 5, rows * 5))\n", "for i, prov in enumerate(provinces, 1):\n", - " data = prov_sex_counts[prov_sex_counts['province'] == prov]\n", + " data = prov_sex_counts[prov_sex_counts[\"province\"] == prov]\n", " plt.subplot(rows, cols, i)\n", - " plt.pie(data['count'], labels=data['sex'], autopct='%1.1f%%', colors=['lightpink', 'skyblue'])\n", + " plt.pie(\n", + " data[\"count\"],\n", + " labels=data[\"sex\"],\n", + " autopct=\"%1.1f%%\",\n", + " colors=[\"lightpink\", \"skyblue\"],\n", + " )\n", " plt.title(f\"Distribution of Surnames by Sex\\nin {prov}\")\n", - " plt.axis('equal')\n", + " plt.axis(\"equal\")\n", "\n", "plt.tight_layout()\n", "plt.show()" @@ -2329,13 +2434,19 @@ ], "source": [ "# surnames per region (aggregated)\n", - "top_surnames_region = surnames_by_region.sort_values('count', ascending=False).drop_duplicates('province').head(12)\n", - "plt.figure(figsize=(10,6))\n", - "sns.barplot(y='province', x='count', data=top_surnames_region, hue='surname', dodge=False)\n", + "top_surnames_region = (\n", + " surnames_by_region.sort_values(\"count\", ascending=False)\n", + " .drop_duplicates(\"province\")\n", + " .head(12)\n", + ")\n", + "plt.figure(figsize=(10, 6))\n", + "sns.barplot(\n", + " y=\"province\", x=\"count\", data=top_surnames_region, hue=\"surname\", dodge=False\n", + ")\n", "plt.title(\"Most Common Surname per Region\")\n", "plt.xlabel(\"Count\")\n", "plt.ylabel(\"Region\")\n", - "plt.legend(title=\"Surname\", bbox_to_anchor=(1.05, 1), loc='upper left')\n", + "plt.legend(title=\"Surname\", bbox_to_anchor=(1.05, 1), loc=\"upper left\")\n", "plt.show()" ] }, @@ -2358,26 +2469,41 @@ ], "source": [ "# Map of the most common surname by province in DRC\n", - "top_surnames = df_simple.groupby(['province', 'surname']).size().reset_index(name='count')\n", - "top_surnames = top_surnames.sort_values(['province', 'count'], ascending=[True, False])\n", - "top_surnames = top_surnames.drop_duplicates(subset='province', keep='first')\n", - "top_surnames['province_clean'] = top_surnames['province'].str.upper().str.strip() \\\n", - " .str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8')\n", + "top_surnames = (\n", + " df_simple.groupby([\"province\", \"surname\"]).size().reset_index(name=\"count\")\n", + ")\n", + "top_surnames = top_surnames.sort_values([\"province\", \"count\"], ascending=[True, False])\n", + "top_surnames = top_surnames.drop_duplicates(subset=\"province\", keep=\"first\")\n", + "top_surnames[\"province_clean\"] = (\n", + " top_surnames[\"province\"]\n", + " .str.upper()\n", + " .str.strip()\n", + " .str.normalize(\"NFKD\")\n", + " .str.encode(\"ascii\", errors=\"ignore\")\n", + " .str.decode(\"utf-8\")\n", + ")\n", "\n", - "gdf_named = gdf_merged.merge(top_surnames[['province_clean', 'surname']], \n", - " on='province_clean', how='left')\n", + "gdf_named = gdf_merged.merge(\n", + " top_surnames[[\"province_clean\", \"surname\"]], on=\"province_clean\", how=\"left\"\n", + ")\n", "\n", "fig, ax = plt.subplots(figsize=(12, 12))\n", - "gdf_named.plot(column='count', cmap='PuBu', edgecolor='black', legend=True, ax=ax)\n", + "gdf_named.plot(column=\"count\", cmap=\"PuBu\", edgecolor=\"black\", legend=True, ax=ax)\n", "\n", "for idx, row in gdf_named.iterrows():\n", - " if pd.notna(row['surname']):\n", - " centroid = row['geometry'].centroid\n", - " plt.text(centroid.x, centroid.y, row['surname'], \n", - " horizontalalignment='center', fontsize=8, color='black')\n", + " if pd.notna(row[\"surname\"]):\n", + " centroid = row[\"geometry\"].centroid\n", + " plt.text(\n", + " centroid.x,\n", + " centroid.y,\n", + " row[\"surname\"],\n", + " horizontalalignment=\"center\",\n", + " fontsize=8,\n", + " color=\"black\",\n", + " )\n", "\n", "plt.title(\"Most common surname by province\")\n", - "plt.axis('off')\n", + "plt.axis(\"off\")\n", "plt.show()" ] }, @@ -2400,14 +2526,14 @@ ], "source": [ "# Bar chart surnames by region and sex\n", - "top10_regions = df_simple['province'].value_counts().head(12).index.tolist()\n", - "df_top10 = df_simple[df_simple['province'].isin(top10_regions)]\n", - "plt.figure(figsize=(12,6))\n", - "sns.countplot(data=df_top10, y='province', hue='sex', order=top10_regions)\n", + "top10_regions = df_simple[\"province\"].value_counts().head(12).index.tolist()\n", + "df_top10 = df_simple[df_simple[\"province\"].isin(top10_regions)]\n", + "plt.figure(figsize=(12, 6))\n", + "sns.countplot(data=df_top10, y=\"province\", hue=\"sex\", order=top10_regions)\n", "plt.title(\"Surnames Distribution by Region and Sex\")\n", "plt.xlabel(\"Number of entries\")\n", "plt.ylabel(\"Region\")\n", - "plt.legend(title='Sex')\n", + "plt.legend(title=\"Sex\")\n", "plt.show()" ] }, @@ -2430,11 +2556,16 @@ ], "source": [ "# Pie chart of middle names by sex\n", - "middlenames_sex_count = middlenames_by_province_sex.groupby('sex')['count'].sum()\n", - "plt.figure(figsize=(6,6))\n", - "plt.pie(middlenames_sex_count, labels=middlenames_sex_count.index, autopct='%1.1f%%', colors=['lightpink', 'skyblue'])\n", + "middlenames_sex_count = middlenames_by_province_sex.groupby(\"sex\")[\"count\"].sum()\n", + "plt.figure(figsize=(6, 6))\n", + "plt.pie(\n", + " middlenames_sex_count,\n", + " labels=middlenames_sex_count.index,\n", + " autopct=\"%1.1f%%\",\n", + " colors=[\"lightpink\", \"skyblue\"],\n", + ")\n", "plt.title(\"Distribution of Middle Names by Sex\")\n", - "plt.axis('equal')\n", + "plt.axis(\"equal\")\n", "plt.show()" ] }, @@ -2457,13 +2588,19 @@ ], "source": [ "# most popular middle name per region\n", - "top_middlename_region = middlenames_by_region.sort_values('count', ascending=False).drop_duplicates('province').head(12)\n", - "plt.figure(figsize=(10,6))\n", - "sns.barplot(y='province', x='count', data=top_middlename_region, hue='middle_name', dodge=False)\n", + "top_middlename_region = (\n", + " middlenames_by_region.sort_values(\"count\", ascending=False)\n", + " .drop_duplicates(\"province\")\n", + " .head(12)\n", + ")\n", + "plt.figure(figsize=(10, 6))\n", + "sns.barplot(\n", + " y=\"province\", x=\"count\", data=top_middlename_region, hue=\"middle_name\", dodge=False\n", + ")\n", "plt.title(\"Most Common Middle Name per Region\")\n", "plt.xlabel(\"Count\")\n", "plt.ylabel(\"Region\")\n", - "plt.legend(title=\"Middle Name\", bbox_to_anchor=(1.05, 1), loc='upper left')\n", + "plt.legend(title=\"Middle Name\", bbox_to_anchor=(1.05, 1), loc=\"upper left\")\n", "plt.show()" ] }, @@ -2486,26 +2623,41 @@ ], "source": [ "# Map of the most common middle by province in DRC\n", - "top_surnames = df_simple.groupby(['province', 'middle_name']).size().reset_index(name='count')\n", - "top_surnames = top_surnames.sort_values(['province', 'count'], ascending=[True, False])\n", - "top_surnames = top_surnames.drop_duplicates(subset='province', keep='first')\n", - "top_surnames['province_clean'] = top_surnames['province'].str.upper().str.strip() \\\n", - " .str.normalize('NFKD').str.encode('ascii', errors='ignore').str.decode('utf-8')\n", + "top_surnames = (\n", + " df_simple.groupby([\"province\", \"middle_name\"]).size().reset_index(name=\"count\")\n", + ")\n", + "top_surnames = top_surnames.sort_values([\"province\", \"count\"], ascending=[True, False])\n", + "top_surnames = top_surnames.drop_duplicates(subset=\"province\", keep=\"first\")\n", + "top_surnames[\"province_clean\"] = (\n", + " top_surnames[\"province\"]\n", + " .str.upper()\n", + " .str.strip()\n", + " .str.normalize(\"NFKD\")\n", + " .str.encode(\"ascii\", errors=\"ignore\")\n", + " .str.decode(\"utf-8\")\n", + ")\n", "\n", - "gdf_named = gdf_merged.merge(top_surnames[['province_clean', 'middle_name']], \n", - " on='province_clean', how='left')\n", + "gdf_named = gdf_merged.merge(\n", + " top_surnames[[\"province_clean\", \"middle_name\"]], on=\"province_clean\", how=\"left\"\n", + ")\n", "\n", "fig, ax = plt.subplots(figsize=(12, 12))\n", - "gdf_named.plot(column='count', cmap='PuBu', edgecolor='black', legend=True, ax=ax)\n", + "gdf_named.plot(column=\"count\", cmap=\"PuBu\", edgecolor=\"black\", legend=True, ax=ax)\n", "\n", "for idx, row in gdf_named.iterrows():\n", - " if pd.notna(row['middle_name']):\n", - " centroid = row['geometry'].centroid\n", - " plt.text(centroid.x, centroid.y, row['middle_name'], \n", - " horizontalalignment='center', fontsize=8, color='black')\n", + " if pd.notna(row[\"middle_name\"]):\n", + " centroid = row[\"geometry\"].centroid\n", + " plt.text(\n", + " centroid.x,\n", + " centroid.y,\n", + " row[\"middle_name\"],\n", + " horizontalalignment=\"center\",\n", + " fontsize=8,\n", + " color=\"black\",\n", + " )\n", "\n", "plt.title(\"Most common middle name by province\")\n", - "plt.axis('off')\n", + "plt.axis(\"off\")\n", "plt.show()" ] }, @@ -2527,18 +2679,19 @@ } ], "source": [ - "#Bar chart middle name by region and sex\n", - "middlenames_by_sex_region = df_simple.groupby(['province', 'sex', 'middle_name']).size().reset_index(name='count')\n", - "top_middlename_sex_region = middlenames_by_sex_region.sort_values('count', ascending=False).drop_duplicates(['province', 'sex'])\n", + "# Bar chart middle name by region and sex\n", + "middlenames_by_sex_region = (\n", + " df_simple.groupby([\"province\", \"sex\", \"middle_name\"])\n", + " .size()\n", + " .reset_index(name=\"count\")\n", + ")\n", + "top_middlename_sex_region = middlenames_by_sex_region.sort_values(\n", + " \"count\", ascending=False\n", + ").drop_duplicates([\"province\", \"sex\"])\n", "\n", "# Bar chart\n", "plt.figure(figsize=(12, 6))\n", - "sns.barplot(\n", - " data=top_middlename_sex_region,\n", - " x='province',\n", - " y='count',\n", - " hue='sex'\n", - ")\n", + "sns.barplot(data=top_middlename_sex_region, x=\"province\", y=\"count\", hue=\"sex\")\n", "plt.title(\"Most Common Middle Name Count by Region and Sex\")\n", "plt.xlabel(\"Region\")\n", "plt.ylabel(\"Count\")\n", @@ -2578,7 +2731,12 @@ ], "source": [ "# Crossover 1: Firstname vs Surname\n", - "crossover_firstname_surname = df_simple.groupby(['first_name', 'surname']).size().sort_values(ascending=False).head(10)\n", + "crossover_firstname_surname = (\n", + " df_simple.groupby([\"first_name\", \"surname\"])\n", + " .size()\n", + " .sort_values(ascending=False)\n", + " .head(10)\n", + ")\n", "print(\"--- Top 10 Firstname vs Surname Crossovers ---\")\n", "print(crossover_firstname_surname)\n", "print(\"\\n\")" @@ -2614,11 +2772,15 @@ ], "source": [ "# Crossover: Firstname vs Surname vs Sex\n", - "crossover_fname_sname_sex = df_simple.groupby(['sex', 'first_name', 'surname']).size().reset_index(name='count')\n", - "crossover_fname_sname_sex = crossover_fname_sname_sex.sort_values('count', ascending=False).head(10)\n", + "crossover_fname_sname_sex = (\n", + " df_simple.groupby([\"sex\", \"first_name\", \"surname\"]).size().reset_index(name=\"count\")\n", + ")\n", + "crossover_fname_sname_sex = crossover_fname_sname_sex.sort_values(\n", + " \"count\", ascending=False\n", + ").head(10)\n", "\n", "print(\"--- Top 10 Firstname vs Surname Crossovers by Sex ---\")\n", - "for sex, group in crossover_fname_sname_sex.groupby('sex'):\n", + "for sex, group in crossover_fname_sname_sex.groupby(\"sex\"):\n", " print(f\"\\nSEX: {sex}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['first_name']} {row['surname']} — {row['count']}\")" @@ -2643,22 +2805,24 @@ ], "source": [ "# frequency of joint appearance\n", - "top_firstnames = df_simple['first_name'].value_counts().head(10).index\n", - "top_surnames = df_simple['surname'].value_counts().head(10).index\n", + "top_firstnames = df_simple[\"first_name\"].value_counts().head(10).index\n", + "top_surnames = df_simple[\"surname\"].value_counts().head(10).index\n", "\n", "filtered_df = df_simple[\n", - " df_simple['first_name'].isin(top_firstnames) &\n", - " df_simple['surname'].isin(top_surnames)\n", + " df_simple[\"first_name\"].isin(top_firstnames)\n", + " & df_simple[\"surname\"].isin(top_surnames)\n", "]\n", "\n", - "cooccurrence = filtered_df.groupby(['first_name', 'surname']).size().unstack(fill_value=0)\n", + "cooccurrence = (\n", + " filtered_df.groupby([\"first_name\", \"surname\"]).size().unstack(fill_value=0)\n", + ")\n", "\n", - "#heatmap\n", + "# heatmap\n", "plt.figure(figsize=(12, 10))\n", - "sns.heatmap(cooccurrence, annot=True, fmt='d', cmap='Blues')\n", - "plt.title('Heatmap of First Name vs Surname Cooccurrence')\n", - "plt.xlabel('Surname')\n", - "plt.ylabel('First Name')\n", + "sns.heatmap(cooccurrence, annot=True, fmt=\"d\", cmap=\"Blues\")\n", + "plt.title(\"Heatmap of First Name vs Surname Cooccurrence\")\n", + "plt.xlabel(\"Surname\")\n", + "plt.ylabel(\"First Name\")\n", "plt.tight_layout()\n", "plt.show()" ] @@ -2693,7 +2857,12 @@ ], "source": [ "# Crossover 2: Firstname vs Middle Name\n", - "crossover_firstname_middlename = df_simple.groupby(['first_name', 'middle_name']).size().sort_values(ascending=False).head(10)\n", + "crossover_firstname_middlename = (\n", + " df_simple.groupby([\"first_name\", \"middle_name\"])\n", + " .size()\n", + " .sort_values(ascending=False)\n", + " .head(10)\n", + ")\n", "print(\"--- Top 10 Firstname vs Middle Name Crossovers ---\")\n", "print(crossover_firstname_middlename)\n", "print(\"\\n\")" @@ -2718,20 +2887,22 @@ ], "source": [ "# frequency of joint appearance\n", - "top_middlenames = df_simple['middle_name'].value_counts().head(10).index\n", + "top_middlenames = df_simple[\"middle_name\"].value_counts().head(10).index\n", "\n", "filtered_df = df_simple[\n", - " df_simple['first_name'].isin(top_firstnames) &\n", - " df_simple['middle_name'].isin(top_middlenames)\n", + " df_simple[\"first_name\"].isin(top_firstnames)\n", + " & df_simple[\"middle_name\"].isin(top_middlenames)\n", "]\n", "\n", - "cooccurrence = filtered_df.groupby(['first_name', 'middle_name']).size().unstack(fill_value=0)\n", + "cooccurrence = (\n", + " filtered_df.groupby([\"first_name\", \"middle_name\"]).size().unstack(fill_value=0)\n", + ")\n", "\n", "plt.figure(figsize=(12, 10))\n", - "sns.heatmap(cooccurrence, annot=True, fmt='d', cmap='Greens')\n", - "plt.title('Heatmap of First Name vs Middle Name Cooccurrence')\n", - "plt.xlabel('Middle Name')\n", - "plt.ylabel('First Name')\n", + "sns.heatmap(cooccurrence, annot=True, fmt=\"d\", cmap=\"Greens\")\n", + "plt.title(\"Heatmap of First Name vs Middle Name Cooccurrence\")\n", + "plt.xlabel(\"Middle Name\")\n", + "plt.ylabel(\"First Name\")\n", "plt.tight_layout()\n", "plt.show()" ] @@ -2764,11 +2935,17 @@ ], "source": [ "# Crossover: Firstname vs Middle Name vs Sex\n", - "crossover_fname_middlename_sex = df_simple.groupby(['sex', 'first_name', 'middle_name']).size().reset_index(name='count')\n", - "crossover_fname_middlename_sex = crossover_fname_middlename_sex.sort_values('count', ascending=False).head(10)\n", + "crossover_fname_middlename_sex = (\n", + " df_simple.groupby([\"sex\", \"first_name\", \"middle_name\"])\n", + " .size()\n", + " .reset_index(name=\"count\")\n", + ")\n", + "crossover_fname_middlename_sex = crossover_fname_middlename_sex.sort_values(\n", + " \"count\", ascending=False\n", + ").head(10)\n", "\n", "print(\"--- Top 10 Firstname vs Middle Name Crossovers by Sex ---\")\n", - "for sex, group in crossover_fname_middlename_sex.groupby('sex'):\n", + "for sex, group in crossover_fname_middlename_sex.groupby(\"sex\"):\n", " print(f\"\\nSEX: {sex}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['first_name']} {row['middle_name']} — {row['count']}\")" @@ -2805,7 +2982,12 @@ "source": [ "# Crossover 3: Surname vs Middle Name\n", "print(\"--- Top 10 Surname vs Middle Name Crossovers ---\")\n", - "crossover_surname_middlename = df_simple.groupby(['surname', 'middle_name']).size().sort_values(ascending=False).head(10)\n", + "crossover_surname_middlename = (\n", + " df_simple.groupby([\"surname\", \"middle_name\"])\n", + " .size()\n", + " .sort_values(ascending=False)\n", + " .head(10)\n", + ")\n", "print(crossover_surname_middlename)\n", "print(\"\\n\")" ] @@ -2829,20 +3011,22 @@ ], "source": [ "# frequency of joint appearance\n", - "top_surnames = df_simple['surname'].value_counts().head(10).index \n", - "top_middlenames = df_simple['middle_name'].value_counts().head(10).index\n", + "top_surnames = df_simple[\"surname\"].value_counts().head(10).index\n", + "top_middlenames = df_simple[\"middle_name\"].value_counts().head(10).index\n", "filtered_df = df_simple[\n", - " df_simple['surname'].isin(top_surnames) &\n", - " df_simple['middle_name'].isin(top_middlenames)\n", + " df_simple[\"surname\"].isin(top_surnames)\n", + " & df_simple[\"middle_name\"].isin(top_middlenames)\n", "]\n", "\n", - "cooccurrence = filtered_df.groupby(['surname', 'middle_name']).size().unstack(fill_value=0)\n", + "cooccurrence = (\n", + " filtered_df.groupby([\"surname\", \"middle_name\"]).size().unstack(fill_value=0)\n", + ")\n", "\n", "plt.figure(figsize=(12, 10))\n", - "sns.heatmap(cooccurrence, annot=True, fmt='d', cmap='Oranges')\n", - "plt.title('Heatmap of Surname vs Middle Name Cooccurrence')\n", - "plt.xlabel('Middle Name')\n", - "plt.ylabel('Surname')\n", + "sns.heatmap(cooccurrence, annot=True, fmt=\"d\", cmap=\"Oranges\")\n", + "plt.title(\"Heatmap of Surname vs Middle Name Cooccurrence\")\n", + "plt.xlabel(\"Middle Name\")\n", + "plt.ylabel(\"Surname\")\n", "plt.tight_layout()\n", "plt.show()" ] @@ -2875,11 +3059,17 @@ ], "source": [ "# Crossover: Surname vs Middle Name vs Sex\n", - "crossover_surname_middlename_sex = df_simple.groupby(['sex', 'surname', 'middle_name']).size().reset_index(name='count')\n", - "crossover_surname_middlename_sex = crossover_surname_middlename_sex.sort_values('count', ascending=False).head(10)\n", + "crossover_surname_middlename_sex = (\n", + " df_simple.groupby([\"sex\", \"surname\", \"middle_name\"])\n", + " .size()\n", + " .reset_index(name=\"count\")\n", + ")\n", + "crossover_surname_middlename_sex = crossover_surname_middlename_sex.sort_values(\n", + " \"count\", ascending=False\n", + ").head(10)\n", "\n", "print(\"--- Top 10 Surname vs Middle Name Crossovers by Sex ---\")\n", - "for sex, group in crossover_surname_middlename_sex.groupby('sex'):\n", + "for sex, group in crossover_surname_middlename_sex.groupby(\"sex\"):\n", " print(f\"\\nSEX: {sex}\")\n", " for _, row in group.iterrows():\n", " print(f\" {row['surname']} {row['middle_name']} — {row['count']}\")" @@ -2904,29 +3094,29 @@ ], "source": [ "# Calculate the length of first names, surnames, and middle names\n", - "df['firstname_length'] = df_simple['first_name'].str.len()\n", - "df['surname_length'] = df_simple['surname'].str.len()\n", - "df['middlename_length'] = df_simple['middle_name'].str.len()\n", + "df[\"firstname_length\"] = df_simple[\"first_name\"].str.len()\n", + "df[\"surname_length\"] = df_simple[\"surname\"].str.len()\n", + "df[\"middlename_length\"] = df_simple[\"middle_name\"].str.len()\n", "\n", "fig, axes = plt.subplots(1, 3, figsize=(18, 6))\n", "\n", "# Histogram for firstname length\n", - "sns.histplot(df['firstname_length'], kde=True, ax=axes[0], color='skyblue')\n", - "axes[0].set_title('Distribution of First Name Length')\n", - "axes[0].set_xlabel('Number of Letters')\n", - "axes[0].set_ylabel('Frequency')\n", + "sns.histplot(df[\"firstname_length\"], kde=True, ax=axes[0], color=\"skyblue\")\n", + "axes[0].set_title(\"Distribution of First Name Length\")\n", + "axes[0].set_xlabel(\"Number of Letters\")\n", + "axes[0].set_ylabel(\"Frequency\")\n", "\n", "# Histogram for surname length\n", - "sns.histplot(df['surname_length'], kde=True, ax=axes[1], color='lightgreen')\n", - "axes[1].set_title('Distribution of Surname Length')\n", - "axes[1].set_xlabel('Number of Letters')\n", - "axes[1].set_ylabel('Frequency')\n", + "sns.histplot(df[\"surname_length\"], kde=True, ax=axes[1], color=\"lightgreen\")\n", + "axes[1].set_title(\"Distribution of Surname Length\")\n", + "axes[1].set_xlabel(\"Number of Letters\")\n", + "axes[1].set_ylabel(\"Frequency\")\n", "\n", "# Histogram for middle name length\n", - "sns.histplot(df['middlename_length'], kde=True, ax=axes[2], color='salmon')\n", - "axes[2].set_title('Distribution of Middle Name Length')\n", - "axes[2].set_xlabel('Number of Letters')\n", - "axes[2].set_ylabel('Frequency')\n", + "sns.histplot(df[\"middlename_length\"], kde=True, ax=axes[2], color=\"salmon\")\n", + "axes[2].set_title(\"Distribution of Middle Name Length\")\n", + "axes[2].set_xlabel(\"Number of Letters\")\n", + "axes[2].set_ylabel(\"Frequency\")\n", "\n", "plt.tight_layout()\n", "plt.show()" diff --git a/notebooks/names.ipynb b/src/notebooks/names.ipynb similarity index 98% rename from notebooks/names.ipynb rename to src/notebooks/names.ipynb index 146c2bd..519aec1 100644 --- a/notebooks/names.ipynb +++ b/src/notebooks/names.ipynb @@ -1,13 +1,16 @@ { "cells": [ { - "metadata": {}, "cell_type": "markdown", - "source": "# Names Analysis & Modeling", - "id": "ae0a818eafd9bd24" + "id": "ae0a818eafd9bd24", + "metadata": {}, + "source": [ + "# Names Analysis & Modeling" + ] }, { "cell_type": "code", + "execution_count": 1, "id": "initial_id", "metadata": { "ExecuteTime": { @@ -15,48 +18,47 @@ "start_time": "2025-09-28T21:41:26.224407Z" } }, + "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "import pandas as pd\n", "import numpy as np\n", - "import sys \n", - "import os\n", - "from collections import Counter" - ], - "outputs": [], - "execution_count": 1 + "import sys\n", + "import os" + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "584a6fcfcbea71e4", "metadata": { "ExecuteTime": { "end_time": "2025-09-28T21:41:26.471906Z", "start_time": "2025-09-28T21:41:26.234143Z" } }, - "cell_type": "code", + "outputs": [], "source": [ "sys.path.append(os.path.abspath(\"..\"))\n", "\n", - "from core.utils.data_loader import DataLoader\n", - "from core.utils.region_mapper import RegionMapper\n", - "from core.config.pipeline_config import PipelineConfig\n", + "from ners.core.utils.data_loader import DataLoader\n", + "from ners.core.utils.region_mapper import RegionMapper\n", + "from ners.core.config.pipeline_config import PipelineConfig\n", "\n", - "from research.statistics.utils import LETTERS\n", - "from research.statistics.utils import build_category_distribution\n", - "from research.statistics.utils import build_words_token\n", - "from research.statistics.utils import build_transition_probabilities\n", - "from research.statistics.utils import build_transition_comparisons\n", - "from research.statistics.utils import build_ngrams_count\n", - "from research.statistics.plots import plot_transition_matrix\n", - "from research.statistics.plots import plot_letter_frequencies" - ], - "id": "584a6fcfcbea71e4", - "outputs": [], - "execution_count": 2 + "from ners.research.statistics.utils import LETTERS\n", + "from ners.research.statistics.utils import build_category_distribution\n", + "from ners.research.statistics.utils import build_words_token\n", + "from ners.research.statistics.utils import build_transition_probabilities\n", + "from ners.research.statistics.utils import build_transition_comparisons\n", + "from ners.research.statistics.utils import build_ngrams_count\n", + "from ners.research.statistics.plots import plot_transition_matrix\n", + "from ners.research.statistics.plots import plot_letter_frequencies" + ] }, { "cell_type": "code", + "execution_count": 3, "id": "f1a69290-a9c0-40d0-9fe8-a06d8a466671", "metadata": { "ExecuteTime": { @@ -64,6 +66,7 @@ "start_time": "2025-09-28T21:41:26.478191Z" } }, + "outputs": [], "source": [ "config = PipelineConfig(\n", " paths={\n", @@ -73,29 +76,23 @@ " \"outputs_dir\": \"../data/processed\",\n", " \"logs_dir\": \"../logs\",\n", " \"configs_dir\": \"../configs\",\n", - " \"checkpoints_dir\": \"../checkpoints\"\n", + " \"checkpoints_dir\": \"../checkpoints\",\n", " }\n", ")\n", "\n", "loader = DataLoader(config)" - ], - "outputs": [], - "execution_count": 3 + ] }, { + "cell_type": "code", + "execution_count": 4, + "id": "e48c6fd9a213bcd2", "metadata": { "ExecuteTime": { "end_time": "2025-09-28T21:41:53.362337Z", "start_time": "2025-09-28T21:41:26.490902Z" } }, - "cell_type": "code", - "source": [ - "df = loader.load_csv_complete(config.paths.data_dir / \"names_featured.csv\")\n", - "df['province'] = RegionMapper.clean_province(df['province'])\n", - "df.columns" - ], - "id": "e48c6fd9a213bcd2", "outputs": [ { "data": { @@ -112,47 +109,69 @@ "output_type": "execute_result" } ], - "execution_count": 4 + "source": [ + "df = loader.load_csv_complete(config.paths.data_dir / \"names_featured.csv\")\n", + "df[\"province\"] = RegionMapper.clean_province(df[\"province\"])\n", + "df.columns" + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "## Name category distribution", - "id": "46429fc98b67a89f" + "id": "46429fc98b67a89f", + "metadata": {}, + "source": [ + "## Name category distribution" + ] }, { + "cell_type": "code", + "execution_count": 5, + "id": "378147d2abc9ab24", "metadata": { "ExecuteTime": { "end_time": "2025-09-28T21:42:00.759309Z", "start_time": "2025-09-28T21:42:00.246322Z" } }, - "cell_type": "code", + "outputs": [], "source": [ "df_name_categories = build_category_distribution(df)\n", "df_name_categories.head(12)\n", "\n", "# save data\n", "df_name_categories.to_csv(\"../assets/identified_category_distribution.csv\", index=False)" - ], - "id": "378147d2abc9ab24", - "outputs": [], - "execution_count": 5 + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "### Simple vs Compose (all provinces)", - "id": "3c99d846cb37c469" + "id": "3c99d846cb37c469", + "metadata": {}, + "source": [ + "### Simple vs Compose (all provinces)" + ] }, { + "cell_type": "code", + "execution_count": 6, + "id": "ae30e79a975010d4", "metadata": { "ExecuteTime": { "end_time": "2025-09-28T21:42:04.015038Z", "start_time": "2025-09-28T21:42:00.766470Z" } }, - "cell_type": "code", + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA9MAAAH+CAYAAACfoF2EAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAlQ1JREFUeJzs3Xd4VGXax/HvOTNpJEBC6L036VUULKCI2BELIiyray+rrivqq+ju2rtiFxULKmJBsWBDpHeQ3lsoKYT0OjPnvH8MBCI1kORM+X2uay5gZjJznyHJc+7z3M/9GLZt24iIiIiIiIjIcTOdDkBEREREREQk2CiZFhERERERESkjJdMiIiIiIiIiZaRkWkRERERERKSMlEyLiIiIiIiIlJGSaREREREREZEyUjItIiIiIiIiUkZKpkVERERERETKSMm0hCTbtp0OISBiCBb6rERE5HgFwpgRCDGIiPOUTEulGzFiBG3atCm5tW3blq5duzJkyBA+/PBDvF5vqef379+f+++//7hf/7fffmP06NHHfN79999P//79T/h9jiQ7O5v77ruPRYsWldw3YsQIRowYcdKvfTzK6ziOJCUlhWeeeYZBgwbRuXNn+vbty80331zqeI/X4T4rEREJXhrjK1ZFjvEZGRk8+eSTnHPOOXTo0IFevXrxt7/9jV9++aVC3k8kFLidDkDCU/v27XnkkUcA8Pl8ZGVlMWPGDJ588kkWLVrESy+9hGn6r/W8+uqrxMXFHfdrjx8//ried+uttzJy5Mgyx34sa9as4ZtvvuHyyy8vuW//sQa7xYsXc9ttt5GQkMDIkSNp1qwZmZmZTJw4kREjRvDkk09y6aWXHvfrHe6zEhGR4KYxPvgUFhYyfPhwfD4fN954I02aNCEnJ4cff/yR22+/nQcffJC//e1vTocpEnCUTIsj4uLi6NKlS6n7+vfvT/PmzXn88cf57rvvuPjiiwH/oFwRGjduXCGvezgtW7astPeqKJmZmdx11100bdqU999/n5iYmJLHzjvvPG688UbGjBlD3759qVmzpoORioiIkzTGB5+pU6eyadMmfvrpJ5o2bVpy/znnnENhYSGvvPIK1157LS6Xy7kgRQKQyrwloFx77bXUqVOHzz77rOS+v5Y07R+EO3XqxKmnnsq9995LSkoK4C+1WrBgAQsWLKBNmzbMnz+f+fPn06ZNGz777DPOPvtsunXrxuzZsw8pAQPweDw89thj9OzZkx49ejB69Gj27t1b8vjhSrn2v/7+99p/JXzkyJElz/3r1xUVFfHaa68xaNAgOnbsyMCBA3n77bexLKvUe/3f//0fb7/9NmeddRYdO3bk6quvZvny5cf8HI92HNOnT6dNmzbMmjWr1NcsWrSINm3asHjx4sO+5uTJk0lNTeXBBx8slUgDmKbJvffey/Dhw8nNzS25f9KkSQwZMoQuXbrQqVMnLrnkEn788ceSz+1wnxXAr7/+ypAhQ+jYsSOnn346jz32GPn5+aXec/r06QwZMoROnTpx3nnn8d1333HuuecyduzYkuekpqbywAMPcOaZZ9KpUyeGDh3Kb7/9Vup12rRpw6uvvlryWq+++iodO3bkhRdeKPW8goICunfvzhtvvHHkD15ERI5IY3zgjvF79uwBKBXjfjfddBO33norxcXFJfetX7+em266iW7dutGtWzduu+02kpKSSh6//fbb6dixI5s3by65b+zYsbRr144FCxYc8xhFgoWSaQkopmnSp08fli9ffsi6KvCXGd93330MHDiQd955hwceeIB58+bxr3/9C/CXWrVv35727dszceJETjnllJKvffXVVxk9ejRjxoyha9euh33/H3/8kVWrVvHUU08xevRopk+fzg033IDP5zuu+E855RTGjBkDwJgxYw5b+mXbNjfffDPjxo3jiiuu4M0332TQoEG89NJLhzz/p59+4rfffuOhhx7ihRdeYM+ePdxxxx3HjOdox9GvXz9q167NN998U+prJk+eTNOmTenevfthX3PmzJnUrFmTTp06Hfbxtm3bMnr06JIr2hMmTGDMmDGcc845vPXWWzz33HNERkZy7733kpycfMTPasqUKdx22200b96c1157jdtvv51vv/2WW2+9taThy7x587j11lupV68eY8eOZfjw4TzyyCPs3r27JJ49e/YwdOhQFi1axN13383YsWNp0KABt912G99++22p2N98800uuugiXnnlFc477zzOOeccpkyZUqrBzC+//EJ+fn6ZythFROQAjfGBO8b369cPt9vN3/72N1599VWWLVuGx+MBoFOnTlx//fUlF9K3bNnC1VdfTXp6Ok8//TSPP/44SUlJDBs2jPT0dAAeffRRqlSpUnLMK1eu5M033+S6666jV69e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/bZt2zJhwgRefPFF7rvvPmzbpnXr1rz22msMGDCA/Px8HnjgAVq3bs31118PQGxsLGPGjOGWW25h3Lhx3HTTTeXyWYg4zbCP1AlIRELeI488wp9//nnIlfdA99tvv1G3bt1Se4xu2LCBCy+8sEzJ8rH88MMP3Hffffzxxx+HNDwTEREJZME6xosEE81Mi4ShDz/8kM2bN/P555/z7LPPOh1Omc2aNYsffviBe++9l2bNmpGSksIbb7xB8+bN6du370m//q+//sqKFSv47LPPGDJkiBJpEREJGsE+xosEEyXTImFo0aJFzJw5k7/97W9ceOGFTodTZqNHjyY6Opo33niD1NRU4uPj6devH//617/KpeP2jh07+OCDD+jevTv//ve/yyFiERGRyhHsY7xIMFGZt4iIiIiIiEgZaWssERERERERkTJSMi0iIiIiIiJSRkqmRURERERERMpIybSIiIiIiIhIGSmZFhERERERESkjJdMiIiIiIiIiZaRkWkRERERERKSMlEyLiIiIiIiIlJGSaREREREREZEyUjItIiIiIiIiUkZKpkVERERERETKSMm0iIiIiIiISBkpmRYREREREREpIyXTIiIiIiIiImWkZFpERERERESkjJRMi4iIiIiIiJSRkmkRERERERGRMlIyLSIiIiIiIlJGSqZFREREREREykjJtIiIiIiIiEgZKZkWERERERERKSMl0yIiIiIiIiJlpGRaREREREREpIyUTIuIiIiIiIiUkZJpERERERERkTJSMi0iIiIiIiJSRkqmRURERERERMpIybSIiIiIiIhIGSmZFhERERERESkjJdMiIiIiIiIiZaRkWkRERERERKSMlEyLiIiIiIiIlJGSaREREREREZEyUjItIiIiIiIiUkZKpkVERERERETKSMm0iIiIiIiISBkpmRYREREREREpIyXTIiIiIiIiImWkZFpERERERESkjJRMi4iIiIiIiJSRkmkRERERERGRMlIyLSIiIiIiIlJGSqZFREREREREykjJtIiIiIiIiEgZKZkWERERERERKSMl0yIiIiIiIiJlpGRaREREREREpIyUTIuIiIiIiIiUkZJpERERERERkTJSMi0iIiIiIiJSRkqmRURERERERMrI7XQAIgJey8K2AANcpoFpGIc8p9DjI6vAQ2Z+MfnFPnyWjdey8e27eS2L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Di54Aeq0989eB/jWHRkZGVx11VXUrl2bxx9/nIYNG7JixQr+97//kZSUxMMPP+x0iCJSjvY3F5uzKZ2Hv1nJtvR8p0MSKX95afDN7bDwPbjgOWjQXY1DpVIomZZy5bNssgs8PP7DGr5cskPdQCX0bZ8Lb/WFbqP8V8UjYwN6lvr5558nMjKSd999l6ioKAAaNWpEdHQ0t956K9deey3NmjVzOEoRKQ8+y2ZPbhFjvlnFT6uSnQ5HpOLtWgLjBkDHK+G8xyGmhhqUSYXS5RopF16fhc+yeX/2Fs545ne+WKxEWsKI5YNF78LLnWHxeP+WHT6v01Edori4mO+//57hw4eXJNL7nX322YwfP54GDRqQlZXFww8/zGmnnUb37t3597//TVaWv8Jk/vz59O/fny+++ILTTz+dnj178s4777Bw4UIGDRpE165due+++7As/zrMESNG8OqrrzJs2DA6d+7MNddcw6ZNm0reNzk5mX/+85/06tWL3r1789hjj1Fc7F8S4vF4eOihh+jduzddu3bl5ptvJiUlpeRrf/nlFwYPHkznzp0ZOnQoCxYsqOiPUCQo7B+T356xibOena5EWsKLbfvLvl/uAnNe8ZeC+7SsQSqGkmk5Kfu7fy7YspfzXprBY9+vIaco8JIIkUpRkAHf/wveOhN2LfbfZwdOc5/t27eTn59Px44dD3nMMAxOPfVUIiMjuf3221mzZg1vvvkm77//Pps2beL+++8veW5qaiq//vorH330ETfffDMvvPACTzzxBE899RQvvPACP/zwA7/99lvJ89966y3OO+88vvrqK+rUqcONN95IcXExxcXF/O1vf6OgoICPPvqIl156ienTp/PMM88AMGHCBBYuXMh7773HF198QV5eHk888QQAa9euZfTo0dxyyy18++23XHzxxdxwww1s27atgj9FkcBl7buKvWhbBgNfnMHTU9dR4PE5HJWIQ4pz4ddH4bVesGnfmGTp50HKV+DWIkrAsyyb1JxCHv12ta56ixwseTm8OxA6XA6DnoIqiQFRZpadnQ1A1apVj/ictWvXsmDBAqZOnVpS7v3ss88yePBgNm/eDPhnjEePHk2zZs2oX78+zzzzDMOHD6dLly4AtGvXruS5AGeccQajRo0C4H//+x/9+vVj9uzZWJZFSkoKn3/+OdWrVwdgzJgx3HLLLdx9993s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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "fig, axes = plt.subplots(1, 2, figsize=(10, 10))\n", "\n", @@ -160,17 +179,14 @@ "labels = [\"Simple\", \"Compose\"]\n", "values = [\n", " len(df.query(\"identified_category == 'simple'\")),\n", - " len(df.query(\"identified_category == 'compose'\"))\n", + " len(df.query(\"identified_category == 'compose'\")),\n", "]\n", "axes[0].pie(values, labels=labels, autopct=\"%1.1f%%\", startangle=90)\n", "axes[0].set_title(\"Distribution by Category\")\n", "\n", "# Pie 2: Male vs Female\n", "labels = [\"Male\", \"Female\"]\n", - "values = [\n", - " len(df.query(\"sex == 'm'\")),\n", - " len(df.query(\"sex == 'f'\"))\n", - "]\n", + "values = [len(df.query(\"sex == 'm'\")), len(df.query(\"sex == 'f'\"))]\n", "axes[1].pie(values, labels=labels, autopct=\"%1.1f%%\", startangle=90)\n", "axes[1].set_title(\"Distribution by Sex\")\n", "\n", @@ -184,46 +200,44 @@ "plt.savefig(\"../assets/distribution_grid.svg\")\n", "\n", "plt.show()" - ], - "id": "ae30e79a975010d4", - "outputs": [ - { - "data": { - "text/plain": [ - "
" - ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA9MAAAH+CAYAAACfoF2EAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAlQ1JREFUeJzs3Xd4VGXax/HvOTNpJEBC6L036VUULKCI2BELIiyray+rrivqq+ju2rtiFxULKmJBsWBDpHeQ3lsoKYT0OjPnvH8MBCI1kORM+X2uay5gZjJznyHJc+7z3M/9GLZt24iIiIiIiIjIcTOdDkBEREREREQk2CiZFhERERERESkjJdMiIiIiIiIiZaRkWkRERERERKSMlEyLiIiIiIiIlJGSaREREREREZEyUjItIiIiIiIiUkZKpkVERERERETKSMm0hCTbtp0OISBiCBb6rERE5HgFwpgRCDGIiPOUTEulGzFiBG3atCm5tW3blq5duzJkyBA+/PBDvF5vqef379+f+++//7hf/7fffmP06NHHfN79999P//79T/h9jiQ7O5v77ruPRYsWldw3YsQIRowYcdKvfTzK6ziOJCUlhWeeeYZBgwbRuXNn+vbty80331zqeI/X4T4rEREJXhrjK1ZFjvEZGRk8+eSTnHPOOXTo0IFevXrxt7/9jV9++aVC3k8kFLidDkDCU/v27XnkkUcA8Pl8ZGVlMWPGDJ588kkWLVrESy+9hGn6r/W8+uqrxMXFHfdrjx8//ried+uttzJy5Mgyx34sa9as4ZtvvuHyyy8vuW//sQa7xYsXc9ttt5GQkMDIkSNp1qwZmZmZTJw4kREjRvDkk09y6aWXHvfrHe6zEhGR4KYxPvgUFhYyfPhwfD4fN954I02aNCEnJ4cff/yR22+/nQcffJC//e1vTocpEnCUTIsj4uLi6NKlS6n7+vfvT/PmzXn88cf57rvvuPjiiwH/oFwRGjduXCGvezgtW7astPeqKJmZmdx11100bdqU999/n5iYmJLHzjvvPG688UbGjBlD3759qVmzpoORioiIkzTGB5+pU6eyadMmfvrpJ5o2bVpy/znnnENhYSGvvPIK1157LS6Xy7kgRQKQyrwloFx77bXUqVOHzz77rOS+v5Y07R+EO3XqxKmnnsq9995LSkoK4C+1WrBgAQsWLKBNmzbMnz+f+fPn06ZNGz777DPOPvtsunXrxuzZsw8pAQPweDw89thj9OzZkx49ejB69Gj27t1b8vjhSrn2v/7+99p/JXzkyJElz/3r1xUVFfHaa68xaNAgOnbsyMCBA3n77bexLKvUe/3f//0fb7/9NmeddRYdO3bk6quvZvny5cf8HI92HNOnT6dNmzbMmjWr1NcsWrSINm3asHjx4sO+5uTJk0lNTeXBBx8slUgDmKbJvffey/Dhw8nNzS25f9KkSQwZMoQuXbrQqVMnLrnkEn788ceSz+1wnxXAr7/+ypAhQ+jYsSOnn346jz32GPn5+aXec/r06QwZMoROnTpx3nnn8d1333HuuecyduzYkuekpqbywAMPcOaZZ9KpUyeGDh3Kb7/9Vup12rRpw6uvvlryWq+++iodO3bkhRdeKPW8goICunfvzhtvvHHkD15ERI5IY3zgjvF79uwBKBXjfjfddBO33norxcXFJfetX7+em266iW7dutGtWzduu+02kpKSSh6//fbb6dixI5s3by65b+zYsbRr144FCxYc8xhFgoWSaQkopmnSp08fli9ffsi6KvCXGd93330MHDiQd955hwceeIB58+bxr3/9C/CXWrVv35727dszceJETjnllJKvffXVVxk9ejRjxoyha9euh33/H3/8kVWrVvHUU08xevRopk+fzg033IDP5zuu+E855RTGjBkDwJgxYw5b+mXbNjfffDPjxo3jiiuu4M0332TQoEG89NJLhzz/p59+4rfffuOhhx7ihRdeYM+ePdxxxx3HjOdox9GvXz9q167NN998U+prJk+eTNOmTenevfthX3PmzJnUrFmTTp06Hfbxtm3bMnr06JIr2hMmTGDMmDGcc845vPXWWzz33HNERkZy7733kpycfMTPasqUKdx22200b96c1157jdtvv51vv/2WW2+9taThy7x587j11lupV68eY8eOZfjw4TzyyCPs3r27JJ49e/YwdOhQFi1axN13383YsWNp0KABt912G99++22p2N98800uuugiXnnlFc477zzOOeccpkyZUqrBzC+//EJ+fn6ZythFROQAjfGBO8b369cPt9vN3/72N1599VWWLVuGx+MBoFOnTlx//fUlF9K3bNnC1VdfTXp6Ok8//TSPP/44SUlJDBs2jPT0dAAeffRRqlSpUnLMK1eu5M033+S6666jV69e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/bZt2zJhwgRefPFF7rvvPmzbpnXr1rz22msMGDCA/Px8HnjgAVq3bs31118PQGxsLGPGjOGWW25h3Lhx3HTTTeXyWYg4zbCP1AlIRELeI488wp9//nnIlfdA99tvv1G3bt1Se4xu2LCBCy+8sEzJ8rH88MMP3Hffffzxxx+HNDwTEREJZME6xosEE81Mi4ShDz/8kM2bN/P555/z7LPPOh1Omc2aNYsffviBe++9l2bNmpGSksIbb7xB8+bN6du370m//q+//sqKFSv47LPPGDJkiBJpEREJGsE+xosEEyXTImFo0aJFzJw5k7/97W9ceOGFTodTZqNHjyY6Opo33niD1NRU4uPj6devH//617/KpeP2jh07+OCDD+jevTv//ve/yyFiERGRyhHsY7xIMFGZt4iIiIiIiEgZaWssERERERERkTJSMi0iIiIiIiJSRkqmRURERERERMpIybSIiIiIiIhIGSmZFhERERERESkjJdMiIiIiIiIiZaRkWkRERERERKSMlEyLiIiIiIiIlJGSaREREREREZEyUjItIiIiIiIiUkZKpkVERERERETKSMm0iIiIiIiISBkpmRYREREREREpIyXTIiIiIiIiImWkZFpERERERESkjJRMi4iIiIiIiJSRkmkRERERERGRMlIyLSIiIiIiIlJGSqZFREREREREykjJtIiIiIiIiEgZKZkWERERERERKSMl0yIiIiIiIiJlpGRaREREREREpIyUTIuIiIiIiIiUkZJpERERERERkTJSMi0iIiIiIiJSRkqmRURERERERMpIybSIiIiIiIhIGSmZFhERERERESkjJdMiIiIiIiIiZaRkWkRERERERKSMlEyLiIiIiIiIlJGSaREREREREZEyUjItIiIiIiIiUkZKpkVERERERETKSMm0iIiIiIiISBkpmRYREREREREpIyXTIiIiIiIiImWkZFpERERERESkjJRMi4iIiIiIiJSRkmkRERERERGRMlIyLSIiIiIiIlJGSqZFREREREREykjJtIiIiIiIiEgZKZkWERERERERKSMl0yIiIiIiIiJlpGRaREREREREpIyUTIuIiIiIiIiUkZJpERERERERkTJSMi0iIiIiIiJSRkqmRURERERERMrI7XQAIgJey8K2AANcpoFpGIc8p9DjI6vAQ2Z+MfnFPnyWjdey8e27eS2L01vUJLIoHWPXMjDd4HKDGbHvz303dzRUSYToeDD/cj3N8lISiOmGw8QhIiISyjw+CwC3aWAcYRz0+ixyi7zkFHrJLvSQW+TF6/OPx5btH5/7tqxJVPFejJ1LDozBpuvAnxGxUKUGRFeHiJhD38S2wPKBbfvHa1On7SKBRj+VIpVg/+Aa4TqQvKblFJGWU8ie3GLS84rJyCsmI3//nx725heTmV/M3rxiMvM9FHmtY77PggcHUHv3Yvj06mMHZZj+pDquNsTWhrhaEFvrwN/j6kDV+v6/xySUHsRtGyyPP1FXwi0iIkHC3pfoGga4D7qg7PFZpGQXsn1vPkl7C9iZmc+enGKyCz1kF3jILvSSU+ghu8CfPB/PmDzvgQHUSV0Gn1x57MDcURBTw59cV0nc9/dEqJJw4N+xNf3jdNV6/rF7P5/HPxYr2RapdPqpEykntm3j9dm4XAdmlgs9Pram57EuOYfNaXlsTstlU1oeW/bkUeDxORywBXlp/hurjv5cw/DPZO9PvGs0gzqnQN1OUKcDRFfzP8/y+v/UgC4iIg7z+KySai/LttmZUcDG1Fx2ZPiT5Z0ZBezMLGBHRgFpuUXYtoPBeosgZ7f/djwiqkBiS6jZ6sCftdpBYosDs9y25R+XdeFbpMLojFfkBFi2jWXZuPfNNCdnFbIhNYeNqblsTstjU5r/z+TsQocjLSe2DQUZ/lvaOtg6s/Tj1er7k+s6Hfx/1usCNZr7y9gAfMUazEVEpEL8tforv9jL2uQcVu7MYs3ubNbszmFdco7zF7HLkycfkpf7b39Vtd6+JLsV1GwJNdtArbZQrZ6/Ks3n8Y/PhloniZwsJdMix8FrWZgYmKZBocfH0u0ZLNiyl0XbMli6PZPcIq/TITore5f/tuGXA/e5o6Bm6wMJdt1OUK+Tv2Qc/IO5K8KZeEVEJGh5fFbJeuaU7EL+TMpk9e5s1uzOZvXubHZkFDg7y+y0/TPcW2aUvj+qKjTsCY16Q5PT/H+PiAHL8s9iu5QWiJSVfmpEDsPjs0qucKfnFjFvczqLtmWwcOte1uzOwWeF8yh9nLxFkLzCfztYbC2o3xWanwWtzvNfNbdtf5MVDeQiIvIXB4/JOzMLmLVhD/O3pDN/8152ZhY4HF0QKcqBTdP8N/DPTtfpAI1PhUanQtO+B9Zi+4rBFelcrCJBQmeuIhwYqC3bZktaHvM2p7NwawaLtu1lR4YG6nKVlwYbfvbffnrQXyLe/GxoMQBaDoCYeP8aL8NUCZqISBg6OHlO2pvPzIOS55BZPhUILB/s/tN/m/+W/77qjaBx7wPJda02B0rDVU0mcggl0xKWbNu/fYXbZbI3r4ifVqUwbW0q87ekk10Q5iXblS17Fyyb4L8Zhr8cvEV/aHmuvxTN5dYgLiIS4rw+C7fLJCOvmJ9WJzN7wx7mb9lLak6R06GFl6wkWJEEK77w/zuqKjQ7E9peCG0v8Dcc1ZgsUkLJtIQN376tMEzDYF1yDj+tSua3tams2JkV3murAoltH7hKPutFf7fSpqfvS64HqiRcRCREWLaNbYPLNNi+N58flu/m59UpLEvKQCupAkhRDqz9zn8zXdC4jz+pbn+pv7LM8oLhUoNRCVs6G5WQ5rNsTMOffy3aupfvlu/ml9UpKhMLFp58f1OzDb8ADxwoCW8zGFoPAtMEG/+fIiIS0HyWhWH4t6patTObH1fu5qdVKWxKy3U6NDkelg+2zvLfpj7gX2+9P7Gu097fyAz7wE4eImFAybSEHJ9l7dtTEuZtTue75bv4eVUK6XnFTocmJ+vgkvCYBOhwOXQdCfU7g8+r2WoRkQBj2TbYYGMzZ2M6U1cl88vqFJVvh4KUlf7bH0/711q3HQxtL/J3CjdMf4dwJdYS4nTmKSFj/3qrZdszmbhoBz+vTiYz3+N0WFJRCjJg4Tj/rWZr6HKN/xZXR+u5REQctn9M3piay2cLtjN52S726qJ26MpK8jcxm/+W/2J32wug+9+hYQ9d7JaQpu9sCWo+y8JlmmQXevh8YRKfLkhSuVg42rMefn0Ufvuvv1FKl2ug/SX+bT10ZVxEpFJ4LQu3aZJT6OHLJTuZtCiJVbuynQ5LKltBBiz92H+r1Ra6/w26XOtvXmZ5wVT6IaFD380SlPZf8V6yPZOP521j6spkiryW02GJ02wLNv/uv31/D7S7GLqOgCZ91CRFRKQC2LaNZYMBzNmYzsSFSfy6JkVjsvilrfWvr/71UWh3EfS43l8GrqRaQoS+iyVoHDwLPXFhEp8t2M6mtDynw5JAVZRzYH11fBPofJU/sY5vrDJwEZGTtP+idlJGAZ8t2M6XS3aQkq110HIE3iL/dlsrvoDEFtDtb9BtpL8kXIm1BDF950rAK5mF3pbJR/O28dMqzUJLGWVugz+e8d8a94HTbvfvmamkWkSkTPaPyYu2ZfDmH5v4Y32atpeUsknfBL+MgWn/gzYXQI/roPmZSqolKOk7VgKWz7IpKPbx6cLtmoWW8rN9rv9Wqw2cfjd0uhL/Vh76dSgiciRey8LAYMryXYybuUVroeXk+TywerL/ltAUuo+CXjeCO1q9TiRo6OxRAopt29g25BZ5efOPTXw0dxs5RV6nw5JQlLYOJt8M05+A0+7wl5yZbg3gIiL72LaNDRQU+/ho3jbGz95Kcnah02FJKMrY6l9XPesl6H0j9LkDouIAQ71OJKApmZaAsH/Azi7w8Mb0TXw8bxt5xT6nw5JwkLkdfvi3vwT81Fug9826Ki4iYc1n2bhMg+TsQt6ZsZmJC5M0JkvlKMz0j8dzX4ee/4C+d0F0dZRUS6BSMi2OsvcttNqbV8zr0zfxyfztFHg0YIsD8tL8W2vNesk/gJ9+574BHDBMR0MTEakM+5PoTWm5vPLbBn5cmYzP0oJocUBxLsx+CRa85a8c6/cviK0F2BqTJaAomRZHWJaNYcCe3GLGTtvAxIVJaiomgaEoG2a9APPfgK7XQt9/QbV6YFlgagAXkdCzP4nelp7Hcz+v48eVyWoqJoHBUwDz34TF70OX4XDGv6Faff9WmEqqJQAomZZKZdk2pmGQmlPEK79t4IvFOyj2KYmWAOQpgAXvwKL3oeMV/gE8sQVYPpWAi0hI2D8m78os4Lmf1zHlz11oIloCkrcIFr0HSz6ETlfBmaMhoYnGZHGckmmpFPvLuXdnFvLybxv4eukOPD6N2BIELC/8+Sks/wzaXQwDH4PqDXVFXESCmmXb7M0t5tmf1/HF4h0q55bgYHlh2QT/mNz+Uuj/sD+p1pgsDlEyLRXOa1kUeSye+3kdH83dhlcDtgQj24bV38D6qXDqbf6r4qYbXPo1KiLBw2fZFHp8jJ22gfFztlLoUXWYBCHLByu/hDXfQq+b4OwHwR2lbS6l0uk7TiqM12dhmgZfLt7BM1PXkZ5X7HRIIifPW+RfU738Mzj3f9BxqP9KeRAN4FlZWbzxxhv8/PPPpKenU79+fa666ipGjhyJqXXhIiHJ67OwgfdmbeH16ZvIKvA4HZLIyfN5YO6rsHwinPMIdB0BPq8udEul0XealDvLsjFNgzW7s/m/yStZviPL6ZBEyl/2Lvjyelg4Di54Aeq0989eB/jWHRkZGVx11VXUrl2bxx9/nIYNG7JixQr+97//kZSUxMMPP+x0iCJSjvY3F5uzKZ2Hv1nJtvR8p0MSKX95afDN7bDwPbjgOWjQXY1DpVIomZZy5bNssgs8PP7DGr5cskPdQCX0bZ8Lb/WFbqP8V8UjYwN6lvr5558nMjKSd999l6ioKAAaNWpEdHQ0t956K9deey3NmjVzOEoRKQ8+y2ZPbhFjvlnFT6uSnQ5HpOLtWgLjBkDHK+G8xyGmhhqUSYXS5RopF16fhc+yeX/2Fs545ne+WKxEWsKI5YNF78LLnWHxeP+WHT6v01Edori4mO+//57hw4eXJNL7nX322YwfP54GDRqQlZXFww8/zGmnnUb37t3597//TVaWv8Jk/vz59O/fny+++ILTTz+dnj178s4777Bw4UIGDRpE165due+++7As/zrMESNG8OqrrzJs2DA6d+7MNddcw6ZNm0reNzk5mX/+85/06tWL3r1789hjj1Fc7F8S4vF4eOihh+jduzddu3bl5ptvJiUlpeRrf/nlFwYPHkznzp0ZOnQoCxYsqOiPUCQo7B+T356xibOena5EWsKLbfvLvl/uAnNe8ZeC+7SsQSqGkmk5Kfu7fy7YspfzXprBY9+vIaco8JIIkUpRkAHf/wveOhN2LfbfZwdOc5/t27eTn59Px44dD3nMMAxOPfVUIiMjuf3221mzZg1vvvkm77//Pps2beL+++8veW5qaiq//vorH330ETfffDMvvPACTzzxBE899RQvvPACP/zwA7/99lvJ89966y3OO+88vvrqK+rUqcONN95IcXExxcXF/O1vf6OgoICPPvqIl156ienTp/PMM88AMGHCBBYuXMh7773HF198QV5eHk888QQAa9euZfTo0dxyyy18++23XHzxxdxwww1s27atgj9FkcBl7buKvWhbBgNfnMHTU9dR4PE5HJWIQ4pz4ddH4bVesGnfmGTp50HKV+DWIkrAsyyb1JxCHv12ta56ixwseTm8OxA6XA6DnoIqiQFRZpadnQ1A1apVj/ictWvXsmDBAqZOnVpS7v3ss88yePBgNm/eDPhnjEePHk2zZs2oX78+zzzzDMOHD6dLly4AtGvXruS5AGeccQajRo0C4H//+x/9+vVj9uzZWJZFSkoKn3/+OdWrVwdgzJgx3HLLLdx9993s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" - }, - "metadata": {}, - "output_type": "display_data", - "jetTransient": { - "display_id": null - } - } - ], - "execution_count": 6 + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "### Simple vs Compose by Province", - "id": "d31d8ae890cdfece" + "id": "d31d8ae890cdfece", + "metadata": {}, + "source": [ + "### Simple vs Compose by Province" + ] }, { + "cell_type": "code", + "execution_count": 7, + "id": "6d5c1abb55b7076a", "metadata": { "ExecuteTime": { "end_time": "2025-09-28T21:42:04.514885Z", "start_time": "2025-09-28T21:42:04.038820Z" } }, - "cell_type": "code", + "outputs": [ + { + "data": { + "image/png": "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6SXNmzdPiYmJWrZsmWXsF198oXvuuUexsbFq3LixBg0apLS0NJs53377bSUlJenjjz/WggULdPHiRY0YMaLA7+NWI4QCAAAAAAC4hf744w8ZDAZVqlRJlStX1vPPP68333wz18v6hg4dqho1aqhLly4qV66cOnfurPvvv18NGzZUs2bNdPToUcvYe+65Ry+//LKqVaumkSNHysfHR6tXr7aa7/Lly1q0aJHGjx+vevXqKTg4WNOnT9fOnTvtckP0guByPAAAAAAAgFuoRYsWql69urp27apatWopPDxcvXr10rFjx2zGBgYGWv5dvHhxBQQEWP38z5VY/7z0zs3NTbVq1dKRI0es5jtx4oSys7PVu3dvq+0mk0nHjh1TcHDwzb69QiOEAgAAAAAAuIVKlCihpUuXaufOndqyZYu++uorLVmyRK+99prNWHd3d6uf3dzyvmjNw8M6xjEajTbjjUajJGnx4sUqWbKk1b5y5coV6H3calyOBwAAAAAAcAvt2bNHc+bM0X333aeRI0dq7dq1yszMtAmRCmr//v2WfxuNRh04cMBmZVNgYKDc3d11/vx5BQUFKSgoSN7e3poyZYrOnTt3U+e/WayEAgAAAAAAuIWKFy+uDz74QOXLl1ezZs30448/KiMjQ+fPn7+peXfu3Kn58+erdevWWrRokS5fvqyOHTtajfH29lavXr30xhtvaMKECSpXrpymTJmikydPqnLlyjd1/ptFCAUAAAAAAFyOl5eX056nZs2amjRpkmbNmqUJEyaoUqVKevPNN1W+fPmbqiUsLEw//PCDZs6cqVq1aumTTz5RmTJlbMZFRUVp2rRpGj58uLKzs9W4cWN99NFHNpf+/dcM5txuzQ44KaPRqMTERMUkGrX35EVHlwMn07F2BU3uUUfJycnKzMx0dDkAAACAw3h6eiotLU0hISEODx5uxpUrV/T777+ratWqKl68uGW72WyWwWD4z+r4r8+Xm6ioKEnS1KlTHVpHbvL6Pf0b94SyszNnzuj1119XixYtVK9ePXXu3Fnz5s1TTk6OJCklJUXBwcFWr9q1a6tFixaaOHGi1V3ww8LC9NVXX0mSduzYYXPctVdYWJjV3G+//bZNXTExMYqIiJAkRURE5DlXcHCwUlJSJEkZGRkKCQlR3759beb76quvLOfNTVRUVJ7zx8TEFPLTBQAAAADc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UP+BiIgIBQUFadKkSTb7Lly4IEkqU6ZMrsde237+/HnLti5duig0NFShoaGqU6eOXn75ZUVGRurpp5++YS2lS5eWJF26dCnPMX/99ZdGjBih0NBQxcfH6/fff7/hvJ07d9aGDRssP69Zs0YtWrTQHXfcccNjAQAAAABA0UcI9R9wd3fXG2+8oa+//jrX+zZJVy/Ly82ZM2ckSWXLlrVs++ijjxQXF6dZs2apSpUqatSokQYPHnzDy/Ek6eLFi5Ikb29vzZ492xJmhYaGateuXZKkjIwM9evXT5988omqVaumkSNH2twc/d+6dOmin376SefOnZNkeymep6enpKsrt/7NZDLJw8PjhrUDAAAAAADXRQj1H2nQoIEeeeQRTZo0SZcvX7Zsr1u3rtzd3ZWUlJTrcUlJSQoODpaXl5dlW6VKlRQUFKRmzZppzpw5+vrrrzVt2rR81XHw4EF5enrqrrvuUu/evRUXF2d51alTR5J055136vnnn5eHh4cmTpyovXv36tNPP73uvPfee6/uvfdebdy4UXv37lVaWprCw8Mt+729vSVJ6enpNsf+/ffflhVaAAAAAACgaCKE+g+9/PLLysjIsLpJua+vr9q2batZs2bJaDRajU9NTdWyZcv06KOP5jlnlSpVNGzYMC1atEg///zzDWv46quvFBYWpmLFiqls2bIKCgqyvIoXLy5JViuq6tSpo379+undd9+94WV5Xbp00aZNm7Rx40aFhYWpRIkSln2lSpVSYGCg9uzZY3WM0WjUvn37VKtWrRvWDgAAAAAAXBch1H/ojjvu0Msvv6w//vjDavvo0aN14cIFDRw4ULt27dLJkye1YcMGRUZGqkmTJurbt+91542MjFS1atU0YcIEq8vmLly4oLNnz+r06dPat2+fXnrpJe3bt0/PP/98geoePny4ypcvf8PL8jp37qydO3dq/fr16tq1q83+J554Qu+++64SEhKUkpKin3/+WS+++KK8vLzUrl27AtUEAAAAAABcCzfi+Y/17NlTy5cvt9zrSbr6BL0vv/xSs2bN0ssvv6y0tDQFBgaqd+/e6tevn9zcrp8Venh4aMyYMerfv7+WL1+uXr16SZKGDRsmSXJzc1O5cuXUoEEDffHFF7r77rsLVHOJEiU0fvx4Pf300/rss8/05JNP5jouICBANWrU0O+//67777/fZn//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8PDQuHHj9MQTT1g+v/wwGo1au3at/vrrL0sIJV39fa1YsUJDhw7N91wAAAAAAKBocfhKqGurktzd3TVp0iQdOnRIc+bMkXR1Rc/WrVs1aNAgq9U7CxYskCTL6ppt27Zp+fLlNnOXKVNGvr6+kq4+Fa9MmTKKjY21mqtz585as2aNrly5YnN8QECAgoKCFBQUZLmJeO/evbV06VKdPn3aamxOTo4+/PBDtW3bVr6+vvLw8FCnTp30+eefKysry2rs5s2btXnzZlWoUEGS1K1bN3311VeWS/OuOXDggGJjYwt8qd7y5ctVu3ZtBQYGFui4f2rUqJEefvhhTZw4Md/HfP/990pLS9N7771n9RlHRUXp2LFj2r17d6HrAQAAAAAArs3hK6H+qWbNmurfv78lzPn1119lNBoVGRlp8zS6li1bKjY2VoMHD9bQoUP14osvqlixYuratas8PT21e/duzZ07V1OmTJF0dUVV165dVaNGDat5+vfvr4SEBG3cuDFfq4369Omjb775RhEREXrllVdUu3ZtnTx5Uh988IHS09M1evRoy9hhw4apV69eevrppzVs2DDdeeed2rFjh958801FRkbqnnvukSRFRkYqISFBERERevHFF3X33XcrKSlJ06ZNU1hYmB544IE860lPT9fZs2dlNpv1119/admyZVq9erXN/bUyMjJyvYywRIkSVpft/dMrr7yS6+qsvCQkJOjee+9V+/btrbYHBQVp9uzZiouLU4MGDSRJhw4d0tatW63G1a1bV3fccUe+zwcAAAAAAFyHU4VQ0tXgZv369Ro5cqTKlCmjBx54wCaAkq6GQYMHD1ZiYqIefPBBeXl5af78+VqyZImys7MVHBysyZMnKzw8XImJiUpJSVHPnj1t5qlXr55q166t2NjYfIVQbm5umjVrlj799FPNnDlTJ06ckK+vr9q2bau33nrLsvJKkvz8/LRkyRLFxMTo5Zdf1vnz51WlShUNHz5cffr0sYwrXry4PvvsM33wwQcaP368/vzzT/n7+6tnz54aMGCADAZDnvVMnjxZkydPlsFgkK+vr2rVqqVPP/3U5vLC+fPn53rj9549e2rSpEm5zu3r66sXX3xRY8eOveHnkpWVpQ0bNui5556z2VesWDH16NFDy5Yts4R0n3zyic0T+D755BM1b978hucCAAAAAACux2A2m82OLgLIL6PRqMTERMUkGrX35EVHlwMUeR1rV9DkHnWUnJyszMxMR5cDAACAfPL09FRaWppCQkIst8EBHM3h94QCAAAAAABA0UcIBQAAAAAAALsjhAIAAAAAAIDdEUIBAAAAAADA7gihAAAAAAAAYHeEUAAAAAAAALA7QigAAAAAAADYHSEUAAAAAAAA7I4QCgAAAAAAAHZHCAUAAAAAAAC783B0AUBhBJUrqSyTo6sAir6AsiUkSV5eXg6uBAAAAAXh4cHXfTgfuhIuaWzXmnJ3d3d0GcBtwWw2y9/f39FlAAAAoACMRqNOnTrl6DIAK1yOB5dkNpsdXQKQJ7PZrCtXrhSZPjUYDI4uAbdYUetRFD30KFwBfQpnR2/CGRFCwSXxBxXOzGw26/Tp0/QpnBY9CmdHj8IV0KdwdvQmnBEhFAAAAAAAAOyOEAoAAAAAAAB2RwgFAHbg6enp6BKA66JH4ezoUbgC+hQACoan48ElubmRn8J5ubm5qVKlSo4uA8gTPQpnR4/CFdCncHZ8Z4IzoisB3HLcBBEAAAAA8G+shIJLmrBqv347m+HoMpCL+6uV07Nh1ZSamqqsrCxHlwMAAADcljw8+LoP50NXwiUln8vQgVMXHV0GcnFXuZKSpKysLGVmZjq4GgAAAOD2ZDKZHF0CYIPL8QAAAAAAAGB3hFAAAAAAAACwO0IoAAAAAAAA2B0hFAAAAAAAAOyOEAoAAAAAAAB2RwgFAAAAAAAAuyOEAgAAAAAAgN0RQgEAAAAAAMDuCKEAAAAAAABgd4RQAAAAAAAAsDsPRxdQ1IWFhemPP/7Idd+CBQvUtGlT5eTk6NNPP1VsbKxSUlLk6+ur8PBwDR06VL6+vpbxERERatKkiYYNG2Y1z44dOxQZGamDBw/mun3IkCF6/vnnrbbl5eGHH9bUqVMVHByc55hNmzapcuXK+a4nIiJCO3futBpTqlQp1alTR2PGjFH16tXzPBcAAAAAACgaCKH+A6NGjVKnTp1stvv4+MhkMumZZ55RSkqKXn75ZdWqVUsnTpzQ+++/r169emnx4sWqWLFioc6bkJCgKlWqaOXKlRoxYoQMBoNCQ0O1bds2y5gWLVooJiZGoaGhkqTixYtb9v1z+z/9MxjLr6eeekpPPfWUJMlsNuvEiROaNGmSnnvuOa1du1ZubizKAwAAAACgKCOE+g+ULl1afn5+ue77/PPPtW/fPsXHx6t8+fKSpICAADVo0EB9+vTRpEmT9N577xX4nNnZ2Vq3bp1ee+01jR49Wjt37lTTpk3l5eVlU4uPj0+u9eW1vTBKlixpNVeFChU0evRo9e3bV4cOHVKNGjVuyXkAAAAAAIBzYvmJgy1dulQ9e/a0BFDXeHl56ZlnntHGjRv1119/FXje7du3Kz09XeHh4apfv77i4uJuUcW3jpeXlyTJ3d3dwZUAAAAAAAB7I4RyoKysLO3fv1/16tXLdX/Dhg1lNBq1b9++As+dkJCgBg0ayMfHR+Hh4Vq7dq0yMjJutuRb5syZM5o5c6buvfde3X333Y4uBwAAAAAA2BmX4/0Hxo0bp4kTJ1ptq1SpkubPny/p6k26c1OmTBlJKvBKqCtXrmjTpk0aPny4JKl9+/aaMWOG1q9fr4ceeijf8wwcONBmlVLDhg01d+7cAtUjSXPmzLG8X6PRKElq3ry55syZw0ooAAAAAABuA4RQ/4Hhw4erffv2Vts8PDx0xx13SJJOnz6d63Hp6emSrt5T6toxJpPJZpzJZJKHx///VW7ZskWXLl1SeHi4JCkoKEjVq1dXXFxcgUKo6Oho1a9f32rbP29cnt96JKl3796KiIhQVlaWPvvsM3333Xd64YUXFBAQkO96AAAAAACA6yKE+g+UK1dOQUFBue6rUaOGkpKS1KNHD5t9u3fvliTVqlVL0tUw6low9U/p6emWoEq6eimeJHXo0MGyzWQy6fDhw0pNTZW/v3++6q5YsWKedRekHunqTc6vzTVx4kQNHDhQzzzzjFatWmUzFgAAAAAAFD3cE8rBHn30US1fvlypqamSpAMHDqhLly765ptv9NFHH6l169aqUKGCJCk4OFiJiYk2c/z888+WoOrixYvaunWrBg0apLi4OMtrwYIFkqQVK1bcstrzU09uDAaDJkyYoAsXLuitt966ZfUAAAAAAADnRQj1H0hPT9fZs2dtXhkZGerTp4+aNGmiyMhIbdiwQaVKlVKjRo00aNAgJSUlKSoqyjLPI488oiNHjig6OlpHjhzRkSNHtGDBAi1evFj9+vWTJG3YsEFGo1GRkZGqXr265dWkSRO1bNlSsbGx+a77woULudadmZmZ73ryUqlSJT3zzDP63//+p/379xfiUwUAAAAAAK7EYDabzY4uoigLCwvTH3/8keu+ESNGaOjQocrJydEnn3yi2NhYpaSkqGzZsmrZsqVSU1N18uRJTZ48WQ0aNJAkJSUl6Z133tHevXuVnZ2tatWqafDgwWrXrp0k6emnn5aXl5c+/PBDm/Nt2bJFgwcP1v/+9z+FhIRIurqaacGCBWratKnV2ODg4Dzf0/Tp09W9e/d81SNJERERatKkiYYNG2Y1T1ZWljp37iw/Pz8tXrz4Bp/kVUajUYmJiYpJNGrvyYv5Ogb/rY61K2hyjzpKTk62BJYAAAAA/luenp5KS0tTSEgID4OC0yCEcmJms1lr1qzRXXfddd3L224nhFDOjxAKAAAAcDxCKDgjbkzuxAwGgzp16uToMgAAAAAAAG4a94QCAAAAAACA3RFCAQAAAAAAwO4IoQAAAAAAAGB3hFAAAAAAAACwO0IoAAAAAAAA2B0hFAAAAAAAAOyOEAoAAAAAAAB2RwgFAAAAAAAAuyOEAgAAAAAAgN15OLoAoDCCypVUlsnRVSA3AWVLSJK8vLwcXAkAAABw+/Lw4Os+nA9dCZc0tmtNubu7O7oM5MFsNsvf39/RZQAAAAC3LaPRqFOnTjm6DMAKl+PBJZlMLINyZgaDwdElOJTJZFJqaip9CqdFj8LZ0aNwBfQpnB29CWdECAUAdpCVleXoEoDrokfh7OhRuAL6FAAKhhAKAAAAAAAAdkcIBZd0u1/uBedmMBgUGBhIn8Jp0aNwdvQoXAF9CmdHb8IZEUIBgB3k5OQ4ugTguuhRODt6FK6APgWAgiGEgksym82OLgHIk9ls1rlz5+hTOC16FM6OHoUroE/h7OhNOCMPRxcAFIabG/lpQZjNZpbj/ofc3Nzk7+/v6DKAPNGjcHb0KFwBfQpnx3cmOCNCKLikCav267ezGY4uwyXcX62cng2rptTUVJ7gAgAAANwmPDz4ug/nQ1fCJSWfy9CBUxcdXYZLuKtcSUlXHyGcmZnp4GoAAAAA/BdMJpOjSwBssD4PAAAAAAAAdkcIBQAAAAAAALsjhAIAAAAAAIDdEUIBAAAAAADA7gihAAAAAAAAYHeEUAAAAAAAALA7QigAAAAAAADYHSEUAAAAAAAA7I4QCgAAAAAAAHZHCHWTgoODrV733XefxowZo0uXLtmMPXHihIKDg/XKK6/kOldSUpKefvpphYaGKjQ0VI8//ri2b9+erzri4uLUq1cvhYaGqkWLFnrttdeUmppqMy4hIUG9evVS/fr11axZMw0bNkwHDhywGhMREaG2bdsqMzPTantKSoqCg4OVkpJitX3p0qXq1auXGjRoYKl78+bNNuc+c+aMXn/9dbVo0UL16tVT586dNW/ePOXk5OTrPQIAAAAAANdFCHULxMTEaNu2bdq6datmz56tvXv3avr06TbjVq9erSpVqmjjxo02IdWpU6fUr18/hYaGatmyZVq+fLnuu+8+DRo0SD///PN1zz9lyhRNmTJFjz76qOLi4vTBBx/o7NmzeuKJJ5SWlmZV55gxY9SlSxetWrVK8+bN0x133KHevXvr+++/t5rzxIkTmj179g3f++jRozV58mQ99NBDio2N1fLly9WqVSuNGDFCa9eutYxLTU1Vr169lJKSopkzZyohIUHPPvusPv/8cw0ZMkQmk+mG5wIAAAAAAK6LEOoW8PHxkZ+fnypWrKiQkBA988wzWrNmjc24+Ph4PfHEE/L09NS6deus9q1fv16VK1fWc889p2rVqunuu+/WsGHD1LhxYy1fvjzPc+/atUufffaZPvjgA/Xq1UtBQUGqX7++PvjgA+Xk5Oizzz6TJO3bt0+zZs3SBx98oH79+qlKlSqqVauWJkyYoJ49e2rkyJFWK58CAgI0d+5cHTt2LM9zf/PNN1q+fLnmz5+vxx9/XEFBQbr77rs1aNAgDRkyRB988IFl7MSJExUYGKi5c+eqUaNGCgwMVKdOnbRo0SLt2rVLS5Ysye/HDQAAAAAAXBAhlB2UKFHCZtvhw4d16NAhNW3aVC1btlRsbKzVfjc3N/3xxx9KTk622j5t2jQNHz48z3PFxcWpXr16atSokU0NH374oR5//HFJ0rJly1S7dm01b97cZo6hQ4fq9OnT+vbbby3bunfvrurVq2vChAl5nnvZsmVq1aqVQkNDbfZFRkZaArA///xTmzdv1sCBA+Xu7m41rlKlSurRo4e+/PLLPM8DAAAAAABcHyHULZaWlqaFCxeqW7duVtvj4+MVEBCgGjVqKDw8XD/++KP++OMPy/4HH3xQxYsXV6dOnfTUU09p7ty5OnTokCpWrKjy5cvneb4DBw6obt26ue6rVauWKlSoIOnq/abyGufr66u77rpLe/futWxzc3PTG2+8oe+//16rV6/O9bjExEQ1bNgw133e3t7y9fWVdHUVltlszvP8DRs21IEDB5SVlZX7mwQAAAAAAC6PEOoWGDhwoEJDQxUSEqJmzZrp119/VUREhNWY1atXKywsTJLUqlUreXl5KS4uzrK/XLlyWrZsmR555BHt379fb775prp27ap+/frp3LlzeZ47PT1d3t7eN6zxwoULKlOmTJ77fXx8dP78eattdevWVe/evTVlyhRdvHjR5pi//vpLZcuWtfyclZVluan6tdfJkyd14cIFScrz/Ne2//v8AAAAAACg6CCEugWio6MVFxenuLg4ffHFF2rRooX69OljCY/27t2r5ORktW3bVpJUqlQpNW/eXCtWrLCa584779SECRO0fft2LVu2TAMHDlRiYqLGjBkjSRowYIBVwCNJZcuW1d9//33DGn18fPTnn3/muf/MmTNWgdI1L7zwgkwmk959991c5/znuT09PS2fw5w5c5SRkSGTySQfHx9JyvP8Z86csbwXAAAAAABQNHk4uoCioGLFigoKCpIk3XXXXapdu7aaNm2qNWvW6IknnlBCQoIk6amnnrIcYzKZZDab9dNPP6lhw4b66KOPVLduXTVr1kxubm6qW7eu6tatq4CAAE2bNk2SNGnSJF25csXq3LVr11ZSUlKudX322Wf6888/9dJLL6l+/fr66aefch139uxZnTp1KtfL5cqUKaNXX31VI0eOVNOmTa321atXT3v27LH8bDAYLJ/DP+/9VLduXbm7uyspKUl33nmnzTmSkpIUHBwsLy+vXOsDAAAAAACuj5VQduDm5iaz2Syj0SiTyaQ1a9aoe/fullVCcXFxio2Nlbe3t+WSvN27d2vhwoU2c5UpU8Zyb6VrYde1lyR17dpVe/futQmYLl26pM8++0xGo1GS1LNnTx08eFAbN260OceHH36o8uXL64EHHsj1/XTv3l2NGjXS5MmTrbb37t1bX3/9tfbt22dzzOnTpy3/9vX1Vdu2bTVr1ixLPdekpqZq2bJlevTRR3M9NwAAAAAAKBoIoW6BCxcu6OzZszp79qyOHTumCRMmyGg0KiwsTLt27dLp06cVERGh6tWrW141a9ZUt27dtGbNGmVmZmrQoEHaunWrRo8eraSkJCUnJ2v16tV688039eSTT+Z57tDQUPXq1UtDhw7VsmXLdPz4ce3cuVMDBw6Um5ubBg4cKEmqUaOGRowYoVdeeUULFy7UiRMndPDgQUVHR2v58uWa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N0IoeAQfH58qX4yV73/74wqobsnJyXrnnXf06quvqk2bNvLx8akyQ6+8vJxeRbVavHix2rdv7zJjr9LFvlPpUVQ3u92u4uJivfLKKwoNDZX0y01zV61apbCwMPoUlrBjxw598MEH+vTTT+Xr66sOHTro+PHjWrp0qZo1a0afwlIudx56sXOAevXqVVeJqOG4HA8eoXHjxjp16pTOnz9vjBUWFsrX15cvTLhVYmKi3nrrLSUnJ+uOO+6Q9Eu//vjjjy7r/fjjj1WmPgNmysrK0qZNmxQVFaWoqChlZmYqMzNTUVFR9CgsIzg4WD4+PkYAJUktW7bU0aNH6VNYxt69exUWFuYSLLVt21ZHjhyhT2E5l+vJiy0PDg6uthpRsxFCwSPceOONstvtLjfM27Vrlzp06CAvL9oY7rF48WKlpqZq/vz5uvPOO43xyMhIffvttzp79qwxtmvXLkVGRrqjTNRQ7733njIzM5WRkaGMjAzFxMQoJiZGGRkZioyM1Ndff208UcfpdGr37t30KKpdZGSkysrKdOjQIWMsPz9foaGh9Ckso1GjRiooKHCZPZKfn6+mTZvSp7Ccy52HRkZGateuXcay0tJS7du3j55FteHXOzyCn5+f7rnnHj3//PPas2ePNm3apOXLl2v06NHuLg01VF5enpYsWaLx48crOjpahYWFxqtr164KCQlRXFyccnNzlZKSoj179ujee+91d9moQUJDQxUWFma86tatq7p16yosLEz9+/fXTz/9pBdffFEHDx7Uiy++qNLSUg0YMMDdZaOGadWqlfr06aO4uDjt379fW7duVUpKikaMGEGfwjJiYmJUu3ZtPfvsszp06JA2b96sv/3tbxo1ahR9Csu53HnosGHDtHv3bqWkpCg3N1dxcXFq2rSpunXr5ubKUVPYnJWxPWBxpaWlev755/XRRx/J399fDz30kMaOHevuslBDpaSk6JVXXrngsgMHDqigoEDPPPOMcnJyFBYWpvj4eN1yyy3VXCXw/2bMmCFJeumllyRJe/bsUUJCgvLy8hQREaFZs2apbdu27iwRNdSZM2eUmJiojRs3ys/PTyNHjtTkyZNls9noU1hGZcC0Z88eBQYG6oEHHtCYMWPoU1hCRESE3n33XSNIutx56Keffqo5c+bo2LFjioqKUmJiopo1a+au8lHDEEIBAAAAAADAdFyO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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ - "df_name_categories_pct = df_name_categories.div(df_name_categories.sum(axis=1), axis=0) * 100\n", + "df_name_categories_pct = (\n", + " df_name_categories.div(df_name_categories.sum(axis=1), axis=0) * 100\n", + ")\n", "ax = df_name_categories_pct.plot.barh(\n", - " stacked=True,\n", - " figsize=(12, 6),\n", - " colormap=\"tab20c\",\n", - " width=0.85\n", + " stacked=True, figsize=(12, 6), colormap=\"tab20c\", width=0.85\n", ")\n", "\n", "ax.set_xlabel(\"Proportion (%)\")\n", @@ -239,67 +253,44 @@ "plt.savefig(\"../assets/identified_category_distribution_by_province.svg\")\n", "\n", "plt.show()" - ], - "id": "6d5c1abb55b7076a", - "outputs": [ - { - "data": { - "text/plain": [ - "
" - ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAABKEAAAJOCAYAAABvBRRKAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAlKpJREFUeJzs3X98zfX///H72S+/xjRGM7OkzG+bnxFh8ys/SxRqo0Io9Lv5EWF+plIrUagQvUMbNr9/lKhILE1+hIxlfmTRGPtxzvn+4eN8O52NbZzOOXO7Xi7ncrHX6/l6vh7n7PHe+3LuPV+vl8FsNpsFAAAAAAAA2JGbowsAAAAAAABA0UcIBQAAAAAAALsjhAIAAAAAAIDdEUIBAAAAAADA7gihAAAAAAAAYHeEUAAAAAAAALA7QigAAAAAAADYHSEUAAAAAAAA7M7D0QUABWEymZSTkyM3NzcZDAZHlwMAAAAATslsNstkMsnDw0Nubqw/gXMghIJLycnJ0S+//OLoMgAAAADAJdStW1deXl6OLgOQRAgFF3Mtwa9du7Y8PT0dXA2QO5PJpJSUFFWuXJn/6gSnRI/C2dGjcAX0KZxddna29u3bR3/CqRBCwaVcuwTP3d1d7u7uDq4GyJ3BYJCbm5vc3d35P304JXoUzo4ehSugT+HsTCaTJHEbEzgV/lrCJfGHFM7MYDCoXLly9CmcFj0KZ0ePwhXQp3B29CacESuh4JL4gwpnZjAY5O3t7egygDzRo3B29ChcAX0KZ8d3JjgjVkLBJV1bWgo4I5PJpJMnT9KncFr0KJwdPQpXQJ/C2dGbcEashAIAO8jOznZ0CcB10aNwdvQoXAF9Cvy3jEYj/7tzQp6envm+ZzMhFAAAAAAAcFpms1mnTp3S+fPnHV0K8lC2bFndeeedN7wMlBAKAAAAAAA4rWsBVIUKFVSyZEnud+VEzGazMjIydObMGUmSv7//dccTQsEl8UcHzsxgMKhChQr0KZwWPQpnR4/CFdCncHZFpTeNRqMlgCpXrpyjy0EuSpQoIUk6c+aMKlSocN1L8wih4JKKyh9UFE0Gg8HyhxhwRvQonB09CldAn8LZFZXvTNfuAVWyZEkHV4Lrufb7yc7Ovm4IxdPxAACADbPZ7OgSAAAALIpKqFZU5ff3w0oouKQJq/brt7MZji4DAIqk+6uV07Nh1ZSamqqsrCxHlwMAAArBw4Ov+4Vx4cIFffjhh1q/fr3OnTunSpUq6bHHHlNkZKTc3G68juf7779XhQoVVK1atf+gWtdDV8IlJZ/L0IFTFx1dBgAUSXeVu7qcOisrS5mZmQ6uBgAAFIbJZHJ0CS7nr7/+0mOPPaYKFSpo0qRJqly5sn755RdNnDhRJ06c0Ouvv37DOfr3768FCxYQQuWBEAoAAAAAANz23nrrLXl5eWnevHkqVqyYJCkwMFDFixfX0KFD9cQTT6hq1aoOrtK1cU8oAAAAAABwW8vKylJCQoIef/xxSwB1TZs2bfTpp58qICBAhw8f1tNPP63Q0FDVrVtXffv21ZEjRyRJYWFhkqTIyEjFxMRIknbt2qUePXqoXr166tq1q9atW2c196effqqWLVuqQYMGio6OVkREhL766itJUmZmpt588021atVKISEhGjx4sFJTUyVJKSkpCg4O1gcffKDGjRtr1KhRatCggdavX2+ZOzs7W02bNtX3339vnw+tEAihAAAAAADAbe348ePKyMhQ3bp1bfYZDAbdd9998vDw0ODBgxUQEKAVK1boiy++kNFo1JtvvilJWrZsmSQpJiZGTz31lM6ePatnnnlGPXr00KpVqzRgwABFRUVp165dkqSVK1fqvffe06hRo/S///1PKSkp+vHHHy3nHTdunDZs2KBp06bpiy++UE5OjoYOHWp1qeXu3bu1fPlyDRo0SG3btrUKub777jt5eHioSZMmdvnMCoPL8QAAAAAAwG3t77//liSVLl06zzFXrlxR79691bdvX5UsefUemg8//LDmzp0rSfL19ZUk+fj4qFSpUvr444/VvHlzPfHEE5KkoKAg7d+/X5999pkaNWqkxYsXq1+/fnrwwQclSdOmTVOrVq0kXb1B+ooVK/Txxx/rvvvukyTNmDFDrVu31vbt2y2XBfbr109VqlSRJHXu3FkvvPCCMjMzVaxYMa1du1YdO3aUu7v7Lf2sbgYhFAAAAAAAuK2VLVtW0tXwJy8lS5ZUnz59FBcXp6SkJB09elS//vqrypcvn+v4o0ePasuWLQoNDbVsy87OtgRIBw8e1KBBgyz7fHx8LPuOHTsmk8mk+vXrW9VYtWpVHTlyxDIuICDAsv/++++Xl5eXvv32W7Vq1UobN27U7NmzC/hJ2BchFAAAAAAAuK1VqVJFpUuX1r59+1SvXj2b/UOGDNGjjz6q6dOn64477lBYWJi6dOmio0ePav78+bnOmZOTo65du2rw4MFW2z08rkYx7u7uMpvNVvuu/fzv+1JdYzQarS7H++c4Dw8PdejQQevWrZOnp6e8vb3VoEGDfLz7/w73hAIAAAAAALc1Dw8PderUSZ9//rmysrKs9m3evFmbN2/WiRMndObMGS1YsEADBgxQ8+bNdfLkSZsg6ZqqVasqOTlZQUFBltemTZu0atUqSdI999yjffv2WcZfvHhRycnJkq4+lc/Dw0OJiYmW/X/99ZeSk5Ov+4S+rl27auvWrdq8ebM6duwog8FQ2I/ELgihAAAAAADAbW/YsGG6ePGinn76ae3cuVPHjx/X0qVLFRUVpcjISNWtW1cZGRnauHGjUlJStHTpUpvQqmTJkvrtt9+Unp6uvn37KikpSe+8846OHTumVatW6e2331alSpUkSREREVqwYIHWr1+vI0eOaNSoUcrIyJDBYFCpUqXUq1cvTZw4UTt27NCBAwf0yiuv6M4779T999+f53to2LChSpQoodjYWHXu3Nnun1lBcTkeAAAAAAC47fn5+WnJkiWKiYnRyy+/rPPnz6tKlSoaPny4+vTpI3d3dz377LMaP368MjMzFRwcrLFjx2r06NE6ffq0KlasqIiICE2fPl3Hjx/XqFGjNHv2bM2YMUPz5s1TxYoVFRUVpW7dukm6eiPx5ORkjRs3TpmZmXrssccUEBAgT09PSdJrr72madOmafjw4crKylLz5s316aefysvLK8/3YDAY1LFjR23evFl16tT5Tz63gjCY81o3hv9cdna2Zs+erbi4OJ0+fVrly5dXhw4dNGzYMHl7eysqKkqSNHXqVKvjUlJSFB4erk2bNqly5cqKiopSbGysZb+Xl5cCAwP12GOPKTIy8rrL8YKDg7VgwQI1bdrUsm3r1q0aMmSIBg8erGHDhlnqmDJlitq0aaPu3bvrhRdesJnrww8/1KpVq7R69WpFRESoSZMmGjZsmNWYHTt2KDIyUgcPHszXZ2Q0GpWYmKiYRKP2nryYr2MAAAXTsXYFTe5RR8nJycrMzHR0OQAAoBA8PT2VlpamkJAQp3o6WkFduXJFv//+u6pWrarixYs7upxbaufOnQoMDJS/v7+kq/eQuu+++/TBBx9YfScvqJdeeklBQUEaPnz4rSr1hvL7e2IllBOZMWOGvvvuO0VHRyswMFAnTpzQpEmTlJycXOA72j/44IMaPXq0JCkjI0M//PCDpk6dqr///tsmCLqen3/+WSNGjFDfvn1tjjMYDOrUqZPWr1+fawi1Zs0adenSpUB1AwAAAABwO9i4caP27Nmj8ePHq1SpUlqwYIG8vb0VEhJSqPkSExO1b98+bdq0SfHx8be22FuEe0I5kdjYWI0YMULNmjVT5cqV1axZM73xxhvasmWLzpw5U6C5ihcvLj8/P/n5+SkoKEiPPfaYRo0apTlz5uj06dP5muPo0aMaNGiQOnbsqFGjRuU65trTAA4fPmxz7MGDB9W1a9cC1Q0AAAAAwO1g+PDhqlq1qp588kl1795dR48e1dy5c/N8Mt6NfPvtt5oxY4ZeeOEFVa5c+RZXe2sQQjkRg8GgH374wepxi6GhoUpISNAdd9xx0/N369ZNnp6e2rp16w3Hnj59WgMGDFDTpk0VHR2d5yV8tWrV0t13363169dbbV+zZo3q16+vwMDAm64bAAAAAICixtvbW9OnT9eOHTuUmJioTz75RPfcc0+h5xs2bJj27Nmjfv363cIqby1CKCcSGRmphQsXKiwsTOPGjdO6det05coV3XPPPZYbk92MYsWKqXLlyjarlv4tPT1dAwYM0Pnz5zV16tQbXj/cuXNnmxBq7dq1XIoHAAAAAAAsCKGcyLPPPqs333xTd955p7788ksNHz5cLVu21PLly2/ZOby9vXXp0qXrjhk3bpy8vLxkMpk0f/78G87ZtWtX7d+/XydOnJAkHTlyREeOHFGnTp1uSc0AAAAAAMD1EUI5mW7duumLL77Qd999pxkzZujee+/V6NGjlZSUJA8PD6tL9a659oDD/KyWunjxory9vXXy5EmFhoZaXmPHjrWM8fX11fz58zV8+HDNnj1bBw4cuO6cQUFBqlOnjmU11Jo1a9SsWTOVL1/eMiav2k0mkzw8uD8+AAAAAABFHSGUkzhw4ICmTp1q+fmOO+5Q165dtXDhQt1555364YcfVLp0aaWnp9sc+/fff0uSSpcufd1zZGZm6tixY7r33ntVoUIFxcXFWV4jRoywjBs5cqR8fHzUr18/Va9eXSNHjlROTs515+7atas2bNggKfen4uVVe3p6+g3rBgAAAAAAro8QykkYjUZ98skn+vXXX622e3l5qXjx4vL19VVwcLCSkpKUnZ1tNebnn3/WXXfdpZIlS173HKtWrZLBYFCbNm3k4eGhoKAgy6tcuXKWcdfuAeXu7q5Jkybp0KFDmjNnznXnfvDBB/XLL79o165dOnHihNq1a2e1Pzg4WImJiTbH/fzzz6pVq9Z15wYAAAAAAK6PEMpJ1K5dW61bt9bQoUO1atUqpaSkKDExUePGjVNWVpbat2+vdu3ayWAw6NVXX9WBAweUnJysuLg4vfvuu+rfv7/VfFeuXNHZs2d19uxZJScna9GiRZo8ebKGDBkiX1/ffNdVs2ZN9e/fXx9++KEOHjyY57iKFSuqYcOGio6OVuvWreXt7W21/5FHHtGRI0cUHR1tuWfUggULtHjxYqe+cz8AAAAAALg1uBmPE5k5c6Zmz56t999/XydPnlTJkiXVokULLVq0yBLqLFq0SG+++ab69++vjIwMValSRS+99JIeffRRq7nWrFmjNWvWSLp6M/KqVatqzJgx6tGjR4HrGjZsmNavX6+RI0fqyy+/zHNcly5d9Prrr+vZZ5+12XfnnXdq4cKFeuedd9S7d29lZ2erWrVqmj59ulq1alXgmgAAAAAAgGsxmK/d1RpwAUajUYmJiYpJNGrvyYuOLgcAiqSOtStoco86Sk5OVmZmpqPLAQAAheDp6am0tDSFhIRYbrniiq5cuaLff/9dVatWVfHixR1dDvKQ398Tl+MBAAAAAACXYjT9t+tp/uvzFVVcjgcAAAAAAFyKu5tBo2P36fc/L9n9XFXLl9Kkh2sX+Ljk5GRNmDBBu3fvlo+Pj5566ilFRkbqyJEjmjx5svbs2aNSpUrpscce09ChQ+Xm5qaYmBidOHFCpUuX1ldffaU77rhDEyZM0LFjxzRr1iyZTCYNHTpUkZGRkq4+BCw6Olpz5szRuXPnFBYWpgkTJqhUqVKSpD179mj69Onav3+/fH19NXDgQPXp00eSdPLkSY0ZM0Z79uxR8eLF1alTJ0VFRcnT01Nms1mzZs3SkiVLdOXKFTVq1Ehjx45VpUqVbuqzJIQCAAAAAAAu5/c/L+nAKee8TUtmZqaeeuop1a5dW19++aVOnDihl156ST4+Ppo8ebLCwsK0dOlS/f777xozZoy8vb0tDxxbvXq1BgwYoBUrVujtt9/W888/r0aNGmnhwoVau3atpk2bpi5dulgeOvbuu+8qOjpa5cqV06hRozR27Fi99dZbOnLkiPr166f+/ftr0qRJ+vnnnzV+/HiVL19e7dq108SJE1WyZEnFxcXp3LlzGj58uO6++249/vjjWrRokVatWqW33npL5cuX1/z58/XUU09p1apV8vT0LPTnwuV4AAAAAAAAt9C2bduUlpamyZMn695771VYWJjGjBmj8+fPq0SJEpo4caKqVaumtm3basSIEZo7d67l2DvuuEMjRoxQlSpV9PDDDys9PV2jR49WtWrV9PTTTysnJ0fJycmW8QMHDlTr1q1Vt25djR49WmvWrFF6erq+/PJL1apVSy+++KLuvvtuPfzww3riiScs5/rjjz9UunRpVapUSQ0aNNBHH31keXDY3Llz9eqrr6pp06aqVq2aJkyYoAsXLujbb7+9qc+FEAoAAAAAAOAWunaT7mtPupekRx55REePHlXt2rXl4fH/L0wLDQ3V2bNn9ffff0uSKleuLIPBIEmWm3wHBARY/ZyVlWU5vkGDBpZ/16lTR0ajUb///ruOHDmievXqWdUVGhqqI0eOSJIGDBigVatWqVmzZnrxxRd18uRJVa5cWZcuXdKpU6f0wgsvKDQ0VKGhoWrUqJHOnz+vY8eO3dTnwuV4AAAAAAAAt9A/Q6Z/KlasmM02k8kk6erT4PM61s0t7zVE/7w87tpcbm5ueZ7r2nm6deumZs2aaePGjfr66681fPhwDRw4UE8//bSkq5f5Va1a1ep4Hx+fPOvID1ZCAQAAAAAA3EJ33XWXkpOTdfnyZcu2adOmafHixdq3b5+ys7Mt2/fs2SNfX1+VLVu2UOfav3+/5d9JSUny9PRU1apVVbVqVf38889WY/fs2WMJlt555x2dO3dOffr00Zw5c/T8889r/fr1KlOmjMqVK6ezZ88qKChIQUFB8vf315tvvqnff/+9UDVeQwgFAAAAAABwC7Vo0ULly5fX2LFjdeTIEW3atElffPGFZs6cqaysLMv2jRs3KiYmRn369LFcgldQ7733nnbu3Kmff/5Z0dHRevjhh1WqVCn17dtX+/fv19tvv63ff/9dsbGxWrx4sR5//HFJ0tGjRzVhwgQdOHBAv/32m7755hvVqlVLktS/f3/NnDlTmzdv1rFjxzRmzBjt3r1bd9999019LlyOBwAAAAAAXE7V8qWc9jweHh6aNWuWJkyYoIcffljly5fXq6++qrZt26pSpUqaNGmSHnroIfn6+qpfv3565plnCl3fQw89pKioKP3999/q3LmzRo8eLUmqVKmS5syZo+nTp2v+/PmqVKmSoqKi9Mgjj0iS3njjDY0fP14RERHKyclR69atLcc+/fTTunTpksaOHauLFy+qTp06mjdv3k1fjmcwm83mm5oB+A8ZjUYlJiYqJtGovSed81GcAODqOtauoMk96ig5OVmZmZmOLgcAABSCp6en0tLSFBISInd3d0eXU2hXrlyx3OT72k25JcloMsvdrXArhwrjvz5ffgUHB2vBggVq2rSpQ+vI6/f0b1yOBwAAAAAAXMp/HQg5YwDlirgcDy4pqFxJZZkcXQUAFE0BZUtIkry8vBxcCQAAKKy8ns4GOBJdCZc0tmtNl15SCgDOzmw2y9/f39FlAACAQjIajTp16pSjy4CdHTx40NElFAiX48ElmUwsg4LzMplMSk1NpU/htPLTo4V9OgtwK/B3FK6APoWzozfhjAihAMAOsrKyHF0CcF30KJwdPQpXQJ8CQMEQQsEl8V/o4cwMBoN8fHzoUzgtehTOjh6FK6BP4ezoTTgj7gkFl8QfVDgzg8GgsmXLOroMIE/0KJwdPQpXQJ/C2fGdCc6IlVBwSVzfDGdmMpl07tw5+hROix6Fs6NH4QroUzg7ehPOiJVQcElubuSnyJ3ZbHb4f/Vxc3NTuXLlHFoDcD30KJwdPQpXQJ/C2fGdCc6IEAouacKq/frtbIajy4CTub9aOT0bVk2pqancKBQAAAC3NQ8Pvu47ox07digyMlIHDx685XMHBwdrwYIFatq06S2f+1ahK+GSks9l6MCpi44uA07mrnIlJV19Uk1mZqaDqwEAAAAch8vxnFNoaKi2bdvm6DIchvV5AAAAAADApZjNZpc8n5eXl/z8/G7JXK6IlVAAAAAAAMClGAyG/+w2HF5eXvL39y/wcQsWLNAnn3yiP//8U/fee69GjRolo9FouRwvJSVF4eHhmjNnjiZMmKC//vpLjzzyiB599FFFRUXp6NGjatq0qd566y15e3srKipK3t7eSklJ0Xfffae7775bY8eOVYMGDWzOnZWVpenTp2vVqlWSpJYtW2rMmDEOf6onK6EAAAAAAIDLuXYbDnu/ChN0/frrr5o+fbrGjRunNWvWqFGjRnr++edzvUzyo48+0qxZszRx4kQtXLhQzz33nF566SXNmzdPiYmJWrZsmWXsF198oXvuuUexsbFq3LixBg0apLS0NJs53377bSUlJenjjz/WggULdPHiRY0YMaLA7+NWI4QCAAAAAAC4hf744w8ZDAZVqlRJlStX1vPPP68333wz18v6hg4dqho1aqhLly4qV66cOnfurPvvv18NGzZUs2bNdPToUcvYe+65Ry+//LKqVaumkSNHysfHR6tXr7aa7/Lly1q0aJHGjx+vevXqKTg4WNOnT9fOnTvtckP0guByPAAAAAAAgFuoRYsWql69urp27apatWopPDxcvXr10rFjx2zGBgYGWv5dvHhxBQQEWP38z5VY/7z0zs3NTbVq1dKRI0es5jtx4oSys7PVu3dvq+0mk0nHjh1TcHDwzb69QiOEAgAAAAAAuIVKlCihpUuXaufOndqyZYu++uorLVmyRK+99prNWHd3d6uf3dzyvmjNw8M6xjEajTbjjUajJGnx4sUqWbKk1b5y5coV6H3calyOBwAAAAAAcAvt2bNHc+bM0X333aeRI0dq7dq1yszMtAmRCmr//v2WfxuNRh04cMBmZVNgYKDc3d11/vx5BQUFKSgoSN7e3poyZYrOnTt3U+e/WayEAgAAAAAAuIWKFy+uDz74QOXLl1ezZs30448/KiMjQ+fPn7+peXfu3Kn58+erdevWWrRokS5fvqyOHTtajfH29lavXr30xhtvaMKECSpXrpymTJmikydPqnLlyjd1/ptFCAUAAAAAAFyOl5eX056nZs2amjRpkmbNmqUJEyaoUqVKevPNN1W+fPmbqiUsLEw//PCDZs6cqVq1aumTTz5RmTJlbMZFRUVp2rRpGj58uLKzs9W4cWN99NFHNpf+/dcM5txuzQ44KaPRqMTERMUkGrX35EVHlwMn07F2BU3uUUfJycnKzMx0dDkAAACAw3h6eiotLU0hISEODx5uxpUrV/T777+ratWqKl68uGW72WyWwWD4z+r4r8+Xm6ioKEnS1KlTHVpHbvL6Pf0b94SyszNnzuj1119XixYtVK9ePXXu3Fnz5s1TTk6OJCklJUXBwcFWr9q1a6tFixaaOHGi1V3ww8LC9NVXX0mSduzYYXPctVdYWJjV3G+//bZNXTExMYqIiJAkRURE5DlXcHCwUlJSJEkZGRkKCQlR3759beb76quvLOfNTVRUVJ7zx8TEFPLTBQAAAADc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UP+BiIgIBQUFadKkSTb7Lly4IEkqU6ZMrsde237+/HnLti5duig0NFShoaGqU6eOXn75ZUVGRurpp5++YS2lS5eWJF26dCnPMX/99ZdGjBih0NBQxcfH6/fff7/hvJ07d9aGDRssP69Zs0YtWrTQHXfcccNjAQAAAABA0UcI9R9wd3fXG2+8oa+//jrX+zZJVy/Ly82ZM2ckSWXLlrVs++ijjxQXF6dZs2apSpUqatSokQYPHnzDy/Ek6eLFi5Ikb29vzZ492xJmhYaGateuXZKkjIwM9evXT5988omqVaumkSNH2twc/d+6dOmin376SefOnZNkeymep6enpKsrt/7NZDLJw8PjhrUDAAAAAADXRQj1H2nQoIEeeeQRTZo0SZcvX7Zsr1u3rtzd3ZWUlJTrcUlJSQoODpaXl5dlW6VKlRQUFKRmzZppzpw5+vrrrzVt2rR81XHw4EF5enrqrrvuUu/evRUXF2d51alTR5J055136vnnn5eHh4cmTpyovXv36tNPP73uvPfee6/uvfdebdy4UXv37lVaWprCw8Mt+729vSVJ6enpNsf+/ffflhVaAAAAAACgaCKE+g+9/PLLysjIsLpJua+vr9q2batZs2bJaDRajU9NTdWyZcv06KOP5jlnlSpVNGzYMC1atEg///zzDWv46quvFBYWpmLFiqls2bIKCgqyvIoXLy5JViuq6tSpo379+undd9+94WV5Xbp00aZNm7Rx40aFhYWpRIkSln2lSpVSYGCg9uzZY3WM0WjUvn37VKtWrRvWDgAAAAAAXBch1H/ojjvu0Msvv6w//vjDavvo0aN14cIFDRw4ULt27dLJkye1YcMGRUZGqkmTJurbt+91542MjFS1atU0YcIEq8vmLly4oLNnz+r06dPat2+fXnrpJe3bt0/PP/98geoePny4ypcvf8PL8jp37qydO3dq/fr16tq1q83+J554Qu+++64SEhKUkpKin3/+WS+++KK8vLzUrl27AtUEAAAAAABcCzfi+Y/17NlTy5cvt9zrSbr6BL0vv/xSs2bN0ssvv6y0tDQFBgaqd+/e6tevn9zcrp8Venh4aMyYMerfv7+WL1+uXr16SZKGDRsmSXJzc1O5cuXUoEEDffHFF7r77rsLVHOJEiU0fvx4Pf300/rss8/05JNP5jouICBANWrU0O+//67777/fZn//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8PDQuHHj9MQTT1g+v/wwGo1au3at/vrrL0sIJV39fa1YsUJDhw7N91wAAAAAAKBocfhKqGurktzd3TVp0iQdOnRIc+bMkXR1Rc/WrVs1aNAgq9U7CxYskCTL6ppt27Zp+fLlNnOXKVNGvr6+kq4+Fa9MmTKKjY21mqtz585as2aNrly5YnN8QECAgoKCFBQUZLmJeO/evbV06VKdPn3aamxOTo4+/PBDtW3bVr6+vvLw8FCnTp30+eefKysry2rs5s2btXnzZlWoUEGS1K1bN3311VeWS/OuOXDggGJjYwt8qd7y5ctVu3ZtBQYGFui4f2rUqJEefvhhTZw4Md/HfP/990pLS9N7771n9RlHRUXp2LFj2r17d6HrAQAAAAAArs3hK6H+qWbNmurfv78lzPn1119lNBoVGRlp8zS6li1bKjY2VoMHD9bQoUP14osvqlixYuratas8PT21e/duzZ07V1OmTJF0dUVV165dVaNGDat5+vfvr4SEBG3cuDFfq4369Omjb775RhEREXrllVdUu3ZtnTx5Uh988IHS09M1evRoy9hhw4apV69eevrppzVs2DDdeeed2rFjh958801FRkbqnnvukSRFRkYqISFBERERevHFF3X33XcrKSlJ06ZNU1hYmB544IE860lPT9fZs2dlNpv1119/admyZVq9erXN/bUyMjJyvYywRIkSVpft/dMrr7yS6+qsvCQkJOjee+9V+/btrbYHBQVp9uzZiouLU4MGDSRJhw4d0tatW63G1a1bV3fccUe+zwcAAAAAAFyHU4VQ0tXgZv369Ro5cqTKlCmjBx54wCaAkq6GQYMHD1ZiYqIefPBBeXl5af78+VqyZImys7MVHBysyZMnKzw8XImJiUpJSVHPnj1t5qlXr55q166t2NjYfIVQbm5umjVrlj799FPNnDlTJ06ckK+vr9q2bau33nrLsvJKkvz8/LRkyRLFxMTo5Zdf1vnz51WlShUNHz5cffr0sYwrXry4PvvsM33wwQcaP368/vzzT/n7+6tnz54aMGCADAZDnvVMnjxZkydPlsFgkK+vr2rVqqVPP/3U5vLC+fPn53rj9549e2rSpEm5zu3r66sXX3xRY8eOveHnkpWVpQ0bNui5556z2VesWDH16NFDy5Yts4R0n3zyic0T+D755BM1b978hucCAAAAAACux2A2m82O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1IEDB5SVlZX7mwQAAAAAAC6PEOoWGDhwoEJDQxUSEqJmzZrp119/VUREhNWY1atXKywsTJLUqlUreXl5KS4uzrK/XLlyWrZsmR555BHt379fb775prp27ap+/frp3LlzeZ47PT1d3t7eN6zxwoULKlOmTJ77fXx8dP78eattdevWVe/evTVlyhRdvHjR5pi//vpLZcuWtfyclZVluan6tdfJkyd14cIFScrz/Ne2//v8AAAAAACg6CCEugWio6MVFxenuLg4ffHFF2rRooX69OljCY/27t2r5ORktW3bVpJUqlQpNW/eXCtWrLCa584779SECRO0fft2LVu2TAMHDlRiYqLGjBkjSRowYIBVwCNJZcuW1d9//33DGn18fPTnn3/muf/MmTNWgdI1L7zwgkwmk959991c5/znuT09PS2fw5w5c5SRkSGTySQfHx9JyvP8Z86csbwXAAAAAABQNHk4uoCioGLFigoKCpIk3XXXXapdu7aaNm2qNWvW6IknnlBCQoIk6amnnrIcYzKZZDab9dNPP6lhw4b66KOPVLduXTVr1kxubm6qW7eu6tatq4CAAE2bNk2SNGnSJF25csXq3LVr11ZSUlKudX322Wf6888/9dJLL6l+/fr66aefch139uxZnTp1KtfL5cqUKaNXX31VI0eOVNOmTa321atXT3v27LH8bDAYLJ/DP+/9VLduXbm7uyspKUl33nmnzTmSkpIUHBwsLy+vXOsDAAAAAACuj5VQduDm5iaz2Syj0SiTyaQ1a9aoe/fullVCcXFxio2Nlbe3t+WSvN27d2vhwoU2c5UpU8Zyb6VrYde1lyR17dpVe/futQmYLl26pM8++0xGo1GS1LNnTx08eFAbN260OceHH36o8uXL64EHHsj1/XTv3l2NGjXS5MmTrbb37t1bX3/9tfbt22dzzOnTpy3/9vX1Vdu2bTVr1ixLPdekpqZq2bJlevTRR3M9NwAAAAAAKBoIoW6BCxcu6OzZszp79qyOHTumCRMmyGg0KiwsTLt27dLp06cVERGh6tWrW141a9ZUt27dtGbNGmVmZmrQoEHaunWrRo8eraSkJCUnJ2v16tV688039eSTT+Z57tDQUPXq1UtDhw7VsmXLdPz4ce3cuVMDBw6Um5ubBg4cKEmqUaOGRowYoVdeeUULFy7UiRMndPDgQUVHR2v58uWa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N0IoeAQfH58qX4yV73/74wqobsnJyXrnnXf06quvqk2bNvLx8akyQ6+8vJxeRbVavHix2rdv7zJjr9LFvlPpUVQ3u92u4uJivfLKKwoNDZX0y01zV61apbCwMPoUlrBjxw598MEH+vTTT+Xr66sOHTro+PHjWrp0qZo1a0afwlIudx56sXOAevXqVVeJqOG4HA8eoXHjxjp16pTOnz9vjBUWFsrX15cvTLhVYmKi3nrrLSUnJ+uOO+6Q9Eu//vjjjy7r/fjjj1WmPgNmysrK0qZNmxQVFaWoqChlZmYqMzNTUVFR9CgsIzg4WD4+PkYAJUktW7bU0aNH6VNYxt69exUWFuYSLLVt21ZHjhyhT2E5l+vJiy0PDg6uthpRsxFCwSPceOONstvtLjfM27Vrlzp06CAvL9oY7rF48WKlpqZq/vz5uvPOO43xyMhIffvttzp79qwxtmvXLkVGRrqjTNRQ7733njIzM5WRkaGMjAzFxMQoJiZGGRkZioyM1Ndff208UcfpdGr37t30KKpdZGSkysrKdOjQIWMsPz9foaGh9Ckso1GjRiooKHCZPZKfn6+mTZvSp7Ccy52HRkZGateuXcay0tJS7du3j55FteHXOzyCn5+f7rnnHj3//PPas2ePNm3apOXLl2v06NHuLg01VF5enpYsWaLx48crOjpahYWFxqtr164KCQlRXFyccnNzlZKSoj179ujee+91d9moQUJDQxUWFma86tatq7p16yosLEz9+/fXTz/9pBdffFEHDx7Uiy++qNLSUg0YMMDdZaOGadWqlfr06aO4uDjt379fW7duVUpKikaMGEGfwjJiYmJUu3ZtPfvsszp06JA2b96sv/3tbxo1ahR9Csu53HnosGHDtHv3bqWkpCg3N1dxcXFq2rSpunXr5ubKUVPYnJWxPWBxpaWlev755/XRRx/J399fDz30kMaOHevuslBDpaSk6JVXXrngsgMHDqigoEDPPPOMcnJyFBYWpvj4eN1yyy3VXCXw/2bMmCFJeumllyRJe/bsUUJCgvLy8hQREaFZs2apbdu27iwRNdSZM2eUmJiojRs3ys/PTyNHjtTkyZNls9noU1hGZcC0Z88eBQYG6oEHHtCYMWPoU1hCRESE3n33XSNIutx56Keffqo5c+bo2LFjioqKUmJiopo1a+au8lHDEEIBAAAAAADAdFyOBwAAAAAAANMRQgEAAAAAAMB0hFAAAAAAAAAwHSEUAAAAAAAATEcIBQAAAAAAANMRQgEAAAAAAMB0hFAAAAAAAAAwHSEUAAAAAAAATEcIBQAALCkmJkYRERHGq127durfv7/efvttd5fm4p///KdOnDghSVq0aJFGjRpl2rHKyso0ZMgQnTp1Sg6HQ3FxcercubNGjRpl1CBJ//rXvzR06FA5nU6X7UeNGqWDBw+aVh8AAMClEEIBAADLio+P17Zt27Rt2zZt2rRJjzzyiJKSkpSRkeHu0iRJP/zwg6ZPn67S0lJJ0rhx47Ro0SLTjpeSkqLbbrtNDRo00ObNm7Vz506lpaUpICBAKSkpxnqvvfaaJk2aJJvN5rL95MmTNWvWLNPqAwAAuBRCKAAAYFkBAQEKDg5WcHCwQkJCNGTIEHXv3l0fffSRu0uTpCozjerWravrrrvOlGP9/PPPevfdd3X//fdLkvLz89WpUyeFh4fr1ltvVX5+viQpNzdXhw8fVmxsbJV93Hzzzfrxxx/11VdfmVIjAADApRBCAQAAj2K321W7dm1Jv1xelpiYqNjYWPXp00fFxcU6duyYHnvsMXXt2lXdunXT7NmzVV5eLklKT0/XiBEj9PLLLysqKkp9+vRRWlqasW+Hw6Fly5YpNjZWHTt21KhRo3TgwAFjeUREhBYuXKhu3bpp4sSJRtATGxur9PT0Kpfjff311xoxYoQ6deqkmJgYrVq1ylg2Y8YMzZ07V9OnT1dkZKR69+59yRlemZmZatmypRo3bixJatKkiQ4ePKjy8nLt27dPISEhkqQlS5bo0UcfrTILqtJv6wAAAKguhFAAAMAjnDt3Th999JG2b9/uMssnPT1dycnJWrx4sby9vTVmzBiVlpbqvffe04IFC/TJJ58oKSnJWP+bb77Rd999p9WrV2vKlCmaNWuWtm3bJumXy9iWL1+u+Ph4rVu3TqGhoXr44YdVUlJibL9lyxatWrVKTz75pBFgpaWlaeDAgS715uXlacyYMbrpppuUnp6uqVOnat68edq4caOxzsqVK9WuXTv94x//UL9+/ZSQkKAzZ85c8PNv3bpVt9xyi/G+X79+8vf3V2RkpLZt26bx48crLy9PBQUF6tu370X/Hnv06KFt27ZVmcUFAABgNkIoAABgWQkJCYqKilJUVJQ6duyop59+WmPGjNFdd91lrNOnTx917txZ7du319atW3X8+HElJycrIiJC3bt318yZM7Vq1Sr9/PPPkiSbzaakpCS1adNG9957r+68806tWbNGTqdTK1as0GOPPabY2FiFh4crMTFRtWrV0t///nfjePfff79atWql1q1bKzAwUJIUGBgoX19fl9rXrFmjtm3b6vHHH1erVq00ZMgQ/fnPf9ayZcuMdSIiIjR+/Hg1a9ZMjz32mM6ePavc3NwL/l3s27dP4eHhxntvb2+tXLlSW7du1aZNm9SsWTNjFlROTo4GDx6sAQMGaPv27S77CQ8PV1FRkX744Ydr/L8CAABwbezuLgAAAOBipk2bpn79+kmSfHx8FBwcrFq1armsExoaavw5Ly9PLVq0UP369Y2xzp076/z58/r+++8lSWFhYQoKCjKWt2/fXqmpqTpx4oSKiooUGRlpLKtdu7bat2+vvLy8Cx7vUvLy8tSxY0eXsaioKKWmphrvW7RoYfzZ399fknT+/PkL7u/kyZNq0KBBlfGGDRsax8vPz1ffvn01cOBAPfHEE7r++us1YcIEbdmyRT4+PpJk7OPkyZNq2rTpFX0WAACA3wMhFAAAsKygoCCFhYVdcp3KcOW3f65UUVHh8l+73V5luZeX1wW3rVzucDgueYzL1VXJ4XAYdUgy7m31axe7TM5ms7ls+1tLly7Vo48+qtOnTys/P189e/Y0ZmcdOnRIN9xwg1FD5f4AAACqE5fjAQCAP4yWLVvq3//+t4qKioyx7Oxs2e12NW/eXJJUUFBgXJonSXv37lWbNm0UEBCghg0bKjs721h27tw5ffvtt2rZsuUFj3epIKdly5bKyclxGfv6668vuq/LCQoKcvlcv3bo0CHl5eXp9ttvl5fXL6d3lWFTRUWFS7B16tQpSVJwcPA11QEAAHCtCKEAAMAfRo8ePdSsWTM99dRTOnDggL744gslJiZq0KBBqlevniSppKRECQkJysvL05o1a7RhwwaNHDlSkjR27Fj99a9/1ebNm5WXl6fnnntOZWVlVW46XsnPz0+StH//fpdgS5JGjhyp7777TvPnz9ehQ4e0bt06vf/++3rggQeu6bO1bdvW5Ul9v7Z06VJNnDhRNptN9erVU1hYmNasWaMPP/xQkutlfwcOHFDDhg2Np+wBAABUFy7HAwAAfxi1atXSkiVLlJiYqPvuu09169bV4MGD9fjjjxvrhISEKDg4WPfee6+Cg4OVnJys6OhoSdK4ceNUXFys5557TsXFxYqKitJ7771n3ID8twIDA3XXXXdp+vTpevLJJ12WNWnSRK+//rqSkpK0fPlyNWnSRDNmzNCwYcOu6bP16tVL6enpVcYLCgqUm5urefPmGWOJiYmKi4vT+fPnNWfOHCMsk6Rdu3apZ8+eXI4HAACqnc3J83kBAEANkZ6ersWLF2vz5s3uLuWqFRcXq0+fPlq/fv0V3xz9t5xOp/r27at58+apS5cuv3OFAAAAl8bleAAAAB7A399fDzzwgNasWXPN+9i+fbsaNWpEAAUAANyCEAoAAMBDTJw4UVu2bDFuLn61li5dqueff/73LQoAAOAKcTkeAAAAAAAATMdMKAAAAAAAAJiOEAoAAAAAAACmI4QCAAAAAACA6QihAAAAAAAAYDpCKAAAAAAAAJiOEAoAAAAAAACmI4QCAAAAAACA6QihAAAAAAAAYDpCKAAAAAAAAJju/wDhXkbswhUM9AAAAABJRU5ErkJggg==" - }, - "metadata": {}, - "output_type": "display_data", - "jetTransient": { - "display_id": null - } - } - ], - "execution_count": 7 + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "## Native Names vs Surnames", - "id": "1973b08d18c2258e" + "id": "1973b08d18c2258e", + "metadata": {}, + "source": [ + "## Native Names vs Surnames" + ] }, { + "cell_type": "code", + "execution_count": 8, + "id": "1e7dde234bb3504f", "metadata": { "ExecuteTime": { "end_time": "2025-09-28T21:42:05.285962Z", "start_time": "2025-09-28T21:42:04.523383Z" } }, - "cell_type": "code", - "source": "df_base = df.query(\"identified_category == 'simple'\")", - "id": "1e7dde234bb3504f", "outputs": [], - "execution_count": 8 + "source": [ + "df_base = df.query(\"identified_category == 'simple'\")" + ] }, { + "cell_type": "code", + "execution_count": 9, + "id": "24a4ad40319f441b", "metadata": { "ExecuteTime": { "end_time": "2025-09-28T21:42:36.611043Z", "start_time": "2025-09-28T21:42:05.308895Z" } }, - "cell_type": "code", - "source": [ - "df_names = build_words_token(df_base, 'identified_name', 'name')\n", - "df_names = df_names[['name', 'province', 'sex']].reset_index(drop=True)\n", - "df_names.describe().T" - ], - "id": "24a4ad40319f441b", "outputs": [ { "data": { - "text/plain": [ - " count unique top freq\n", - "name 10015595 644336 ilunga 82342\n", - "province 10015595 12 KINSHASA 2106077\n", - "sex 10015595 2 m 6033856" - ], "text/html": [ "
\n", "