mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[ML] Creating category validation package (#161261)
Moves the server and client side code which performs analysis on data to
see whether it is suitable for categorization.
This is currently only used by the categorization job wizard to display
this callout:

However this analysis will be useful for the Log Pattern Analysis
feature and so moving the code to a package allows easier sharing
between ML and AIOPs plugins.
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
85c85e90f9
commit
219426dc7a
36 changed files with 354 additions and 126 deletions
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
|
@ -484,6 +484,7 @@ x-pack/plugins/maps @elastic/kibana-gis
|
|||
x-pack/packages/maps/vector_tile_utils @elastic/kibana-gis
|
||||
x-pack/packages/ml/agg_utils @elastic/ml-ui
|
||||
x-pack/packages/ml/anomaly_utils @elastic/ml-ui
|
||||
x-pack/packages/ml/category_validator @elastic/ml-ui
|
||||
x-pack/packages/ml/data_frame_analytics_utils @elastic/ml-ui
|
||||
x-pack/packages/ml/data_grid @elastic/ml-ui
|
||||
x-pack/packages/ml/date_picker @elastic/ml-ui
|
||||
|
|
|
@ -500,6 +500,7 @@
|
|||
"@kbn/maps-vector-tile-utils": "link:x-pack/packages/maps/vector_tile_utils",
|
||||
"@kbn/ml-agg-utils": "link:x-pack/packages/ml/agg_utils",
|
||||
"@kbn/ml-anomaly-utils": "link:x-pack/packages/ml/anomaly_utils",
|
||||
"@kbn/ml-category-validator": "link:x-pack/packages/ml/category_validator",
|
||||
"@kbn/ml-data-frame-analytics-utils": "link:x-pack/packages/ml/data_frame_analytics_utils",
|
||||
"@kbn/ml-data-grid": "link:x-pack/packages/ml/data_grid",
|
||||
"@kbn/ml-date-picker": "link:x-pack/packages/ml/date_picker",
|
||||
|
|
|
@ -962,6 +962,8 @@
|
|||
"@kbn/ml-agg-utils/*": ["x-pack/packages/ml/agg_utils/*"],
|
||||
"@kbn/ml-anomaly-utils": ["x-pack/packages/ml/anomaly_utils"],
|
||||
"@kbn/ml-anomaly-utils/*": ["x-pack/packages/ml/anomaly_utils/*"],
|
||||
"@kbn/ml-category-validator": ["x-pack/packages/ml/category_validator"],
|
||||
"@kbn/ml-category-validator/*": ["x-pack/packages/ml/category_validator/*"],
|
||||
"@kbn/ml-data-frame-analytics-utils": ["x-pack/packages/ml/data_frame_analytics_utils"],
|
||||
"@kbn/ml-data-frame-analytics-utils/*": ["x-pack/packages/ml/data_frame_analytics_utils/*"],
|
||||
"@kbn/ml-data-grid": ["x-pack/packages/ml/data_grid"],
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
"packages/ml/data_grid",
|
||||
"packages/ml/date_picker",
|
||||
"packages/ml/trained_models_utils",
|
||||
"packages/ml/category_validator",
|
||||
"plugins/ml"
|
||||
],
|
||||
"xpack.monitoring": ["plugins/monitoring"],
|
||||
|
|
3
x-pack/packages/ml/category_validator/README.md
Normal file
3
x-pack/packages/ml/category_validator/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# @kbn/ml-category-validator
|
||||
|
||||
Provides functions for validating data to see whether it is suitable for categorization
|
|
@ -6,76 +6,136 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { VALIDATION_RESULT } from '../types/categories';
|
||||
|
||||
export const NUMBER_OF_CATEGORY_EXAMPLES = 5;
|
||||
/**
|
||||
* The number of category examples to use for analysis.
|
||||
*/
|
||||
export const CATEGORY_EXAMPLES_SAMPLE_SIZE = 1000;
|
||||
|
||||
/**
|
||||
* The warning limit for category examples. If the category examples validation falls below this limit, a warning is triggered.
|
||||
*/
|
||||
export const CATEGORY_EXAMPLES_WARNING_LIMIT = 0.75;
|
||||
|
||||
/**
|
||||
* The error limit for category examples. If the category examples validation falls below this limit, an error is triggered.
|
||||
*/
|
||||
export const CATEGORY_EXAMPLES_ERROR_LIMIT = 0.02;
|
||||
|
||||
/**
|
||||
* The valid token count for category examples.
|
||||
*/
|
||||
export const VALID_TOKEN_COUNT = 3;
|
||||
|
||||
/**
|
||||
* The limit for the median line length of category examples.
|
||||
*/
|
||||
export const MEDIAN_LINE_LENGTH_LIMIT = 400;
|
||||
|
||||
/**
|
||||
* The limit for the percentage of null values in category examples.
|
||||
*/
|
||||
export const NULL_COUNT_PERCENT_LIMIT = 0.75;
|
||||
|
||||
/**
|
||||
* Enum representing the validation status of category examples.
|
||||
*/
|
||||
export enum CATEGORY_EXAMPLES_VALIDATION_STATUS {
|
||||
VALID = 'valid',
|
||||
PARTIALLY_VALID = 'partially_valid',
|
||||
INVALID = 'invalid',
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum representing the validation results for field examples.
|
||||
*/
|
||||
export enum VALIDATION_RESULT {
|
||||
NO_EXAMPLES,
|
||||
FAILED_TO_TOKENIZE,
|
||||
TOO_MANY_TOKENS,
|
||||
TOKEN_COUNT,
|
||||
MEDIAN_LINE_LENGTH,
|
||||
NULL_VALUES,
|
||||
INSUFFICIENT_PRIVILEGES,
|
||||
}
|
||||
|
||||
/**
|
||||
* Description for each validation result.
|
||||
*/
|
||||
export const VALIDATION_CHECK_DESCRIPTION = {
|
||||
/**
|
||||
* Examples were successfully loaded.
|
||||
*/
|
||||
[VALIDATION_RESULT.NO_EXAMPLES]: i18n.translate(
|
||||
'xpack.ml.models.jobService.categorization.messages.validNoDataFound',
|
||||
{
|
||||
defaultMessage: 'Examples were successfully loaded.',
|
||||
defaultMessage: 'Examples were successfully loaded.',
|
||||
}
|
||||
),
|
||||
) as string,
|
||||
/**
|
||||
* The loaded examples were tokenized successfully.
|
||||
*/
|
||||
[VALIDATION_RESULT.FAILED_TO_TOKENIZE]: i18n.translate(
|
||||
'xpack.ml.models.jobService.categorization.messages.validFailureToGetTokens',
|
||||
{
|
||||
defaultMessage: 'The examples loaded were tokenized successfully.',
|
||||
defaultMessage: 'The loaded examples were tokenized successfully.',
|
||||
}
|
||||
),
|
||||
) as string,
|
||||
/**
|
||||
* More than {tokenCount} tokens per example were found in over {percentage}% of the loaded examples.
|
||||
*/
|
||||
[VALIDATION_RESULT.TOKEN_COUNT]: i18n.translate(
|
||||
'xpack.ml.models.jobService.categorization.messages.validTokenLength',
|
||||
{
|
||||
defaultMessage:
|
||||
'More than {tokenCount} tokens per example were found in over {percentage}% of the examples loaded.',
|
||||
'More than {tokenCount} tokens per example were found in over {percentage}% of the loaded examples.',
|
||||
values: {
|
||||
percentage: Math.floor(CATEGORY_EXAMPLES_WARNING_LIMIT * 100),
|
||||
tokenCount: VALID_TOKEN_COUNT,
|
||||
},
|
||||
}
|
||||
),
|
||||
) as string,
|
||||
/**
|
||||
* The median line length of the loaded examples was less than {medianCharCount} characters.
|
||||
*/
|
||||
[VALIDATION_RESULT.MEDIAN_LINE_LENGTH]: i18n.translate(
|
||||
'xpack.ml.models.jobService.categorization.messages.validMedianLineLength',
|
||||
{
|
||||
defaultMessage:
|
||||
'The median line length of the examples loaded was less than {medianCharCount} characters.',
|
||||
'The median line length of the loaded examples was less than {medianCharCount} characters.',
|
||||
values: {
|
||||
medianCharCount: MEDIAN_LINE_LENGTH_LIMIT,
|
||||
},
|
||||
}
|
||||
),
|
||||
) as string,
|
||||
/**
|
||||
* Less than {percentage}% of the loaded examples were null.
|
||||
*/
|
||||
[VALIDATION_RESULT.NULL_VALUES]: i18n.translate(
|
||||
'xpack.ml.models.jobService.categorization.messages.validNullValues',
|
||||
{
|
||||
defaultMessage: 'Less than {percentage}% of the examples loaded were null.',
|
||||
defaultMessage: 'Less than {percentage}% of the loaded examples were null.',
|
||||
values: {
|
||||
percentage: Math.floor(100 - NULL_COUNT_PERCENT_LIMIT * 100),
|
||||
},
|
||||
}
|
||||
),
|
||||
) as string,
|
||||
/**
|
||||
* Less than 10000 tokens were found in total in the loaded examples.
|
||||
*/
|
||||
[VALIDATION_RESULT.TOO_MANY_TOKENS]: i18n.translate(
|
||||
'xpack.ml.models.jobService.categorization.messages.validTooManyTokens',
|
||||
{
|
||||
defaultMessage: 'Less than 10000 tokens were found in total in the examples loaded.',
|
||||
defaultMessage: 'Less than 10000 tokens were found in total in the loaded examples.',
|
||||
}
|
||||
),
|
||||
) as string,
|
||||
/**
|
||||
* The user has sufficient privileges to perform the checks.
|
||||
*/
|
||||
[VALIDATION_RESULT.INSUFFICIENT_PRIVILEGES]: i18n.translate(
|
||||
'xpack.ml.models.jobService.categorization.messages.validUserPrivileges',
|
||||
{
|
||||
defaultMessage: 'The user has sufficient privileges to perform the checks.',
|
||||
}
|
||||
),
|
||||
) as string,
|
||||
};
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
import {
|
||||
CATEGORY_EXAMPLES_VALIDATION_STATUS,
|
||||
VALIDATION_RESULT,
|
||||
} from '../constants/categorization';
|
||||
|
||||
/**
|
||||
* Token
|
||||
*/
|
||||
export interface Token {
|
||||
/**
|
||||
* The token string.
|
||||
*/
|
||||
token: string;
|
||||
/**
|
||||
* The starting offset of the token.
|
||||
*/
|
||||
start_offset: number;
|
||||
/**
|
||||
* The ending offset of the token.
|
||||
*/
|
||||
end_offset: number;
|
||||
/**
|
||||
* The type of the token.
|
||||
*/
|
||||
type: string;
|
||||
/**
|
||||
* The position of the token.
|
||||
*/
|
||||
position: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Categorization analyzer with additional properties.
|
||||
*/
|
||||
export type CategorizationAnalyzer = estypes.MlCategorizationAnalyzerDefinition & {
|
||||
/**
|
||||
* The analyzer used for categorization.
|
||||
*/
|
||||
analyzer?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Field example for a category.
|
||||
*/
|
||||
export interface CategoryFieldExample {
|
||||
/**
|
||||
* The text of the field example.
|
||||
*/
|
||||
text: string;
|
||||
/**
|
||||
* The tokens extracted from the field example.
|
||||
*/
|
||||
tokens: Token[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Result of a field example check.
|
||||
*/
|
||||
export interface FieldExampleCheck {
|
||||
/**
|
||||
* The ID of the validation result.
|
||||
*/
|
||||
id: VALIDATION_RESULT;
|
||||
/**
|
||||
* The validation status of the field example.
|
||||
*/
|
||||
valid: CATEGORY_EXAMPLES_VALIDATION_STATUS;
|
||||
/**
|
||||
* The message associated with the validation result.
|
||||
*/
|
||||
message: string;
|
||||
}
|
25
x-pack/packages/ml/category_validator/index.ts
Normal file
25
x-pack/packages/ml/category_validator/index.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export { categorizationExamplesProvider } from './src/examples';
|
||||
export type {
|
||||
CategorizationAnalyzer,
|
||||
CategoryFieldExample,
|
||||
FieldExampleCheck,
|
||||
Token,
|
||||
} from './common/types/categories';
|
||||
export {
|
||||
CATEGORY_EXAMPLES_ERROR_LIMIT,
|
||||
CATEGORY_EXAMPLES_SAMPLE_SIZE,
|
||||
CATEGORY_EXAMPLES_VALIDATION_STATUS,
|
||||
CATEGORY_EXAMPLES_WARNING_LIMIT,
|
||||
MEDIAN_LINE_LENGTH_LIMIT,
|
||||
NULL_COUNT_PERCENT_LIMIT,
|
||||
VALID_TOKEN_COUNT,
|
||||
VALIDATION_CHECK_DESCRIPTION,
|
||||
VALIDATION_RESULT,
|
||||
} from './common/constants/categorization';
|
12
x-pack/packages/ml/category_validator/jest.config.js
Normal file
12
x-pack/packages/ml/category_validator/jest.config.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test/jest_node',
|
||||
rootDir: '../../../..',
|
||||
roots: ['<rootDir>/x-pack/packages/ml/category_validator'],
|
||||
};
|
5
x-pack/packages/ml/category_validator/kibana.jsonc
Normal file
5
x-pack/packages/ml/category_validator/kibana.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"type": "shared-common",
|
||||
"id": "@kbn/ml-category-validator",
|
||||
"owner": "@elastic/ml-ui"
|
||||
}
|
6
x-pack/packages/ml/category_validator/package.json
Normal file
6
x-pack/packages/ml/category_validator/package.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "@kbn/ml-category-validator",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"license": "Elastic License 2.0"
|
||||
}
|
|
@ -7,29 +7,53 @@
|
|||
|
||||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
import { IScopedClusterClient } from '@kbn/core/server';
|
||||
import { chunk } from 'lodash';
|
||||
import type { IScopedClusterClient } from '@kbn/core/server';
|
||||
import type { RuntimeMappings } from '@kbn/ml-runtime-field-utils';
|
||||
import { CATEGORY_EXAMPLES_SAMPLE_SIZE } from '../../../../../common/constants/categorization_job';
|
||||
import {
|
||||
import { CATEGORY_EXAMPLES_SAMPLE_SIZE } from '../common/constants/categorization';
|
||||
import type {
|
||||
Token,
|
||||
CategorizationAnalyzer,
|
||||
CategoryFieldExample,
|
||||
} from '../../../../../common/types/categories';
|
||||
import { IndicesOptions } from '../../../../../common/types/anomaly_detection_jobs';
|
||||
} from '../common/types/categories';
|
||||
import { ValidationResults } from './validation_results';
|
||||
|
||||
/**
|
||||
* The size of each chunk for processing examples.
|
||||
*
|
||||
*/
|
||||
const CHUNK_SIZE = 100;
|
||||
|
||||
export function categorizationExamplesProvider({
|
||||
asCurrentUser,
|
||||
asInternalUser,
|
||||
}: IScopedClusterClient) {
|
||||
/**
|
||||
* Provides methods for checking whether categories can be
|
||||
* produced from a field.
|
||||
*
|
||||
* @export
|
||||
* @param client - IScopedClusterClient
|
||||
*/
|
||||
export function categorizationExamplesProvider(client: IScopedClusterClient) {
|
||||
const { asCurrentUser, asInternalUser } = client;
|
||||
const validationResults = new ValidationResults();
|
||||
|
||||
/**
|
||||
* Retrieves the tokens for the provided examples and analyzer.
|
||||
*
|
||||
* @async
|
||||
* @param {string} indexPatternTitle
|
||||
* @param {estypes.QueryDslQueryContainer} query
|
||||
* @param {number} size
|
||||
* @param {string} categorizationFieldName
|
||||
* @param {(string | undefined)} timeField
|
||||
* @param {number} start
|
||||
* @param {number} end
|
||||
* @param {CategorizationAnalyzer} analyzer
|
||||
* @param {(RuntimeMappings | undefined)} runtimeMappings
|
||||
* @param {(estypes.IndicesOptions | undefined)} indicesOptions
|
||||
* @returns {Promise<{ examples: CategoryFieldExample[]; error?: Error }>}
|
||||
*/
|
||||
async function categorizationExamples(
|
||||
indexPatternTitle: string,
|
||||
query: any,
|
||||
query: estypes.QueryDslQueryContainer,
|
||||
size: number,
|
||||
categorizationFieldName: string,
|
||||
timeField: string | undefined,
|
||||
|
@ -37,8 +61,8 @@ export function categorizationExamplesProvider({
|
|||
end: number,
|
||||
analyzer: CategorizationAnalyzer,
|
||||
runtimeMappings: RuntimeMappings | undefined,
|
||||
indicesOptions: IndicesOptions | undefined
|
||||
): Promise<{ examples: CategoryFieldExample[]; error?: any }> {
|
||||
indicesOptions: estypes.IndicesOptions | undefined
|
||||
): Promise<{ examples: CategoryFieldExample[]; error?: Error }> {
|
||||
if (timeField !== undefined) {
|
||||
const range = {
|
||||
range: {
|
||||
|
@ -178,7 +202,7 @@ export function categorizationExamplesProvider({
|
|||
|
||||
async function validateCategoryExamples(
|
||||
indexPatternTitle: string,
|
||||
query: any,
|
||||
query: estypes.QueryDslQueryContainer,
|
||||
size: number,
|
||||
categorizationFieldName: string,
|
||||
timeField: string | undefined,
|
||||
|
@ -186,7 +210,7 @@ export function categorizationExamplesProvider({
|
|||
end: number,
|
||||
analyzer: CategorizationAnalyzer,
|
||||
runtimeMappings: RuntimeMappings | undefined,
|
||||
indicesOptions: IndicesOptions | undefined
|
||||
indicesOptions: estypes.IndicesOptions | undefined
|
||||
) {
|
||||
const resp = await categorizationExamples(
|
||||
indexPatternTitle,
|
11
x-pack/packages/ml/category_validator/src/util.ts
Normal file
11
x-pack/packages/ml/category_validator/src/util.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export function getMedianStringLength(strings: string[]) {
|
||||
const sortedStringLengths = strings.map((s) => s.length).sort((a, b) => a - b);
|
||||
return sortedStringLengths[Math.floor(sortedStringLengths.length / 2)] || 0;
|
||||
}
|
|
@ -13,13 +13,10 @@ import {
|
|||
CATEGORY_EXAMPLES_VALIDATION_STATUS,
|
||||
CATEGORY_EXAMPLES_ERROR_LIMIT,
|
||||
CATEGORY_EXAMPLES_WARNING_LIMIT,
|
||||
} from '../../../../../common/constants/categorization_job';
|
||||
import {
|
||||
FieldExampleCheck,
|
||||
CategoryFieldExample,
|
||||
VALIDATION_RESULT,
|
||||
} from '../../../../../common/types/categories';
|
||||
import { getMedianStringLength } from '../../../../../common/util/string_utils';
|
||||
} from '../common/constants/categorization';
|
||||
import type { FieldExampleCheck, CategoryFieldExample } from '../common/types/categories';
|
||||
import { getMedianStringLength } from './util';
|
||||
|
||||
export class ValidationResults {
|
||||
private _results: FieldExampleCheck[] = [];
|
21
x-pack/packages/ml/category_validator/tsconfig.json
Normal file
21
x-pack/packages/ml/category_validator/tsconfig.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "target/types",
|
||||
"types": [
|
||||
"jest",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*"
|
||||
],
|
||||
"kbn_references": [
|
||||
"@kbn/i18n",
|
||||
"@kbn/core",
|
||||
"@kbn/ml-runtime-field-utils",
|
||||
]
|
||||
}
|
|
@ -33,3 +33,5 @@ export const DEFAULT_RARE_BUCKET_SPAN = '1h';
|
|||
export const DEFAULT_QUERY_DELAY = '60s';
|
||||
|
||||
export const SHARED_RESULTS_INDEX_NAME = 'shared';
|
||||
|
||||
export const NUMBER_OF_CATEGORY_EXAMPLES = 5;
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../constants/categorization_job';
|
||||
|
||||
export type CategoryId = number;
|
||||
|
||||
export interface Category {
|
||||
|
@ -20,39 +18,3 @@ export interface Category {
|
|||
partition_field_name?: string; // TODO: make non-optional once fields have been added to the results
|
||||
partition_field_value?: string; // TODO: make non-optional once fields have been added to the results
|
||||
}
|
||||
|
||||
export interface Token {
|
||||
token: string;
|
||||
start_offset: number;
|
||||
end_offset: number;
|
||||
type: string;
|
||||
position: number;
|
||||
}
|
||||
|
||||
export interface CategorizationAnalyzer {
|
||||
char_filter?: any[];
|
||||
tokenizer?: string;
|
||||
filter?: any[];
|
||||
analyzer?: string;
|
||||
}
|
||||
|
||||
export interface CategoryFieldExample {
|
||||
text: string;
|
||||
tokens: Token[];
|
||||
}
|
||||
|
||||
export enum VALIDATION_RESULT {
|
||||
NO_EXAMPLES,
|
||||
FAILED_TO_TOKENIZE,
|
||||
TOO_MANY_TOKENS,
|
||||
TOKEN_COUNT,
|
||||
MEDIAN_LINE_LENGTH,
|
||||
NULL_VALUES,
|
||||
INSUFFICIENT_PRIVILEGES,
|
||||
}
|
||||
|
||||
export interface FieldExampleCheck {
|
||||
id: VALIDATION_RESULT;
|
||||
valid: CATEGORY_EXAMPLES_VALIDATION_STATUS;
|
||||
message: string;
|
||||
}
|
||||
|
|
|
@ -5,14 +5,14 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CategorizationAnalyzer } from './categories';
|
||||
import * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
export interface MlServerDefaults {
|
||||
anomaly_detectors: {
|
||||
categorization_examples_limit?: number;
|
||||
model_memory_limit?: string;
|
||||
model_snapshot_retention_days?: number;
|
||||
categorization_analyzer?: CategorizationAnalyzer;
|
||||
categorization_analyzer?: estypes.MlCategorizationAnalyzerDefinition;
|
||||
};
|
||||
datafeeds: { scroll_size?: number };
|
||||
}
|
||||
|
|
|
@ -14,8 +14,19 @@ import {
|
|||
ML_JOB_AGGREGATION,
|
||||
} from '@kbn/ml-anomaly-utils';
|
||||
import type { SavedSearch } from '@kbn/saved-search-plugin/public';
|
||||
import {
|
||||
type CategorizationAnalyzer,
|
||||
type CategoryFieldExample,
|
||||
type FieldExampleCheck,
|
||||
VALIDATION_RESULT,
|
||||
CATEGORY_EXAMPLES_VALIDATION_STATUS,
|
||||
} from '@kbn/ml-category-validator';
|
||||
import { JobCreator } from './job_creator';
|
||||
import { Job, Datafeed, Detector } from '../../../../../../common/types/anomaly_detection_jobs';
|
||||
import type {
|
||||
Job,
|
||||
Datafeed,
|
||||
Detector,
|
||||
} from '../../../../../../common/types/anomaly_detection_jobs';
|
||||
import { createBasicDetector } from './util/default_configs';
|
||||
import {
|
||||
JOB_TYPE,
|
||||
|
@ -23,13 +34,7 @@ import {
|
|||
DEFAULT_BUCKET_SPAN,
|
||||
DEFAULT_RARE_BUCKET_SPAN,
|
||||
} from '../../../../../../common/constants/new_job';
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../../../common/constants/categorization_job';
|
||||
import {
|
||||
CategorizationAnalyzer,
|
||||
CategoryFieldExample,
|
||||
FieldExampleCheck,
|
||||
VALIDATION_RESULT,
|
||||
} from '../../../../../../common/types/categories';
|
||||
|
||||
import { getRichDetectors } from './util/general';
|
||||
import { CategorizationExamplesLoader } from '../results_loader';
|
||||
import { getNewJobDefaults } from '../../../../services/ml_server_info';
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import { ReactElement } from 'react';
|
||||
import { combineLatest, Observable, ReplaySubject, Subject } from 'rxjs';
|
||||
import { map, startWith, tap } from 'rxjs/operators';
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '@kbn/ml-category-validator';
|
||||
import {
|
||||
basicJobValidation,
|
||||
basicDatafeedValidation,
|
||||
|
@ -24,7 +25,7 @@ import {
|
|||
JobExistsResult,
|
||||
GroupsExistResult,
|
||||
} from './validators';
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../../../common/constants/categorization_job';
|
||||
|
||||
import { JOB_TYPE } from '../../../../../../common/constants/new_job';
|
||||
|
||||
// delay start of validation to allow the user to make changes
|
||||
|
|
|
@ -6,13 +6,11 @@
|
|||
*/
|
||||
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import { IndexPatternTitle } from '../../../../../../common/types/kibana';
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '@kbn/ml-category-validator';
|
||||
import { NUMBER_OF_CATEGORY_EXAMPLES } from '../../../../../../common/constants/new_job';
|
||||
import type { IndexPatternTitle } from '../../../../../../common/types/kibana';
|
||||
import { CategorizationJobCreator } from '../job_creator';
|
||||
import { ml } from '../../../../services/ml_api_service';
|
||||
import {
|
||||
NUMBER_OF_CATEGORY_EXAMPLES,
|
||||
CATEGORY_EXAMPLES_VALIDATION_STATUS,
|
||||
} from '../../../../../../common/constants/categorization_job';
|
||||
|
||||
export class CategorizationExamplesLoader {
|
||||
private _jobCreator: CategorizationJobCreator;
|
||||
|
|
|
@ -18,15 +18,14 @@ import { i18n } from '@kbn/i18n';
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
||||
import {
|
||||
CategorizationAnalyzer,
|
||||
FieldExampleCheck,
|
||||
} from '../../../../../../../../../common/types/categories';
|
||||
import { EditCategorizationAnalyzerFlyout } from '../../../common/edit_categorization_analyzer_flyout';
|
||||
import {
|
||||
type CategorizationAnalyzer,
|
||||
type FieldExampleCheck,
|
||||
VALIDATION_RESULT,
|
||||
CATEGORY_EXAMPLES_VALIDATION_STATUS,
|
||||
VALIDATION_CHECK_DESCRIPTION,
|
||||
} from '../../../../../../../../../common/constants/categorization_job';
|
||||
import { VALIDATION_RESULT } from '../../../../../../../../../common/types/categories';
|
||||
} from '@kbn/ml-category-validator';
|
||||
|
||||
import { EditCategorizationAnalyzerFlyout } from '../../../common/edit_categorization_analyzer_flyout';
|
||||
|
||||
interface Props {
|
||||
validationChecks: FieldExampleCheck[];
|
||||
|
@ -96,9 +95,12 @@ export const ExamplesValidCallout: FC<Props> = ({
|
|||
const AnalyzerUsed: FC<{ categorizationAnalyzer: CategorizationAnalyzer }> = ({
|
||||
categorizationAnalyzer,
|
||||
}) => {
|
||||
let analyzer = '';
|
||||
let analyzer: string | null = null;
|
||||
|
||||
if (categorizationAnalyzer?.tokenizer !== undefined) {
|
||||
if (
|
||||
categorizationAnalyzer?.tokenizer !== undefined &&
|
||||
typeof categorizationAnalyzer.tokenizer === 'string'
|
||||
) {
|
||||
analyzer = categorizationAnalyzer.tokenizer;
|
||||
} else if (categorizationAnalyzer?.analyzer !== undefined) {
|
||||
analyzer = categorizationAnalyzer.analyzer;
|
||||
|
@ -106,13 +108,15 @@ const AnalyzerUsed: FC<{ categorizationAnalyzer: CategorizationAnalyzer }> = ({
|
|||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.newJob.wizard.pickFieldsStep.categorizationFieldAnalyzer"
|
||||
defaultMessage="Analyzer used: {analyzer}"
|
||||
values={{ analyzer }}
|
||||
/>
|
||||
</div>
|
||||
{analyzer !== null ? (
|
||||
<div>
|
||||
<FormattedMessage
|
||||
id="xpack.ml.newJob.wizard.pickFieldsStep.categorizationFieldAnalyzer"
|
||||
defaultMessage="Analyzer used: {analyzer}"
|
||||
values={{ analyzer }}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
<div>
|
||||
<EditCategorizationAnalyzerFlyout />
|
||||
</div>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
import React, { FC } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { EuiBasicTable, EuiCodeBlock } from '@elastic/eui';
|
||||
import { CategoryFieldExample } from '../../../../../../../../../common/types/categories';
|
||||
import { CategoryFieldExample } from '@kbn/ml-category-validator';
|
||||
|
||||
interface Props {
|
||||
fieldExamples: CategoryFieldExample[] | null;
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
|
||||
import React, { FC, useContext, useEffect, useState } from 'react';
|
||||
import { EuiHorizontalRule } from '@elastic/eui';
|
||||
import {
|
||||
CATEGORY_EXAMPLES_VALIDATION_STATUS,
|
||||
type CategoryFieldExample,
|
||||
type FieldExampleCheck,
|
||||
} from '@kbn/ml-category-validator';
|
||||
import { getToastNotificationService } from '../../../../../../../services/toast_notification_service';
|
||||
|
||||
import { JobCreatorContext } from '../../../job_creator_context';
|
||||
|
@ -18,11 +23,6 @@ import { CategorizationPerPartitionField } from '../categorization_partition_fie
|
|||
import { FieldExamples } from './field_examples';
|
||||
import { ExamplesValidCallout } from './examples_valid_callout';
|
||||
import { InvalidCssVersionCallout } from './invalid_ccs_version_valid_callout';
|
||||
import {
|
||||
CategoryFieldExample,
|
||||
FieldExampleCheck,
|
||||
} from '../../../../../../../../../common/types/categories';
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../../../../../../common/constants/categorization_job';
|
||||
import { LoadingWrapper } from '../../../charts/loading_wrapper';
|
||||
|
||||
interface Props {
|
||||
|
|
|
@ -9,12 +9,12 @@ import React, { FC, useContext, useEffect, useState } from 'react';
|
|||
import { EuiBasicTable, EuiText } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { extractErrorProperties } from '@kbn/ml-error-utils';
|
||||
import { NUMBER_OF_CATEGORY_EXAMPLES } from '../../../../../../../../../common/constants/new_job';
|
||||
import { JobCreatorContext } from '../../../job_creator_context';
|
||||
import { CategorizationJobCreator } from '../../../../../common/job_creator';
|
||||
import { Results } from '../../../../../common/results_loader';
|
||||
import { ml } from '../../../../../../../services/ml_api_service';
|
||||
import { useToastNotificationService } from '../../../../../../../services/toast_notification_service';
|
||||
import { NUMBER_OF_CATEGORY_EXAMPLES } from '../../../../../../../../../common/constants/categorization_job';
|
||||
|
||||
export const TopCategories: FC = () => {
|
||||
const { displayErrorToast } = useToastNotificationService();
|
||||
|
|
|
@ -9,6 +9,12 @@ import { Observable } from 'rxjs';
|
|||
import { useMemo } from 'react';
|
||||
import type { AggFieldNamePair } from '@kbn/ml-anomaly-utils';
|
||||
import type { RuntimeMappings } from '@kbn/ml-runtime-field-utils';
|
||||
import {
|
||||
type CategorizationAnalyzer,
|
||||
type CategoryFieldExample,
|
||||
type FieldExampleCheck,
|
||||
CATEGORY_EXAMPLES_VALIDATION_STATUS,
|
||||
} from '@kbn/ml-category-validator';
|
||||
import { HttpService } from '../http_service';
|
||||
import { useMlKibana } from '../../contexts/kibana';
|
||||
|
||||
|
@ -25,12 +31,7 @@ import type { JobMessage } from '../../../../common/types/audit_message';
|
|||
import type { JobAction } from '../../../../common/constants/job_actions';
|
||||
import type { Group } from '../../../../common/types/groups';
|
||||
import type { ExistingJobsAndGroups } from '../job_service';
|
||||
import type {
|
||||
CategorizationAnalyzer,
|
||||
CategoryFieldExample,
|
||||
FieldExampleCheck,
|
||||
} from '../../../../common/types/categories';
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../common/constants/categorization_job';
|
||||
|
||||
import type { Category } from '../../../../common/types/categories';
|
||||
import type {
|
||||
JobsExistResponse,
|
||||
|
|
|
@ -5,5 +5,4 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export { categorizationExamplesProvider } from './examples';
|
||||
export { topCategoriesProvider } from './top_categories';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
import { CategoryId, Category } from '../../../../../common/types/categories';
|
||||
import type { CategoryId, Category } from '../../../../../common/types/categories';
|
||||
import type { MlClient } from '../../../../lib/ml_client';
|
||||
|
||||
export function topCategoriesProvider(mlClient: MlClient) {
|
||||
|
|
|
@ -6,4 +6,4 @@
|
|||
*/
|
||||
|
||||
export { newJobChartsProvider } from './charts';
|
||||
export { categorizationExamplesProvider, topCategoriesProvider } from './categorization';
|
||||
export { topCategoriesProvider } from './categorization';
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { schema } from '@kbn/config-schema';
|
||||
import { categorizationExamplesProvider } from '@kbn/ml-category-validator';
|
||||
import { ML_INTERNAL_BASE_PATH } from '../../common/constants/app';
|
||||
import { wrapError } from '../client/error_wrapper';
|
||||
import type { RouteInitialization } from '../types';
|
||||
|
@ -32,7 +33,6 @@ import {
|
|||
import { jobIdSchema } from './schemas/anomaly_detectors_schema';
|
||||
|
||||
import { jobServiceProvider } from '../models/job_service';
|
||||
import { categorizationExamplesProvider } from '../models/job_service/new_job';
|
||||
import { getAuthorizationHeader } from '../lib/request_authorization';
|
||||
import type { Datafeed, Job } from '../../common/types/anomaly_detection_jobs';
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@
|
|||
"@kbn/ml-kibana-theme",
|
||||
"@kbn/ml-runtime-field-utils",
|
||||
"@kbn/ml-date-utils",
|
||||
"@kbn/ml-category-validator",
|
||||
"@kbn/deeplinks-ml",
|
||||
"@kbn/core-notifications-browser-mocks",
|
||||
"@kbn/unified-field-list",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '@kbn/ml-plugin/common/constants/categorization_job';
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '@kbn/ml-category-validator';
|
||||
import type { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
import type { FieldStatsType } from '../common/types';
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '@kbn/ml-plugin/common/constants/categorization_job';
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '@kbn/ml-category-validator';
|
||||
import type { PickFieldsConfig, DatafeedConfig, Detector } from './types';
|
||||
import type { FtrProviderContext } from '../../../ftr_provider_context';
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '@kbn/ml-plugin/common/constants/categorization_job';
|
||||
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '@kbn/ml-category-validator';
|
||||
import type { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import type { MlCommonFieldStatsFlyout } from './field_stats_flyout';
|
||||
|
||||
|
|
|
@ -135,6 +135,7 @@
|
|||
"@kbn/profiling-plugin",
|
||||
"@kbn/observability-onboarding-plugin",
|
||||
"@kbn/bfetch-plugin",
|
||||
"@kbn/uptime-plugin"
|
||||
"@kbn/uptime-plugin",
|
||||
"@kbn/ml-category-validator"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -4658,6 +4658,10 @@
|
|||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@kbn/ml-category-validator@link:x-pack/packages/ml/category_validator":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
||||
"@kbn/ml-data-frame-analytics-utils@link:x-pack/packages/ml/data_frame_analytics_utils":
|
||||
version "0.0.0"
|
||||
uid ""
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue