-
Notifications
You must be signed in to change notification settings - Fork 18
FEAT: quarto monitoring dashboard template #203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2a2a969
b14b8bf
194e86f
3a03ddc
a023dc7
4d94e4d
5e3ef8d
90c0dcf
27dce4d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| from importlib_resources import files as _files | ||
| import shutil | ||
| from pathlib import Path | ||
|
|
||
|
|
||
| def model_card(path="."): | ||
| """ | ||
| Create a model card for documentation | ||
|
|
||
| Parameters | ||
| ---------- | ||
| path : str | ||
| Path to save model card | ||
|
|
||
| Notes | ||
| ----- | ||
| This model card is generated as a Quarto document. For more info on | ||
| Quarto, visit https://quarto.org/ | ||
| """ | ||
| src_path = _files("vetiver") / "templates/model_card.qmd" | ||
|
|
||
| return shutil.copy(src=src_path, dst=path) | ||
|
|
||
|
|
||
| def monitoring_dashboard(path: str = "."): | ||
| """ | ||
| Generate a monitoring dashboard template | ||
|
|
||
| Parameters | ||
| ---------- | ||
| path : str | ||
| Path to save monitoring dashboard | ||
|
|
||
| Notes | ||
| ----- | ||
| This model card is generated as a Quarto document. For more info on | ||
| Quarto, visit https://quarto.org/ | ||
| """ | ||
| p = Path(path) | ||
| src_path = p / _files("vetiver") / "templates" / "monitoring_dashboard.qmd" | ||
|
|
||
| return shutil.copy(src=src_path, dst=path) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| --- | ||
| title: "Monitoring dashboard" | ||
| format: | ||
| dashboard: | ||
| orientation: columns | ||
| logo: https://github.com/rstudio/vetiver-python/blob/main/docs/figures/logo.png?raw=true | ||
| output: asis | ||
| jupyter: python3 | ||
| --- | ||
|
|
||
| ```{python} | ||
| #| include: false | ||
| #| tags: [parameters] | ||
|
|
||
| # import model and metadata | ||
| import pins | ||
| from IPython.display import display, Markdown, IFrame | ||
| from datetime import datetime, timedelta | ||
| import pandas as pd | ||
| import plotly.express as px | ||
| from sklearn import metrics | ||
| from vetiver import VetiverModel, compute_metrics, plot_metrics | ||
| from sklearn.metrics import recall_score, accuracy_score | ||
|
|
||
| raw = "https://colorado.rstudio.com/rsc" | ||
| paths = {"chicago-model-python": "chicago-model-python/"} | ||
| board = pins.board_url(raw, paths, allow_pickle_read=True) | ||
| v = VetiverModel.from_pin(board, "chicago-model-python") | ||
| v_meta = board.pin_meta("chicago-model-python") | ||
| days_old = datetime.today() - datetime.strptime(v_meta.created, "%Y%m%dT%H%M%SZ") | ||
| ``` | ||
|
|
||
| ```{python} | ||
| ## the next few lines are an example model, here is a place to | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This might be a little heavyweight to just load in monitoring data, but I wonder if something like mtcars is too simple?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do think something like mtcars is too simple because it doesn't have dates. This seems pretty reasonable, although some kind of built-in data would be great too. |
||
| ## add any code you need to import new data and make predictions | ||
|
|
||
| # import new data to track performance over time | ||
| raw = "https://colorado.rstudio.com/rsc" | ||
| paths = {"new-data": "inspections-new-data/"} | ||
| board = pins.board_url(raw, paths, allow_pickle_read=True) | ||
| inspections_new = board.pin_read("new-data") | ||
|
|
||
| # make predictions | ||
| inspections_new["preds"] = v.model.predict( | ||
| inspections_new.drop(columns=["results", "aka_name", "inspection_date"]) | ||
| ) | ||
|
|
||
| # map results | ||
| inspections_new["preds"] = inspections_new["preds"].map({"PASS": 0, "FAIL": 1}) | ||
| inspections_new["results"] = inspections_new["results"].map({"PASS": 0, "FAIL": 1}) | ||
| ``` | ||
|
|
||
| # Model info | ||
|
|
||
| ## Column | ||
| ### Row {height="33%"} | ||
| ::: {.valuebox} | ||
| `{python} v.description` | ||
|
|
||
| `{python} v.model_name` | ||
| ::: | ||
|
|
||
| ::: {.valuebox} | ||
| Model age | ||
|
|
||
| `{python} days_old.days` days old | ||
| ::: | ||
|
|
||
| ### Row | ||
|
|
||
| Model details | ||
|
|
||
| - This model has the prototype: | ||
|
|
||
| ``` | ||
| `{python} v.prototype.construct().schema().get("properties")` | ||
| ``` | ||
|
|
||
| - The model was created by ... | ||
|
|
||
| # Model metrics | ||
|
|
||
| ## Column | ||
| ```{python} | ||
| import itables | ||
|
|
||
| td = timedelta(weeks = 4) | ||
| metric_set = [accuracy_score, recall_score] | ||
|
|
||
| metrics_df = compute_metrics( | ||
| data = inspections_new, | ||
| date_var = "inspection_date", | ||
| period = td, | ||
| metric_set = metric_set, | ||
| truth = "results", | ||
| estimate = "preds" | ||
| ) | ||
| itables.show(metrics_df) | ||
| ``` | ||
|
|
||
| ```{python} | ||
| plot_metrics(metrics_df).show() | ||
| ``` | ||
|
|
||
| ## Column {.sidebar} | ||
|
|
||
| This tab is used to see model performance over time. In this context, _performance_ is the statistical properties of the model, eg, accuracy and recall. | ||
|
|
||
| You can add custom information and metrics here. | ||
|
|
||
| # Explore validation data | ||
|
|
||
| ```{python} | ||
| fig = px.histogram(inspections_new, x = "facility_type") | ||
| fig.show() | ||
| ``` | ||
|
|
||
| ## Column {.sidebar} | ||
|
|
||
| Write your own code to make visualizations or tables with the new validation data, and/or the new predictions. | ||
|
|
||
|
|
||
| # API visual documentation | ||
|
|
||
| ## Column | ||
|
|
||
| ```{python} | ||
| from IPython.display import IFrame | ||
| IFrame('https://colorado.posit.co/rsc/chicago-inspections-python', width=750, height=350) | ||
| ``` | ||
| --- | ||
|
|
||
|
|
||
| ## Column {.sidebar} | ||
|
|
||
| Interact directly with your model via its visual documentation, and get `curl` examples. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| --- | ||
| title: "Monitoring dashboard" | ||
| format: | ||
| dashboard: | ||
| orientation: columns | ||
| logo: https://github.com/rstudio/vetiver-python/blob/main/docs/figures/logo.png?raw=true | ||
| output: asis | ||
| jupyter: python3 | ||
| --- | ||
|
|
||
| ```{python} | ||
| #| include: false | ||
| #| tags: [parameters] | ||
|
|
||
| # import model and metadata | ||
| import pins | ||
| from IPython.display import display, Markdown, IFrame | ||
| from datetime import datetime, timedelta | ||
| import pandas as pd | ||
| import plotly.express as px | ||
| from sklearn import metrics | ||
| from vetiver import VetiverModel, compute_metrics, plot_metrics | ||
| from sklearn.metrics import recall_score, accuracy_score | ||
|
|
||
| raw = "https://colorado.rstudio.com/rsc" | ||
| paths = {"chicago-model-python": "chicago-model-python/"} | ||
| board = pins.board_url(raw, paths, allow_pickle_read=True) | ||
| v = VetiverModel.from_pin(board, "chicago-model-python") | ||
| v_meta = board.pin_meta("chicago-model-python") | ||
| days_old = datetime.today() - datetime.strptime(v_meta.created, "%Y%m%dT%H%M%SZ") | ||
| ``` | ||
|
|
||
| ```{python} | ||
| ## the next few lines are an example model, here is a place to | ||
| ## add any code you need to import new data and make predictions | ||
|
|
||
| # import new data to track performance over time | ||
| raw = "https://colorado.rstudio.com/rsc" | ||
| paths = {"new-data": "inspections-new-data/"} | ||
| board = pins.board_url(raw, paths, allow_pickle_read=True) | ||
| inspections_new = board.pin_read("new-data") | ||
|
|
||
| # make predictions | ||
| inspections_new["preds"] = v.model.predict( | ||
| inspections_new.drop(columns=["results", "aka_name", "inspection_date"]) | ||
| ) | ||
|
|
||
| # map results | ||
| inspections_new["preds"] = inspections_new["preds"].map({"PASS": 0, "FAIL": 1}) | ||
| inspections_new["results"] = inspections_new["results"].map({"PASS": 0, "FAIL": 1}) | ||
| ``` | ||
|
|
||
| # Model info | ||
|
|
||
| ## Column | ||
| ### Row {height="33%"} | ||
| ::: {.valuebox} | ||
| `{python} v.description` | ||
|
|
||
| `{python} v.model_name` | ||
| ::: | ||
|
|
||
| ::: {.valuebox} | ||
| Model age | ||
|
|
||
| `{python} days_old.days` days old | ||
| ::: | ||
|
|
||
| ### Row | ||
|
|
||
| Model details | ||
|
|
||
| - This model has the prototype: | ||
|
|
||
| ``` | ||
| `{python} v.prototype.construct().schema().get("properties")` | ||
| ``` | ||
|
|
||
| - The model was created by ... | ||
|
|
||
| # Model metrics | ||
|
|
||
| ## Column | ||
| ```{python} | ||
| import itables | ||
|
|
||
| td = timedelta(weeks = 4) | ||
| metric_set = [accuracy_score, recall_score] | ||
|
|
||
| metrics_df = compute_metrics( | ||
| data = inspections_new, | ||
| date_var = "inspection_date", | ||
| period = td, | ||
| metric_set = metric_set, | ||
| truth = "results", | ||
| estimate = "preds" | ||
| ) | ||
| itables.show(metrics_df) | ||
| ``` | ||
|
|
||
| ```{python} | ||
| plot_metrics(metrics_df).show() | ||
| ``` | ||
|
|
||
| ## Column {.sidebar} | ||
|
|
||
| This tab is used to see model performance over time. In this context, _performance_ is the statistical properties of the model, eg, accuracy and recall. | ||
|
|
||
| You can add custom information and metrics here. | ||
|
|
||
| # Explore validation data | ||
|
|
||
| ```{python} | ||
| fig = px.histogram(inspections_new, x = "facility_type") | ||
| fig.show() | ||
| ``` | ||
|
|
||
| ## Column {.sidebar} | ||
|
|
||
| Write your own code to make visualizations or tables with the new validation data, and/or the new predictions. | ||
|
|
||
|
|
||
| # API visual documentation | ||
|
|
||
| ## Column | ||
|
|
||
| ```{python} | ||
| from IPython.display import IFrame | ||
| IFrame('https://colorado.posit.co/rsc/chicago-inspections-python', width=750, height=350) | ||
| ``` | ||
| --- | ||
|
|
||
|
|
||
| ## Column {.sidebar} | ||
|
|
||
| Interact directly with your model via its visual documentation, and get `curl` examples. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| import vetiver | ||
| from tempfile import TemporaryDirectory | ||
| from pathlib import Path | ||
|
|
||
|
|
||
| def test_monitoring_dashboard(snapshot): | ||
| with TemporaryDirectory() as tempdir: | ||
| file_path = Path(tempdir, "monitoring_dashboard.qmd") | ||
| vetiver.monitoring_dashboard(path=file_path) | ||
| snapshot.snapshot_dir = "./vetiver/tests/snapshots" | ||
| contents = open(file_path).read() | ||
| snapshot.assert_match(contents, "monitoring_dashboard.qmd") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could previously
vetiver.model_card.model_cardORvetiver.model_card. The first option is no longer available, it is nowvetiver.templates.model_cardor you can stillvetiver.model_card. I doubt anyone is usingvetiver.model_card.model_card, so I feel pretty okay making this swap.