[ML] DFAnalytics results: ensure ml result fields are shown in data grid (#68305)
* wip: ensure top classes and influencer result col show up correctly * ensure ml subFields columns are populated
This commit is contained in:
parent
bc3918671c
commit
e2f11e9fe9
5 changed files with 43 additions and 7 deletions
|
@ -29,6 +29,7 @@ import {
|
||||||
FEATURE_IMPORTANCE,
|
FEATURE_IMPORTANCE,
|
||||||
FEATURE_INFLUENCE,
|
FEATURE_INFLUENCE,
|
||||||
OUTLIER_SCORE,
|
OUTLIER_SCORE,
|
||||||
|
TOP_CLASSES,
|
||||||
} from '../../data_frame_analytics/common/constants';
|
} from '../../data_frame_analytics/common/constants';
|
||||||
import { formatHumanReadableDateTimeSeconds } from '../../util/date_utils';
|
import { formatHumanReadableDateTimeSeconds } from '../../util/date_utils';
|
||||||
import { getNestedProperty } from '../../util/object_utils';
|
import { getNestedProperty } from '../../util/object_utils';
|
||||||
|
@ -110,7 +111,10 @@ export const getDataGridSchemasFromFieldTypes = (fieldTypes: FieldTypes, results
|
||||||
schema = 'numeric';
|
schema = 'numeric';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field.includes(`${resultsField}.${FEATURE_IMPORTANCE}`)) {
|
if (
|
||||||
|
field.includes(`${resultsField}.${FEATURE_IMPORTANCE}`) ||
|
||||||
|
field.includes(`${resultsField}.${TOP_CLASSES}`)
|
||||||
|
) {
|
||||||
schema = 'json';
|
schema = 'json';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,6 +228,16 @@ export const getPredictionFieldName = (
|
||||||
return predictionFieldName;
|
return predictionFieldName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getNumTopClasses = (
|
||||||
|
analysis: AnalysisConfig
|
||||||
|
): ClassificationAnalysis['classification']['num_top_classes'] => {
|
||||||
|
let numTopClasses;
|
||||||
|
if (isClassificationAnalysis(analysis) && analysis.classification.num_top_classes !== undefined) {
|
||||||
|
numTopClasses = analysis.classification.num_top_classes;
|
||||||
|
}
|
||||||
|
return numTopClasses;
|
||||||
|
};
|
||||||
|
|
||||||
export const getNumTopFeatureImportanceValues = (
|
export const getNumTopFeatureImportanceValues = (
|
||||||
analysis: AnalysisConfig
|
analysis: AnalysisConfig
|
||||||
):
|
):
|
||||||
|
|
|
@ -7,4 +7,5 @@
|
||||||
export const DEFAULT_RESULTS_FIELD = 'ml';
|
export const DEFAULT_RESULTS_FIELD = 'ml';
|
||||||
export const FEATURE_IMPORTANCE = 'feature_importance';
|
export const FEATURE_IMPORTANCE = 'feature_importance';
|
||||||
export const FEATURE_INFLUENCE = 'feature_influence';
|
export const FEATURE_INFLUENCE = 'feature_influence';
|
||||||
|
export const TOP_CLASSES = 'top_classes';
|
||||||
export const OUTLIER_SCORE = 'outlier_score';
|
export const OUTLIER_SCORE = 'outlier_score';
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
getNumTopClasses,
|
||||||
getNumTopFeatureImportanceValues,
|
getNumTopFeatureImportanceValues,
|
||||||
getPredictedFieldName,
|
getPredictedFieldName,
|
||||||
getDependentVar,
|
getDependentVar,
|
||||||
|
@ -18,7 +19,7 @@ import { Field } from '../../../../common/types/fields';
|
||||||
import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../../../../../../src/plugins/data/public';
|
import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../../../../../../src/plugins/data/public';
|
||||||
import { newJobCapsService } from '../../services/new_job_capabilities_service';
|
import { newJobCapsService } from '../../services/new_job_capabilities_service';
|
||||||
|
|
||||||
import { FEATURE_IMPORTANCE, FEATURE_INFLUENCE, OUTLIER_SCORE } from './constants';
|
import { FEATURE_IMPORTANCE, FEATURE_INFLUENCE, OUTLIER_SCORE, TOP_CLASSES } from './constants';
|
||||||
|
|
||||||
export type EsId = string;
|
export type EsId = string;
|
||||||
export type EsDocSource = Record<string, any>;
|
export type EsDocSource = Record<string, any>;
|
||||||
|
@ -177,6 +178,7 @@ export const getDefaultFieldsFromJobCaps = (
|
||||||
|
|
||||||
const featureImportanceFields = [];
|
const featureImportanceFields = [];
|
||||||
const featureInfluenceFields = [];
|
const featureInfluenceFields = [];
|
||||||
|
const topClassesFields = [];
|
||||||
const allFields: any = [];
|
const allFields: any = [];
|
||||||
let type: ES_FIELD_TYPES | undefined;
|
let type: ES_FIELD_TYPES | undefined;
|
||||||
let predictedField: string | undefined;
|
let predictedField: string | undefined;
|
||||||
|
@ -207,13 +209,14 @@ export const getDefaultFieldsFromJobCaps = (
|
||||||
type = newJobCapsService.getFieldById(dependentVariable)?.type;
|
type = newJobCapsService.getFieldById(dependentVariable)?.type;
|
||||||
const predictionFieldName = getPredictionFieldName(jobConfig.analysis);
|
const predictionFieldName = getPredictionFieldName(jobConfig.analysis);
|
||||||
const numTopFeatureImportanceValues = getNumTopFeatureImportanceValues(jobConfig.analysis);
|
const numTopFeatureImportanceValues = getNumTopFeatureImportanceValues(jobConfig.analysis);
|
||||||
|
const numTopClasses = getNumTopClasses(jobConfig.analysis);
|
||||||
|
|
||||||
const defaultPredictionField = `${dependentVariable}_prediction`;
|
const defaultPredictionField = `${dependentVariable}_prediction`;
|
||||||
predictedField = `${resultsField}.${
|
predictedField = `${resultsField}.${
|
||||||
predictionFieldName ? predictionFieldName : defaultPredictionField
|
predictionFieldName ? predictionFieldName : defaultPredictionField
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
if ((numTopFeatureImportanceValues ?? 0) > 0 && needsDestIndexFields === true) {
|
if ((numTopFeatureImportanceValues ?? 0) > 0) {
|
||||||
featureImportanceFields.push({
|
featureImportanceFields.push({
|
||||||
id: `${resultsField}.${FEATURE_IMPORTANCE}`,
|
id: `${resultsField}.${FEATURE_IMPORTANCE}`,
|
||||||
name: `${resultsField}.${FEATURE_IMPORTANCE}`,
|
name: `${resultsField}.${FEATURE_IMPORTANCE}`,
|
||||||
|
@ -221,6 +224,14 @@ export const getDefaultFieldsFromJobCaps = (
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((numTopClasses ?? 0) > 0) {
|
||||||
|
topClassesFields.push({
|
||||||
|
id: `${resultsField}.${TOP_CLASSES}`,
|
||||||
|
name: `${resultsField}.${TOP_CLASSES}`,
|
||||||
|
type: KBN_FIELD_TYPES.UNKNOWN,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Only need to add these fields if we didn't use dest index pattern to get the fields
|
// Only need to add these fields if we didn't use dest index pattern to get the fields
|
||||||
if (needsDestIndexFields === true) {
|
if (needsDestIndexFields === true) {
|
||||||
allFields.push(
|
allFields.push(
|
||||||
|
@ -234,7 +245,12 @@ export const getDefaultFieldsFromJobCaps = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allFields.push(...fields, ...featureImportanceFields, ...featureInfluenceFields);
|
allFields.push(
|
||||||
|
...fields,
|
||||||
|
...featureImportanceFields,
|
||||||
|
...featureInfluenceFields,
|
||||||
|
...topClassesFields
|
||||||
|
);
|
||||||
allFields.sort(({ name: a }: { name: string }, { name: b }: { name: string }) =>
|
allFields.sort(({ name: a }: { name: string }, { name: b }: { name: string }) =>
|
||||||
sortExplorationResultsFields(a, b, jobConfig)
|
sortExplorationResultsFields(a, b, jobConfig)
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,7 +19,11 @@ import {
|
||||||
import { SavedSearchQuery } from '../../../../../contexts/ml';
|
import { SavedSearchQuery } from '../../../../../contexts/ml';
|
||||||
|
|
||||||
import { getIndexData, getIndexFields, DataFrameAnalyticsConfig } from '../../../../common';
|
import { getIndexData, getIndexFields, DataFrameAnalyticsConfig } from '../../../../common';
|
||||||
import { DEFAULT_RESULTS_FIELD, FEATURE_IMPORTANCE } from '../../../../common/constants';
|
import {
|
||||||
|
DEFAULT_RESULTS_FIELD,
|
||||||
|
FEATURE_IMPORTANCE,
|
||||||
|
TOP_CLASSES,
|
||||||
|
} from '../../../../common/constants';
|
||||||
import { sortExplorationResultsFields, ML__ID_COPY } from '../../../../common/fields';
|
import { sortExplorationResultsFields, ML__ID_COPY } from '../../../../common/fields';
|
||||||
|
|
||||||
export const useExplorationResults = (
|
export const useExplorationResults = (
|
||||||
|
@ -47,8 +51,9 @@ export const useExplorationResults = (
|
||||||
25,
|
25,
|
||||||
// reduce default selected rows from 20 to 8 for performance reasons.
|
// reduce default selected rows from 20 to 8 for performance reasons.
|
||||||
8,
|
8,
|
||||||
// by default, hide feature-importance columns and the doc id copy
|
// by default, hide feature-importance and top-classes columns and the doc id copy
|
||||||
(d) => !d.includes(`.${FEATURE_IMPORTANCE}.`) && d !== ML__ID_COPY
|
(d) =>
|
||||||
|
!d.includes(`.${FEATURE_IMPORTANCE}.`) && !d.includes(`.${TOP_CLASSES}.`) && d !== ML__ID_COPY
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
Loading…
Reference in a new issue