Skip to content

Commit c95aeb4

Browse files
authored
explanation fixes (#88)
* fixed shap, lime, and lime temporal results * lime now based on lime temporal results * added drop down to select shap and lime analysis * fixed preview of part of dataset
1 parent 6f4006b commit c95aeb4

File tree

20 files changed

+174
-352
lines changed

20 files changed

+174
-352
lines changed

src/__tests__/actions/ServerActions.test.js

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
getSplits,
77
postSplit,
88
postTraining,
9-
getLimeValues,
109
getShapValues,
1110
getIceValues,
1211
getSkaterValues,
@@ -26,13 +25,13 @@ import {JOB_DELETED, jobsFailed, jobsRetrieved, trainingFailed,
2625
encodedUniqueValuesRetrieved, encodedUniqueValuesFailed} from '../../actions/JobActions';
2726
import {logInfoFailed, logInfoRetrieved, logListFailed, logListsRetrieved} from '../../actions/LogActions';
2827
import {splitFailed, splitsFailed, splitsRetrieved, splitSucceeded} from '../../actions/SplitActions';
29-
import {limeValueListFailed, limeValueListRetrieved, shapValueListRetrieved,
28+
import {shapValueListRetrieved,
3029
shapValueListFailed, iceValueListRetrieved, iceValueListFailed,
3130
skaterValueListRetrieved, skaterValueListFailed, retrainValueListRetrieved,
3231
retrainValueListFailed, cmfeedbackValueListRetrieved,
3332
cmfeedbackValueListFailed} from '../../actions/ExplanationActions';
3433
import {limeTemporalStabilityResult, encodedUniqueDFResultList, temporalStabilityResult,
35-
limeList, shapResult, iceResultList, skaterResult,
34+
shapResult, iceResultList, skaterResult,
3635
retrainResult, cmFeedbackResult, decodedDFResultList, traceList} from '../../../stories/Explanation';
3736
import {temporalLimePredictionListRetrieved, temporalPredictionListRetrieved,
3837
temporalPredictionListFailed, temporalLimePredictionListFailed} from '../../actions/PredictionAction';
@@ -322,27 +321,6 @@ describe('ServerActions', function () {
322321
});
323322
});
324323

325-
describe('getLime', () => {
326-
it('dispatches limeRetrieved on success', () => {
327-
mockXHR.responseText = JSON.stringify(limeList);
328-
329-
getLimeValues({jobId: 1, traceId: 1})(dispatch);
330-
mockXHR.onreadystatechange();
331-
332-
expect(dispatch.mock.calls[0][0])
333-
.toEqual(limeValueListRetrieved(limeList));
334-
});
335-
it('dispatches limeRetreived on error', () => {
336-
standardError(mockXHR);
337-
338-
getLimeValues({jobId: 1, traceId: 1})(dispatch);
339-
mockXHR.onreadystatechange();
340-
341-
expect(dispatch.mock.calls[0][0])
342-
.toEqual(limeValueListFailed(error.error));
343-
});
344-
});
345-
346324
describe('getShap', () => {
347325
it('dispatches shapRetrieved on success', () => {
348326
mockXHR.responseText = JSON.stringify(shapResult);
Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,33 @@
11
import React from 'react';
22
import {shallow} from 'enzyme';
33
import ShapResult from '../../../components/explanation/ShapResult';
4-
import {shapResult} from '../../../../stories/Explanation';
5-
import InlineSVG from 'svg-inline-react';
6-
import CircularProgress from 'react-md/lib/Progress/CircularProgress';
4+
import {shapData} from '../../../../stories/Explanation';
5+
import HorizontalBarChartCard from '../../../components/chart/HorizontalBarChartCard';
76

87
describe('Shap result', () => {
98
it('renders with data', () => {
109
const element = shallow(<ShapResult
11-
shapValueList={shapResult[1]}
10+
jobs={[]}
11+
shapValueList={shapData[0]}
1212
traceId={'12'}
1313
jobId={11}
1414
shapSelectedTrace={'2_3301'}
15+
attributeId={'prefix_1'}
1516
isShapValuesLoaded={true}/>);
1617
expect(element).toBeDefined();
17-
expect(element.find(InlineSVG).length).toBe(1);
18-
expect(element.find(CircularProgress).length).toBe(0);
18+
expect(element.find(HorizontalBarChartCard).length).toBe(1);
1919
});
2020

2121
it('renders without data', () => {
2222
const element = shallow(<ShapResult
23-
shapValueList={{}}
23+
jobs={[]}
24+
shapValueList={shapData[1]}
2425
traceId={'12'}
2526
jobId={11}
2627
shapSelectedTrace={'2_3301'}
28+
attributeId={''}
2729
isShapValuesLoaded={false}/>);
2830
expect(element).toBeDefined();
29-
expect(element.find(InlineSVG).length).toBe(0);
30-
expect(element.find(CircularProgress).length).toBe(1);
31+
expect(element.find(HorizontalBarChartCard).length).toBe(0);
3132
});
3233
});

src/__tests__/components/explanation/post_hoc.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ describe('Lime result', () => {
2121
jobs={[]}
2222
isLimeValuesLoaded={true}
2323
traceId={1}
24-
limeValueList={parseLimeResult(limeList)}/>);
24+
limeValueList={parseLimeResult(limeList, '2_100', 'prefix_5')}/>);
2525
expect(element).toBeDefined();
2626
expect(element.find(HorizontalBarChartCard).length).toBe(1);
2727
});

src/__tests__/reducers/Explanation.test.js

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import explanation from '../../reducers/Explanation';
2-
import {limeValueListRequested, limeValueListRetrieved, limeValueListFailed,
3-
shapValueListFailed, shapValueListRequested, shapValueListRetrieved,
2+
import {shapValueListFailed, shapValueListRequested, shapValueListRetrieved,
43
iceValueListFailed, iceValueListRequested, iceValueListRetrieved,
54
skaterValueListFailed, skaterValueListRequested, skaterValueListRetrieved,
65
cmfeedbackValueListFailed, cmfeedbackValueListRequested, cmfeedbackValueListRetrieved,
76
retrainValueListFailed, retrainValueListRequested,
87
retrainValueListRetrieved} from '../../actions/ExplanationActions';
9-
import {limeList, shapResult, iceResultList, skaterResult,
8+
import {shapResult, iceResultList, skaterResult,
109
retrainResult, cmFeedbackResult} from '../../../stories/Explanation';
1110

1211

@@ -31,29 +30,6 @@ describe('Explanation reducer', () => {
3130
expect(explanation(undefined, {})).toEqual(initialState);
3231
});
3332

34-
describe('LIME List requested', () => {
35-
const stateWithRequest = explanation(undefined, limeValueListRequested());
36-
37-
it('changes fetchState when lime requesting', () => {
38-
expect(stateWithRequest.fetchState).toEqual({inFlight: true});
39-
expect(stateWithRequest.isLimeValuesLoaded).toEqual(false);
40-
});
41-
42-
it('changes fetchState when lime request completed', () => {
43-
const state2 = explanation(stateWithRequest, limeValueListRetrieved(limeList));
44-
expect(state2.fetchState).toEqual({inFlight: false});
45-
expect(state2.isLimeValuesLoaded).toEqual(true);
46-
const {limeValueList} = state2;
47-
expect(limeValueList).toEqual(limeList);
48-
});
49-
50-
it('changes fetchState when lime request failed', () => {
51-
const state2 = explanation(stateWithRequest, limeValueListFailed('error'));
52-
expect(state2.fetchState).toEqual({inFlight: false, error: 'error'});
53-
expect(state2.isLimeValuesLoaded).toEqual(true);
54-
});
55-
});
56-
5733
describe('SHAP List requested', () => {
5834
const stateWithRequest = explanation(undefined, shapValueListRequested());
5935

src/__tests__/reducers/Lime.test.js

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/__tests__/util/dataReducers.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ describe('generates data for prefix chart', () => {
4646
});
4747

4848
it('parse lime values', () => {
49-
const limeValues = parseLimeResult(limeList);
49+
const limeValues = parseLimeResult(limeList, '2_100', 'prefix_5');
5050
expect(limeValues.labels.length).toEqual(5);
5151
expect(limeValues.values.length).toEqual(5);
5252
});

src/actions/ExplanationActions.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
11
import {createPayloadForwardingAction} from './index';
2-
export const LIME_VALUE_LIST_REQUESTED = 'LIME_VALUE_LIST_REQUESTED';
3-
export const limeValueListRequested = createPayloadForwardingAction(LIME_VALUE_LIST_REQUESTED);
4-
export const LIME_VALUE_LIST_RETRIEVED = 'LIME_VALUE_LIST_RETRIEVED';
5-
export const limeValueListRetrieved = createPayloadForwardingAction(LIME_VALUE_LIST_RETRIEVED);
6-
export const LIME_VALUE_LIST_FAILED = 'LIME_VALUE_LIST_FAILED';
7-
export const limeValueListFailed = createPayloadForwardingAction(LIME_VALUE_LIST_FAILED);
82

93
export const ICE_VALUE_LIST_REQUESTED = 'ICE_VALUE_LIST_REQUESTED';
104
export const iceValueListRequested = createPayloadForwardingAction(ICE_VALUE_LIST_REQUESTED);

src/actions/LimeActions.js

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/actions/ServerActions.js

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {JOB_DELETED, jobsFailed, jobsRetrieved, trainingFailed,
55
encodedUniqueValuesRetrieved, encodedUniqueValuesFailed} from './JobActions';
66
import {logInfoFailed, logInfoRetrieved, logListFailed, logListsRetrieved} from './LogActions';
77
import {traceListFailed, traceListRetrieved} from './TraceActions';
8-
import {limeValueListFailed, limeValueListRetrieved} from './LimeActions';
98
import {splitFailed, splitsFailed, splitsRetrieved, splitSucceeded} from './SplitActions';
109
import {modelsFailed, modelsRetrieved} from './ModelActions';
1110
import {predictionFailed, predictionSucceeded, replayFailed, replaySucceeded} from './RuntimeActions';
@@ -159,21 +158,9 @@ export const getTraceList = ({id}) => (dispatch) => {
159158
);
160159
};
161160

162-
export const getLimeValues = ({jobId, traceId}) => (dispatch) => {
161+
export const getShapValues = ({jobId, traceId, attributeId}) => (dispatch) => {
163162
jsonAjax(
164-
SERVER_URL + `/explanation/lime/${jobId}&${traceId}/`,
165-
'GET',
166-
null,
167-
(limeList) => {
168-
dispatch(limeValueListRetrieved(limeList));
169-
},
170-
({error}) => dispatch(limeValueListFailed(error))
171-
);
172-
};
173-
174-
export const getShapValues = ({jobId, traceId}) => (dispatch) => {
175-
jsonAjax(
176-
SERVER_URL + `/explanation/shap/${jobId}&${traceId}/`,
163+
SERVER_URL + `/explanation/shap/${jobId}&${traceId}&${attributeId}/`,
177164
'GET',
178165
null,
179166
(shapResult) => {

src/components/explanation/DecodedDFTable.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class DecodedDFTable extends PureComponent {
4545
<CardTitle title="Decoded dataframe result"></CardTitle>
4646
<CardText>
4747
{this.props.jobId != '' ?
48-
'Decoded dataframe result with job id: '+ this.props.jobId: ''}
48+
'First 100 lines of decoded dataframe for job ID: '+ this.props.jobId: ''}
4949
</CardText>
5050
{!this.props.isDecodedValueLoaded ? <CircularProgress id="query-indeterminate-progress"/> : null}
5151
<CardText>

0 commit comments

Comments
 (0)