{"id":752,"date":"2020-08-27T16:55:59","date_gmt":"2020-08-27T16:55:59","guid":{"rendered":"https:\/\/data-science.gotoauthority.com\/2020\/08\/27\/explainable-and-reproducible-machine-learning-model-development-with-dalex-and-neptune\/"},"modified":"2020-08-27T16:55:59","modified_gmt":"2020-08-27T16:55:59","slug":"explainable-and-reproducible-machine-learning-model-development-with-dalex-and-neptune","status":"publish","type":"post","link":"https:\/\/wealthrevelation.com\/data-science\/2020\/08\/27\/explainable-and-reproducible-machine-learning-model-development-with-dalex-and-neptune\/","title":{"rendered":"Explainable and Reproducible Machine Learning Model Development with DALEX and Neptune"},"content":{"rendered":"<div id=\"post-\">\n<p><b>By <a href=\"https:\/\/www.linkedin.com\/in\/jakub-czakon-2b797b69\/\" rel=\"noopener noreferrer\" target=\"_blank\">Jakub Czakon<\/a>, Sr Data Scientist at neptune.ai, <a href=\"https:\/\/www.linkedin.com\/in\/pbiecek\/\" rel=\"noopener noreferrer\" target=\"_blank\">Przemys\u0142aw Biecek<\/a>, Founder of MI2DataLab &amp; Adam Rydelek, Research Engineer at MI2DataLab<\/b><\/p>\n<p><img alt=\"\" class=\"aligncenter\" data-lazy-loaded=\"1\" src=\"https:\/\/i1.wp.com\/neptune.ai\/wp-content\/uploads\/Dalex-Neptune.jpg?fit=1920%2C1377&amp;ssl=1\" width=\"100%\"><\/p>\n<p>Machine learning model development is hard, especially in the real world.<\/p>\n<p>Typically, you need to:<\/p>\n<ul>\n<li>understand the business problem,\n<\/li>\n<li>gather the data,\n<\/li>\n<li>explore it,\n<\/li>\n<li>set up a proper validation scheme,\n<\/li>\n<li>implement models and tune parameters,\n<\/li>\n<li>deploy them in a way that makes sense for the business,\n<\/li>\n<li>inspect model results only to find out new problems that you have to deal with.\n<\/li>\n<\/ul>\n<p>And that is not all.<\/p>\n<p>You should have the\u00a0<strong>experiments<\/strong>\u00a0you run and\u00a0<strong>models<\/strong>\u00a0you train\u00a0<strong>versioned<\/strong>\u00a0in case you or anyone else needs to inspect them or reproduce the results in the future. From my experience, this moment comes when you least expect it and the feeling of \u201cI wish I had thought about it before\u201d is so very real (and painful).<\/p>\n<p>But there is even more.<\/p>\n<p>With ML models serving real people, misclassified cases (which are a natural consequence of using ML) are affecting peoples\u2019 lives and sometimes treating them very unfairly.\u00a0 It makes the ability to\u00a0<strong>explain your models\u2019 predictions<\/strong>\u00a0a requirement rather than just a nice to have.<\/p>\n<p>So what can you do about it?<\/p>\n<p>Fortunately, today there are tools that make dealing with both of those problems possible.<\/p>\n<p>The best part is you can combine them to\u00a0<strong>have your models versioned, reproducible, and explainable<\/strong>.<\/p>\n<p><strong>Read on to learn how to:<\/strong><\/p>\n<ul>\n<li>explain machine learning models with\u00a0<strong>DALEX<\/strong>\u00a0explainers\n<\/li>\n<li>make your models versioned and experiments reproducible with\u00a0<strong>Neptune<\/strong>\n<\/li>\n<li>automatically save model explainers and interactive explanation charts for every training run with\u00a0<strong>Neptune + DALEX integration<\/strong>\n<\/li>\n<li>compare, debug, and audit every model you build with\u00a0<strong>versioned explainers<\/strong>\n<\/li>\n<\/ul>\n<p>Let\u2019s dive in.<\/p>\n<p>\u00a0<\/p>\n<h3>Explainable Machine Learning with DALEX<\/h3>\n<p>\u00a0<br \/>Nowadays a model that scores high on the test set is often not enough. That\u2019s why there is a growing interest in eXplainable Artificial Intelligence (<strong>XAI<\/strong>), which is a set of methods and techniques that make you understand the model\u2019s behavior.<\/p>\n<p>There are many XAI methods available in multiple programming languages. Some of the most commonly used in machine learning are\u00a0<em>LIME<\/em>,\u00a0<em>SHAP,\u00a0<\/em>or\u00a0<em>PDP<\/em>, but there are many more.<\/p>\n<p>It is easy to get lost in the vast amount of techniques and that is where the\u00a0<strong>eXplainable Artificial Intelligence pyramid<\/strong>\u00a0comes in handy. It gathers the needs related to the exploration of models into an extensible drill-down map. The left side is about needs related to a single instance, the right side to a model as a whole. Consecutive layers dig into more and more detailed questions about the model behavior (local or global).<\/p>\n<div>\n<img src=\"https:\/\/i2.wp.com\/neptune.ai\/wp-content\/uploads\/2020\/07\/xai_pyramid.png\" alt=\"Figure\" width=\"100%\"><br \/><span><\/p>\n<p><\/span>\n<\/div>\n<p>\u00a0<\/p>\n<p>DALEX (available in R and Python) is a tool that\u00a0<strong>helps you to understand how<\/strong>\u00a0complex models are working. It currently works for tabular data only (but text and vision will come in the future).<\/p>\n<p>It is integrated with most popular frameworks used for building machine learning models like\u00a0<em>keras, sklearn, xgboost, lightgbm, H2O\u00a0<\/em>and many more!<\/p>\n<p>The core object in\u00a0<strong>DALEX<\/strong>\u00a0is an\u00a0<strong>explainer<\/strong>. It connects training or evaluation data and a trained model and extracts all the information that you need to explain it.<\/p>\n<p>Once you have it you can create visualizations, show model parameters, and dive into other model-related information. You can share it with your team or save it for later.<\/p>\n<p>Creating an explainer for any model is really easy, as you can see in this example using\u00a0<em>sklearn<\/em>!<\/p>\n<div>\n<pre><code>import dalex as dx\r\nimport pandas as pd\r\nfrom sklearn.ensemble import RandomForestClassifier\r\nfrom sklearn.preprocessing import LabelEncoder\r\n\r\ndata = dx.datasets.load_titanic()\r\nle = preprocessing.LabelEncoder()\r\nfor feature in ['gender', 'class', 'embarked']:\r\n\tdata[feature] = le.fit_transform(data[feature])\r\n\r\nX = data.drop(columns='survived')\r\ny = data.survived\r\n\r\nclassifier = RandomForestClassifier()\r\nclassifier.fit(X, y)\r\n\r\nexp = dx.Explainer(classifier, X, y, label = \"Titanic Random Forest\")<\/code><\/pre>\n<\/div>\n<p>\u00a0<\/p>\n<h3><strong>Model explanation for observations (local explanations)<\/strong><\/h3>\n<p>\u00a0<br \/>When you want to understand\u00a0<strong>why your model made a particular prediction<\/strong>, local explanations are your best friend.<\/p>\n<p>It all starts with a prediction and moving down the left half of the pyramid above you can explore and understand what happened.<\/p>\n<p>DALEX gives you a bunch of methods that show the influence of each variable locally:<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/github.com\/slundberg\/shap\" rel=\"noopener noreferrer\" target=\"_blank\">SHAP<\/a>: calculates contributions of features to the model prediction using classic Shapley values\n<\/li>\n<li>\n<a href=\"https:\/\/pbiecek.github.io\/breakDown\/\" rel=\"noopener noreferrer\" target=\"_blank\">Break Down<\/a>: decomposes predictions into parts that can be attributed to each variable with so-called \u201cgreedy explanations\u201d\n<\/li>\n<li>\n<a href=\"https:\/\/pbiecek.github.io\/breakDown\/reference\/break_down.html\" rel=\"noopener noreferrer\" target=\"_blank\">Break Down with interactions<\/a>: extends \u201cgreedy explanations\u201d to account for feature interactions\n<\/li>\n<\/ul>\n<p>Moving down the pyramid, the next crucial part of local explanations is\u00a0<strong>understanding the sensitivity of the model\u00a0<\/strong>to changes in feature values.<\/p>\n<p>There is an easy way to plot such information in DALEX:<\/p>\n<ul>\n<li>\n<a href=\"https:\/\/github.com\/pbiecek\/ceterisParibus\" rel=\"noopener noreferrer\" target=\"_blank\">Ceteris Paribus<\/a>: shows changes in model prediction allowing for differences only in a single variable while keeping all others constant\n<\/li>\n<\/ul>\n<p>Following up on our example Random Forest model created on the Titanic dataset, we can easily create the plots mentioned above.<\/p>\n<div>\n<pre><code>observation = pd.DataFrame({'gender': ['male'],\r\n                   \t    'age': [25],\r\n                   \t    'class': ['1st'],\r\n                   \t    'embarked': ['Southampton'],\r\n                       \t    'fare': [72],\r\n                   \t    'sibsp': [0],\r\n                   \t    'parch': 0},\r\n                  \t    index = ['John'])\r\n\r\n# Variable influence plots - Break Down &amp; SHAP\r\nbd = exp.predict_parts(observation , type='break_down')\r\nbd_inter = exp.predict_parts(observation, type='break_down_interactions')\r\nbd.plot(bd_inter)\r\n\r\nshap = exp.predict_parts(observation, type = 'shap', B = 10)\r\nshap.plot(max_vars=5)\r\n\r\n# Ceteris Paribus plots\r\ncp = exp.predict_profile(observation)\r\ncp.plot(variable_type = \"numerical\")\r\ncp.plot(variable_type = \"categorical\")<\/code><\/pre>\n<\/div>\n<p><img alt=\"local explanations dalex\" class=\"aligncenter\" data-recalc-dims=\"1\" src=\"https:\/\/i2.wp.com\/neptune.ai\/wp-content\/uploads\/dalex_local_ADAM.gif?resize=1024%2C291&amp;ssl=1\" width=\"100%\"><\/p>\n<p>\u00a0<\/p>\n<h3><strong>Model understanding (global explanations)<\/strong><\/h3>\n<p>\u00a0<br \/>When you want to understand\u00a0<strong>which features are generally important for your model<\/strong>\u00a0when it makes decisions you should look into global explanations.<\/p>\n<p>To understand the model on the global level DALEX provides you with the variable importance plots. Variable importance plots, specifically\u00a0<a href=\"https:\/\/christophm.github.io\/interpretable-ml-book\/feature-importance.html\" rel=\"noopener noreferrer\" target=\"_blank\">permutation feature importance<\/a>, enable the user to understand each variable\u2019s influence on the model as a whole, and distinguish the most important ones.<\/p>\n<p>Such visualizations can be seen as a global equivalent of SHAP and Break Down plots which depict similar information for a single observation.<\/p>\n<p>Moving down the pyramid, on a dataset level, there are techniques such as Partial Dependence Profiles and Accumulated Local Dependence that let you\u00a0<strong>visualize the way the model reacts as a function of selected variables.<\/strong><\/p>\n<p>Now let\u2019s create some global explanations for our example.<\/p>\n<div>\n<pre><code># Variable importance\r\n\r\nvi = exp.model_parts()\r\nvi.plot(max_vars=5)\r\n\r\n# Partial and Accumulated Dependence Profiles\r\n\r\npdp_num = exp.model_profile(type = 'partial')\r\nale_num = exp.model_profile(type = 'accumulated')\r\n\r\npdp_num.plot(ale_num)\r\n\r\npdp_cat = exp.model_profile(type = 'partial', \r\nvariable_type='categorical',\r\nvariables = [\"gender\",\"class\"])\r\nale_cat = exp.model_profile(type = 'accumulated',\r\n          variable_type='categorical',\r\n          variables = [\"gender\",\"class\"])\r\n\r\nale_cat.plot(pdp_cat)<\/code><\/pre>\n<\/div>\n<p><img alt=\"global explanations dalex\" class=\"aligncenter\" data-recalc-dims=\"1\" src=\"https:\/\/i0.wp.com\/neptune.ai\/wp-content\/uploads\/2020\/07\/global_gif.gif?resize=1024%2C288&amp;ssl=1\" width=\"100%\"><\/p>\n<p>\u00a0<\/p>\n<h3><strong>Reusable and organized explanation objects<\/strong><\/h3>\n<p>\u00a0<br \/>A clean, structured, and easy to use collection\u00a0 of XAI visualizations is great but there is more to DALEX than that.<\/p>\n<p>Packaging your models in\u00a0<strong>DALEX explainers<\/strong>\u00a0gives you a\u00a0<strong>reusable and organized way of storing and versioning<\/strong>\u00a0any work you do with machine learning\u00a0<strong>models<\/strong>.<\/p>\n<p>The explainer object created using DALEX contains:<\/p>\n<ul>\n<li>a model to be explained,\n<\/li>\n<li>model name and class,\n<\/li>\n<li>task type,\n<\/li>\n<li>data which will be used to calculate the explanations,\n<\/li>\n<li>model predictions for such data,\n<\/li>\n<li>predict function,\n<\/li>\n<li>model residuals,\n<\/li>\n<li>sampling weights for observations,\n<\/li>\n<li>additional model information (package, version, etc.)\n<\/li>\n<\/ul>\n<p>Having all this information stored in a single object makes creating local and global explanations easy (as we saw before).<\/p>\n<p>It also makes reviewing, sharing, and comparing models and explanations at every stage of model development possible.<\/p>\n<p>\u00a0<\/p>\n<h3>Experiment and model versioning with Neptune<\/h3>\n<p>\u00a0<br \/>In the perfect world, all your machine learning models and experiments are versioned in the same way as you version your software projects.<\/p>\n<p>Unfortunately, to keep track of your ML projects you need way more than just committing your code to Github.<\/p>\n<p>In a nutshell, to\u00a0<strong>version machine learning models properly<\/strong>\u00a0you should keep track of:<\/p>\n<ul>\n<li>code, notebooks, and configuration files\n<\/li>\n<li>environment\n<\/li>\n<li>parameters\n<\/li>\n<li>datasets\n<\/li>\n<li>model files\n<\/li>\n<li>results like evaluation metrics, performance charts or predictions\n<\/li>\n<\/ul>\n<p>Some of those things work nicely with .git (code, environment configs) but others not so much.<\/p>\n<p>Neptune makes it easy to keep track of all that by letting you log everything and anything you feel is important.<\/p>\n<p>You just add a few lines to your scripts:<\/p>\n<div>\n<pre><code>import neptune\r\nfrom neptunecontrib.api import *\r\nfrom neptunecontrib.versioning.data import *\r\n\r\nneptune.init('YOU\/YOUR_PROJECT')\r\n\r\nneptune.create_experiment(\r\n          params={'lr': 0.01, 'depth': 30, 'epoch_nr': 10}, # parameters\r\n          upload_source_files=['**\/*.py', # scripts\r\n                               'requirements.yaml']) # environment\r\nlog_data_version('\/path\/to\/dataset') # data version\r\n#\r\n# your training logic\r\n#\r\nneptune.log_metric('test_auc', 0.82) # metrics\r\nlog_chart('ROC curve', fig) # performance charts\r\nlog_pickle('model.pkl', clf) # model file<\/code><\/pre>\n<\/div>\n<p>And every experiment or model training you run is versioned and waiting for you in the Neptune app (and database\u00a0\ud83d\ude42).<\/p>\n<div>\n<img src=\"https:\/\/i2.wp.com\/neptune.ai\/wp-content\/uploads\/2020\/07\/model_versioning.gif?resize=800%2C665&amp;ssl=1\" alt=\"Figure\" width=\"100%\"><br \/><span><\/p>\n<p><\/span>\n<\/div>\n<p>\u00a0<\/p>\n<p>Your team can access all of the experiments and models, compare results, and find the information quickly.<\/p>\n<p>You may be thinking: \u201cOk great, so I have my models versioned but\u201d:<\/p>\n<ul>\n<li>what if I want to debug the model weeks or months after they were trained?\n<\/li>\n<li>what if I want to see the prediction explanations or variable importance for every experiment run?\n<\/li>\n<li>what if somebody asks me to check if this model is unfairly biased and I don\u2019t have the code or data it was trained on?\n<\/li>\n<\/ul>\n<p>I hear you, and that\u2019s where DALEX integration comes in!<\/p>\n<p>\u00a0<\/p>\n<h3>DALEX + Neptune = versioned and explainable models<\/h3>\n<p>\u00a0<br \/>Why not have your DALEX\u00a0<strong>explainers logged and versioned for every experiment<\/strong>\u00a0with interactive explanation charts rendered in a nice UI, easy to share with anyone you want.<\/p>\n<p>Exactly, why not!<\/p>\n<p>With Neptune-DALEX integration, you can get all that at a cost of 3 additional lines.<\/p>\n<p>Also, there are some very real benefits that come with this:<\/p>\n<ul>\n<li>You can\u00a0<strong>review models<\/strong>\u00a0that others created and share yours easily\n<\/li>\n<li>You can\u00a0<strong>compare<\/strong>\u00a0the behavior of any of the created models\n<\/li>\n<li>You can\u00a0<strong>trace and audit every model<\/strong>\u00a0for unwanted bias and other problems\n<\/li>\n<li>You can\u00a0<strong>debug<\/strong>\u00a0and compare models for which the training data, code or parameters are missing\n<\/li>\n<\/ul>\n<p>Ok, it sounds cool, but how does it actually work?<\/p>\n<p>Let\u2019s get into this now.<\/p>\n<p>\u00a0<\/p>\n<h3><strong>Version local explanations<\/strong><\/h3>\n<p>\u00a0<br \/>To log local model explanations you just need to:<\/p>\n<ul>\n<li>Create an observation vector\n<\/li>\n<li>Create your DALEX explainer object\n<\/li>\n<li>Pass them to the\u00a0<code>log_local_explanations<\/code>\u00a0function from\u00a0<code>neptunecontrib<\/code>\n<\/li>\n<\/ul>\n<div>\n<pre><code>from neptunecontrib.api import log_local_explanations\r\n\r\nobservation = pd.DataFrame({'gender': ['male'],\r\n                   \t    'age': [25],\r\n                   \t    'class': ['1st'],\r\n                   \t    'embarked': ['Southampton'],\r\n                       \t    'fare': [72],\r\n                   \t    'sibsp': [0],\r\n                   \t    'parch': 0},\r\n                  \t    index = ['John'])\r\n\r\nlog_local_explanations(expl, observation)<\/code><\/pre>\n<\/div>\n<p>Interactive explanation charts will be waiting for you in the \u201cArtifacts\u201d section of the Neptune app:<\/p>\n<div>\n<img src=\"https:\/\/i0.wp.com\/neptune.ai\/wp-content\/uploads\/dalex_local_explanations.gif?resize=800%2C472&amp;ssl=1\" alt=\"Figure\" width=\"100%\"><br \/><span><\/p>\n<p><\/span>\n<\/div>\n<p>\u00a0<\/p>\n<p>The following plots are created:<\/p>\n<ul>\n<li>variable importance\n<\/li>\n<li>partial dependence (if numerical features are specified)\n<\/li>\n<li>accumulated dependence (if categorical features are specified)\n<\/li>\n<\/ul>\n<p>\u00a0<\/p>\n<h3><strong>Version global explanations<\/strong><\/h3>\n<p>\u00a0<br \/>With global model explanations it\u2019s even simpler:<\/p>\n<ul>\n<li>Create your DALEX explainer object\n<\/li>\n<li>Pass it to the\u00a0<code>log_global_explanations<\/code>\u00a0function from\u00a0<code>neptunecontrib<\/code>\n<\/li>\n<li>(optional) specify categorical features for which you would like to plot\n<\/li>\n<\/ul>\n<div>\n<pre><code>from neptunecontrib.api import log_global_explanations\r\n\r\nlog_global_explanations(expl, categorical_features=[\"gender\", \"class\"])<\/code><\/pre>\n<\/div>\n<p>That\u2019s it. Now you can go to the \u201cArtifacts\u201d section and find your local explanations charts:<\/p>\n<div>\n<img src=\"https:\/\/i2.wp.com\/neptune.ai\/wp-content\/uploads\/dalex_global_explanations.gif?resize=800%2C472&amp;ssl=1\" alt=\"Figure\" width=\"100%\"><br \/><span><\/p>\n<p><\/span>\n<\/div>\n<p>\u00a0<\/p>\n<p>The following plots are created:<\/p>\n<ul>\n<li>break down,\n<\/li>\n<li>break down with interactions,\n<\/li>\n<li>shap,\n<\/li>\n<li>ceteris paribus for numeric variables,\n<\/li>\n<li>ceteris paribus for categorical variables\n<\/li>\n<\/ul>\n<p>\u00a0<\/p>\n<h3><strong>Version explainer objects\u00a0<\/strong><\/h3>\n<p>\u00a0<br \/>But if you really want to version your explanations you should\u00a0<strong>version the explainer object<\/strong>\u00a0itself.<\/p>\n<p>The benefits of saving it?:<\/p>\n<ul>\n<li>You can always create a visual representation of it later\n<\/li>\n<li>You can dive into details in the tabular format\n<\/li>\n<li>You can use it however you like (even if you don\u2019t know how at the moment\u00a0\ud83d\ude42)\n<\/li>\n<\/ul>\n<p>and it\u2019s super simple:<\/p>\n<div>\n<pre><code>from neptunecontrib.api import log_explainer\r\n\r\nlog_explainer('explainer.pkl', expl)<\/code><\/pre>\n<\/div>\n<p>You may be thinking:\u00a0 \u201cHow else am I going to use the explainer objects?\u201d<\/p>\n<p>Let me show you in the next sections.<\/p>\n<p>\u00a0<\/p>\n<h3><strong>Fetch and analyze explanations of trained models<\/strong><\/h3>\n<p>\u00a0<br \/>First of all, if you logged your explainer to Neptune you can fetch it directly into your script or notebook:<\/p>\n<div>\n<pre><code>import neptune\r\nfrom neptunecontrib.api import get_pickle\r\n\r\nproject = neptune.init(api_token='ANONYMOUS',\r\n                       project_qualified_name='shared\/dalex-integration')\r\nexperiment = project.get_experiments(id='DAL-68')[0]\r\nexplainer = get_pickle(filename='explainer.pkl', experiment=experiment)<\/code><\/pre>\n<\/div>\n<p>Now that you have the model explanation you can debug your model.<\/p>\n<p>One possible scenario is that you have an observation for which your model fails miserably.<\/p>\n<p>You want to figure out why.<\/p>\n<p>If you have your DALEX explainer object saved you can:<\/p>\n<ul>\n<li>create local explanations and see what happened.\n<\/li>\n<li>check how changing features affect the results.\n<\/li>\n<\/ul>\n<div>\n<img src=\"https:\/\/i0.wp.com\/neptune.ai\/wp-content\/uploads\/dalex_explainer_after-1.gif?resize=800%2C670&amp;ssl=1\" alt=\"Figure\" width=\"100%\"><br \/><span><\/p>\n<p><\/span>\n<\/div>\n<p>\u00a0<\/p>\n<p>Of course, you can do way more, especially if you want to compare models and explanations.<\/p>\n<p>Let\u2019s dive into that now!<\/p>\n<p>\u00a0<\/p>\n<h3><strong>Compare models and explanations\u00a0<\/strong><\/h3>\n<p>\u00a0<br \/>What if you want to:<\/p>\n<ul>\n<li>compare the current model idea with the models that are running in production?\n<\/li>\n<li>see whether experimental ideas from last year would work better on freshly collected data?\n<\/li>\n<\/ul>\n<p>Having a clean structure of experiments and models and a single place where you store them makes it really easy to do.<\/p>\n<p>You can compare experiments based on parameters, data version, or metrics in the Neptune UI:<\/p>\n<div>\n<img src=\"https:\/\/i0.wp.com\/neptune.ai\/wp-content\/uploads\/dalex_exp_comparison.gif?resize=800%2C587&amp;ssl=1\" alt=\"Figure\" width=\"100%\"><br \/><span><\/p>\n<p><\/span>\n<\/div>\n<p>\u00a0<\/p>\n<p>You\u00a0<strong>see the diffs in two clicks<\/strong>\u00a0and can drill down to whatever info you need with one or two more.<\/p>\n<p>Ok, it is really useful when it comes to comparing hyperparameters and metrics but what about the explainers?<\/p>\n<p>You can go into each experiment and\u00a0<a href=\"https:\/\/ui.neptune.ai\/o\/shared\/org\/dalex-integration\/e\/DAL-78\/artifacts?path=charts%2F&amp;file=Break%20Down%20Interactions.html\" rel=\"noopener noreferrer\" target=\"_blank\">look at the interactive explanation charts<\/a>\u00a0to see if there is something fishy going on with your model.<\/p>\n<p>What\u2019s better, Neptune lets you access all the information you logged programmatically, including model explainers.<br \/>You can\u00a0<strong>fetch explainer objects for each experiment and compare them<\/strong>. Just use\u00a0<code>get_pickle<\/code>\u00a0function from\u00a0<code>neptunecontrib<\/code>\u00a0and then visualize multiple explainers with DALEX\u00a0<code>.plot<\/code>:<\/p>\n<div>\n<pre><code>experiments =project.get_experiments(id=['DAL-68','DAL-69','DAL-70','DAL-71'])\r\n\r\nshaps = []\r\nfor exp in experiments:\r\n\tauc_score = exp.get_numeric_channels_values('auc')['auc'].tolist()[0]\r\n\tlabel = f'{exp.id} | AUC: {auc_score:.3f}'\r\n\r\n\texplainer_ = get_pickle(filename='explainer.pkl', experiment=exp)\r\n    \r\n\tsh = explainer_.predict_parts(new_observation, type='shap', B = 10)\r\n\tsh.result.label = label\r\n\tshaps.append(sh)\r\n\r\nshaps[0].plot(shaps[1:])<\/code><\/pre>\n<\/div>\n<div>\n<img src=\"https:\/\/i0.wp.com\/neptune.ai\/wp-content\/uploads\/dalex_comparison.png?resize=1024%2C695&amp;ssl=1\" alt=\"Figure\" width=\"100%\"><br \/><span><\/p>\n<p><\/span>\n<\/div>\n<p>\u00a0<\/p>\n<p>That is the beauty of DALEX plots. You can pass multiple explainers and they will do the magic.<\/p>\n<p>Of course, you can compare previously trained models with the one that you are currently working on to see if you are going in the right direction. Just append it to the list of explainers and pass to the\u00a0<code>.plot<\/code>\u00a0method.<\/p>\n<p>\u00a0<\/p>\n<h3><strong>Final thoughts<\/strong><\/h3>\n<p>\u00a0<br \/>Ok, to sum up.<\/p>\n<p>In this article, you\u2019ve learned about:<\/p>\n<ul>\n<li>Various model explanation techniques and how to package those explanations with\u00a0 DALEX explainers\n<\/li>\n<li>How you can version machine learning models and experiments with Neptune\n<\/li>\n<li>How to version model explainers and interactive explanation charts for every training you run with Neptune + DALEX integration\n<\/li>\n<li>How to compare and debug models you train with explainers\n<\/li>\n<\/ul>\n<p>With all that information, I hope your model development process will now be more organized, reproducible, and explainable.<\/p>\n<p>Happy training!<\/p>\n<p><a href=\"https:\/\/docs.neptune.ai\/integrations\/dalex.html\" rel=\"noopener noreferrer\" target=\"_blank\"><img alt=\"\" class=\"aligncenter\" data-lazy-loaded=\"1\" src=\"https:\/\/i0.wp.com\/neptune.ai\/wp-content\/uploads\/CTA-Dalex-integration.jpg?fit=1367%2C730&amp;ssl=1\" width=\"100%\"><\/a><\/p>\n<p>\u00a0<br \/><a href=\"https:\/\/www.linkedin.com\/in\/jakub-czakon-2b797b69\/\" rel=\"noopener noreferrer\" target=\"_blank\"><strong>Jakub Czakon<\/strong><\/a> is Senior Data Scientist at neptune.ai.<\/p>\n<p><a href=\"https:\/\/www.linkedin.com\/in\/pbiecek\/\" rel=\"noopener noreferrer\" target=\"_blank\"><strong>Przemys\u0142aw Biecek<\/strong><\/a> is Founder of MI2DataLab, Principal Data Scientist at Samsung R&amp;D Institute Poland.<\/p>\n<p><strong>Adam Rydelek<\/strong> is a Research Engineer at MI2DataLab, Student in Data Science at Warsaw University of Technology.<\/p>\n<p><a href=\"https:\/\/neptune.ai\/blog\/explainable-and-reproducible-machine-learning-with-dalex-and-neptune\" target=\"_blank\" rel=\"noopener noreferrer\">Original<\/a>. Reposted with permission.<\/p>\n<p><b>Related:<\/b><\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/www.kdnuggets.com\/2020\/08\/explainable-reproducible-machine-learning-model-development-dalex-neptune.html<\/p>\n","protected":false},"author":0,"featured_media":753,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"https:\/\/wealthrevelation.com\/data-science\/wp-json\/wp\/v2\/posts\/752"}],"collection":[{"href":"https:\/\/wealthrevelation.com\/data-science\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wealthrevelation.com\/data-science\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/wealthrevelation.com\/data-science\/wp-json\/wp\/v2\/comments?post=752"}],"version-history":[{"count":0,"href":"https:\/\/wealthrevelation.com\/data-science\/wp-json\/wp\/v2\/posts\/752\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wealthrevelation.com\/data-science\/wp-json\/wp\/v2\/media\/753"}],"wp:attachment":[{"href":"https:\/\/wealthrevelation.com\/data-science\/wp-json\/wp\/v2\/media?parent=752"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wealthrevelation.com\/data-science\/wp-json\/wp\/v2\/categories?post=752"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wealthrevelation.com\/data-science\/wp-json\/wp\/v2\/tags?post=752"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}