def UpdateSheet(self): self.tableClinicalStatistic.clear() self.tableClinicalStatistic.setSortingEnabled(False) if self.comboSheet.currentText() == TRAIN: df = self.sheet_dict[TRAIN] elif self.comboSheet.currentText() == CV_VAL: df = self.sheet_dict[CV_VAL] elif self.comboSheet.currentText() == TEST: df = self.sheet_dict[TEST] else: mylog.error('Wrong key in the result table, or may click clear') return df.sort_index(inplace=True) self.tableClinicalStatistic.setRowCount(df.shape[0]) self.tableClinicalStatistic.setColumnCount(df.shape[1] + 1) headerlabels = df.columns.tolist() headerlabels.insert(0, 'Models Name') self.tableClinicalStatistic.setHorizontalHeaderLabels(headerlabels) for row_index in range(df.shape[0]): for col_index in range(df.shape[1] + 1): if col_index == 0: self.tableClinicalStatistic.setItem( row_index, col_index, QTableWidgetItem(df.index[row_index])) else: self.tableClinicalStatistic.setItem( row_index, col_index, QTableWidgetItem(str(df.iloc[row_index, col_index - 1]))) self.tableClinicalStatistic.setSortingEnabled(True)
def ShowOneResult(self): if not self.tableClinicalStatistic.selectedIndexes(): return None index = self.tableClinicalStatistic.selectedIndexes()[0] row = index.row() one_item = self.tableClinicalStatistic.item(row, 0) pipeline_name = str(one_item.text()) normalizer, dr, fs, fn, fitter = pipeline_name.split('_') fitter_folder = os.path.join(self._root_folder, normalizer, dr, fs + '_' + fn, fitter) self._current_fitter.Load(fitter_folder) self.textEditModelDescription.setText(self._current_fitter.Summary()) try: if CheckTextInCombo(pipeline_name, self.comboSurvivalModel): self.comboSurvivalModel.setCurrentText(pipeline_name) self.UpdateSurvivalCurve() part_name = self._FullName2PartName(pipeline_name) if CheckTextInCombo(part_name, self.comboCindexModel): self.comboCindexModel.setCurrentText(part_name) self.UpdateFeature() if CheckTextInCombo(pipeline_name, self.comboModelContribution): self.comboModelContribution.setCurrentText(pipeline_name) self.UpdateFeature() except Exception as e: mylog.error(e)
def SaveFigure(self): dlg = QFileDialog() dlg.setFileMode(QFileDialog.DirectoryOnly) dlg.setOption(QFileDialog.ShowDirsOnly) if dlg.exec_(): store_folder = dlg.selectedFiles()[0] try: self.canvasSurvival.getFigure().savefig(os.path.join( store_folder, 'SurvivalCurve.eps'), dpi=1200) self.canvasSurvival.getFigure().savefig(os.path.join( store_folder, 'SurvivalCurve.jpg'), dpi=300) except Exception as e: mylog.error('Saving Survival Curve {}'.format(e.__str__())) QMessageBox.about( self, 'Save Figure Failed', 'There is no SurvivalCurve figure.\n' + e.__str__()) try: self.canvasFeature.getFigure().savefig(os.path.join( store_folder, 'Feature Contribution.eps'), dpi=1200) self.canvasFeature.getFigure().savefig(os.path.join( store_folder, 'Feature Contribution.jpg'), dpi=300) except Exception as e: mylog.error('Saving Feature Contribution {}'.format( e.__str__())) QMessageBox.about( self, 'Save Figure Failed', 'There is no Feature Contribution figure.\n' + e.__str__())
def LoadReducer(self, store_folder): with open(os.path.join(store_folder, '{}.csv'.format(TRANSFORM_TYPE_SUB_FEATURES)), 'r', newline='') as file: reader = csv.reader(file) for row in reader: if row[0] == TRANSFORM_TYPE: assert(row [1] == TRANSFORM_TYPE_SUB) elif row[0] == TRANSFORM_TYPE_SUB_FEATURES: self.info = row[1:] else: mylog.error('The first work of the dimension reducer file is not correct.') raise ValueError
def Transform(self, dc: DataContainer, store_folder=None, store_key=None): for sub_feature in self.sub_features: if sub_feature not in dc.feature_name: mylog.error('DataContainer does not have the sub feature') raise KeyError new_dc = FeatureSelector().SelectByName(dc, self.sub_features) if store_folder is not None and store_key is not None: new_dc.Save(os.path.join(store_folder, '{}_reduced_features.csv'.format(store_key))) return new_dc
def LoadResult(self): dlg = QFileDialog() dlg.setFileMode(QFileDialog.DirectoryOnly) dlg.setOption(QFileDialog.ShowDirsOnly) if dlg.exec_(): self._root_folder = dlg.selectedFiles()[0] if not os.path.exists(self._root_folder): return try: if self.sae.LoadResult(self._root_folder): self.lineEditResultPath.setText(self._root_folder) self.SetResultDescription() self.SetResultTable() self.InitialUi() self.buttonSaveFigure.setEnabled(True) self.UpdateFeature() self.buttonClearResult.setEnabled(True) self.buttonLoadResult.setEnabled(False) # self.buttonGenerateDescription.setEnabled(True) self.radioSurvivalSplitDataset.setEnabled(True) self.radioSurvivalSplitFeature.setEnabled(True) self.radioContribution.setEnabled(True) self.radioVariance.setEnabled(True) self.checkSurvivalKM.setEnabled(True) self.radioSurvivalSplitDataset.setChecked(True) self.radioContribution.setChecked(True) self.UpdateFeature() self.UpdateSurvival() self._is_loading = True else: QMessageBox().about( self, "Load Failed", "The results were built by SAE with the previous version and can not be " "loaded.") except Exception as ex: QMessageBox.about(self, "Load Error", ex.__str__()) mylog.error('Load Error, The reason is ' + traceback.format_exception(ex)) self.ClearAll() raise ex
def MakePipelines(self): self.__normalizers = [] if self.checkNormalizeNone.isChecked(): self.__normalizers.append(NormalizerNone) if self.checkNormalizeMinMax.isChecked(): self.__normalizers.append(NormalizerMinMax) if self.checkNormalizeZscore.isChecked(): self.__normalizers.append(NormalizerZscore) if self.checkNormalizeMean.isChecked(): self.__normalizers.append(NormalizerMean) self.__dimension_reducers = [] if self.checkDimensionReduceNone.isChecked(): self.__dimension_reducers.append(DimensionReducerNone()) if self.checkDimensionReducePCC.isChecked(): self.__dimension_reducers.append(DimensionReducerPcc()) self.__feature_selectors = [] if self.checkFeatureSelectorNone.isChecked(): self.__feature_selectors.append(FeatureSelectorAll) if self.checkFeatureSelectorCluster.isChecked(): self.__feature_selectors.append(FeatureSelectorCluster) self.__feature_numbers = np.arange(self.spinBoxMinFeatureNumber.value(), self.spinBoxMaxFeatureNumber.value() + 1).tolist() self.__fitters = [] if self.checkCoxPH.isChecked(): self.__fitters.append(CoxPH()) # if self.checkAalen.isChecked(): # self.__fitters.append(AalenAdditive()) if len(self.__fitters) == 0: mylog.error('Process classifier list length is zero.') return False cv = CrossValidation(k=int(self.spinCvFold.value())) self.pipeline_manager.SetCV(cv) self.pipeline_manager.SetNormalizers(self.__normalizers) self.pipeline_manager.SetReducers(self.__dimension_reducers) self.pipeline_manager.SetFeatureNumbers(self.__feature_numbers) self.pipeline_manager.SetFeatureSelectors(self.__feature_selectors) self.pipeline_manager.SetFitters(self.__fitters) return True
def Run(self): if self.train_dc.IsEmpty(): QMessageBox.about(self, '', 'Training data is empty.') mylog.warning('Training data is empty.') return dlg = QFileDialog() dlg.setFileMode(QFileDialog.DirectoryOnly) dlg.setOption(QFileDialog.ShowDirsOnly) if dlg.exec_(): store_folder = dlg.selectedFiles()[0] if len(os.listdir(store_folder)) > 0: reply = QMessageBox.question(self, 'Continue?', 'The folder is not empty, if you click Yes, ' 'the data would be clear in this folder', QMessageBox.Yes, QMessageBox.No) if reply == QMessageBox.Yes: try: for file in os.listdir(store_folder): if os.path.isdir(os.path.join(store_folder, file)): shutil.rmtree(os.path.join(store_folder, file)) else: os.remove(os.path.join(store_folder, file)) except PermissionError: mylog.error('Permission Error: {}'.format(store_folder)) QMessageBox().about(self, 'Warning', 'Is there any opened files?') return except OSError: mylog.error('Permission Error: {}'.format(store_folder)) QMessageBox().about(self, 'Warning', 'Is there any opened files?') return else: return if self.MakePipelines(): self.thread.moveToThread(QThread()) self.thread.SetProcessForm(self, store_folder) self.thread.signal.connect(self.textEditVerbose.setPlainText) self.thread.start() self.SetLoadState(False) self.SetRunState(False) else: mylog.error('Make pipeline failed. Pipeline must include Fitter and CV method.') QMessageBox.about(self, 'Pipeline Error', 'Pipeline must include Fitter and CV method')
def run(self): self._process_form.pipeline_manager.SaveInfo(self.store_folder) try: for total, num, group in self._process_form.pipeline_manager.RunCV( self._process_form.train_dc, self.store_folder): text = "Cross Validation:\nGroup {}: {} / {}".format(int(group), num, total) self.signal.emit(text) except Exception as e: print(traceback.format_exc()) mylog.error('Thread RunCV Failed: ', e.__str__()) try: for total, num in self._process_form.pipeline_manager.EstimateCV( self.store_folder, self._process_form.train_dc.event_name, self._process_form.train_dc.duration_name): text = "Cross Validation:\nDone.\n\n" \ "Merging CV Results:\n{} / {}".format(num, total) self.signal.emit(text) except Exception as e: mylog.error('Thread MergeCV Result Failed: ', e.__str__()) try: for total, num in self._process_form.pipeline_manager.RunWithoutCV(self._process_form.train_dc, self._process_form.test_dc, self.store_folder): text = "Corss Validation Done.\n\nCV Result Merge Done\n\n" \ "Model Developing:\n{} / {}".format(num, total) self.signal.emit(text) except Exception: mylog.error("Thread RunWithoutCV Failed: ", e.__str__()) text = "Model Developing:\nDone.\n\nCross Validation:\nDone.\n\nMerging CV Results:\nDone.\n" self.signal.emit(text) self._process_form.SetLoadState(True) self._process_form.SetRunState(True)
def LoadData(self): if self.lineEditTrainingData.text(): try: self.train_dc.Load(self.lineEditTrainingData.text(), self.event_name, self.duration_name) mylog.info('Open CSV file ' + self.lineEditTrainingData.text() + ' succeed.') self.spinBoxMaxFeatureNumber.setValue(len(self.train_dc.feature_name)) except OSError as reason: message = 'Open SCV file Error, The reason is ' + str(reason) mylog.error(message) QMessageBox.information(self, 'Error', message) return except ValueError: message = 'Open SCV file ' + self.lineEditTrainingData.text() + ' Failed. because of value error.' mylog.error(message) QMessageBox.information(self, 'Error', message) return except Exception as e: message = 'Unexpected Error: {}'.format(e.__str__()) mylog.error(message) QMessageBox.information(self, 'Error', message) return if self.lineEditTestingData.text(): try: self.test_dc.Load(self.lineEditTestingData.text(), self.event_name, self.duration_name) mylog.info('Open CSV file ' + self.lineEditTestingData.text() + ' succeed.') except OSError as reason: message = 'Open SCV file Error, The reason is ' + str(reason) mylog.error(message) QMessageBox.information(self, 'Error', message) return except ValueError: message = 'Open SCV file ' + self.lineEditTrainingData.text() + ' Failed. because of value error.' mylog.error(message) QMessageBox.information(self, 'Error', message) return except KeyError: message = 'The event key {} and duration key {} do not exist in testing data set.'.format( self.comboEvent.currentText(), self.comboDuration.currentText() ) mylog.error(message) QMessageBox.information(self, 'Error', message) return except Exception as e: message = 'Unexpected Error: {}'.format(e.__str__()) mylog.error(message) QMessageBox.information(self, 'Error', message) return else: self.test_dc = DataContainer() self.SetRunState(True) self.spinCvFold.setMaximum(len(self.train_dc.case_name)) self.spinCvFold.setValue(5) self.UpdateDataDescription()