class OWRuleViewer(widget.OWWidget): name = "CN2 Rule Viewer" description = "Review rules induced from data." icon = "icons/CN2RuleViewer.svg" priority = 1140 keywords = [] class Inputs: data = Input("Data", Table) classifier = Input("Classifier", _RuleClassifier) class Outputs: selected_data = Output("Selected Data", Table, default=True) annotated_data = Output(ANNOTATED_DATA_SIGNAL_NAME, Table) compact_view = settings.Setting(False) want_basic_layout = True want_main_area = True want_control_area = False def __init__(self): self.data = None self.classifier = None self.selected = None self.model = CustomRuleViewerTableModel(parent=self) self.model.set_horizontal_header_labels([ "IF conditions", "", "THEN class", "Distribution", "Probabilities [%]", "Quality", "Length" ]) self.proxy_model = QSortFilterProxyModel(parent=self) self.proxy_model.setSourceModel(self.model) self.proxy_model.setSortRole(self.model.SortRole) self.view = gui.TableView(self, wordWrap=False) self.view.setModel(self.proxy_model) self.view.verticalHeader().setVisible(True) self.view.horizontalHeader().setStretchLastSection(False) self.view.selectionModel().selectionChanged.connect(self.commit) self.dist_item_delegate = DistributionItemDelegate(self) self.view.setItemDelegateForColumn(3, self.dist_item_delegate) self.mainArea.layout().setContentsMargins(0, 0, 0, 0) self.mainArea.layout().addWidget(self.view) bottom_box = gui.hBox(widget=self.mainArea, box=None, margin=0, spacing=0) original_order_button = QPushButton("Restore original order", autoDefault=False) original_order_button.setFixedWidth(180) bottom_box.layout().addWidget(original_order_button) original_order_button.clicked.connect(self.restore_original_order) gui.separator(bottom_box, width=5, height=0) gui.checkBox(widget=bottom_box, master=self, value="compact_view", label="Compact view", callback=self.on_update) @Inputs.data def set_data(self, data): self.data = data self.commit() @Inputs.classifier def set_classifier(self, classifier): self.classifier = classifier self.selected = None self.model.clear() if classifier is not None and hasattr(classifier, "rule_list"): self.model.set_vertical_header_labels( list(range(len(classifier.rule_list)))) self.dist_item_delegate.color_schema = \ [QColor(*c) for c in classifier.domain.class_var.colors] self.model.wrap(self.classifier.domain, self.classifier.rule_list) self.on_update() self.commit() def on_update(self): self._save_selected() self.model.set_compact_view(self.compact_view) if self.compact_view: self.view.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Interactive) # QHeaderView.Stretch else: self.view.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.view.resizeColumnsToContents() self.view.resizeRowsToContents() self._restore_selected() def _save_selected(self, actual=False): self.selected = None selection_model = self.view.selectionModel() if selection_model.hasSelection(): if not actual: selection = selection_model.selection() else: selection = self.proxy_model.mapSelectionToSource( selection_model.selection()) self.selected = sorted( set(index.row() for index in selection.indexes())) def _restore_selected(self): if self.selected is not None: selection_model = self.view.selectionModel() for row in self.selected: selection_model.select( self.proxy_model.index(row, 0), selection_model.Select | selection_model.Rows) def restore_original_order(self): self.proxy_model.sort(-1) def copy_to_clipboard(self): self._save_selected(actual=True) if self.selected is not None: output = "\n".join( [str(self.classifier.rule_list[i]) for i in self.selected]) QApplication.clipboard().setText(output) def commit(self): data_output = None self._save_selected(actual=True) selected_indices = [] data = self.data or self.classifier and self.classifier.instances if (self.selected is not None and data is not None and self.classifier is not None and data.domain.attributes == self.classifier.original_domain.attributes): status = np.ones(data.X.shape[0], dtype=bool) for i in self.selected: rule = self.classifier.rule_list[i] status &= rule.evaluate_data(data.X) selected_indices = status.nonzero()[0] data_output = data.from_table_rows(data, selected_indices) \ if len(selected_indices) else None self.Outputs.selected_data.send(data_output) self.Outputs.annotated_data.send( create_annotated_table(data, selected_indices)) def send_report(self): if self.classifier is not None: self.report_domain("Data domain", self.classifier.original_domain) self.report_items("Rule induction algorithm", self.classifier.params) self.report_table("Induced rules", self.view) def sizeHint(self): return QSize(800, 450)
class OWRuleViewer(widget.OWWidget): name = "CN2 Rule Viewer" description = "Review rules induced from data." icon = "icons/CN2RuleViewer.svg" priority = 1140 class Inputs: data = Input("Data", Table) classifier = Input("Classifier", _RuleClassifier) class Outputs: selected_data = Output("Selected Data", Table, default=True) annotated_data = Output(ANNOTATED_DATA_SIGNAL_NAME, Table) compact_view = settings.Setting(False) want_basic_layout = True want_main_area = True want_control_area = False def __init__(self): self.data = None self.classifier = None self.selected = None self.model = CustomRuleViewerTableModel(parent=self) self.model.set_horizontal_header_labels( ["IF conditions", "", "THEN class", "Distribution", "Probabilities [%]", "Quality", "Length"]) self.proxy_model = QSortFilterProxyModel(parent=self) self.proxy_model.setSourceModel(self.model) self.proxy_model.setSortRole(self.model.SortRole) self.view = gui.TableView(self, wordWrap=False) self.view.setModel(self.proxy_model) self.view.verticalHeader().setVisible(True) self.view.horizontalHeader().setStretchLastSection(False) self.view.selectionModel().selectionChanged.connect(self.commit) self.dist_item_delegate = DistributionItemDelegate(self) self.view.setItemDelegateForColumn(3, self.dist_item_delegate) self.mainArea.layout().setContentsMargins(0, 0, 0, 0) self.mainArea.layout().addWidget(self.view) bottom_box = gui.hBox(widget=self.mainArea, box=None, margin=0, spacing=0) original_order_button = QPushButton( "Restore original order", autoDefault=False) original_order_button.setFixedWidth(180) bottom_box.layout().addWidget(original_order_button) original_order_button.clicked.connect(self.restore_original_order) gui.separator(bottom_box, width=5, height=0) gui.checkBox(widget=bottom_box, master=self, value="compact_view", label="Compact view", callback=self.on_update) self.report_button.setFixedWidth(180) bottom_box.layout().addWidget(self.report_button) @Inputs.data def set_data(self, data): self.data = data self.commit() @Inputs.classifier def set_classifier(self, classifier): self.classifier = classifier self.selected = None self.model.clear() if classifier is not None and hasattr(classifier, "rule_list"): self.model.set_vertical_header_labels( list(range(len(classifier.rule_list)))) self.dist_item_delegate.color_schema = \ [QColor(*c) for c in classifier.domain.class_var.colors] self.model.wrap(self.classifier.domain, self.classifier.rule_list) self.on_update() self.commit() def on_update(self): self._save_selected() self.model.set_compact_view(self.compact_view) if self.compact_view: self.view.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Interactive) # QHeaderView.Stretch else: self.view.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.view.resizeColumnsToContents() self.view.resizeRowsToContents() self._restore_selected() def _save_selected(self, actual=False): self.selected = None selection_model = self.view.selectionModel() if selection_model.hasSelection(): selection = (selection_model.selection() if not actual else self.proxy_model.mapSelectionToSource( selection_model.selection())) self.selected = sorted(set(index.row() for index in selection.indexes())) def _restore_selected(self): if self.selected is not None: selection_model = self.view.selectionModel() for row in self.selected: selection_model.select(self.proxy_model.index(row, 0), selection_model.Select | selection_model.Rows) def restore_original_order(self): self.proxy_model.sort(-1) def copy_to_clipboard(self): self._save_selected(actual=True) if self.selected is not None: output = "\n".join([str(self.classifier.rule_list[i]) for i in self.selected]) QApplication.clipboard().setText(output) def commit(self): data_output = None self._save_selected(actual=True) selected_indices = [] data = self.data or self.classifier and self.classifier.instances if (self.selected is not None and data is not None and self.classifier is not None and data.domain.attributes == self.classifier.original_domain.attributes): status = np.ones(data.X.shape[0], dtype=bool) for i in self.selected: rule = self.classifier.rule_list[i] status &= rule.evaluate_data(data.X) selected_indices = status.nonzero()[0] data_output = data.from_table_rows(data, selected_indices) \ if len(selected_indices) else None self.Outputs.selected_data.send(data_output) self.Outputs.annotated_data.send(create_annotated_table(data, selected_indices)) def send_report(self): if self.classifier is not None: self.report_domain("Data domain", self.classifier.original_domain) self.report_items("Rule induction algorithm", self.classifier.params) self.report_table("Induced rules", self.view) def sizeHint(self): return QSize(800, 450)
class OWRuleViewer(widget.OWWidget): name = "CN2规则查看器(CN2 Rule Viewer)" description = "查看由数据引发的规则。" icon = "icons/CN2RuleViewer.svg" priority = 1140 keywords = ["cn2guize", "guize"] category = "可视化(Visualize)" class Inputs: data = Input("数据(Data)", Table, replaces=["Data"]) classifier = Input("分类器(Classifier)", _RuleClassifier, replaces=["Classifier"]) class Outputs: selected_data = Output("选定的数据(Selected Data)", Table, default=True, replaces=["Selected Data"]) annotated_data = Output("数据(Data)", Table, replaces=["Data"]) compact_view = settings.Setting(False) want_basic_layout = True want_main_area = False want_control_area = True def __init__(self): super().__init__() self.data = None self.classifier = None self.selected = None self.model = CustomRuleViewerTableModel(parent=self) self.model.set_horizontal_header_labels( ["如果条件", "", "然后类别", "分布", "概率 [%]", "质量", "长度"]) self.proxy_model = QSortFilterProxyModel(parent=self) self.proxy_model.setSourceModel(self.model) self.proxy_model.setSortRole(self.model.SortRole) self.view = gui.TableView(self, wordWrap=False) self.view.setModel(self.proxy_model) self.view.verticalHeader().setVisible(True) self.view.horizontalHeader().setStretchLastSection(False) self.view.selectionModel().selectionChanged.connect(self.commit) self.dist_item_delegate = DistributionItemDelegate(self) self.view.setItemDelegateForColumn(3, self.dist_item_delegate) self.controlArea.layout().addWidget(self.view) gui.checkBox( widget=self.buttonsArea, master=self, value="compact_view", label="紧凑型视图", callback=self.on_update, ) gui.rubber(self.buttonsArea) original_order_button = gui.button( self.buttonsArea, self, "恢复原始顺序", autoDefault=False, callback=self.restore_original_order, attribute=Qt.WA_LayoutUsesWidgetRect, ) original_order_button.clicked.connect(self.restore_original_order) @Inputs.data def set_data(self, data): self.data = data self.commit() @Inputs.classifier def set_classifier(self, classifier): self.classifier = classifier self.selected = None self.model.clear() if classifier is not None and hasattr(classifier, "rule_list"): self.model.set_vertical_header_labels( list(range(len(classifier.rule_list)))) self.dist_item_delegate.color_schema = [ QColor(*c) for c in classifier.domain.class_var.colors ] self.model.wrap(self.classifier.domain, self.classifier.rule_list) self.on_update() self.commit() def on_update(self): self._save_selected() self.model.set_compact_view(self.compact_view) if self.compact_view: self.view.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Interactive) # QHeaderView.Stretch else: self.view.horizontalHeader().setSectionResizeMode( QHeaderView.ResizeToContents) self.view.resizeColumnsToContents() self.view.resizeRowsToContents() self._restore_selected() def _save_selected(self, actual=False): self.selected = None selection_model = self.view.selectionModel() if selection_model.hasSelection(): if not actual: selection = selection_model.selection() else: selection = self.proxy_model.mapSelectionToSource( selection_model.selection()) self.selected = sorted( set(index.row() for index in selection.indexes())) def _restore_selected(self): if self.selected is not None: selection_model = self.view.selectionModel() for row in self.selected: selection_model.select( self.proxy_model.index(row, 0), selection_model.Select | selection_model.Rows, ) def restore_original_order(self): self.proxy_model.sort(-1) def copy_to_clipboard(self): self._save_selected(actual=True) if self.selected is not None: output = "\n".join( [str(self.classifier.rule_list[i]) for i in self.selected]) QApplication.clipboard().setText(output) def commit(self): data_output = None self._save_selected(actual=True) selected_indices = [] data = self.data or self.classifier and self.classifier.instances if (self.selected is not None and data is not None and self.classifier is not None and data.domain.attributes == self.classifier.original_domain.attributes): status = np.ones(data.X.shape[0], dtype=bool) for i in self.selected: rule = self.classifier.rule_list[i] status &= rule.evaluate_data(data.X) selected_indices = status.nonzero()[0] data_output = (data.from_table_rows(data, selected_indices) if len(selected_indices) else None) self.Outputs.selected_data.send(data_output) self.Outputs.annotated_data.send( create_annotated_table(data, selected_indices)) def send_report(self): if self.classifier is not None: self.report_domain("Data domain", self.classifier.original_domain) self.report_items("Rule induction algorithm", self.classifier.params) self.report_table("Induced rules", self.view) def sizeHint(self): return QSize(800, 450)