Skip to content

Commit

Permalink
[ML] Listing all categorization wizard checks (#60502)
Browse files Browse the repository at this point in the history
* [ML] Listing all categorization wizard checks

* fixing translation

* changes based on review

* moving check

* adding real values to messages

* reordering checks enum

* fixing types

* updating tests

* updating id
  • Loading branch information
jgowdyelastic authored Mar 20, 2020
1 parent 2c25520 commit f18c571
Show file tree
Hide file tree
Showing 17 changed files with 167 additions and 48 deletions.
80 changes: 80 additions & 0 deletions x-pack/plugins/ml/common/constants/categorization_job.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { i18n } from '@kbn/i18n';
import { VALIDATION_RESULT } from '../types/categories';

export const NUMBER_OF_CATEGORY_EXAMPLES = 5;
export const CATEGORY_EXAMPLES_SAMPLE_SIZE = 1000;
export const CATEGORY_EXAMPLES_WARNING_LIMIT = 0.75;
export const CATEGORY_EXAMPLES_ERROR_LIMIT = 0.02;

export const VALID_TOKEN_COUNT = 3;
export const MEDIAN_LINE_LENGTH_LIMIT = 400;
export const NULL_COUNT_PERCENT_LIMIT = 0.75;

export enum CATEGORY_EXAMPLES_VALIDATION_STATUS {
VALID = 'valid',
PARTIALLY_VALID = 'partially_valid',
INVALID = 'invalid',
}

export const VALIDATION_CHECK_DESCRIPTION = {
[VALIDATION_RESULT.NO_EXAMPLES]: i18n.translate(
'xpack.ml.models.jobService.categorization.messages.validNoDataFound',
{
defaultMessage: 'Examples were successfully loaded.',
}
),
[VALIDATION_RESULT.FAILED_TO_TOKENIZE]: i18n.translate(
'xpack.ml.models.jobService.categorization.messages.validFailureToGetTokens',
{
defaultMessage: 'The examples loaded were tokenized successfully.',
}
),
[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.',
values: {
percentage: Math.floor(CATEGORY_EXAMPLES_WARNING_LIMIT * 100),
tokenCount: VALID_TOKEN_COUNT,
},
}
),
[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.',
values: {
medianCharCount: MEDIAN_LINE_LENGTH_LIMIT,
},
}
),
[VALIDATION_RESULT.NULL_VALUES]: i18n.translate(
'xpack.ml.models.jobService.categorization.messages.validNullValues',
{
defaultMessage: 'Less than {percentage}% of the examples loaded were null.',
values: {
percentage: Math.floor(100 - NULL_COUNT_PERCENT_LIMIT * 100),
},
}
),
[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.',
}
),
[VALIDATION_RESULT.INSUFFICIENT_PRIVILEGES]: i18n.translate(
'xpack.ml.models.jobService.categorization.messages.validUserPrivileges',
{
defaultMessage: 'The user has sufficient privileges to perform the checks.',
}
),
};
12 changes: 0 additions & 12 deletions x-pack/plugins/ml/common/constants/new_job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,3 @@ export const DEFAULT_RARE_BUCKET_SPAN = '1h';
export const DEFAULT_QUERY_DELAY = '60s';

export const SHARED_RESULTS_INDEX_NAME = 'shared';

// Categorization
export const NUMBER_OF_CATEGORY_EXAMPLES = 5;
export const CATEGORY_EXAMPLES_SAMPLE_SIZE = 1000;
export const CATEGORY_EXAMPLES_WARNING_LIMIT = 0.75;
export const CATEGORY_EXAMPLES_ERROR_LIMIT = 0.02;

export enum CATEGORY_EXAMPLES_VALIDATION_STATUS {
VALID = 'valid',
PARTIALLY_VALID = 'partially_valid',
INVALID = 'invalid',
}
8 changes: 4 additions & 4 deletions x-pack/plugins/ml/common/types/categories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../constants/new_job';
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../constants/categorization_job';

export type CategoryId = number;

Expand Down Expand Up @@ -39,12 +39,12 @@ export interface CategoryFieldExample {
}

export enum VALIDATION_RESULT {
NO_EXAMPLES,
FAILED_TO_TOKENIZE,
TOO_MANY_TOKENS,
TOKEN_COUNT,
MEDIAN_LINE_LENGTH,
NULL_VALUES,
NO_EXAMPLES,
TOO_MANY_TOKENS,
FAILED_TO_TOKENIZE,
INSUFFICIENT_PRIVILEGES,
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import {
CREATED_BY_LABEL,
DEFAULT_BUCKET_SPAN,
DEFAULT_RARE_BUCKET_SPAN,
CATEGORY_EXAMPLES_VALIDATION_STATUS,
} from '../../../../../../common/constants/new_job';
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../../../common/constants/categorization_job';
import { ML_JOB_AGGREGATION } from '../../../../../../common/constants/aggregation_types';
import {
CategorizationAnalyzer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { JobCreator, JobCreatorType, isCategorizationJobCreator } from '../job_c
import { populateValidationMessages, checkForExistingJobAndGroupIds } from './util';
import { ExistingJobsAndGroups } from '../../../../services/job_service';
import { cardinalityValidator, CardinalityValidatorResult } from './validators';
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../../../common/constants/new_job';
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../../../common/constants/categorization_job';

// delay start of validation to allow the user to make changes
// e.g. if they are typing in a new value, try not to validate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ml } from '../../../../services/ml_api_service';
import {
NUMBER_OF_CATEGORY_EXAMPLES,
CATEGORY_EXAMPLES_VALIDATION_STATUS,
} from '../../../../../../common/constants/new_job';
} from '../../../../../../common/constants/categorization_job';

export class CategorizationExamplesLoader {
private _jobCreator: CategorizationJobCreator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@
*/

import React, { FC, Fragment } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiAccordion, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import { CalendarsSelection } from './components/calendars';
import { CustomUrlsSelection } from './components/custom_urls';

const ButtonContent = <Fragment>Additional settings</Fragment>;
const buttonContent = i18n.translate(
'xpack.ml.newJob.wizard.jobDetailsStep.additionalSectionButton',
{
defaultMessage: 'Additional settings',
}
);

interface Props {
additionalExpanded: boolean;
Expand All @@ -22,7 +28,7 @@ export const AdditionalSection: FC<Props> = ({ additionalExpanded, setAdditional
<EuiSpacer />
<EuiAccordion
id="advanced-section"
buttonContent={ButtonContent}
buttonContent={buttonContent}
onToggle={setAdditionalExpanded}
initialIsOpen={additionalExpanded}
data-test-subj="mlJobWizardToggleAdditionalSettingsSection"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { ModelMemoryLimitInput } from '../../../common/model_memory_limit';
import { JobCreatorContext } from '../../../job_creator_context';
import { JOB_TYPE } from '../../../../../../../../../common/constants/new_job';

const ButtonContent = i18n.translate(
const buttonContent = i18n.translate(
'xpack.ml.newJob.wizard.jobDetailsStep.advancedSectionButton',
{
defaultMessage: 'Advanced',
Expand Down Expand Up @@ -55,7 +55,7 @@ export const AdvancedSection: FC<Props> = ({ advancedExpanded, setAdvancedExpand
<EuiSpacer size="xl" />
<EuiAccordion
id="advanced-section"
buttonContent={ButtonContent}
buttonContent={buttonContent}
onToggle={setAdvancedExpanded}
initialIsOpen={advancedExpanded}
data-test-subj="mlJobWizardToggleAdvancedSection"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@
*/

import React, { FC } from 'react';
import { EuiCallOut, EuiSpacer, EuiCallOutProps } from '@elastic/eui';
import {
EuiCallOut,
EuiSpacer,
EuiCallOutProps,
EuiAccordion,
EuiListGroup,
EuiListGroupItemProps,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';

Expand All @@ -14,14 +21,25 @@ import {
FieldExampleCheck,
} from '../../../../../../../../../common/types/categories';
import { EditCategorizationAnalyzerFlyout } from '../../../common/edit_categorization_analyzer_flyout';
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../../../../../../common/constants/new_job';
import {
CATEGORY_EXAMPLES_VALIDATION_STATUS,
VALIDATION_CHECK_DESCRIPTION,
} from '../../../../../../../../../common/constants/categorization_job';
import { VALIDATION_RESULT } from '../../../../../../../../../common/types/categories';

interface Props {
validationChecks: FieldExampleCheck[];
overallValidStatus: CATEGORY_EXAMPLES_VALIDATION_STATUS;
categorizationAnalyzer: CategorizationAnalyzer;
}

const allChecksButtonContent = i18n.translate(
'xpack.ml.newJob.wizard.jobDetailsStep.allChecksButton',
{
defaultMessage: 'View all checks performed',
}
);

export const ExamplesValidCallout: FC<Props> = ({
overallValidStatus,
validationChecks,
Expand Down Expand Up @@ -66,6 +84,10 @@ export const ExamplesValidCallout: FC<Props> = ({
))}
<EuiSpacer size="s" />
{analyzerUsed}
<EuiSpacer size="s" />
<EuiAccordion id="all-checks" buttonContent={allChecksButtonContent}>
<AllValidationChecks validationChecks={validationChecks} />
</EuiAccordion>
</EuiCallOut>
);
};
Expand Down Expand Up @@ -96,3 +118,28 @@ const AnalyzerUsed: FC<{ categorizationAnalyzer: CategorizationAnalyzer }> = ({
</>
);
};

const AllValidationChecks: FC<{ validationChecks: FieldExampleCheck[] }> = ({
validationChecks,
}) => {
const list: EuiListGroupItemProps[] = Object.keys(VALIDATION_CHECK_DESCRIPTION).map((k, i) => {
const failedCheck = validationChecks.find(vc => vc.id === i);
if (
failedCheck !== undefined &&
failedCheck?.valid !== CATEGORY_EXAMPLES_VALIDATION_STATUS.VALID
) {
return {
iconType: 'cross',
label: failedCheck.message,
size: 's',
};
}
return {
iconType: 'check',
label: VALIDATION_CHECK_DESCRIPTION[i as VALIDATION_RESULT],
size: 's',
};
});

return <EuiListGroup listItems={list} maxWidth={false} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
CategoryFieldExample,
FieldExampleCheck,
} from '../../../../../../../../../common/types/categories';
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../../../../../../common/constants/new_job';
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../../../../../../common/constants/categorization_job';
import { LoadingWrapper } from '../../../charts/loading_wrapper';

interface Props {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ 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 { NUMBER_OF_CATEGORY_EXAMPLES } from '../../../../../../../../../common/constants/new_job';
import { NUMBER_OF_CATEGORY_EXAMPLES } from '../../../../../../../../../common/constants/categorization_job';

export const TopCategories: FC = () => {
const { jobCreator: jc, resultsLoader } = useContext(JobCreatorContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
CategoryFieldExample,
FieldExampleCheck,
} from '../../../../common/types/categories';
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../common/constants/new_job';
import { CATEGORY_EXAMPLES_VALIDATION_STATUS } from '../../../../common/constants/categorization_job';
import { Category } from '../../../../common/types/categories';

export const jobs = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import { chunk } from 'lodash';
import { SearchResponse } from 'elasticsearch';
import { CATEGORY_EXAMPLES_SAMPLE_SIZE } from '../../../../../common/constants/new_job';
import { CATEGORY_EXAMPLES_SAMPLE_SIZE } from '../../../../../common/constants/categorization_job';
import {
Token,
CategorizationAnalyzer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@

import { i18n } from '@kbn/i18n';
import {
VALID_TOKEN_COUNT,
MEDIAN_LINE_LENGTH_LIMIT,
NULL_COUNT_PERCENT_LIMIT,
CATEGORY_EXAMPLES_VALIDATION_STATUS,
CATEGORY_EXAMPLES_ERROR_LIMIT,
CATEGORY_EXAMPLES_WARNING_LIMIT,
} from '../../../../../common/constants/new_job';
} from '../../../../../common/constants/categorization_job';
import {
FieldExampleCheck,
CategoryFieldExample,
VALIDATION_RESULT,
} from '../../../../../common/types/categories';
import { getMedianStringLength } from '../../../../../common/util/string_utils';

const VALID_TOKEN_COUNT = 3;
const MEDIAN_LINE_LENGTH_LIMIT = 400;
const NULL_COUNT_PERCENT_LIMIT = 0.75;

export class ValidationResults {
private _results: FieldExampleCheck[] = [];

Expand Down Expand Up @@ -187,7 +186,6 @@ export class ValidationResults {
valid: CATEGORY_EXAMPLES_VALIDATION_STATUS.PARTIALLY_VALID,
message,
});
return;
}
}

Expand Down
Loading

0 comments on commit f18c571

Please sign in to comment.