diff --git a/modules/src/evidently/evidently_iris.ipynb b/modules/src/evidently/evidently_iris.ipynb deleted file mode 100644 index 54f657bb0..000000000 --- a/modules/src/evidently/evidently_iris.ipynb +++ /dev/null @@ -1,37 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "initial_id", - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/modules/src/evidently_iris/evidently_iris.ipynb b/modules/src/evidently_iris/evidently_iris.ipynb new file mode 100644 index 000000000..c3299f82f --- /dev/null +++ b/modules/src/evidently_iris/evidently_iris.ipynb @@ -0,0 +1,1295 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8f92a6bb-e4b4-4b5d-91c7-2e99c97798c6", + "metadata": {}, + "source": [ + "# Evidently Iris Demo\n", + "\n", + "In this notebook, we’ll import the hub’s Evidently demo app, which monitors data quality and drift on Scikit-Learn’s Iris dataset. We’ll run it using the `evaluate()` method with a slightly modified dataset as the monitored data.\n", + "\n", + "The Evidently Iris module demonstrates a simple example of integrating MLRun with Evidently for data monitoring, which you can adapt to fit your own project needs or use as a reference implementation." + ] + }, + { + "cell_type": "markdown", + "id": "a6775277-5f4f-4261-9a06-5c6d87cb85c7", + "metadata": {}, + "source": [ + "## Set up an MLRun project and prepare the data" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d7a8c256-035f-4261-b494-f3f3cbd8c77c", + "metadata": {}, + "outputs": [], + "source": [ + "import mlrun\n", + "project = mlrun.get_or_create_project(\"evidently-demo\",'./evidently-demo')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "1e89667f-f84e-492a-a886-61104bc5ce49", + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.datasets import load_iris\n", + "import pandas as pd\n", + "from mlrun.feature_store.api import norm_column_name\n", + "\n", + "iris = load_iris()\n", + "columns = [norm_column_name(col) for col in iris.feature_names]\n", + "current_df = pd.DataFrame(iris.data, columns=columns)\n", + "current_df[\"sepal_length_cm\"] += 0.3 # simulate drift" + ] + }, + { + "cell_type": "markdown", + "id": "af6e56af-c99d-481e-a32e-f7e5eac4ae3a", + "metadata": {}, + "source": [ + "## Get the module from the hub and edit its defaults" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "35a4bb6b-d15e-4bfd-8d04-2fa188cb36cc", + "metadata": {}, + "outputs": [], + "source": [ + "hub_mod = mlrun.get_hub_module(\"hub://evidently_iris\", download_files=True)\n", + "src_file_path = hub_mod.get_module_file_path()" + ] + }, + { + "cell_type": "markdown", + "id": "ba0c043b-7356-44da-b6d2-84eb02718482", + "metadata": {}, + "source": [ + "We need to modify the class defaults to include the Evidently workspace path and project ID parameters. This can be done in one of two ways: either by editing the downloaded source file directly and then evaluating with the standard class, or - as we’ll do now - by adding an inheriting class to the same file and evaluating using that new class.\n", + "\n", + "(Note: this is only needed when runnning the app using `evaluate()`. When setting it as a real-time function we can simply pass the parameters)." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "4e9253a9-58bd-4732-8eb1-80a7d15b2e7a", + "metadata": {}, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "import uuid\n", + "\n", + "ws = Path(\"./evidently_workspace\")\n", + "ws.mkdir(parents=True, exist_ok=True) # will create if missing\n", + "evidently_project_id = str(uuid.uuid4())\n", + "\n", + "wrapper_code = f\"\"\"\n", + "class EvidentlyIrisMonitoringAppWithWorkspaceSet(EvidentlyIrisMonitoringApp):\n", + " def __init__(self) -> None:\n", + " super().__init__(evidently_workspace_path=\"{ws}\", evidently_project_id=\"{evidently_project_id}\")\n", + " \"\"\"\n", + "\n", + "with open(src_file_path, \"a\") as f:\n", + " f.write(wrapper_code)" + ] + }, + { + "cell_type": "markdown", + "id": "5776541f-2d6f-4c10-9246-75fe14e1bbea", + "metadata": {}, + "source": [ + "Now we can actually import it as a module, using the `module()` method" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "3742576d-6da2-423d-8c1c-2861712a698f", + "metadata": {}, + "outputs": [], + "source": [ + "app_module = hub_mod.module()\n", + "evidently_app = app_module.EvidentlyIrisMonitoringAppWithWorkspaceSet" + ] + }, + { + "cell_type": "markdown", + "id": "57a81ea8-f203-4152-9492-a0f7b916d02b", + "metadata": {}, + "source": [ + "## Run the app\n", + "We are ready to call `evaluate()` (notice that the run is linked to the current (active) project that we created at the beggining of the notebook)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "d8103577-8523-4b64-bd67-e93bbde8dd06", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> 2025-11-17 09:14:43,241 [info] Changing function name - adding `\"-batch\"` suffix: {\"func_name\":\"evidentlyirismonitoringappwithworkspaceset-batch\"}\n", + "> 2025-11-17 09:14:43,580 [info] Storing function: {\"db\":\"http://mlrun-api:8080\",\"name\":\"evidentlyirismonitoringappwithworkspaceset-batch--handler\",\"uid\":\"9ecf72a1bd82498c92d5897809b6a438\"}\n", + "> 2025-11-17 09:14:43,856 [info] downloading v3io:///projects/evidently-demo/artifacts/evidentlyirismonitoringappwithworkspaceset-batch_sample_data.parquet to local temp file\n", + "> 2025-11-17 09:14:43,890 [info] Running evidently app\n", + "> 2025-11-17 09:14:46,214 [info] Logged evidently object\n" + ] + }, + { + "data": { + "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", + "
projectuiditerstartendstatekindnamelabelsinputsparametersresultsartifact_uris
evidently-demo0Nov 17 09:14:43NaTcompletedrunevidentlyirismonitoringappwithworkspaceset-batch--handler
v3io_user=iguazio
kind=local
owner=iguazio
host=jupyter-97c64f97b-8qtcv
sample_data
write_output=False
existing_data_handling=fail_on_overlap
stream_profile=None
return={result_name: 'data_drift_test', result_value: 0.5, result_kind: 0, result_status: 1, result_extra_data: '{}'}
evidently_report=store://artifacts/evidently-demo/evidentlyirismonitoringappwithworkspaceset-batch--handler_evidently_report#0@9ecf72a1bd82498c92d5897809b6a438^2f82c069b396f23b4daae81540ffa386b44f165c
\n", + "
\n", + "
\n", + "
\n", + " Title\n", + " ×\n", + "
\n", + " \n", + "
\n", + "
\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/html": [ + " > to track results use the .show() or .logs() methods or click here to open in UI" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "> 2025-11-17 09:14:46,354 [info] Run execution finished: {\"name\":\"evidentlyirismonitoringappwithworkspaceset-batch--handler\",\"status\":\"completed\"}\n" + ] + } + ], + "source": [ + "# Evaluate directly on the sample data\n", + "run_result = evidently_app.evaluate(\n", + " func_path=hub_mod.get_module_file_path(),\n", + " sample_data=current_df,\n", + " run_local=True)" + ] + }, + { + "cell_type": "markdown", + "id": "2c6843cd-70d4-4e1a-8aa2-52b6ef5b0ec9", + "metadata": {}, + "source": [ + "## Examine the results\n", + "Notice that the 0.5 value in the demo run result is not derived from Evidently’s drift metrics, but is a constant placeholder added for demonstration only.\n", + "\n", + "Let's take a look at the artifact the app generated for us:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "7f1680f5-0ee7-4a82-a351-f8348bf398cc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
\n", + "
\n", + " \n", + " \n", + " \n", + " \n", + "\n", + " \n", + " \n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "artifact_key = f\"{run_result.metadata.name}_evidently_report\"\n", + "artifact = project.get_artifact(artifact_key)\n", + "artifact.to_dataitem().show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "mlrun-base-py311", + "language": "python", + "name": "conda-env-mlrun-base-py311-py" + }, + "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.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/modules/src/evidently/evidently_iris.py b/modules/src/evidently_iris/evidently_iris.py similarity index 100% rename from modules/src/evidently/evidently_iris.py rename to modules/src/evidently_iris/evidently_iris.py diff --git a/modules/src/evidently/item.yaml b/modules/src/evidently_iris/item.yaml similarity index 96% rename from modules/src/evidently/item.yaml rename to modules/src/evidently_iris/item.yaml index c6a2abc2c..262b7e1b7 100644 --- a/modules/src/evidently/item.yaml +++ b/modules/src/evidently_iris/item.yaml @@ -16,6 +16,6 @@ spec: kind: monitoring_application requirements: - scikit-learn~=1.5.2 - - evidently~=0.7.6 + - evidently~=0.7.5 - pandas version: 1.0.0 \ No newline at end of file diff --git a/modules/src/evidently/requirements.txt b/modules/src/evidently_iris/requirements.txt similarity index 60% rename from modules/src/evidently/requirements.txt rename to modules/src/evidently_iris/requirements.txt index bd4abb36f..6bd12d901 100644 --- a/modules/src/evidently/requirements.txt +++ b/modules/src/evidently_iris/requirements.txt @@ -1,3 +1,3 @@ scikit-learn~=1.5.2 -evidently~=0.7.6 +evidently~=0.7.5 pandas \ No newline at end of file diff --git a/modules/src/evidently/test_evidently_iris.py b/modules/src/evidently_iris/test_evidently_iris.py similarity index 100% rename from modules/src/evidently/test_evidently_iris.py rename to modules/src/evidently_iris/test_evidently_iris.py