diff --git a/x-pack/plugins/ml/public/application/components/data_grid/common.ts b/x-pack/plugins/ml/public/application/components/data_grid/common.ts index 44a2473f7593..7d0559c21511 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/common.ts +++ b/x-pack/plugins/ml/public/application/components/data_grid/common.ts @@ -29,6 +29,7 @@ import { FEATURE_IMPORTANCE, FEATURE_INFLUENCE, OUTLIER_SCORE, + TOP_CLASSES, } from '../../data_frame_analytics/common/constants'; import { formatHumanReadableDateTimeSeconds } from '../../util/date_utils'; import { getNestedProperty } from '../../util/object_utils'; @@ -110,7 +111,10 @@ export const getDataGridSchemasFromFieldTypes = (fieldTypes: FieldTypes, results schema = 'numeric'; } - if (field.includes(`${resultsField}.${FEATURE_IMPORTANCE}`)) { + if ( + field.includes(`${resultsField}.${FEATURE_IMPORTANCE}`) || + field.includes(`${resultsField}.${TOP_CLASSES}`) + ) { schema = 'json'; } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts index 0b4e6d27b96e..16d888a9da27 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/analytics.ts @@ -228,6 +228,16 @@ export const getPredictionFieldName = ( 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 = ( analysis: AnalysisConfig ): diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts index 51b2918012c8..2f14dfdfdfca 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/constants.ts @@ -7,4 +7,5 @@ export const DEFAULT_RESULTS_FIELD = 'ml'; export const FEATURE_IMPORTANCE = 'feature_importance'; export const FEATURE_INFLUENCE = 'feature_influence'; +export const TOP_CLASSES = 'top_classes'; export const OUTLIER_SCORE = 'outlier_score'; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts index 8db349b395cf..0a64886c80a6 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/fields.ts @@ -5,6 +5,7 @@ */ import { + getNumTopClasses, getNumTopFeatureImportanceValues, getPredictedFieldName, getDependentVar, @@ -18,7 +19,7 @@ import { Field } from '../../../../common/types/fields'; import { ES_FIELD_TYPES, KBN_FIELD_TYPES } from '../../../../../../../src/plugins/data/public'; 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 EsDocSource = Record; @@ -177,6 +178,7 @@ export const getDefaultFieldsFromJobCaps = ( const featureImportanceFields = []; const featureInfluenceFields = []; + const topClassesFields = []; const allFields: any = []; let type: ES_FIELD_TYPES | undefined; let predictedField: string | undefined; @@ -207,13 +209,14 @@ export const getDefaultFieldsFromJobCaps = ( type = newJobCapsService.getFieldById(dependentVariable)?.type; const predictionFieldName = getPredictionFieldName(jobConfig.analysis); const numTopFeatureImportanceValues = getNumTopFeatureImportanceValues(jobConfig.analysis); + const numTopClasses = getNumTopClasses(jobConfig.analysis); const defaultPredictionField = `${dependentVariable}_prediction`; predictedField = `${resultsField}.${ predictionFieldName ? predictionFieldName : defaultPredictionField }`; - if ((numTopFeatureImportanceValues ?? 0) > 0 && needsDestIndexFields === true) { + if ((numTopFeatureImportanceValues ?? 0) > 0) { featureImportanceFields.push({ id: `${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 if (needsDestIndexFields === true) { 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 }) => sortExplorationResultsFields(a, b, jobConfig) ); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts index e391b90e6eb9..b8b5a16c84e8 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/use_exploration_results.ts @@ -19,7 +19,11 @@ import { import { SavedSearchQuery } from '../../../../../contexts/ml'; 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'; export const useExplorationResults = ( @@ -47,8 +51,9 @@ export const useExplorationResults = ( 25, // reduce default selected rows from 20 to 8 for performance reasons. 8, - // by default, hide feature-importance columns and the doc id copy - (d) => !d.includes(`.${FEATURE_IMPORTANCE}.`) && d !== ML__ID_COPY + // by default, hide feature-importance and top-classes columns and the doc id copy + (d) => + !d.includes(`.${FEATURE_IMPORTANCE}.`) && !d.includes(`.${TOP_CLASSES}.`) && d !== ML__ID_COPY ); useEffect(() => {