enable new Model Overview experience in OSS RAI Dashboard by default (#1647)

This commit is contained in:
Ilya Matiach 2022-08-18 15:36:27 -04:00 коммит произвёл GitHub
Родитель 323055795a
Коммит 22c68a11b6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
25 изменённых файлов: 486 добавлений и 990 удалений

2
.github/workflows/CI-e2e-notebooks.yml поставляемый
Просмотреть файл

@ -48,7 +48,7 @@ jobs:
# TODO: add macos
operatingSystem: [ubuntu-latest, windows-latest]
pythonVersion: [3.6, 3.7, 3.8, 3.9]
flights: ["", "newModelOverviewExperience", "dataBalanceExperience"]
flights: ["", "dataBalanceExperience"]
notebookGroup: ["nb_group_1", "nb_group_2"]
runs-on: ${{ matrix.operatingSystem }}

Просмотреть файл

@ -1,7 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
export interface IModelAssessmentData {
isClassification?: boolean;
isMulticlass?: boolean;
}

Просмотреть файл

@ -1,23 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { IModelAssessmentData } from "./IModelAssessmentData";
const modelAssessmentDatasets = {
adultCensusIncomeData: {
isClassification: true,
isMulticlass: false
},
bostonData: {
isClassification: false
},
wineData: {
isClassification: true,
isMulticlass: true
}
};
const withType: {
[key in keyof typeof modelAssessmentDatasets]: IModelAssessmentData;
} = modelAssessmentDatasets;
export { withType as modelAssessmentDatasets };

Просмотреть файл

@ -1,61 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
export function describeAxisConfigDialog(): void {
describe("Axis settings dialog", () => {
describe("Y Axis settings dialog", () => {
it("should display settings dialog", () => {
cy.get(
'#OverallMetricChart div[class*="rotatedVerticalBox"] button'
).click();
cy.get("#AxisConfigPanel div.ms-Panel-main").should("exist");
});
it("should be able to hide settings", () => {
cy.get("#AxisConfigPanel button.ms-Panel-closeButton").click();
cy.get("#AxisConfigPanel div.ms-Panel-main").should("not.exist");
});
it("should change to different y-axis title", () => {
cy.get(
'#OverallMetricChart div[class*="rotatedVerticalBox"] button'
).click();
cy.get("#AxisConfigPanel div[class*='ms-ChoiceFieldGroup'] label:eq(1)")
.invoke("text")
.then((text1) => {
cy.get(`#AxisConfigPanel label:contains(${text1})`).click();
cy.get("#AxisConfigPanel").find("button").contains("Apply").click();
cy.get(
'#OverallMetricChart div[class*="rotatedVerticalBox"] button:eq(0)'
).contains(text1);
});
});
});
describe("X Axis settings dialog", () => {
it("should display settings dialog", () => {
cy.get(
'#OverallMetricChart div[class*="horizontalAxis"] button'
).click();
cy.get("#AxisConfigPanel div.ms-Panel-main").should("exist");
});
it("should be able to hide settings", () => {
cy.get("#AxisConfigPanel button.ms-Panel-closeButton").click();
cy.get("#AxisConfigPanel div.ms-Panel-main").should("not.exist");
});
it("should change to different x-axis title", () => {
cy.get(
'#OverallMetricChart div[class*="horizontalAxis"] button'
).click();
cy.get("#AxisConfigPanel div[class*='ms-ChoiceFieldGroup'] label:eq(1)")
.invoke("text")
.then((text1) => {
cy.get(`#AxisConfigPanel label:contains(${text1})`).click();
cy.get("#AxisConfigPanel").find("button").contains("Apply").click();
cy.get(
'#OverallMetricChart div[class*="horizontalAxis"] button:eq(0)'
).contains(text1);
});
});
});
});
}

Просмотреть файл

@ -1,27 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { modelAssessmentDatasets } from "../modelAssessmentDatasets";
import { describeAxisConfigDialog } from "./describeAxisConfigDialog";
import { describeModelPerformanceStats } from "./describeModelPerformanceStats";
const testName = "Model overview";
export function describeModelOverview(
name: keyof typeof modelAssessmentDatasets
): void {
describe(testName, () => {
before(() => {
cy.visit(`#/modelAssessment/${name}/light/english/Version-2`);
});
it("Model overview title", () => {
cy.get("#modelStatisticsHeader").contains("Model overview");
});
describe("Model performance Chart", () => {
describeAxisConfigDialog();
});
describe("Model performance stats", () => {
describeModelPerformanceStats(modelAssessmentDatasets[name]);
});
});
}

Просмотреть файл

@ -1,45 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { IModelAssessmentData } from "../IModelAssessmentData";
export function describeModelPerformanceStats(
modelAssessmentData: IModelAssessmentData
): void {
describe("performance stats", () => {
it("should have legend", () => {
cy.get('#OverallMetricChart g[class*="infolayer"]').should("exist");
});
// stats box currently not available for multiclass
if (!modelAssessmentData.isMulticlass) {
it("should have stats box", () => {
cy.get('#OverallMetricChart div[class*="statsBox"]').should("exist");
});
it("should have some stats", () => {
let expectedMetrics: string[];
if (modelAssessmentData.isClassification) {
expectedMetrics = [
"Accuracy",
"Precision",
"F1 score",
"False positive rate",
"False negative rate",
"Selection rate"
];
} else {
expectedMetrics = [
"Mean squared error",
"Mean absolute error",
"R²",
"Mean prediction"
];
}
expectedMetrics.forEach((metricName) => {
cy.get('#OverallMetricChart div[class*="statsBox"]').contains(
metricName
);
});
});
}
});
}

Просмотреть файл

@ -1,6 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { describeModelOverview } from "../../../describer/modelAssessment/modelOverview/describeModelOverview";
import {
describeModelOverview,
modelAssessmentDatasets
} from "@responsible-ai/e2e";
describeModelOverview("adultCensusIncomeData");
const datasetShape = modelAssessmentDatasets.CensusClassificationModelDebugging;
describeModelOverview(datasetShape, "adultCensusIncomeData", false);

Просмотреть файл

@ -1,6 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { describeModelOverview } from "../../../describer/modelAssessment/modelOverview/describeModelOverview";
describeModelOverview("bostonData");

Просмотреть файл

@ -1,6 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { describeModelOverview } from "../../../describer/modelAssessment/modelOverview/describeModelOverview";
import {
describeModelOverview,
modelAssessmentDatasets
} from "@responsible-ai/e2e";
describeModelOverview("wineData");
const datasetShape = modelAssessmentDatasets.MulticlassDnnModelDebugging;
describeModelOverview(datasetShape, "wineData", false);

Просмотреть файл

@ -1,14 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import {
describeNewModelOverview,
modelAssessmentDatasetsIncludingFlights
} from "@responsible-ai/e2e";
const datasetShape =
modelAssessmentDatasetsIncludingFlights.CensusClassificationModelDebuggingNewModelOverviewExperience;
describeNewModelOverview(
datasetShape,
"CensusClassificationModelDebuggingNewModelOverviewExperience"
);

Просмотреть файл

@ -1,14 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import {
describeNewModelOverview,
modelAssessmentDatasetsIncludingFlights
} from "@responsible-ai/e2e";
const datasetShape =
modelAssessmentDatasetsIncludingFlights.DiabetesDecisionMakingNewModelOverviewExperience;
describeNewModelOverview(
datasetShape,
"DiabetesDecisionMakingNewModelOverviewExperience"
);

Просмотреть файл

@ -1,13 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import {
describeNewModelOverview,
modelAssessmentDatasetsIncludingFlights
} from "@responsible-ai/e2e";
const datasetShape =
modelAssessmentDatasetsIncludingFlights.DiabetesRegressionModelDebuggingNewModelOverviewExperience;
describeNewModelOverview(
datasetShape,
"DiabetesRegressionModelDebuggingNewModelOverviewExperience"
);

Просмотреть файл

@ -1,14 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import {
describeNewModelOverview,
modelAssessmentDatasetsIncludingFlights
} from "@responsible-ai/e2e";
const datasetShape =
modelAssessmentDatasetsIncludingFlights.HousingClassificationModelDebuggingNewModelOverviewExperience;
describeNewModelOverview(
datasetShape,
"HousingClassificationModelDebuggingNewModelOverviewExperience"
);

Просмотреть файл

@ -1,14 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import {
describeNewModelOverview,
modelAssessmentDatasetsIncludingFlights
} from "@responsible-ai/e2e";
const datasetShape =
modelAssessmentDatasetsIncludingFlights.HousingDecisionMakingNewModelOverviewExperience;
describeNewModelOverview(
datasetShape,
"HousingDecisionMakingNewModelOverviewExperience"
);

Просмотреть файл

@ -1,14 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import {
describeNewModelOverview,
modelAssessmentDatasetsIncludingFlights
} from "@responsible-ai/e2e";
const datasetShape =
modelAssessmentDatasetsIncludingFlights.MulticlassDnnModelDebuggingNewModelOverviewExperience;
describeNewModelOverview(
datasetShape,
"MulticlassDnnModelDebuggingNewModelOverviewExperience"
);

Просмотреть файл

@ -7,8 +7,7 @@ export * from "./lib/describer/modelAssessment/dataBalance/describeDataBalance";
export * from "./lib/describer/modelAssessment/dataExplorer/describeDatasetExplorer";
export * from "./lib/describer/modelAssessment/errorAnalysis/describeErrorAnalysis";
export * from "./lib/describer/modelAssessment/featureImportances/individualFeatureImportance/describeIndividualFeatureImportance";
export * from "./lib/describer/modelAssessment/modelOverview/v1/describeModelOverview";
export * from "./lib/describer/modelAssessment/modelOverview/v2/describeModelOverview";
export * from "./lib/describer/modelAssessment/modelOverview/describeModelOverview";
export * from "./lib/describer/modelAssessment/whatIfCounterfactuals/describeWhatIf";
export * from "./lib/describer/modelAssessment/modelAssessmentDatasets";
export * from "./lib/describer/modelAssessment/IModelAssessmentData";

Просмотреть файл

@ -162,20 +162,14 @@ export interface IWhatIfCounterfactualsData {
export enum RAINotebookNames {
"CensusClassificationModelDebugging" = "responsibleaidashboard-census-classification-model-debugging.py",
"CensusClassificationModelDebuggingDataBalanceExperience" = "responsibleaidashboard-census-classification-model-debugging.py",
"CensusClassificationModelDebuggingNewModelOverviewExperience" = "responsibleaidashboard-census-classification-model-debugging.py",
"DiabetesRegressionModelDebugging" = "responsibleaidashboard-diabetes-regression-model-debugging.py",
"DiabetesRegressionModelDebuggingDataBalanceExperience" = "responsibleaidashboard-diabetes-regression-model-debugging.py",
"DiabetesRegressionModelDebuggingNewModelOverviewExperience" = "responsibleaidashboard-diabetes-regression-model-debugging.py",
"HousingClassificationModelDebugging" = "responsibleaidashboard-housing-classification-model-debugging.py",
"HousingClassificationModelDebuggingDataBalanceExperience" = "responsibleaidashboard-housing-classification-model-debugging.py",
"HousingClassificationModelDebuggingNewModelOverviewExperience" = "responsibleaidashboard-housing-classification-model-debugging.py",
"DiabetesDecisionMaking" = "responsibleaidashboard-diabetes-decision-making.py",
"DiabetesDecisionMakingDataBalanceExperience" = "responsibleaidashboard-diabetes-decision-making.py",
"DiabetesDecisionMakingNewModelOverviewExperience" = "responsibleaidashboard-diabetes-decision-making.py",
"HousingDecisionMaking" = "responsibleaidashboard-housing-decision-making.py",
"HousingDecisionMakingDataBalanceExperience" = "responsibleaidashboard-housing-decision-making.py",
"HousingDecisionMakingNewModelOverviewExperience" = "responsibleaidashboard-housing-decision-making.py",
"MulticlassDnnModelDebugging" = "responsibleaidashboard-multiclass-dnn-model-debugging.py",
"MulticlassDnnModelDebuggingDataBalanceExperience" = "responsibleaidashboard-multiclass-dnn-model-debugging.py",
"MulticlassDnnModelDebuggingNewModelOverviewExperience" = "responsibleaidashboard-multiclass-dnn-model-debugging.py"
"MulticlassDnnModelDebuggingDataBalanceExperience" = "responsibleaidashboard-multiclass-dnn-model-debugging.py"
}

Просмотреть файл

@ -499,196 +499,185 @@ const modelAssessmentDatasets: { [name: string]: IModelAssessmentData } = {
}
};
// create copy for newModelOverviewExperience to allow for additions and changes
const modelAssessmentDatasetsNewModelOverviewExperience: {
[name: string]: IModelAssessmentData;
} = _.chain(modelAssessmentDatasets)
.cloneDeep()
.mapKeys((_v, k: string) => `${k}NewModelOverviewExperience`)
.value();
modelAssessmentDatasetsNewModelOverviewExperience.CensusClassificationModelDebuggingNewModelOverviewExperience.modelOverviewData =
{
featureCohortView: {
multiFeatureCohorts: 9,
singleFeatureCohorts: 3
},
hasModelOverviewComponent: true,
initialCohorts: [
{
metrics: {
accuracy: "0.856",
falseNegativeRate: "0.35",
falsePositiveRate: "0.077",
selectionRate: "0.246"
},
name: "All data",
sampleSize: "500"
},
{
metrics: {
accuracy: "0.753",
falseNegativeRate: "0.313",
falsePositiveRate: "0.195",
selectionRate: "0.438"
},
name: "Cohort Age and Hours-Per-Week",
sampleSize: "146"
},
{
metrics: {
accuracy: "0.927",
falseNegativeRate: "0.722",
falsePositiveRate: "0.019",
selectionRate: "0.077"
},
name: "Cohort Marital-Status",
sampleSize: "233"
},
{
metrics: {
accuracy: "0.75",
falseNegativeRate: "0.667",
falsePositiveRate: "0.071",
selectionRate: "0.3"
},
name: "Cohort Index",
sampleSize: "20"
},
{
metrics: {
accuracy: "0.734",
falseNegativeRate: "0",
falsePositiveRate: "1",
selectionRate: "0.734"
},
name: "Cohort Predicted Y",
sampleSize: "109"
},
{
metrics: {
accuracy: "0.65",
falseNegativeRate: "0.35",
falsePositiveRate: "N/A",
selectionRate: "1"
},
name: "Cohort True Y",
sampleSize: "123"
}
],
newCohort: {
modelAssessmentDatasets.CensusClassificationModelDebugging.modelOverviewData = {
featureCohortView: {
multiFeatureCohorts: 9,
singleFeatureCohorts: 3
},
hasModelOverviewComponent: true,
initialCohorts: [
{
metrics: {
accuracy: "0.858",
falseNegativeRate: "0.344",
accuracy: "0.856",
falseNegativeRate: "0.35",
falsePositiveRate: "0.077",
selectionRate: "0.244"
selectionRate: "0.246"
},
name: "CohortCreateE2E-census",
sampleSize: "499"
}
};
modelAssessmentDatasetsNewModelOverviewExperience.DiabetesDecisionMakingNewModelOverviewExperience.modelOverviewData =
{
featureCohortView: {
multiFeatureCohorts: 9,
singleFeatureCohorts: 3
name: "All data",
sampleSize: "500"
},
hasModelOverviewComponent: true,
initialCohorts: [
{
metrics: {
meanAbsoluteError: "3 859.27",
meanPrediction: "154.102",
meanSquaredError: "2 981.101"
},
name: "All data",
sampleSize: "89"
},
{
metrics: {
meanAbsoluteError: "1 961.23",
meanPrediction: "196.629",
meanSquaredError: "4 014.697"
},
name: "Cohort Age and BMI",
sampleSize: "38"
},
{
metrics: {
meanAbsoluteError: "983.52",
meanPrediction: "142.495",
meanSquaredError: "3 829.201"
},
name: "Cohort Index",
sampleSize: "20"
},
{
metrics: {
meanAbsoluteError: "2 084.21",
meanPrediction: "115.086",
meanSquaredError: "2 416.75"
},
name: "Cohort Predicted Y",
sampleSize: "51"
},
{
metrics: {
meanAbsoluteError: "3 744.86",
meanPrediction: "155.306",
meanSquaredError: "2 972.126"
},
name: "Cohort True Y",
sampleSize: "87"
},
{
metrics: {
meanAbsoluteError: "3 597.63",
meanPrediction: "157.301",
meanSquaredError: "4 154.723"
},
name: "Cohort Regression Error",
sampleSize: "63"
}
],
newCohort: {
{
metrics: {
meanAbsoluteError: "3 858.02",
meanPrediction: "153.958",
meanSquaredError: "3 014.96"
accuracy: "0.753",
falseNegativeRate: "0.313",
falsePositiveRate: "0.195",
selectionRate: "0.438"
},
name: "CohortCreateE2E-diabetes",
sampleSize: "88"
}
};
modelAssessmentDatasetsNewModelOverviewExperience.DiabetesRegressionModelDebuggingNewModelOverviewExperience.modelOverviewData =
{
featureCohortView: {
multiFeatureCohorts: 9,
singleFeatureCohorts: 3
name: "Cohort Age and Hours-Per-Week",
sampleSize: "146"
},
hasModelOverviewComponent: true,
initialCohorts: [
{
metrics: {
meanAbsoluteError: "3 859.27",
meanPrediction: "154.102",
meanSquaredError: "2 981.101"
},
name: "All data",
sampleSize: "89"
}
],
newCohort: {
{
metrics: {
meanAbsoluteError: "3 858.02",
meanPrediction: "153.958",
meanSquaredError: "3 014.96"
accuracy: "0.927",
falseNegativeRate: "0.722",
falsePositiveRate: "0.019",
selectionRate: "0.077"
},
name: "CohortCreateE2E-diabetes",
sampleSize: "88"
name: "Cohort Marital-Status",
sampleSize: "233"
},
{
metrics: {
accuracy: "0.75",
falseNegativeRate: "0.667",
falsePositiveRate: "0.071",
selectionRate: "0.3"
},
name: "Cohort Index",
sampleSize: "20"
},
{
metrics: {
accuracy: "0.734",
falseNegativeRate: "0",
falsePositiveRate: "1",
selectionRate: "0.734"
},
name: "Cohort Predicted Y",
sampleSize: "109"
},
{
metrics: {
accuracy: "0.65",
falseNegativeRate: "0.35",
falsePositiveRate: "N/A",
selectionRate: "1"
},
name: "Cohort True Y",
sampleSize: "123"
}
};
modelAssessmentDatasetsNewModelOverviewExperience.HousingClassificationModelDebuggingNewModelOverviewExperience.modelOverviewData =
],
newCohort: {
metrics: {
accuracy: "0.858",
falseNegativeRate: "0.344",
falsePositiveRate: "0.077",
selectionRate: "0.244"
},
name: "CohortCreateE2E-census",
sampleSize: "499"
}
};
modelAssessmentDatasets.DiabetesDecisionMaking.modelOverviewData = {
featureCohortView: {
multiFeatureCohorts: 9,
singleFeatureCohorts: 3
},
hasModelOverviewComponent: true,
initialCohorts: [
{
metrics: {
meanAbsoluteError: "3 859.27",
meanPrediction: "154.102",
meanSquaredError: "2 981.101"
},
name: "All data",
sampleSize: "89"
},
{
metrics: {
meanAbsoluteError: "1 961.23",
meanPrediction: "196.629",
meanSquaredError: "4 014.697"
},
name: "Cohort Age and BMI",
sampleSize: "38"
},
{
metrics: {
meanAbsoluteError: "983.52",
meanPrediction: "142.495",
meanSquaredError: "3 829.201"
},
name: "Cohort Index",
sampleSize: "20"
},
{
metrics: {
meanAbsoluteError: "2 084.21",
meanPrediction: "115.086",
meanSquaredError: "2 416.75"
},
name: "Cohort Predicted Y",
sampleSize: "51"
},
{
metrics: {
meanAbsoluteError: "3 744.86",
meanPrediction: "155.306",
meanSquaredError: "2 972.126"
},
name: "Cohort True Y",
sampleSize: "87"
},
{
metrics: {
meanAbsoluteError: "3 597.63",
meanPrediction: "157.301",
meanSquaredError: "4 154.723"
},
name: "Cohort Regression Error",
sampleSize: "63"
}
],
newCohort: {
metrics: {
meanAbsoluteError: "3 858.02",
meanPrediction: "153.958",
meanSquaredError: "3 014.96"
},
name: "CohortCreateE2E-diabetes",
sampleSize: "88"
}
};
modelAssessmentDatasets.DiabetesRegressionModelDebugging.modelOverviewData = {
featureCohortView: {
multiFeatureCohorts: 9,
singleFeatureCohorts: 3
},
hasModelOverviewComponent: true,
initialCohorts: [
{
metrics: {
meanAbsoluteError: "3 859.27",
meanPrediction: "154.102",
meanSquaredError: "2 981.101"
},
name: "All data",
sampleSize: "89"
}
],
newCohort: {
metrics: {
meanAbsoluteError: "3 858.02",
meanPrediction: "153.958",
meanSquaredError: "3 014.96"
},
name: "CohortCreateE2E-diabetes",
sampleSize: "88"
}
};
modelAssessmentDatasets.HousingClassificationModelDebugging.modelOverviewData =
{
featureCohortView: {
multiFeatureCohorts: 6,
@ -718,34 +707,32 @@ modelAssessmentDatasetsNewModelOverviewExperience.HousingClassificationModelDebu
sampleSize: "729"
}
};
modelAssessmentDatasetsNewModelOverviewExperience.HousingDecisionMakingNewModelOverviewExperience.modelOverviewData =
{
hasModelOverviewComponent: false
};
modelAssessmentDatasetsNewModelOverviewExperience.MulticlassDnnModelDebuggingNewModelOverviewExperience.modelOverviewData =
{
featureCohortView: {
multiFeatureCohorts: 9,
singleFeatureCohorts: 3
},
hasModelOverviewComponent: true,
initialCohorts: [
{
metrics: {
accuracy: "0.674"
},
name: "All data",
sampleSize: "89"
}
],
newCohort: {
modelAssessmentDatasets.HousingDecisionMaking.modelOverviewData = {
hasModelOverviewComponent: false
};
modelAssessmentDatasets.MulticlassDnnModelDebugging.modelOverviewData = {
featureCohortView: {
multiFeatureCohorts: 9,
singleFeatureCohorts: 3
},
hasModelOverviewComponent: true,
initialCohorts: [
{
metrics: {
accuracy: "0.67"
accuracy: "0.674"
},
name: "CohortCreateE2E-multiclass-dnn",
sampleSize: "88"
name: "All data",
sampleSize: "89"
}
};
],
newCohort: {
metrics: {
accuracy: "0.67"
},
name: "CohortCreateE2E-multiclass-dnn",
sampleSize: "88"
}
};
const modelAssessmentDatasetsDataBalanceExperience: {
[name: string]: IModelAssessmentData;
@ -760,15 +747,11 @@ const withType: {
const allDatasets = {
...modelAssessmentDatasets,
...modelAssessmentDatasetsNewModelOverviewExperience,
...modelAssessmentDatasetsDataBalanceExperience
};
const allWithType: {
[key in keyof typeof allDatasets]: IModelAssessmentData;
} = Object.assign(
modelAssessmentDatasetsNewModelOverviewExperience,
modelAssessmentDatasetsDataBalanceExperience
);
} = Object.assign(modelAssessmentDatasetsDataBalanceExperience);
export {
withType as modelAssessmentDatasets,

Просмотреть файл

@ -1,46 +1,56 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { multiSelectComboBox } from "../../../../../util/comboBox";
import { createCohort } from "../../../../../util/createCohort";
import { Locators } from "../../Constants";
import { multiSelectComboBox } from "../../../../util/comboBox";
import { createCohort } from "../../../../util/createCohort";
import { Locators } from "../Constants";
import {
IModelAssessmentData,
RAINotebookNames
} from "../../IModelAssessmentData";
import { modelAssessmentDatasetsIncludingFlights } from "../../modelAssessmentDatasets";
} from "../IModelAssessmentData";
import { modelAssessmentDatasetsIncludingFlights } from "../modelAssessmentDatasets";
const testName = "Model Overview v2";
export function describeNewModelOverview(
export function describeModelOverview(
datasetShape: IModelAssessmentData,
name?: keyof typeof modelAssessmentDatasetsIncludingFlights
name?: keyof typeof modelAssessmentDatasetsIncludingFlights,
isNotebookTest = true
): void {
describe(testName, () => {
before(() => {
if (name) {
const hosts = Cypress.env().hosts;
const hostDetails = hosts.find((obj: { file: string }) => {
return obj.file === RAINotebookNames[name];
});
cy.task("log", hostDetails.host);
cy.visit(hostDetails.host);
}
});
if (isNotebookTest) {
before(() => {
if (name) {
const hosts = Cypress.env().hosts;
const hostDetails = hosts.find((obj: { file: string }) => {
return obj.file === RAINotebookNames[name];
});
cy.task("log", hostDetails.host);
cy.visit(hostDetails.host);
}
});
} else {
before(() => {
cy.visit(`#/modelAssessment/${name}/light/english/Version-2`);
});
}
if (datasetShape.modelOverviewData?.hasModelOverviewComponent) {
it("should have 'Model overview' component in the initial state", () => {
ensureAllModelOverviewBasicElementsArePresent();
ensureAllModelOverviewDatasetCohortsViewBasicElementsArePresent(
datasetShape,
false
false,
isNotebookTest
);
});
it("should show 'Feature cohorts' view when selected", () => {
ensureAllModelOverviewBasicElementsArePresent();
cy.get(Locators.ModelOverviewCohortViewFeatureCohortViewButton).click();
ensureAllModelOverviewFeatureCohortsViewBasicElementsArePresent();
ensureAllModelOverviewFeatureCohortsViewBasicElementsArePresent(
isNotebookTest
);
multiSelectComboBox(
"#modelOverviewFeatureSelection",
datasetShape.featureNames![0],
@ -64,7 +74,7 @@ export function describeNewModelOverview(
});
it("should show new cohorts in charts", () => {
ensureNewCohortsShowUpInCharts(datasetShape);
ensureNewCohortsShowUpInCharts(datasetShape, isNotebookTest);
});
} else {
it("should not have 'Model overview' component", () => {
@ -87,7 +97,8 @@ function ensureAllModelOverviewBasicElementsArePresent() {
function ensureAllModelOverviewDatasetCohortsViewBasicElementsArePresent(
datasetShape: IModelAssessmentData,
includeNewCohort: boolean
includeNewCohort: boolean,
isNotebookTest: boolean
) {
const data = datasetShape.modelOverviewData!;
const initialCohorts = data.initialCohorts!;
@ -95,13 +106,15 @@ function ensureAllModelOverviewDatasetCohortsViewBasicElementsArePresent(
cy.get(Locators.ModelOverviewFeatureConfigurationActionButton).should(
"not.exist"
);
const numberOfCohorts = initialCohorts.length + (includeNewCohort ? 1 : 0);
if (numberOfCohorts <= 1) {
cy.get(Locators.ModelOverviewHeatmapVisualDisplayToggle).should(
"not.exist"
);
} else {
cy.get(Locators.ModelOverviewHeatmapVisualDisplayToggle).should("exist");
if (isNotebookTest) {
const numberOfCohorts = initialCohorts.length + (includeNewCohort ? 1 : 0);
if (numberOfCohorts <= 1) {
cy.get(Locators.ModelOverviewHeatmapVisualDisplayToggle).should(
"not.exist"
);
} else {
cy.get(Locators.ModelOverviewHeatmapVisualDisplayToggle).should("exist");
}
}
cy.get(Locators.ModelOverviewDatasetCohortStatsTable).should("exist");
cy.get(Locators.ModelOverviewDisaggregatedAnalysisTable).should("not.exist");
@ -141,14 +154,16 @@ function ensureAllModelOverviewDatasetCohortsViewBasicElementsArePresent(
});
});
cy.get(Locators.ModelOverviewHeatmapCells)
.should("have.length", cohorts.length * (metricsOrder.length + 1))
.each(($cell) => {
// somehow the cell string is one invisible character longer, trim
expect($cell.text().slice(0, $cell.text().length - 1)).to.be.oneOf(
heatmapCellContents
);
});
if (isNotebookTest) {
cy.get(Locators.ModelOverviewHeatmapCells)
.should("have.length", cohorts.length * (metricsOrder.length + 1))
.each(($cell) => {
// somehow the cell string is one invisible character longer, trim
expect($cell.text().slice(0, $cell.text().length - 1)).to.be.oneOf(
heatmapCellContents
);
});
}
cy.get(
Locators.ModelOverviewDisaggregatedAnalysisBaseCohortDisclaimer
@ -164,24 +179,29 @@ function ensureAllModelOverviewDatasetCohortsViewBasicElementsArePresent(
"not.exist"
);
cy.get(Locators.ModelOverviewMetricChart).should("exist");
cy.get(Locators.ModelOverviewMetricChartBars).should(
"have.length",
cohorts.length
);
// check aria-label of bar chart - aria-label uses comma as delimiter
// between digits for thousands instead of whitespace
const displayedMetric = datasetShape.isRegression
? initialCohorts[0].metrics.meanAbsoluteError
: initialCohorts[0].metrics.accuracy;
const expectedAriaLabel =
!datasetShape.isRegression && !datasetShape.isMulticlass
? `1. ${initialCohorts[0].name}, ${displayedMetric.replace(" ", ",")}.`
: `${initialCohorts[0].name}, ${displayedMetric.replace(" ", ",")}. ${
datasetShape.isRegression ? "Mean absolute error" : "Accuracy"
}.`;
cy.get(Locators.ModelOverviewMetricChartBars)
.first()
.should("have.attr", "aria-label", expectedAriaLabel);
if (isNotebookTest) {
cy.get(Locators.ModelOverviewMetricChartBars).should(
"have.length",
cohorts.length
);
// check aria-label of bar chart - aria-label uses comma as delimiter
// between digits for thousands instead of whitespace
const displayedMetric = datasetShape.isRegression
? initialCohorts[0].metrics.meanAbsoluteError
: initialCohorts[0].metrics.accuracy;
const expectedAriaLabel =
!datasetShape.isRegression && !datasetShape.isMulticlass
? `1. ${initialCohorts[0].name}, ${displayedMetric.replace(
" ",
","
)}.`
: `${initialCohorts[0].name}, ${displayedMetric.replace(" ", ",")}. ${
datasetShape.isRegression ? "Mean absolute error" : "Accuracy"
}.`;
cy.get(Locators.ModelOverviewMetricChartBars)
.first()
.should("have.attr", "aria-label", expectedAriaLabel);
}
} else {
cy.get(Locators.ModelOverviewChartPivotItems).should("have.length", 2);
cy.get(Locators.ModelOverviewProbabilityDistributionChart).should("exist");
@ -189,7 +209,9 @@ function ensureAllModelOverviewDatasetCohortsViewBasicElementsArePresent(
}
}
function ensureAllModelOverviewFeatureCohortsViewBasicElementsArePresent() {
function ensureAllModelOverviewFeatureCohortsViewBasicElementsArePresent(
isNotebookTest: boolean
) {
cy.get(Locators.ModelOverviewFeatureSelection).should("exist");
cy.get(Locators.ModelOverviewFeatureConfigurationActionButton).should(
"exist"
@ -210,10 +232,12 @@ function ensureAllModelOverviewFeatureCohortsViewBasicElementsArePresent() {
"not.exist"
);
cy.get(Locators.ModelOverviewMetricChart).should("not.exist");
cy.get(Locators.MissingParameterPlaceholder).should(
"include.text",
"Select features to generate the feature-based analysis."
);
if (isNotebookTest) {
cy.get(Locators.MissingParameterPlaceholder).should(
"include.text",
"Select features to generate the feature-based analysis."
);
}
}
function ensureAllModelOverviewFeatureCohortsViewElementsAfterSelectionArePresent(
@ -255,15 +279,20 @@ function ensureAllModelOverviewFeatureCohortsViewElementsAfterSelectionArePresen
}
}
function ensureNewCohortsShowUpInCharts(datasetShape: IModelAssessmentData) {
function ensureNewCohortsShowUpInCharts(
datasetShape: IModelAssessmentData,
isNotebookTest: boolean
) {
cy.get(Locators.ModelOverviewCohortViewDatasetCohortViewButton).click();
ensureAllModelOverviewDatasetCohortsViewBasicElementsArePresent(
datasetShape,
false
false,
isNotebookTest
);
createCohort(datasetShape.modelOverviewData?.newCohort?.name);
ensureAllModelOverviewDatasetCohortsViewBasicElementsArePresent(
datasetShape,
true
true,
isNotebookTest
);
}

Просмотреть файл

@ -1,43 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { Locators } from "../../Constants";
import {
IModelAssessmentData,
RAINotebookNames
} from "../../IModelAssessmentData";
import { modelAssessmentDatasetsIncludingFlights } from "../../modelAssessmentDatasets";
import { describeModelPerformanceBoxChart } from "./describeModelPerformanceBoxChart";
import { describeModelPerformanceSideBar } from "./describeModelPerformanceSideBar";
const testName = "Model Overview v1";
export function describeModelOverview(
datasetShape: IModelAssessmentData,
name?: keyof typeof modelAssessmentDatasetsIncludingFlights
): void {
describe(testName, () => {
before(() => {
if (name) {
const hosts = Cypress.env().hosts;
const hostDetails = hosts.find((obj: { file: string }) => {
return obj.file === RAINotebookNames[name];
});
cy.task("log", hostDetails.host);
cy.visit(hostDetails.host);
}
});
if (!datasetShape.modelStatisticsData?.hasModelStatisticsComponent) {
it("should not have 'Model statistics' component for the notebook", () => {
cy.get(Locators.ModelOverviewHeader).should("not.exist");
});
}
if (datasetShape.modelStatisticsData?.hasModelStatisticsComponent) {
describeModelPerformanceBoxChart(datasetShape);
if (datasetShape.modelStatisticsData.hasSideBar) {
describeModelPerformanceSideBar(datasetShape);
}
}
});
}

Просмотреть файл

@ -1,89 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { BarChart } from "../../../../../util/BarChart";
import { BoxChart } from "../../../../../util/BoxChart";
import { Locators } from "../../Constants";
import { IModelAssessmentData } from "../../IModelAssessmentData";
export function describeModelPerformanceBoxChart(
dataShape: IModelAssessmentData
): void {
describe("Model performance box chart", () => {
const props = {
chart: dataShape.isMulticlass
? (undefined as unknown as BoxChart)
: (undefined as unknown as BarChart),
dataShape
};
beforeEach(() => {
if (dataShape.isMulticlass) {
props.chart = new BarChart("#OverallMetricChart");
} else {
props.chart = new BoxChart("#OverallMetricChart");
}
});
it("should render", () => {
expect(props.chart.Elements.length).greaterThan(0);
});
it("should display right y-axis title", () => {
cy.get(
`${Locators.MSCRotatedVerticalBox} span[class*="textContainer"]`
).contains(dataShape.modelStatisticsData?.defaultYAxis || "Cohort");
});
it("should display right x-axis title", () => {
cy.get(
`${Locators.MSCHorizontalAxis} span[class*="textContainer"]`
).contains(
dataShape.modelStatisticsData?.defaultXAxis || "Probability : <=50K"
);
});
it("should change to different y-axis title", () => {
cy.get(`${Locators.MSCRotatedVerticalBox} button`)
.click()
.get(
`${Locators.DECChoiceFieldGroup} label:contains(${dataShape.modelStatisticsData?.yAxisNewPanelValue})`
)
.click();
cy.get(Locators.ApplyButton).click();
cy.get(`${Locators.MSCRotatedVerticalBox}`).contains(
dataShape.modelStatisticsData?.yAxisNewValue || "age"
);
cy.get(`${Locators.MSCRotatedVerticalBox} button`)
.click()
.get(
`${Locators.DECChoiceFieldGroup} label:contains(${dataShape.modelStatisticsData?.defaultYAxis})`
)
.click();
cy.get(Locators.ApplyButton).click();
cy.get(`${Locators.MSCRotatedVerticalBox}`).contains(
dataShape.modelStatisticsData?.defaultYAxis || "Cohort"
);
});
it("should change to different x-axis title", () => {
cy.get(`${Locators.MSCHorizontalAxis} button`).click();
cy.get(`${Locators.DECChoiceFieldGroup} label:eq(2)`)
.invoke("text")
.then((text1) => {
cy.get(`#AxisConfigPanel label:contains(${text1})`).click();
cy.get(Locators.ApplyButton).click();
cy.get(`${Locators.MSCHorizontalAxis} button:eq(0)`).contains(text1);
});
cy.get(`${Locators.MSCHorizontalAxis} button`)
.click()
.get(
`${Locators.DECChoiceFieldGroup} label:contains(${dataShape.modelStatisticsData?.defaultXAxisPanelValue})`
)
.click();
cy.get(Locators.ApplyButton).click();
cy.get(`${Locators.MSCHorizontalAxis}`).contains(
dataShape.modelStatisticsData?.xAxisNewValue || ""
);
});
});
}

Просмотреть файл

@ -1,104 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { BoxChart } from "../../../../../util/BoxChart";
import { createCohort } from "../../../../../util/createCohort";
import { Locators } from "../../Constants";
import { IModelAssessmentData } from "../../IModelAssessmentData";
export function describeModelPerformanceSideBar(
dataShape: IModelAssessmentData
): void {
describe("Model performance side bar", () => {
const props = {
chart: undefined as unknown as BoxChart,
dataShape
};
beforeEach(() => {
props.chart = new BoxChart("#OverallMetricChart");
});
it("Side bar should be updated with updated values", () => {
cy.get(Locators.MSSideBarCards).should(
"have.length",
dataShape.modelStatisticsData?.cohortDropDownValues
? dataShape.modelStatisticsData?.cohortDropDownValues.length
: 0
);
cy.get(`${Locators.MSCRotatedVerticalBox} button`)
.click()
.get(
`${Locators.DECChoiceFieldGroup} label:contains(${dataShape.modelStatisticsData?.yAxisNewPanelValue})`
)
.click();
cy.get(Locators.AxisConfigPanel).then(($panel) => {
if ($panel.find(Locators.MSSideBarNumberOfBinsInput).length > 0) {
cy.get(Locators.MSSideBarNumberOfBinsInput)
.clear()
.type(dataShape.modelStatisticsData?.yAxisNumberOfBins || "5");
}
});
cy.get(Locators.ApplyButton).click();
cy.get(`${Locators.MSCRotatedVerticalBox}`).contains(
dataShape.modelStatisticsData?.yAxisNewValue || "age"
);
cy.get(Locators.MSSideBarCards).should(
"have.length",
dataShape.modelStatisticsData?.yAxisNumberOfBins || "5"
);
// Side bar should be scrollable when data cards overflows
cy.get(Locators.MSScrollable).should("exist");
cy.get(`${Locators.MSCRotatedVerticalBox} button`)
.click()
.get(
`${Locators.DECChoiceFieldGroup} label:contains(${dataShape.modelStatisticsData?.defaultYAxis})`
)
.click();
cy.get(Locators.ApplyButton).click();
cy.get(`${Locators.MSCRotatedVerticalBox}`).contains(
dataShape.modelStatisticsData?.defaultYAxis || "Cohort"
);
cy.get(Locators.MSSideBarCards).should(
"have.length",
dataShape.modelStatisticsData?.cohortDropDownValues
? dataShape.modelStatisticsData?.cohortDropDownValues.length
: 0
);
});
it("Should have dropdown to select cohort when y axis is changed to different value than cohort", () => {
createCohort();
cy.get(`${Locators.MSCRotatedVerticalBox} button`)
.click()
.get(
`${Locators.DECChoiceFieldGroup} label:contains(${dataShape.modelStatisticsData?.yAxisNewPanelValue})`
)
.click();
cy.get(Locators.ApplyButton).click();
cy.get(`${Locators.MSCRotatedVerticalBox}`).contains(
dataShape.modelStatisticsData?.yAxisNewValue || "age"
);
// dropdown contains newly created cohort
cy.get(Locators.MSCohortDropdown).click();
cy.get(Locators.MSDropdownOptions).should("exist");
cy.get(Locators.MSCohortDropdown).click();
// Chart contains newly created cohort
cy.get(`${Locators.MSCRotatedVerticalBox} button`)
.click()
.get(
`${Locators.DECChoiceFieldGroup} label:contains(${dataShape.modelStatisticsData?.defaultYAxis})`
)
.click();
cy.get(Locators.ApplyButton).click();
cy.get(`${Locators.MSCRotatedVerticalBox}`).contains(
dataShape.modelStatisticsData?.defaultYAxis || "Cohort"
);
cy.get(Locators.MSYAxisPoints)
.last()
.should("contain", "CohortCreateE2E");
});
});
}

Просмотреть файл

@ -17,7 +17,6 @@ import {
MissingParametersPlaceholder,
defaultModelAssessmentContext,
ModelAssessmentContext,
OverallMetricChart,
BinaryClassificationMetrics,
RegressionMetrics,
JointDataset,
@ -48,7 +47,6 @@ import { ProbabilityDistributionChart } from "./ProbabilityDistributionChart";
import { getSelectableMetrics } from "./StatsTableUtils";
interface IModelOverviewProps {
showNewModelOverviewExperience: boolean;
telemetryHook?: (message: ITelemetryEvent) => void;
}
@ -266,247 +264,231 @@ export class ModelOverview extends React.Component<
tokens={{ childrenGap: "10px" }}
id="ModelOverview"
>
{!this.props.showNewModelOverviewExperience && (
<>
<Text variant="medium" className={classNames.descriptionText}>
{localization.Interpret.ModelPerformance.helperText}
<Stack tokens={{ childrenGap: "10px" }}>
<Text
variant="medium"
className={classNames.descriptionText}
id="modelOverviewDescription"
>
{localization.ModelAssessment.ModelOverview.topLevelDescription}
</Text>
<Pivot
onLinkClick={this.handleViewPivot}
id="modelOverviewCohortViewSelector"
>
<PivotItem
headerText={
localization.ModelAssessment.ModelOverview
.dataCohortsChartSelectionHeader
}
itemKey={datasetCohortViewPivotKey}
/>
<PivotItem
headerText={
localization.ModelAssessment.ModelOverview
.disaggregatedAnalysisHeatmapHeader
}
itemKey={disaggregatedAnalysisPivotKey}
/>
</Pivot>
{!this.state.datasetCohortViewIsVisible && (
<Text className={classNames.descriptionText}>
{
localization.ModelAssessment.ModelOverview
.featureBasedViewDescription
}
</Text>
<OverallMetricChart telemetryHook={this.props.telemetryHook} />
</>
)}
{this.props.showNewModelOverviewExperience && (
<Stack tokens={{ childrenGap: "10px" }}>
<Text
variant="medium"
className={classNames.descriptionText}
id="modelOverviewDescription"
)}
<Stack horizontal tokens={{ childrenGap: "10px" }}>
<ComboBox
id="modelOverviewMetricSelection"
placeholder={
localization.ModelAssessment.ModelOverview
.metricSelectionDropdownPlaceholder
}
label={localization.ModelAssessment.ModelOverview.metricsDropdown}
selectedKey={this.state.selectedMetrics}
options={selectableMetrics}
onChange={this.onMetricSelectionChange}
multiSelect
className={classNames.dropdown}
styles={FluentUIStyles.limitedSizeMenuDropdown}
/>
<ActionButton
className={classNames.configurationActionButton}
onClick={this.onClickMetricsConfiguration}
iconProps={{ iconName: "ColumnOptions" }}
>
{localization.ModelAssessment.ModelOverview.topLevelDescription}
</Text>
<Pivot
onLinkClick={this.handleViewPivot}
id="modelOverviewCohortViewSelector"
>
<PivotItem
headerText={
localization.ModelAssessment.ModelOverview
.dataCohortsChartSelectionHeader
}
itemKey={datasetCohortViewPivotKey}
/>
<PivotItem
headerText={
localization.ModelAssessment.ModelOverview
.disaggregatedAnalysisHeatmapHeader
}
itemKey={disaggregatedAnalysisPivotKey}
/>
</Pivot>
{!this.state.datasetCohortViewIsVisible && (
<Text className={classNames.descriptionText}>
{
localization.ModelAssessment.ModelOverview
.featureBasedViewDescription
}
</Text>
)}
{
localization.ModelAssessment.ModelOverview
.helpMeChooseMetricsButton
}
</ActionButton>
</Stack>
{!this.state.datasetCohortViewIsVisible && (
<Stack horizontal tokens={{ childrenGap: "10px" }}>
<ComboBox
id="modelOverviewMetricSelection"
id="modelOverviewFeatureSelection"
componentRef={this.featureComboBoxRef}
placeholder={
localization.ModelAssessment.ModelOverview
.metricSelectionDropdownPlaceholder
.featureSelectionDropdownPlaceholder
}
label={
localization.ModelAssessment.ModelOverview.metricsDropdown
localization.ModelAssessment.ModelOverview.featuresDropdown
}
selectedKey={this.state.selectedMetrics}
options={selectableMetrics}
onChange={this.onMetricSelectionChange}
selectedKey={this.state.selectedFeatures}
options={featureSelectionOptions}
onChange={this.onFeatureSelectionChange}
multiSelect
className={classNames.dropdown}
styles={FluentUIStyles.limitedSizeMenuDropdown}
/>
<ActionButton
id="modelOverviewFeatureConfigurationActionButton"
className={classNames.configurationActionButton}
onClick={this.onClickMetricsConfiguration}
onClick={this.onClickFeatureConfiguration}
iconProps={{ iconName: "ColumnOptions" }}
>
{
localization.ModelAssessment.ModelOverview
.helpMeChooseMetricsButton
.helpMeChooseFeaturesButton
}
</ActionButton>
</Stack>
{!this.state.datasetCohortViewIsVisible && (
<Stack horizontal tokens={{ childrenGap: "10px" }}>
<ComboBox
id="modelOverviewFeatureSelection"
componentRef={this.featureComboBoxRef}
placeholder={
localization.ModelAssessment.ModelOverview
.featureSelectionDropdownPlaceholder
}
label={
localization.ModelAssessment.ModelOverview.featuresDropdown
}
selectedKey={this.state.selectedFeatures}
options={featureSelectionOptions}
onChange={this.onFeatureSelectionChange}
multiSelect
className={classNames.dropdown}
styles={FluentUIStyles.limitedSizeMenuDropdown}
/>
<ActionButton
id="modelOverviewFeatureConfigurationActionButton"
className={classNames.configurationActionButton}
onClick={this.onClickFeatureConfiguration}
iconProps={{ iconName: "ColumnOptions" }}
>
)}
{(showHeatmapToggleInDatasetCohortView ||
showHeatmapToggleInFeatureCohortView) && (
<Toggle
id="modelOverviewHeatmapVisualDisplayToggle"
checked={this.state.showHeatmapColors}
label={
localization.ModelAssessment.ModelOverview
.visualDisplayToggleLabel
}
inlineLabel
onChange={this.onVisualDisplayToggleChange}
/>
)}
{this.state.datasetCohortViewIsVisible ? (
<DatasetCohortStatsTable
selectableMetrics={selectableMetrics}
selectedMetrics={this.state.selectedMetrics}
showHeatmapColors={this.state.showHeatmapColors}
/>
) : (
<>
{this.state.selectedFeatures.length === 0 && (
<MissingParametersPlaceholder>
{
localization.ModelAssessment.ModelOverview
.helpMeChooseFeaturesButton
.disaggregatedAnalysisFeatureSelectionPlaceholder
}
</ActionButton>
</Stack>
)}
{(showHeatmapToggleInDatasetCohortView ||
showHeatmapToggleInFeatureCohortView) && (
<Toggle
id="modelOverviewHeatmapVisualDisplayToggle"
checked={this.state.showHeatmapColors}
label={
localization.ModelAssessment.ModelOverview
.visualDisplayToggleLabel
}
inlineLabel
onChange={this.onVisualDisplayToggleChange}
/>
)}
{this.state.datasetCohortViewIsVisible ? (
<DatasetCohortStatsTable
selectableMetrics={selectableMetrics}
selectedMetrics={this.state.selectedMetrics}
showHeatmapColors={this.state.showHeatmapColors}
/>
) : (
<>
{this.state.selectedFeatures.length === 0 && (
<MissingParametersPlaceholder>
{
</MissingParametersPlaceholder>
)}
{this.state.selectedFeatures.length > 0 && (
<>
<Text
className={classNames.generalSemiBoldText}
id="modelOverviewDisaggregatedAnalysisBaseCohortDisclaimer"
>
{localization.formatString(
localization.ModelAssessment.ModelOverview
.disaggregatedAnalysisFeatureSelectionPlaceholder
}
</MissingParametersPlaceholder>
)}
{this.state.selectedFeatures.length > 0 && (
<>
<Text
className={classNames.generalSemiBoldText}
id="modelOverviewDisaggregatedAnalysisBaseCohortDisclaimer"
.disaggregatedAnalysisBaseCohortDislaimer,
this.context.baseErrorCohort.cohort.name
)}
</Text>
{this.context.baseErrorCohort.cohort.filters.length +
this.context.baseErrorCohort.cohort.compositeFilters
.length >
0 && (
<MessageBar
id="modelOverviewDisaggregatedAnalysisBaseCohortWarning"
className={classNames.descriptionText}
>
{localization.formatString(
localization.ModelAssessment.ModelOverview
.disaggregatedAnalysisBaseCohortDislaimer,
.disaggregatedAnalysisBaseCohortWarning,
localization.ErrorAnalysis.Cohort.defaultLabel,
this.context.baseErrorCohort.cohort.name
)}
</Text>
{this.context.baseErrorCohort.cohort.filters.length +
this.context.baseErrorCohort.cohort.compositeFilters
.length >
0 && (
<MessageBar
id="modelOverviewDisaggregatedAnalysisBaseCohortWarning"
className={classNames.descriptionText}
>
{localization.formatString(
localization.ModelAssessment.ModelOverview
.disaggregatedAnalysisBaseCohortWarning,
localization.ErrorAnalysis.Cohort.defaultLabel,
this.context.baseErrorCohort.cohort.name
)}
</MessageBar>
)}
</>
)}
<DisaggregatedAnalysisTable
selectableMetrics={selectableMetrics}
selectedMetrics={this.state.selectedMetrics}
selectedFeatures={this.state.selectedFeatures}
featureBasedCohorts={featureBasedCohorts}
showHeatmapColors={this.state.showHeatmapColors}
/>
</>
)}
<ChartConfigurationFlyout
isOpen={this.state.chartConfigurationIsVisible}
onDismissFlyout={this.onDismissChartConfigurationFlyout}
datasetCohorts={this.context.errorCohorts}
featureBasedCohorts={featureBasedCohorts}
selectedDatasetCohorts={this.state.selectedDatasetCohorts}
selectedFeatureBasedCohorts={
this.state.selectedFeatureBasedCohorts
}
updateCohortSelection={this.updateCohortSelection}
datasetCohortViewIsSelected={
this.state.datasetCohortChartIsVisible
}
/>
<FeatureConfigurationFlyout
isOpen={this.state.featureConfigurationIsVisible}
onDismissFlyout={this.onDismissFeatureConfigurationFlyout}
selectedFeatures={this.state.selectedFeatures}
numberOfContinuousFeatureBins={
this.state.selectedFeaturesContinuousFeatureBins
}
updateSelectedFeatures={this.onFeatureConfigurationChange}
/>
<MetricConfigurationFlyout
isOpen={this.state.metricConfigurationIsVisible}
onDismissFlyout={() => {
this.setState({ metricConfigurationIsVisible: false });
}}
selectedMetrics={this.state.selectedMetrics}
updateSelectedMetrics={this.onMetricConfigurationChange}
selectableMetrics={selectableMetrics}
/>
{someCohortSelected && (
<Pivot id="modelOverviewChartPivot">
{this.context.modelMetadata.modelType === ModelTypes.Binary && (
<PivotItem
headerText={
localization.ModelAssessment.ModelOverview
.probabilityDistributionPivotItem
}
>
<ProbabilityDistributionChart
onChooseCohorts={this.onChooseCohorts}
cohorts={chartCohorts}
telemetryHook={this.props.telemetryHook}
onToggleChange={this.onSplineToggleChange}
showSplineChart={this.state.showSplineChart}
/>
</PivotItem>
)}
</MessageBar>
)}
</>
)}
<DisaggregatedAnalysisTable
selectableMetrics={selectableMetrics}
selectedMetrics={this.state.selectedMetrics}
selectedFeatures={this.state.selectedFeatures}
featureBasedCohorts={featureBasedCohorts}
showHeatmapColors={this.state.showHeatmapColors}
/>
</>
)}
<ChartConfigurationFlyout
isOpen={this.state.chartConfigurationIsVisible}
onDismissFlyout={this.onDismissChartConfigurationFlyout}
datasetCohorts={this.context.errorCohorts}
featureBasedCohorts={featureBasedCohorts}
selectedDatasetCohorts={this.state.selectedDatasetCohorts}
selectedFeatureBasedCohorts={this.state.selectedFeatureBasedCohorts}
updateCohortSelection={this.updateCohortSelection}
datasetCohortViewIsSelected={this.state.datasetCohortChartIsVisible}
/>
<FeatureConfigurationFlyout
isOpen={this.state.featureConfigurationIsVisible}
onDismissFlyout={this.onDismissFeatureConfigurationFlyout}
selectedFeatures={this.state.selectedFeatures}
numberOfContinuousFeatureBins={
this.state.selectedFeaturesContinuousFeatureBins
}
updateSelectedFeatures={this.onFeatureConfigurationChange}
/>
<MetricConfigurationFlyout
isOpen={this.state.metricConfigurationIsVisible}
onDismissFlyout={() => {
this.setState({ metricConfigurationIsVisible: false });
}}
selectedMetrics={this.state.selectedMetrics}
updateSelectedMetrics={this.onMetricConfigurationChange}
selectableMetrics={selectableMetrics}
/>
{someCohortSelected && (
<Pivot id="modelOverviewChartPivot">
{this.context.modelMetadata.modelType === ModelTypes.Binary && (
<PivotItem
headerText={
localization.ModelAssessment.ModelOverview
.metricsVisualizationsPivotItem
.probabilityDistributionPivotItem
}
>
<ModelOverviewMetricChart
<ProbabilityDistributionChart
onChooseCohorts={this.onChooseCohorts}
onApplyMetric={this.onApplyMetric}
selectableMetrics={selectableMetrics}
cohorts={chartCohorts}
cohortStats={labeledStatistics}
selectedMetric={this.state.selectedMetric}
telemetryHook={this.props.telemetryHook}
onToggleChange={this.onSplineToggleChange}
showSplineChart={this.state.showSplineChart}
/>
</PivotItem>
</Pivot>
)}
</Stack>
)}
)}
<PivotItem
headerText={
localization.ModelAssessment.ModelOverview
.metricsVisualizationsPivotItem
}
>
<ModelOverviewMetricChart
onChooseCohorts={this.onChooseCohorts}
onApplyMetric={this.onApplyMetric}
selectableMetrics={selectableMetrics}
cohorts={chartCohorts}
cohortStats={labeledStatistics}
selectedMetric={this.state.selectedMetric}
/>
</PivotItem>
</Pivot>
)}
</Stack>
</Stack>
);
}

Просмотреть файл

@ -28,7 +28,6 @@ import * as React from "react";
import { AddTabButton } from "../../AddTabButton";
import {
isFlightActive,
newModelOverviewExperienceFlight,
dataBalanceExperienceFlight
} from "../../FeatureFlights";
import { GlobalTabKeys } from "../../ModelAssessmentEnums";
@ -183,13 +182,7 @@ export class TabsView extends React.PureComponent<
}
</Text>
</h3>
<ModelOverview
showNewModelOverviewExperience={isFlightActive(
newModelOverviewExperienceFlight,
this.context.featureFlights
)}
telemetryHook={this.props.telemetryHook}
/>
<ModelOverview telemetryHook={this.props.telemetryHook} />
</>
)}
{t.key === GlobalTabKeys.DataAnalysisTab && (

Просмотреть файл

@ -1,15 +1,11 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
export const newModelOverviewExperienceFlight = "newModelOverviewExperience";
export const dataBalanceExperienceFlight = "dataBalanceExperience";
export const featureFlightSeparator = "&";
// add more entries for new feature flights
export const featureFlights = [
newModelOverviewExperienceFlight,
dataBalanceExperienceFlight
];
export const featureFlights = [dataBalanceExperienceFlight];
export function parseFeatureFlights(featureFlights?: string): string[] {
if (featureFlights) {