This repository was archived by the owner on Nov 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 61
Add get_feature_contributions method to Pipeline #186
Closed
Closed
Changes from 14 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
8bba81a
Add calculate_feature_contrinutions method to Pipeline
najeeb-kazmi 788e089
Merge branch 'master' into 91
ganik 41674b6
Merge branch 'master' into 91
ganik 8fa9192
Merge branch 'master' into 91
ganik ff15cf5
typo
najeeb-kazmi 6639669
rename to get_feature_contributions(), add docs, improve sample
najeeb-kazmi 28dad24
Add list of supported models to sample
najeeb-kazmi 41cfb2c
Some PR feedback
najeeb-kazmi a0d4f70
Fix feature contributions for regression and ranking
najeeb-kazmi 818c36e
Implement feature contributions in BasePredictor
najeeb-kazmi 5a80929
Add test to check feature contributions with unpickled pipeline
najeeb-kazmi 6337475
Improve doc, simplify entrypoint graph for feature contributions
najeeb-kazmi 11c388e
Add test to check feature contributions with pipeline loaded from zip
najeeb-kazmi ea3dce4
nit
najeeb-kazmi 93a46fa
PR feedback
najeeb-kazmi c0500d1
Save the model file when pickling a NimbusML Pipeline. (#189)
pieths 266d27d
Remove stored references to X and y in BasePredictor. (#195)
pieths d20c398
Add calculate_feature_contrinutions method to Pipeline
najeeb-kazmi e21f91d
typo
najeeb-kazmi df3bdc7
rename to get_feature_contributions(), add docs, improve sample
najeeb-kazmi a09d6ef
Add list of supported models to sample
najeeb-kazmi c8c851d
Some PR feedback
najeeb-kazmi 80f4655
Fix feature contributions for regression and ranking
najeeb-kazmi 0c208dc
Implement feature contributions in BasePredictor
najeeb-kazmi 042566f
Add test to check feature contributions with unpickled pipeline
najeeb-kazmi 9bd8b4e
Improve doc, simplify entrypoint graph for feature contributions
najeeb-kazmi b142ab1
Add test to check feature contributions with pipeline loaded from zip
najeeb-kazmi af7c37c
nit
najeeb-kazmi e1f12f4
PR feedback
najeeb-kazmi 1a181bd
Adding more tests, implement save_model in BasePipelineItem, and PR f…
najeeb-kazmi e621047
Fix conflicts
najeeb-kazmi 8546a19
one more conflict
najeeb-kazmi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
src/python/nimbusml/examples/PipelineWithFeatureContributions.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| ############################################################################### | ||
| # Pipeline with observation level feature contributions | ||
|
|
||
| # Scoring a dataset with a trained model produces a score, or prediction, for | ||
| # each example. To understand and explain these predictions it can be useful to | ||
| # inspect which features influenced them most significantly. This function | ||
| # computes a model-specific list of per-feature contributions to the score for | ||
| # each example. These contributions can be positive (they make the score | ||
| # higher) or negative (they make the score lower). | ||
|
|
||
| from nimbusml import Pipeline, FileDataStream | ||
| from nimbusml.datasets import get_dataset | ||
| from nimbusml.ensemble import FastTreesBinaryClassifier | ||
| from nimbusml.linear_model import LogisticRegressionBinaryClassifier | ||
|
|
||
| # data input (as a FileDataStream) | ||
| path = get_dataset('uciadult_train').as_filepath() | ||
|
|
||
| data = FileDataStream.read_csv(path) | ||
| print(data.head()) | ||
| # label workclass education ... capital-loss hours-per-week | ||
| # 0 0 Private 11th ... 0 40 | ||
| # 1 0 Private HS-grad ... 0 50 | ||
| # 2 1 Local-gov Assoc-acdm ... 0 40 | ||
| # 3 1 Private Some-college ... 0 40 | ||
| # 4 0 ? Some-college ... 0 30 | ||
|
|
||
| # define the training pipeline with a linear model | ||
| lr_pipeline = Pipeline([LogisticRegressionBinaryClassifier( | ||
| feature=['age', 'education-num', 'hours-per-week'], label='label')]) | ||
|
|
||
| # train the model | ||
| lr_model = lr_pipeline.fit(data) | ||
|
|
||
| # For linear models, the contribution of a given feature is equal to the | ||
| # product of feature value times the corresponding weight. Similarly, for | ||
| # Generalized Additive Models (GAM), the contribution of a feature is equal to | ||
| # the shape function for the given feature evaluated at the feature value. | ||
| lr_feature_contributions = lr_model.get_feature_contributions(data) | ||
|
|
||
| # Print predictions with feature contributions, which give a relative measure | ||
| # of how much each feature impacted the Score. | ||
| print("========== Feature Contributions for Linear Model ==========") | ||
| print(lr_feature_contributions.head()) | ||
| # label ... PredictedLabel Score ... FeatureContributions.hours-per-week | ||
| # 0 0 ... 0 -2.010687 ... 0.833069 | ||
| # 1 0 ... 0 -1.216163 ... 0.809928 | ||
| # 2 1 ... 0 -1.248412 ... 0.485957 | ||
| # 3 1 ... 0 -1.132419 ... 0.583148 | ||
| # 4 0 ... 0 -1.969522 ... 0.437361 | ||
|
|
||
| # define the training pipeline with a tree model | ||
| tree_pipeline = Pipeline([FastTreesBinaryClassifier( | ||
| feature=['age', 'education-num', 'hours-per-week'], label='label')]) | ||
|
|
||
| # train the model | ||
| tree_model = tree_pipeline.fit(data) | ||
|
|
||
| # For tree-based models, the calculation of feature contribution essentially | ||
| # consists in determining which splits in the tree have the most impact on the | ||
| # final score and assigning the value of the impact to the features determining | ||
| # the split. More precisely, the contribution of a feature is equal to the | ||
| # change in score produced by exploring the opposite sub-tree every time a | ||
| # decision node for the given feature is encountered. | ||
| # | ||
| # Consider a simple case with a single decision tree that has a decision node | ||
| # for the binary feature F1. Given an example that has feature F1 equal to | ||
| # true, we can calculate the score it would have obtained if we chose the | ||
| # subtree corresponding to the feature F1 being equal to false while keeping | ||
| # the other features constant. The contribution of feature F1 for the given | ||
| # example is the difference between the original score and the score obtained | ||
| # by taking the opposite decision at the node corresponding to feature F1. This | ||
| # algorithm extends naturally to models with many decision trees. | ||
| tree_feature_contributions = tree_model.get_feature_contributions(data) | ||
|
|
||
| # Print predictions with feature contributions, which give a relative measure | ||
| # of how much each feature impacted the Score. | ||
| print("========== Feature Contributions for Tree Model ==========") | ||
| print(tree_feature_contributions.head()) | ||
| # label ... PredictedLabel Score ... FeatureContributions.hours-per-week | ||
| # 0 0 ... 0 -16.717360 ... -0.608664 | ||
| # 1 0 ... 0 -7.688200 ... -0.541213 | ||
| # 2 1 ... 1 1.571164 ... 0.032862 | ||
| # 3 1 ... 1 2.115638 ... 0.537077 | ||
| # 4 0 ... 0 -23.038410 ... -0.682764 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.