Skip to content

Commit

Permalink
feat(#1144) allow multilabel records in weak supervision (#1233)
Browse files Browse the repository at this point in the history
* show button in sidebar

* allow multilabel

* show labels in summary

* fix lint

* remove unused methods

* show labels in summary table

* remove console.log

* use singular or plural for info message

* change info when dataset is multilabel

* fix fetch metrics call

* uri from labels array

* fix metrics URL

* change copy depend to selected labels number

* fix show "already saved rule" when are selected labels

* fix #1236

* prevent undefined rule

* fix "already saved rule" copy

* reset store logic

* fix: return stored rule

* allow multiple selection when the results are empty

* refactor: force document refresh after rule creation

* fix update metrics when rule has default labels

* labels visualization in rules summary

* display label block

* fix: small fix for load_rules in client

Co-authored-by: Francisco Aranda <francisco@recogn.ai>
Co-authored-by: dcfidalgo <david@recogn.ai>
  • Loading branch information
3 people committed Mar 16, 2022
1 parent 6d0bc55 commit 7deaf16
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 107 deletions.
6 changes: 1 addition & 5 deletions frontend/components/commons/sidebar/SidebarMenu.vue
Expand Up @@ -128,11 +128,7 @@ export default {
return this.dataset !== undefined;
},
showLabellingRules() {
return (
this.isDatasetView &&
!this.dataset.isMultiLabel &&
this.dataset.task === "TextClassification"
);
return this.isDatasetView && this.dataset.task === "TextClassification";
},
},
watch: {
Expand Down
29 changes: 12 additions & 17 deletions frontend/components/core/ReTableInfo.vue
Expand Up @@ -110,6 +110,11 @@
>
{{ itemValue(item, column) | percent }}
</span>
<span v-else-if="column.type === 'array'">
<p v-for="(arrayItem, index) in itemValue(item, column)" :key="index">
{{arrayItem}}{{index + 1 === itemValue(item, column).length ? '' : ','}}
</p>
</span>
<span v-else-if="column.type === 'object'">
<p
v-for="key in Object.keys(itemValue(item, column))"
Expand Down Expand Up @@ -448,9 +453,6 @@ export default {
border-bottom: none;
padding-top: 0;
padding-bottom: 0.2em;
// &:hover {
// background:transparent ;
// }
}
button:not(.re-button) {
cursor: pointer;
Expand Down Expand Up @@ -486,8 +488,6 @@ export default {
text-align: left;
margin-right: 1.5em;
flex: 1 1 0px;
// text-overflow: ellipsis;
// overflow: hidden;
&:nth-last-of-type(-n + 2) {
max-width: 120px;
}
Expand All @@ -497,9 +497,6 @@ export default {
&:nth-of-type(2) {
min-width: 30%;
}
// .task span {
// display: flex;
// }
&:first-child {
flex-shrink: 0;
min-width: 220px;
Expand All @@ -524,15 +521,6 @@ export default {
margin-top: 5em;
height: auto;
}
// &__item:not(.disabled) {
// &:hover,
// &:focus {
// background: $line-lighter-color;
// #{$this}__header & {
// background: transparent;
// }
// }
// }
&__actions {
position: absolute;
right: 2em;
Expand Down Expand Up @@ -593,6 +581,13 @@ export default {
font-weight: 600;
word-break: break-word;
}
.array {
p {
margin-top: 0;
margin-bottom: 0;
display: block;
}
}
.text {
color: $font-medium-color;
p {
Expand Down
Expand Up @@ -63,7 +63,7 @@ export default {
async query(newValue) {
await this.updateCurrentRule({
query: newValue,
label: (this.currentRule || {}).label,
labels: (this.currentRule || {}).labels,
});
},
},
Expand Down Expand Up @@ -91,19 +91,19 @@ export default {
},
},
methods: {
async updateCurrentRule({ query, label }) {
async updateCurrentRule({ query, labels }) {
if (!query) {
return await this.dataset.clearCurrentLabelingRule();
}
if (label) {
if (labels) {
await this.dataset.setCurrentLabelingRule({
query,
label,
labels,
});
} else {
await this.dataset.setCurrentLabelingRule({
query,
label: undefined,
labels: undefined,
});
}
this.saved = false;
Expand Down
Expand Up @@ -46,7 +46,7 @@
:id="label.class"
:key="`${label.class}`"
v-model="selectedLabelsVModel"
:allow-multiple="false"
:allow-multiple="dataset.isMultiLabel"
:label="label"
class="label-button"
:data-title="label.class"
Expand Down Expand Up @@ -95,6 +95,7 @@
import { mapActions } from "vuex";
import { DatasetViewSettings } from "@/models/DatasetViewSettings";
import { TextClassificationDataset } from "@/models/TextClassification";
import _ from "lodash";
import "assets/icons/info";
export default {
Expand Down Expand Up @@ -130,23 +131,29 @@ export default {
return this.dataset.getCurrentLabelingRuleMetrics() || {};
},
selectedLabel() {
if (this.selectedLabelsVModel !== undefined) {
return this.selectedLabelsVModel[0];
selectedLabels() {
if (this.selectedLabelsVModel.length) {
return this.selectedLabelsVModel;
}
},
ruleInfo() {
// TODO: We can improve this
const storedRule =
this.currentRule &&
this.dataset.findRuleByQuery(this.currentRule.query);
const storedRuleLabels = storedRule && storedRule.labels;
const queryWithLabelsIsStored = _.isEqual(
_.sortBy(storedRuleLabels),
_.sortBy(this.selectedLabels)
);
if (this.isSaved) {
return "The rule was saved";
}
if (
this.currentRule &&
this.selectedLabelsVModel.length &&
this.dataset.findRuleByQuery(this.currentRule.query, this.selectedLabel)
) {
return "This query with this label are already saved as rule";
if (this.selectedLabels && queryWithLabelsIsStored) {
return `This query with ${
this.selectedLabels.length > 1 ? "these labels" : "this label"
} are already saved as rule`;
}
},
coveredRecords() {
Expand Down Expand Up @@ -190,16 +197,21 @@ export default {
},
},
watch: {
selectedLabel(newValue) {
// Here send description too --> update Rule
this.$emit("update-rule", {
query: this.query,
label: newValue,
});
selectedLabels: {
handler: function (newValue) {
if (!_.isEqual(_.sortBy(newValue), _.sortBy(this.currentRule.labels))) {
// Here send description too --> update Rule
this.$emit("update-rule", {
query: this.query,
labels: newValue,
});
}
},
deep: true,
},
currentRule(newValue) {
if (newValue && newValue.label) {
this.selectedLabelsVModel = [newValue.label];
if (newValue && newValue.labels) {
this.selectedLabelsVModel = [...newValue.labels];
}
},
},
Expand All @@ -211,7 +223,7 @@ export default {
this.collapseLabels();
this.$emit("save-rule", {
query: this.currentRule.query,
label: this.selectedLabel,
labels: this.selectedLabels,
});
},
expandLabels() {
Expand Down
Expand Up @@ -79,7 +79,7 @@ export default {
class: "table-info__title",
type: "action",
},
{ name: "Label", field: "label", class: "text" },
{ name: "Labels", field: "labels", class: "array", type: "array" },
{
name: "Coverage",
field: "coverage",
Expand Down Expand Up @@ -158,7 +158,7 @@ export default {
name: r.description,
query: r.query,
kind: "select",
label: r.label,
labels: r.labels,
...this.metricsForRule(r),
created_at: r.created_at,
};
Expand Down Expand Up @@ -244,7 +244,7 @@ export default {
<style lang="scss" scoped>
.rules-management {
padding-left: 4em;
padding-top: 7em;
padding-top: 2em;
overflow: auto;
height: 100vh;
&__container {
Expand Down
Expand Up @@ -173,38 +173,6 @@ export default {
formatNumber(value) {
return isNaN(value) ? "-" : this.$options.filters.percent(value);
},
async getMetrics() {
this.metricsTotal = await this.getRulesMetrics({
dataset: this.dataset,
});
},
async getMetricsByRules() {
const responses = await Promise.all(
this.rules.map((rule) => {
return this.getRuleruleMetrics({
dataset: this.dataset,
query: rule.query,
label: rule.label,
});
})
);
responses.forEach((response, idx) => {
this.metricsByRules[this.rules[idx].query] = response;
});
},
async getruleMetrics() {
if (this.query !== undefined) {
const response = await this.getRuleruleMetrics({
dataset: this.dataset,
query: this.query,
label: this.activeLabel,
});
this.ruleMetrics = response;
} else {
this.ruleMetrics = {};
}
},
getValuesByMetricType(type) {
return Object.keys(this.metricsByRules).map((key) => {
return this.metricsByRules[key][type] || 0;
Expand Down

0 comments on commit 7deaf16

Please sign in to comment.