Repository files navigation

Overview

One of the main barriers to more wide-spread adoption of machine learning is the Blackbox problem: users cannot see why the model predicted a certain value.

While simple linear models are relatively easy to explain, more advanced models like Generalized Linear Models, Random Forests and Boosted Trees are hard to explain especially in ways that the average person can understand.

At Clarify Health, we had to solve this problem to get clinicians and health leaders to accept the predictions of our models. As I talked to other data scientists, I realized that this is a common problem.

Hence we are open sourcing our toolkit to explain ML models.

The Transparency project enables data scientists to explain ensemble trees (e.g., XGB, GBM, RF, and decision tree) and GLMs:

  1. The explanation (feature contribution) is in the units of the prediction (e.g., dollars, days, probability etc)

  2. Feature contributions add up to the predicted value so it is easy to see why a certain value was predicted

  3. Can explain the model for any arbitrary sub-population at run-time

  4. Works with Scikit-Learn and Apache Spark models

  5. Can explain models with 100M+ rows in just a few seconds

  6. Enables a what-if analysis to see what the prediction would become if you changed feature inputs

Feel free to use it and contribute to it so we can increase the adoption of machine learning.

Screenshot

Alt text

The "Transparency" Library

Scalable and Fast, local (single level) and global (population level) prediction explanation of:

  • Ensemble trees (e.g., XGB, GBM, RF, and Decision tree)
  • Generalized linear models GLM (support for various families, link powers, and variance powers, e.g., logistic regression)

implemented for models in:

  • Python (Scikit-Learn)
  • Pyspark (Scala and Pyspark).

The Transparency algorithm runs in a fraction of the time required by #SHAP and #LIME and produces aggregable explanations for all predictions. We have successfully used this stable library over millions of EHR records in commercial applications.

Installation:

  • pip install transparency

additional step for Spark users:

Transformer Set

- Scikit-Learn Ensemble Tree Explainer Transformer

fromtransparency.python.explainer.ensemble_treeimportEnsembleTreeExplainerTransformerexpl=EnsembleTreeExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df)
  • estimator: the ensemble tree estimator that has been trained (e.g., random forest, gbm, or xgb)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.

- Scikit-Learn Generalized Linear Model (e.g., Logistic regression) Explainer Transformer

fromtransparency.python.explainer.glmimportGLMExplainerTransformerexpl=GLMExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df, output_proba=False)
  • estimator: the glm estimator that has been trained (e.g., logistic regression)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.
  • if output_proba is set to True, for the case of logistic regression, the output prediction and its corresponding explanation will be proba instead of the classification result

- Pyspark Ensemble Tree Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportEnsembleTreeExplainTransformerEnsembleTreeExplainTransformer(predictionView=predictions_view, featureImportanceView=features_importance_view,
modelPath=rf_model_path, label=label_column,
dropPathColumn=True, isClassification=classification, ensembleType=ensemble_type)
  • Path to load model modelPath

  • Supported ensembleType

    1. dct
    2. gbt
    3. rf
    4. xgboost4j
  • The feature importance extracted from Apache Spark Model Meta Data.featureImportanceView Reference this python script : testutil.common.get_feature_importance

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Importance
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

- Pyspark Generalized Linear Model (GLM) Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportGLMExplainTransformerGLMExplainTransformer(predictionView=predictions_view, coefficientView=coefficients_view,
linkFunctionType=link_function_type, label=label_column, nested=True,
calculateSum=True, family=family, variancePower=variance_power, linkPower=link_power)
  • Supported linkFunctionType

    1. logLink
    2. powerHalfLink
    3. identityLink
    4. logitLink
    5. inverseLink
    6. otherPowerLink
  • The feature coefficient extracted from Apache Spark Model Meta Data.coefficientView Reference this python script : testutil.common.get_feature_coefficients

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Coefficient
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

Example Notebooks

Authors

License

Apache License Version 2.0

About

Model explanation generator

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Overview

One of the main barriers to more wide-spread adoption of machine learning is the Blackbox problem: users cannot see why the model predicted a certain value.

While simple linear models are relatively easy to explain, more advanced models like Generalized Linear Models, Random Forests and Boosted Trees are hard to explain especially in ways that the average person can understand.

At Clarify Health, we had to solve this problem to get clinicians and health leaders to accept the predictions of our models. As I talked to other data scientists, I realized that this is a common problem.

Hence we are open sourcing our toolkit to explain ML models.

The Transparency project enables data scientists to explain ensemble trees (e.g., XGB, GBM, RF, and decision tree) and GLMs:

  1. The explanation (feature contribution) is in the units of the prediction (e.g., dollars, days, probability etc)

  2. Feature contributions add up to the predicted value so it is easy to see why a certain value was predicted

  3. Can explain the model for any arbitrary sub-population at run-time

  4. Works with Scikit-Learn and Apache Spark models

  5. Can explain models with 100M+ rows in just a few seconds

  6. Enables a what-if analysis to see what the prediction would become if you changed feature inputs

Feel free to use it and contribute to it so we can increase the adoption of machine learning.

Screenshot

Alt text

The "Transparency" Library

Scalable and Fast, local (single level) and global (population level) prediction explanation of:

  • Ensemble trees (e.g., XGB, GBM, RF, and Decision tree)
  • Generalized linear models GLM (support for various families, link powers, and variance powers, e.g., logistic regression)

implemented for models in:

  • Python (Scikit-Learn)
  • Pyspark (Scala and Pyspark).

The Transparency algorithm runs in a fraction of the time required by #SHAP and #LIME and produces aggregable explanations for all predictions. We have successfully used this stable library over millions of EHR records in commercial applications.

Installation:

  • pip install transparency

additional step for Spark users:

Transformer Set

- Scikit-Learn Ensemble Tree Explainer Transformer

fromtransparency.python.explainer.ensemble_treeimportEnsembleTreeExplainerTransformerexpl=EnsembleTreeExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df)
  • estimator: the ensemble tree estimator that has been trained (e.g., random forest, gbm, or xgb)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.

- Scikit-Learn Generalized Linear Model (e.g., Logistic regression) Explainer Transformer

fromtransparency.python.explainer.glmimportGLMExplainerTransformerexpl=GLMExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df, output_proba=False)
  • estimator: the glm estimator that has been trained (e.g., logistic regression)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.
  • if output_proba is set to True, for the case of logistic regression, the output prediction and its corresponding explanation will be proba instead of the classification result

- Pyspark Ensemble Tree Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportEnsembleTreeExplainTransformerEnsembleTreeExplainTransformer(predictionView=predictions_view, featureImportanceView=features_importance_view,
modelPath=rf_model_path, label=label_column,
dropPathColumn=True, isClassification=classification, ensembleType=ensemble_type)
  • Path to load model modelPath

  • Supported ensembleType

    1. dct
    2. gbt
    3. rf
    4. xgboost4j
  • The feature importance extracted from Apache Spark Model Meta Data.featureImportanceView Reference this python script : testutil.common.get_feature_importance

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Importance
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

- Pyspark Generalized Linear Model (GLM) Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportGLMExplainTransformerGLMExplainTransformer(predictionView=predictions_view, coefficientView=coefficients_view,
linkFunctionType=link_function_type, label=label_column, nested=True,
calculateSum=True, family=family, variancePower=variance_power, linkPower=link_power)
  • Supported linkFunctionType

    1. logLink
    2. powerHalfLink
    3. identityLink
    4. logitLink
    5. inverseLink
    6. otherPowerLink
  • The feature coefficient extracted from Apache Spark Model Meta Data.coefficientView Reference this python script : testutil.common.get_feature_coefficients

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Coefficient
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

Example Notebooks

Authors

License

Apache License Version 2.0

About

Model explanation generator

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Overview

One of the main barriers to more wide-spread adoption of machine learning is the Blackbox problem: users cannot see why the model predicted a certain value.

While simple linear models are relatively easy to explain, more advanced models like Generalized Linear Models, Random Forests and Boosted Trees are hard to explain especially in ways that the average person can understand.

At Clarify Health, we had to solve this problem to get clinicians and health leaders to accept the predictions of our models. As I talked to other data scientists, I realized that this is a common problem.

Hence we are open sourcing our toolkit to explain ML models.

The Transparency project enables data scientists to explain ensemble trees (e.g., XGB, GBM, RF, and decision tree) and GLMs:

  1. The explanation (feature contribution) is in the units of the prediction (e.g., dollars, days, probability etc)

  2. Feature contributions add up to the predicted value so it is easy to see why a certain value was predicted

  3. Can explain the model for any arbitrary sub-population at run-time

  4. Works with Scikit-Learn and Apache Spark models

  5. Can explain models with 100M+ rows in just a few seconds

  6. Enables a what-if analysis to see what the prediction would become if you changed feature inputs

Feel free to use it and contribute to it so we can increase the adoption of machine learning.

Screenshot

Alt text

The "Transparency" Library

Scalable and Fast, local (single level) and global (population level) prediction explanation of:

  • Ensemble trees (e.g., XGB, GBM, RF, and Decision tree)
  • Generalized linear models GLM (support for various families, link powers, and variance powers, e.g., logistic regression)

implemented for models in:

  • Python (Scikit-Learn)
  • Pyspark (Scala and Pyspark).

The Transparency algorithm runs in a fraction of the time required by #SHAP and #LIME and produces aggregable explanations for all predictions. We have successfully used this stable library over millions of EHR records in commercial applications.

Installation:

  • pip install transparency

additional step for Spark users:

Transformer Set

- Scikit-Learn Ensemble Tree Explainer Transformer

fromtransparency.python.explainer.ensemble_treeimportEnsembleTreeExplainerTransformerexpl=EnsembleTreeExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df)
  • estimator: the ensemble tree estimator that has been trained (e.g., random forest, gbm, or xgb)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.

- Scikit-Learn Generalized Linear Model (e.g., Logistic regression) Explainer Transformer

fromtransparency.python.explainer.glmimportGLMExplainerTransformerexpl=GLMExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df, output_proba=False)
  • estimator: the glm estimator that has been trained (e.g., logistic regression)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.
  • if output_proba is set to True, for the case of logistic regression, the output prediction and its corresponding explanation will be proba instead of the classification result

- Pyspark Ensemble Tree Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportEnsembleTreeExplainTransformerEnsembleTreeExplainTransformer(predictionView=predictions_view, featureImportanceView=features_importance_view,
modelPath=rf_model_path, label=label_column,
dropPathColumn=True, isClassification=classification, ensembleType=ensemble_type)
  • Path to load model modelPath

  • Supported ensembleType

    1. dct
    2. gbt
    3. rf
    4. xgboost4j
  • The feature importance extracted from Apache Spark Model Meta Data.featureImportanceView Reference this python script : testutil.common.get_feature_importance

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Importance
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

- Pyspark Generalized Linear Model (GLM) Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportGLMExplainTransformerGLMExplainTransformer(predictionView=predictions_view, coefficientView=coefficients_view,
linkFunctionType=link_function_type, label=label_column, nested=True,
calculateSum=True, family=family, variancePower=variance_power, linkPower=link_power)
  • Supported linkFunctionType

    1. logLink
    2. powerHalfLink
    3. identityLink
    4. logitLink
    5. inverseLink
    6. otherPowerLink
  • The feature coefficient extracted from Apache Spark Model Meta Data.coefficientView Reference this python script : testutil.common.get_feature_coefficients

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Coefficient
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

Example Notebooks

Authors

License

Apache License Version 2.0

About

Model explanation generator

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Overview

One of the main barriers to more wide-spread adoption of machine learning is the Blackbox problem: users cannot see why the model predicted a certain value.

While simple linear models are relatively easy to explain, more advanced models like Generalized Linear Models, Random Forests and Boosted Trees are hard to explain especially in ways that the average person can understand.

At Clarify Health, we had to solve this problem to get clinicians and health leaders to accept the predictions of our models. As I talked to other data scientists, I realized that this is a common problem.

Hence we are open sourcing our toolkit to explain ML models.

The Transparency project enables data scientists to explain ensemble trees (e.g., XGB, GBM, RF, and decision tree) and GLMs:

  1. The explanation (feature contribution) is in the units of the prediction (e.g., dollars, days, probability etc)

  2. Feature contributions add up to the predicted value so it is easy to see why a certain value was predicted

  3. Can explain the model for any arbitrary sub-population at run-time

  4. Works with Scikit-Learn and Apache Spark models

  5. Can explain models with 100M+ rows in just a few seconds

  6. Enables a what-if analysis to see what the prediction would become if you changed feature inputs

Feel free to use it and contribute to it so we can increase the adoption of machine learning.

Screenshot

Alt text

The "Transparency" Library

Scalable and Fast, local (single level) and global (population level) prediction explanation of:

  • Ensemble trees (e.g., XGB, GBM, RF, and Decision tree)
  • Generalized linear models GLM (support for various families, link powers, and variance powers, e.g., logistic regression)

implemented for models in:

  • Python (Scikit-Learn)
  • Pyspark (Scala and Pyspark).

The Transparency algorithm runs in a fraction of the time required by #SHAP and #LIME and produces aggregable explanations for all predictions. We have successfully used this stable library over millions of EHR records in commercial applications.

Installation:

  • pip install transparency

additional step for Spark users:

Transformer Set

- Scikit-Learn Ensemble Tree Explainer Transformer

fromtransparency.python.explainer.ensemble_treeimportEnsembleTreeExplainerTransformerexpl=EnsembleTreeExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df)
  • estimator: the ensemble tree estimator that has been trained (e.g., random forest, gbm, or xgb)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.

- Scikit-Learn Generalized Linear Model (e.g., Logistic regression) Explainer Transformer

fromtransparency.python.explainer.glmimportGLMExplainerTransformerexpl=GLMExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df, output_proba=False)
  • estimator: the glm estimator that has been trained (e.g., logistic regression)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.
  • if output_proba is set to True, for the case of logistic regression, the output prediction and its corresponding explanation will be proba instead of the classification result

- Pyspark Ensemble Tree Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportEnsembleTreeExplainTransformerEnsembleTreeExplainTransformer(predictionView=predictions_view, featureImportanceView=features_importance_view,
modelPath=rf_model_path, label=label_column,
dropPathColumn=True, isClassification=classification, ensembleType=ensemble_type)
  • Path to load model modelPath

  • Supported ensembleType

    1. dct
    2. gbt
    3. rf
    4. xgboost4j
  • The feature importance extracted from Apache Spark Model Meta Data.featureImportanceView Reference this python script : testutil.common.get_feature_importance

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Importance
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

- Pyspark Generalized Linear Model (GLM) Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportGLMExplainTransformerGLMExplainTransformer(predictionView=predictions_view, coefficientView=coefficients_view,
linkFunctionType=link_function_type, label=label_column, nested=True,
calculateSum=True, family=family, variancePower=variance_power, linkPower=link_power)
  • Supported linkFunctionType

    1. logLink
    2. powerHalfLink
    3. identityLink
    4. logitLink
    5. inverseLink
    6. otherPowerLink
  • The feature coefficient extracted from Apache Spark Model Meta Data.coefficientView Reference this python script : testutil.common.get_feature_coefficients

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Coefficient
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

Example Notebooks

Authors

License

Apache License Version 2.0

About

Model explanation generator

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Overview

One of the main barriers to more wide-spread adoption of machine learning is the Blackbox problem: users cannot see why the model predicted a certain value.

While simple linear models are relatively easy to explain, more advanced models like Generalized Linear Models, Random Forests and Boosted Trees are hard to explain especially in ways that the average person can understand.

At Clarify Health, we had to solve this problem to get clinicians and health leaders to accept the predictions of our models. As I talked to other data scientists, I realized that this is a common problem.

Hence we are open sourcing our toolkit to explain ML models.

The Transparency project enables data scientists to explain ensemble trees (e.g., XGB, GBM, RF, and decision tree) and GLMs:

  1. The explanation (feature contribution) is in the units of the prediction (e.g., dollars, days, probability etc)

  2. Feature contributions add up to the predicted value so it is easy to see why a certain value was predicted

  3. Can explain the model for any arbitrary sub-population at run-time

  4. Works with Scikit-Learn and Apache Spark models

  5. Can explain models with 100M+ rows in just a few seconds

  6. Enables a what-if analysis to see what the prediction would become if you changed feature inputs

Feel free to use it and contribute to it so we can increase the adoption of machine learning.

Screenshot

Alt text

The "Transparency" Library

Scalable and Fast, local (single level) and global (population level) prediction explanation of:

  • Ensemble trees (e.g., XGB, GBM, RF, and Decision tree)
  • Generalized linear models GLM (support for various families, link powers, and variance powers, e.g., logistic regression)

implemented for models in:

  • Python (Scikit-Learn)
  • Pyspark (Scala and Pyspark).

The Transparency algorithm runs in a fraction of the time required by #SHAP and #LIME and produces aggregable explanations for all predictions. We have successfully used this stable library over millions of EHR records in commercial applications.

Installation:

  • pip install transparency

additional step for Spark users:

Transformer Set

- Scikit-Learn Ensemble Tree Explainer Transformer

fromtransparency.python.explainer.ensemble_treeimportEnsembleTreeExplainerTransformerexpl=EnsembleTreeExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df)
  • estimator: the ensemble tree estimator that has been trained (e.g., random forest, gbm, or xgb)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.

- Scikit-Learn Generalized Linear Model (e.g., Logistic regression) Explainer Transformer

fromtransparency.python.explainer.glmimportGLMExplainerTransformerexpl=GLMExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df, output_proba=False)
  • estimator: the glm estimator that has been trained (e.g., logistic regression)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.
  • if output_proba is set to True, for the case of logistic regression, the output prediction and its corresponding explanation will be proba instead of the classification result

- Pyspark Ensemble Tree Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportEnsembleTreeExplainTransformerEnsembleTreeExplainTransformer(predictionView=predictions_view, featureImportanceView=features_importance_view,
modelPath=rf_model_path, label=label_column,
dropPathColumn=True, isClassification=classification, ensembleType=ensemble_type)
  • Path to load model modelPath

  • Supported ensembleType

    1. dct
    2. gbt
    3. rf
    4. xgboost4j
  • The feature importance extracted from Apache Spark Model Meta Data.featureImportanceView Reference this python script : testutil.common.get_feature_importance

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Importance
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

- Pyspark Generalized Linear Model (GLM) Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportGLMExplainTransformerGLMExplainTransformer(predictionView=predictions_view, coefficientView=coefficients_view,
linkFunctionType=link_function_type, label=label_column, nested=True,
calculateSum=True, family=family, variancePower=variance_power, linkPower=link_power)
  • Supported linkFunctionType

    1. logLink
    2. powerHalfLink
    3. identityLink
    4. logitLink
    5. inverseLink
    6. otherPowerLink
  • The feature coefficient extracted from Apache Spark Model Meta Data.coefficientView Reference this python script : testutil.common.get_feature_coefficients

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Coefficient
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

Example Notebooks

Authors

License

Apache License Version 2.0

About

Model explanation generator

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Overview

One of the main barriers to more wide-spread adoption of machine learning is the Blackbox problem: users cannot see why the model predicted a certain value.

While simple linear models are relatively easy to explain, more advanced models like Generalized Linear Models, Random Forests and Boosted Trees are hard to explain especially in ways that the average person can understand.

At Clarify Health, we had to solve this problem to get clinicians and health leaders to accept the predictions of our models. As I talked to other data scientists, I realized that this is a common problem.

Hence we are open sourcing our toolkit to explain ML models.

The Transparency project enables data scientists to explain ensemble trees (e.g., XGB, GBM, RF, and decision tree) and GLMs:

  1. The explanation (feature contribution) is in the units of the prediction (e.g., dollars, days, probability etc)

  2. Feature contributions add up to the predicted value so it is easy to see why a certain value was predicted

  3. Can explain the model for any arbitrary sub-population at run-time

  4. Works with Scikit-Learn and Apache Spark models

  5. Can explain models with 100M+ rows in just a few seconds

  6. Enables a what-if analysis to see what the prediction would become if you changed feature inputs

Feel free to use it and contribute to it so we can increase the adoption of machine learning.

Screenshot

Alt text

The "Transparency" Library

Scalable and Fast, local (single level) and global (population level) prediction explanation of:

  • Ensemble trees (e.g., XGB, GBM, RF, and Decision tree)
  • Generalized linear models GLM (support for various families, link powers, and variance powers, e.g., logistic regression)

implemented for models in:

  • Python (Scikit-Learn)
  • Pyspark (Scala and Pyspark).

The Transparency algorithm runs in a fraction of the time required by #SHAP and #LIME and produces aggregable explanations for all predictions. We have successfully used this stable library over millions of EHR records in commercial applications.

Installation:

  • pip install transparency

additional step for Spark users:

Transformer Set

- Scikit-Learn Ensemble Tree Explainer Transformer

fromtransparency.python.explainer.ensemble_treeimportEnsembleTreeExplainerTransformerexpl=EnsembleTreeExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df)
  • estimator: the ensemble tree estimator that has been trained (e.g., random forest, gbm, or xgb)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.

- Scikit-Learn Generalized Linear Model (e.g., Logistic regression) Explainer Transformer

fromtransparency.python.explainer.glmimportGLMExplainerTransformerexpl=GLMExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df, output_proba=False)
  • estimator: the glm estimator that has been trained (e.g., logistic regression)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.
  • if output_proba is set to True, for the case of logistic regression, the output prediction and its corresponding explanation will be proba instead of the classification result

- Pyspark Ensemble Tree Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportEnsembleTreeExplainTransformerEnsembleTreeExplainTransformer(predictionView=predictions_view, featureImportanceView=features_importance_view,
modelPath=rf_model_path, label=label_column,
dropPathColumn=True, isClassification=classification, ensembleType=ensemble_type)
  • Path to load model modelPath

  • Supported ensembleType

    1. dct
    2. gbt
    3. rf
    4. xgboost4j
  • The feature importance extracted from Apache Spark Model Meta Data.featureImportanceView Reference this python script : testutil.common.get_feature_importance

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Importance
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

- Pyspark Generalized Linear Model (GLM) Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportGLMExplainTransformerGLMExplainTransformer(predictionView=predictions_view, coefficientView=coefficients_view,
linkFunctionType=link_function_type, label=label_column, nested=True,
calculateSum=True, family=family, variancePower=variance_power, linkPower=link_power)
  • Supported linkFunctionType

    1. logLink
    2. powerHalfLink
    3. identityLink
    4. logitLink
    5. inverseLink
    6. otherPowerLink
  • The feature coefficient extracted from Apache Spark Model Meta Data.coefficientView Reference this python script : testutil.common.get_feature_coefficients

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Coefficient
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

Example Notebooks

Authors

License

Apache License Version 2.0

About

Model explanation generator

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Overview

One of the main barriers to more wide-spread adoption of machine learning is the Blackbox problem: users cannot see why the model predicted a certain value.

While simple linear models are relatively easy to explain, more advanced models like Generalized Linear Models, Random Forests and Boosted Trees are hard to explain especially in ways that the average person can understand.

At Clarify Health, we had to solve this problem to get clinicians and health leaders to accept the predictions of our models. As I talked to other data scientists, I realized that this is a common problem.

Hence we are open sourcing our toolkit to explain ML models.

The Transparency project enables data scientists to explain ensemble trees (e.g., XGB, GBM, RF, and decision tree) and GLMs:

  1. The explanation (feature contribution) is in the units of the prediction (e.g., dollars, days, probability etc)

  2. Feature contributions add up to the predicted value so it is easy to see why a certain value was predicted

  3. Can explain the model for any arbitrary sub-population at run-time

  4. Works with Scikit-Learn and Apache Spark models

  5. Can explain models with 100M+ rows in just a few seconds

  6. Enables a what-if analysis to see what the prediction would become if you changed feature inputs

Feel free to use it and contribute to it so we can increase the adoption of machine learning.

Screenshot

Alt text

The "Transparency" Library

Scalable and Fast, local (single level) and global (population level) prediction explanation of:

  • Ensemble trees (e.g., XGB, GBM, RF, and Decision tree)
  • Generalized linear models GLM (support for various families, link powers, and variance powers, e.g., logistic regression)

implemented for models in:

  • Python (Scikit-Learn)
  • Pyspark (Scala and Pyspark).

The Transparency algorithm runs in a fraction of the time required by #SHAP and #LIME and produces aggregable explanations for all predictions. We have successfully used this stable library over millions of EHR records in commercial applications.

Installation:

  • pip install transparency

additional step for Spark users:

Transformer Set

- Scikit-Learn Ensemble Tree Explainer Transformer

fromtransparency.python.explainer.ensemble_treeimportEnsembleTreeExplainerTransformerexpl=EnsembleTreeExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df)
  • estimator: the ensemble tree estimator that has been trained (e.g., random forest, gbm, or xgb)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.

- Scikit-Learn Generalized Linear Model (e.g., Logistic regression) Explainer Transformer

fromtransparency.python.explainer.glmimportGLMExplainerTransformerexpl=GLMExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df, output_proba=False)
  • estimator: the glm estimator that has been trained (e.g., logistic regression)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.
  • if output_proba is set to True, for the case of logistic regression, the output prediction and its corresponding explanation will be proba instead of the classification result

- Pyspark Ensemble Tree Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportEnsembleTreeExplainTransformerEnsembleTreeExplainTransformer(predictionView=predictions_view, featureImportanceView=features_importance_view,
modelPath=rf_model_path, label=label_column,
dropPathColumn=True, isClassification=classification, ensembleType=ensemble_type)
  • Path to load model modelPath

  • Supported ensembleType

    1. dct
    2. gbt
    3. rf
    4. xgboost4j
  • The feature importance extracted from Apache Spark Model Meta Data.featureImportanceView Reference this python script : testutil.common.get_feature_importance

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Importance
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

- Pyspark Generalized Linear Model (GLM) Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportGLMExplainTransformerGLMExplainTransformer(predictionView=predictions_view, coefficientView=coefficients_view,
linkFunctionType=link_function_type, label=label_column, nested=True,
calculateSum=True, family=family, variancePower=variance_power, linkPower=link_power)
  • Supported linkFunctionType

    1. logLink
    2. powerHalfLink
    3. identityLink
    4. logitLink
    5. inverseLink
    6. otherPowerLink
  • The feature coefficient extracted from Apache Spark Model Meta Data.coefficientView Reference this python script : testutil.common.get_feature_coefficients

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Coefficient
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

Example Notebooks

Authors

License

Apache License Version 2.0

About

Model explanation generator

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Overview

One of the main barriers to more wide-spread adoption of machine learning is the Blackbox problem: users cannot see why the model predicted a certain value.

While simple linear models are relatively easy to explain, more advanced models like Generalized Linear Models, Random Forests and Boosted Trees are hard to explain especially in ways that the average person can understand.

At Clarify Health, we had to solve this problem to get clinicians and health leaders to accept the predictions of our models. As I talked to other data scientists, I realized that this is a common problem.

Hence we are open sourcing our toolkit to explain ML models.

The Transparency project enables data scientists to explain ensemble trees (e.g., XGB, GBM, RF, and decision tree) and GLMs:

  1. The explanation (feature contribution) is in the units of the prediction (e.g., dollars, days, probability etc)

  2. Feature contributions add up to the predicted value so it is easy to see why a certain value was predicted

  3. Can explain the model for any arbitrary sub-population at run-time

  4. Works with Scikit-Learn and Apache Spark models

  5. Can explain models with 100M+ rows in just a few seconds

  6. Enables a what-if analysis to see what the prediction would become if you changed feature inputs

Feel free to use it and contribute to it so we can increase the adoption of machine learning.

Screenshot

Alt text

The "Transparency" Library

Scalable and Fast, local (single level) and global (population level) prediction explanation of:

  • Ensemble trees (e.g., XGB, GBM, RF, and Decision tree)
  • Generalized linear models GLM (support for various families, link powers, and variance powers, e.g., logistic regression)

implemented for models in:

  • Python (Scikit-Learn)
  • Pyspark (Scala and Pyspark).

The Transparency algorithm runs in a fraction of the time required by #SHAP and #LIME and produces aggregable explanations for all predictions. We have successfully used this stable library over millions of EHR records in commercial applications.

Installation:

  • pip install transparency

additional step for Spark users:

Transformer Set

- Scikit-Learn Ensemble Tree Explainer Transformer

fromtransparency.python.explainer.ensemble_treeimportEnsembleTreeExplainerTransformerexpl=EnsembleTreeExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df)
  • estimator: the ensemble tree estimator that has been trained (e.g., random forest, gbm, or xgb)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.

- Scikit-Learn Generalized Linear Model (e.g., Logistic regression) Explainer Transformer

fromtransparency.python.explainer.glmimportGLMExplainerTransformerexpl=GLMExplainerTransformer(estimator)
X_test_df=expl.transform(X_test_df, output_proba=False)
  • estimator: the glm estimator that has been trained (e.g., logistic regression)
  • X_test: a Pandas dataframe with features as columns and samples as rows The resulting X_test_df will have 3 added columns: 'prediction', 'feature_contributions' and 'intercept_contribution':
  • 'feature_contributions': column of nested arrays with feature contributions (1 array per row)
  • 'intercept_contribution': column of the same scaler value representing the contribution of the intercept sum(contributions) + contrib_intercept for each row equals the prediction for that row.
  • if output_proba is set to True, for the case of logistic regression, the output prediction and its corresponding explanation will be proba instead of the classification result

- Pyspark Ensemble Tree Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportEnsembleTreeExplainTransformerEnsembleTreeExplainTransformer(predictionView=predictions_view, featureImportanceView=features_importance_view,
modelPath=rf_model_path, label=label_column,
dropPathColumn=True, isClassification=classification, ensembleType=ensemble_type)
  • Path to load model modelPath

  • Supported ensembleType

    1. dct
    2. gbt
    3. rf
    4. xgboost4j
  • The feature importance extracted from Apache Spark Model Meta Data.featureImportanceView Reference this python script : testutil.common.get_feature_importance

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Importance
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

- Pyspark Generalized Linear Model (GLM) Explainer Transformer

fromtransparency.spark.prediction.explainer.treeimportGLMExplainTransformerGLMExplainTransformer(predictionView=predictions_view, coefficientView=coefficients_view,
linkFunctionType=link_function_type, label=label_column, nested=True,
calculateSum=True, family=family, variancePower=variance_power, linkPower=link_power)
  • Supported linkFunctionType

    1. logLink
    2. powerHalfLink
    3. identityLink
    4. logitLink
    5. inverseLink
    6. otherPowerLink
  • The feature coefficient extracted from Apache Spark Model Meta Data.coefficientView Reference this python script : testutil.common.get_feature_coefficients

    1. Feature_Index
    2. Feature
    3. Original_Feature
    4. Coefficient
  • The transformer append 3 main column to the prediction view

    1. contrib_column ==> f"{prediction_{label_column}_contrib : array of contributions
    2. contrib_column_sum ==> f"{contrib_column}_sum"
    3. contrib_column_intercept ==> f"{contrib_column}_intercept"

Example Notebooks

Authors

License

Apache License Version 2.0

About

Model explanation generator

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages