mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[ML] Fixes anomaly charts for rare detectors when model plot is enabled (#66075)
This commit is contained in:
parent
533b4810ca
commit
0124977830
7 changed files with 45 additions and 20 deletions
2
x-pack/plugins/ml/common/util/job_utils.d.ts
vendored
2
x-pack/plugins/ml/common/util/job_utils.d.ts
vendored
|
@ -44,6 +44,8 @@ export function mlFunctionToESAggregation(functionName: string): string | null;
|
|||
|
||||
export function isModelPlotEnabled(job: Job, detectorIndex: number, entityFields: any[]): boolean;
|
||||
|
||||
export function isModelPlotChartableForDetector(job: Job, detectorIndex: number): boolean;
|
||||
|
||||
export function getSafeAggregationName(fieldName: string, index: number): string;
|
||||
|
||||
export function getLatestDataOrBucketTimestamp(
|
||||
|
|
|
@ -105,18 +105,20 @@ export function isModelPlotChartableForDetector(job, detectorIndex) {
|
|||
const dtr = dtrs[detectorIndex];
|
||||
const functionName = dtr.function;
|
||||
|
||||
// Model plot can be charted for any of the functions which map to ES aggregations,
|
||||
// Model plot can be charted for any of the functions which map to ES aggregations
|
||||
// (except rare, for which no model plot results are generated),
|
||||
// plus varp and info_content functions.
|
||||
isModelPlotChartable =
|
||||
mlFunctionToESAggregation(functionName) !== null ||
|
||||
[
|
||||
'varp',
|
||||
'high_varp',
|
||||
'low_varp',
|
||||
'info_content',
|
||||
'high_info_content',
|
||||
'low_info_content',
|
||||
].includes(functionName) === true;
|
||||
functionName !== 'rare' &&
|
||||
(mlFunctionToESAggregation(functionName) !== null ||
|
||||
[
|
||||
'varp',
|
||||
'high_varp',
|
||||
'low_varp',
|
||||
'info_content',
|
||||
'high_info_content',
|
||||
'low_info_content',
|
||||
].includes(functionName) === true);
|
||||
}
|
||||
|
||||
return isModelPlotChartable;
|
||||
|
|
|
@ -307,7 +307,14 @@ describe('ML - job utils', () => {
|
|||
|
||||
const job2 = {
|
||||
analysis_config: {
|
||||
detectors: [{ function: 'count' }, { function: 'info_content' }],
|
||||
detectors: [
|
||||
{ function: 'count' },
|
||||
{ function: 'info_content' },
|
||||
{
|
||||
function: 'rare',
|
||||
by_field_name: 'mlcategory',
|
||||
},
|
||||
],
|
||||
},
|
||||
model_plot_config: {
|
||||
enabled: true,
|
||||
|
@ -325,6 +332,10 @@ describe('ML - job utils', () => {
|
|||
test('returns true for info_content detector when model plot is enabled', () => {
|
||||
expect(isModelPlotChartableForDetector(job2, 1)).toBe(true);
|
||||
});
|
||||
|
||||
test('returns false for rare by mlcategory when model plot is enabled', () => {
|
||||
expect(isModelPlotChartableForDetector(job2, 2)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getPartitioningFieldNames', () => {
|
||||
|
|
|
@ -19,6 +19,7 @@ import { chartLimits, getChartType } from '../../util/chart_utils';
|
|||
import { getEntityFieldList } from '../../../../common/util/anomaly_utils';
|
||||
import {
|
||||
isSourceDataChartableForDetector,
|
||||
isModelPlotChartableForDetector,
|
||||
isModelPlotEnabled,
|
||||
} from '../../../../common/util/job_utils';
|
||||
import { mlResultsService } from '../../services/results_service';
|
||||
|
@ -420,7 +421,7 @@ function processRecordsForDisplay(anomalyRecords) {
|
|||
// is chartable, and if model plot is enabled for the job.
|
||||
const job = mlJobService.getJob(record.job_id);
|
||||
let isChartable = isSourceDataChartableForDetector(job, record.detector_index);
|
||||
if (isChartable === false) {
|
||||
if (isChartable === false && isModelPlotChartableForDetector(job, record.detector_index)) {
|
||||
// Check if model plot is enabled for this job.
|
||||
// Need to check the entity fields for the record in case the model plot config has a terms list.
|
||||
const entityFields = getEntityFieldList(record);
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
import { getEntityFieldList } from '../../../common/util/anomaly_utils';
|
||||
import {
|
||||
isSourceDataChartableForDetector,
|
||||
isModelPlotChartableForDetector,
|
||||
isModelPlotEnabled,
|
||||
} from '../../../common/util/job_utils';
|
||||
import { parseInterval } from '../../../common/util/parse_interval';
|
||||
|
@ -636,7 +637,10 @@ export async function loadAnomaliesTableData(
|
|||
// TODO - when job_service is moved server_side, move this to server endpoint.
|
||||
const job = mlJobService.getJob(jobId);
|
||||
let isChartable = isSourceDataChartableForDetector(job, anomaly.detectorIndex);
|
||||
if (isChartable === false) {
|
||||
if (
|
||||
isChartable === false &&
|
||||
isModelPlotChartableForDetector(job, anomaly.detectorIndex)
|
||||
) {
|
||||
// Check if model plot is enabled for this job.
|
||||
// Need to check the entity fields for the record in case the model plot config has a terms list.
|
||||
// If terms is specified, model plot is only stored if both the partition and by fields appear in the list.
|
||||
|
|
|
@ -9,7 +9,10 @@ import _ from 'lodash';
|
|||
import { Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { ml } from '../services/ml_api_service';
|
||||
import { isModelPlotEnabled } from '../../../common/util/job_utils';
|
||||
import {
|
||||
isModelPlotChartableForDetector,
|
||||
isModelPlotEnabled,
|
||||
} from '../../../common/util/job_utils';
|
||||
// @ts-ignore
|
||||
import { buildConfigFromDetector } from '../util/chart_config_builder';
|
||||
import { mlResultsService } from '../services/results_service';
|
||||
|
@ -24,7 +27,10 @@ function getMetricData(
|
|||
latestMs: number,
|
||||
interval: string
|
||||
): Observable<ModelPlotOutput> {
|
||||
if (isModelPlotEnabled(job, detectorIndex, entityFields)) {
|
||||
if (
|
||||
isModelPlotChartableForDetector(job, detectorIndex) &&
|
||||
isModelPlotEnabled(job, detectorIndex, entityFields)
|
||||
) {
|
||||
// Extract the partition, by, over fields on which to filter.
|
||||
const criteriaFields = [];
|
||||
const detector = job.analysis_config.detectors[detectorIndex];
|
||||
|
|
|
@ -36,6 +36,7 @@ import { ResizeChecker } from '../../../../../../src/plugins/kibana_utils/public
|
|||
import { ANOMALIES_TABLE_DEFAULT_QUERY_SIZE } from '../../../common/constants/search';
|
||||
import {
|
||||
isModelPlotEnabled,
|
||||
isModelPlotChartableForDetector,
|
||||
isSourceDataChartableForDetector,
|
||||
isTimeSeriesViewDetector,
|
||||
mlFunctionToESAggregation,
|
||||
|
@ -506,11 +507,9 @@ export class TimeSeriesExplorer extends React.Component {
|
|||
contextForecastData: undefined,
|
||||
focusChartData: undefined,
|
||||
focusForecastData: undefined,
|
||||
modelPlotEnabled: isModelPlotEnabled(
|
||||
currentSelectedJob,
|
||||
selectedDetectorIndex,
|
||||
entityControls
|
||||
),
|
||||
modelPlotEnabled:
|
||||
isModelPlotChartableForDetector(currentSelectedJob, selectedDetectorIndex) &&
|
||||
isModelPlotEnabled(currentSelectedJob, selectedDetectorIndex, entityControls),
|
||||
hasResults: false,
|
||||
dataNotChartable: false,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue