Ejemplo n.º 1
0
    def __init__(self, parent=None):
        self._root_folder = ''
        self._fae = FeatureAnalysisPipelines()
        self.sheet_dict = dict()
        self.logger = eclog(os.path.split(__file__)[-1]).GetLogger()
        self.__is_ui_ready = False

        super(VisualizationConnection, self).__init__(parent)
        self.setupUi(self)

        self.buttonLoadResult.clicked.connect(self.LoadAll)
        self.buttonClearResult.clicked.connect(self.ClearAll)
        self.buttonSave.clicked.connect(self.Save)
        self.buttonGenerateDescription.clicked.connect(self.GenerateDescription)

        self.__plt_roc = self.canvasROC.getFigure().add_subplot(111)
        self.__plt_plot = self.canvasPlot.getFigure().add_subplot(111)
        self.__contribution = self.canvasFeature.getFigure().add_subplot(111)

        # Update Sheet
        self.tableClinicalStatistic.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableClinicalStatistic.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.comboSheet.currentIndexChanged.connect(self.UpdateSheet)
        self.checkMaxFeatureNumber.stateChanged.connect(self.UpdateSheet)
        # self.tableClinicalStatistic.doubleClicked.connect(self.ShowOneResult)
        self.tableClinicalStatistic.itemSelectionChanged.connect(self.ShowOneResult)

        # Update ROC canvas
        self.comboNormalizer.currentIndexChanged.connect(self.UpdateROC)
        self.comboDimensionReduction.currentIndexChanged.connect(self.UpdateROC)
        self.comboFeatureSelector.currentIndexChanged.connect(self.UpdateROC)
        self.comboClassifier.currentIndexChanged.connect(self.UpdateROC)
        self.spinBoxFeatureNumber.valueChanged.connect(self.UpdateROC)
        self.checkROCCVTrain.stateChanged.connect(self.UpdateROC)
        self.checkROCCVValidation.stateChanged.connect(self.UpdateROC)
        self.checkROCTrain.stateChanged.connect(self.UpdateROC)
        self.checkROCTest.stateChanged.connect(self.UpdateROC)

        # Update Plot canvas
        self.comboPlotX.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotY.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotNormalizer.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotDimensionReduction.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotFeatureSelector.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotClassifier.currentIndexChanged.connect(self.UpdatePlot)
        self.spinPlotFeatureNumber.valueChanged.connect(self.UpdatePlot)

        self.checkPlotCVTrain.stateChanged.connect(self.UpdatePlot)
        self.checkPlotCVValidation.stateChanged.connect(self.UpdatePlot)
        self.checkPlotTrain.stateChanged.connect(self.UpdatePlot)
        # self.checkPlotTest.stateChanged.connect(self.UpdatePlot)

        # Update Contribution canvas
        self.radioContributionFeatureSelector.toggled.connect(self.UpdateContribution)
        self.radioContributionClassifier.toggled.connect(self.UpdateContribution)
        self.comboContributionNormalizor.currentIndexChanged.connect(self.UpdateContribution)
        self.comboContributionDimension.currentIndexChanged.connect(self.UpdateContribution)
        self.comboContributionFeatureSelector.currentIndexChanged.connect(self.UpdateContribution)
        self.comboContributionClassifier.currentIndexChanged.connect(self.UpdateContribution)
        self.spinContributeFeatureNumber.valueChanged.connect(self.UpdateContribution)
Ejemplo n.º 2
0
    def __init__(self, parent=None):
        self._root_folder = ''
        self._fae = FeatureAnalysisPipelines()
        self._training_data_container = DataContainer()
        self._testing_data_container = DataContainer()
        self._current_pipeline = OnePipeline()

        super(ReportConnection, self).__init__(parent)
        self.setupUi(self)

        self.buttonLoadTrainingData.clicked.connect(self.LoadTrainingData)
        self.buttonClearTrainingData.clicked.connect(self.ClearTrainingData)
        self.buttonLoadTestingData.clicked.connect(self.LoadTestingData)
        self.buttonClearTestingData.clicked.connect(self.ClearTestingData)

        self.buttonLoadResult.clicked.connect(self.LoadAll)
        self.buttonClearResult.clicked.connect(self.ClearAll)

        self.buttonGenerate.clicked.connect(self.Generate)

        self.__plt_roc = self.canvasROC.getFigure().add_subplot(111)

        # Update ROC canvas
        self.comboNormalizer.currentIndexChanged.connect(self.UpdateROC)
        self.comboDimensionReduction.currentIndexChanged.connect(
            self.UpdateROC)
        self.comboFeatureSelector.currentIndexChanged.connect(self.UpdateROC)
        self.comboClassifier.currentIndexChanged.connect(self.UpdateROC)
        self.spinBoxFeatureNumber.valueChanged.connect(self.UpdateROC)
        self.checkROCTrain.stateChanged.connect(self.UpdateROC)
        self.checkROCValidation.stateChanged.connect(self.UpdateROC)
        self.checkROCTest.stateChanged.connect(self.UpdateROC)

        self.SetPipelineStateButton(False)
Ejemplo n.º 3
0
    def __init__(self, parent=None):
        self.training_data_container = DataContainer()
        self.testing_data_container = DataContainer()
        self.fae = FeatureAnalysisPipelines()
        self.logger = eclog(os.path.split(__file__)[-1]).GetLogger()
        self.__process_normalizer_list = []
        self.__process_dimension_reduction_list = []
        self.__process_feature_selector_list = []
        self.__process_feature_number_list = []
        self.__process_classifier_list = []

        super(ProcessConnection, self).__init__(parent)
        self.setupUi(self)

        self.buttonLoadTrainingData.clicked.connect(self.LoadTrainingData)
        self.buttonLoadTestingData.clicked.connect(self.LoadTestingData)

        self.checkNormalizeUnit.clicked.connect(self.UpdatePipelineText)
        self.checkNormalizeZeroCenter.clicked.connect(self.UpdatePipelineText)
        self.checkNormalizeUnitWithZeroCenter.clicked.connect(
            self.UpdatePipelineText)
        self.checkNormalizationAll.clicked.connect(self.SelectAllNormalization)

        self.checkPCA.clicked.connect(self.UpdatePipelineText)
        self.checkRemoveSimilarFeatures.clicked.connect(
            self.UpdatePipelineText)
        self.checkPreprocessAll.clicked.connect(self.SelectAllPreprocess)

        self.spinBoxMinFeatureNumber.valueChanged.connect(
            self.MinFeatureNumberChange)
        self.spinBoxMaxFeatureNumber.valueChanged.connect(
            self.MaxFeatureNumberChange)

        self.checkANOVA.clicked.connect(self.UpdatePipelineText)
        self.checkRFE.clicked.connect(self.UpdatePipelineText)
        self.checkRelief.clicked.connect(self.UpdatePipelineText)
        self.checkMRMR.clicked.connect(self.UpdatePipelineText)
        self.checkFeatureSelectorAll.clicked.connect(
            self.SelectAllFeatureSelector)

        self.checkSVM.clicked.connect(self.UpdatePipelineText)
        self.checkLDA.clicked.connect(self.UpdatePipelineText)
        self.checkAE.clicked.connect(self.UpdatePipelineText)
        self.checkRF.clicked.connect(self.UpdatePipelineText)
        self.checkLogisticRegression.clicked.connect(self.UpdatePipelineText)
        self.checkLRLasso.clicked.connect(self.UpdatePipelineText)
        self.checkAdaboost.clicked.connect(self.UpdatePipelineText)
        self.checkDecisionTree.clicked.connect(self.UpdatePipelineText)
        self.checkNaiveBayes.clicked.connect(self.UpdatePipelineText)
        self.checkGaussianProcess.clicked.connect(self.UpdatePipelineText)
        self.checkClassifierAll.clicked.connect(self.SelectAllClassifier)

        self.radio5folder.clicked.connect(self.UpdatePipelineText)
        self.radio10Folder.clicked.connect(self.UpdatePipelineText)
        self.radioLOO.clicked.connect(self.UpdatePipelineText)

        self.buttonRun.clicked.connect(self.Run)

        self.UpdatePipelineText()
        self.SetStateButtonBeforeLoading(False)
Ejemplo n.º 4
0
    def __init__(self, parent=None):
        self._root_folder = ''
        self._fae = FeatureAnalysisPipelines()
        self.sheet_dict = dict()

        super(VisualizationConnection, self).__init__(parent)
        self.setupUi(self)

        self.buttonLoadResult.clicked.connect(self.LoadAll)
        self.buttonClearResult.clicked.connect(self.ClearAll)
        self.buttonSave.clicked.connect(self.Save)

        self.__plt_roc = self.canvasROC.getFigure().add_subplot(111)
        self.__plt_plot = self.canvasPlot.getFigure().add_subplot(111)
        self.__contribution = self.canvasFeature.getFigure().add_subplot(111)

        # Update Sheet
        self.comboSheet.currentIndexChanged.connect(self.UpdateSheet)
        self.checkMaxFeatureNumber.stateChanged.connect(self.UpdateSheet)

        # Update ROC canvas
        self.comboNormalizer.currentIndexChanged.connect(self.UpdateROC)
        self.comboDimensionReduction.currentIndexChanged.connect(self.UpdateROC)
        self.comboFeatureSelector.currentIndexChanged.connect(self.UpdateROC)
        self.comboClassifier.currentIndexChanged.connect(self.UpdateROC)
        self.spinBoxFeatureNumber.valueChanged.connect(self.UpdateROC)
        self.checkROCCVTrain.stateChanged.connect(self.UpdateROC)
        self.checkROCCVValidation.stateChanged.connect(self.UpdateROC)
        self.checkROCTrain.stateChanged.connect(self.UpdateROC)
        self.checkROCTest.stateChanged.connect(self.UpdateROC)

        # Update Plot canvas
        self.comboPlotX.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotY.currentIndexChanged.connect(self.UpdatePlot)
        self.checkPlotMaximum.stateChanged.connect(self.UpdatePlot)
        self.comboPlotNormalizer.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotDimensionReduction.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotFeatureSelector.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotClassifier.currentIndexChanged.connect(self.UpdatePlot)
        self.spinPlotFeatureNumber.valueChanged.connect(self.UpdatePlot)

        self.checkPlotCVTrain.stateChanged.connect(self.UpdatePlot)
        self.checkPlotCVValidation.stateChanged.connect(self.UpdatePlot)
        self.checkPlotTrain.stateChanged.connect(self.UpdatePlot)
        self.checkPlotTest.stateChanged.connect(self.UpdatePlot)

        # Update Contribution canvas
        self.checkContributionShow.stateChanged.connect(self.UpdateContribution)
        self.radioContributionFeatureSelector.toggled.connect(self.UpdateContribution)
        self.radioContributionClassifier.toggled.connect(self.UpdateContribution)
        self.comboContributionFeatureSelector.currentIndexChanged.connect(self.UpdateContribution)
        self.comboContributionClassifier.currentIndexChanged.connect(self.UpdateContribution)
        self.spinFeatureSelectorFeatureNumber.valueChanged.connect(self.UpdateContribution)
        self.spinClassifierFeatureNumber.valueChanged.connect(self.UpdateContribution)
Ejemplo n.º 5
0
    def __init__(self, parent=None):
        self.__training_data_container = DataContainer()
        self.__testing_data_container = DataContainer()
        self.__fae = FeatureAnalysisPipelines()

        self.__process_normalizer_list = []
        self.__process_dimension_reduction_list = []
        self.__process_feature_selector_list = []
        self.__process_feature_number_list = []
        self.__process_classifier_list = []

        super(ProcessConnection, self).__init__(parent)
        self.setupUi(self)

        self.buttonLoadTrainingData.clicked.connect(self.LoadTrainingData)
        self.buttonLoadTestingData.clicked.connect(self.LoadTestingData)

        self.checkNormalizeUnit.clicked.connect(self.UpdatePipelineText)
        self.checkNormalizeZeroCenter.clicked.connect(self.UpdatePipelineText)
        self.checkNormalizeUnitWithZeroCenter.clicked.connect(
            self.UpdatePipelineText)

        self.checkPCA.clicked.connect(self.UpdatePipelineText)
        self.checkRemoveSimilarFeatures.clicked.connect(
            self.UpdatePipelineText)

        self.spinBoxMinFeatureNumber.valueChanged.connect(
            self.MinFeatureNumberChange)
        self.spinBoxMaxFeatureNumber.valueChanged.connect(
            self.MaxFeatureNumberChange)

        self.checkANOVA.clicked.connect(self.UpdatePipelineText)
        self.checkRFE.clicked.connect(self.UpdatePipelineText)
        self.checkRelief.clicked.connect(self.UpdatePipelineText)

        self.checkSVM.clicked.connect(self.UpdatePipelineText)
        self.checkLDA.clicked.connect(self.UpdatePipelineText)
        self.checkAE.clicked.connect(self.UpdatePipelineText)
        self.checkRF.clicked.connect(self.UpdatePipelineText)

        self.buttonRun.clicked.connect(self.Run)

        self.UpdatePipelineText()
Ejemplo n.º 6
0
    def ClearAll(self):
        self.buttonLoadResult.setEnabled(True)
        self.buttonClearResult.setEnabled(False)

        self._fae = FeatureAnalysisPipelines()
        self.textEditDescription.setPlainText('')
        self.lineEditResultPath.setText('')
        self.InitialUi()

        self.checkROCTrain.setChecked(False)
        self.checkROCValidation.setChecked(False)
        self.checkROCTest.setChecked(False)

        self.spinBoxFeatureNumber.setValue(1)

        self.canvasROC.getFigure().clear()
        self.canvasROC.draw()

        self.SetPipelineStateButton(False)
Ejemplo n.º 7
0
class ProcessConnection(QWidget, Ui_Process):
    def __init__(self, parent=None):
        self.training_data_container = DataContainer()
        self.testing_data_container = DataContainer()
        self.fae = FeatureAnalysisPipelines()
        self.logger = eclog(os.path.split(__file__)[-1]).GetLogger()
        self.__process_normalizer_list = []
        self.__process_dimension_reduction_list = []
        self.__process_feature_selector_list = []
        self.__process_feature_number_list = []
        self.__process_classifier_list = []

        super(ProcessConnection, self).__init__(parent)
        self.setupUi(self)

        self.buttonLoadTrainingData.clicked.connect(self.LoadTrainingData)
        self.buttonLoadTestingData.clicked.connect(self.LoadTestingData)

        self.checkNormalizeUnit.clicked.connect(self.UpdatePipelineText)
        self.checkNormalizeZeroCenter.clicked.connect(self.UpdatePipelineText)
        self.checkNormalizeUnitWithZeroCenter.clicked.connect(self.UpdatePipelineText)
        self.checkNormalizationAll.clicked.connect(self.SelectAllNormalization)

        self.checkPCA.clicked.connect(self.UpdatePipelineText)
        self.checkRemoveSimilarFeatures.clicked.connect(self.UpdatePipelineText)
        self.checkPreprocessAll.clicked.connect(self.SelectAllPreprocess)

        self.spinBoxMinFeatureNumber.valueChanged.connect(self.MinFeatureNumberChange)
        self.spinBoxMaxFeatureNumber.valueChanged.connect(self.MaxFeatureNumberChange)

        self.checkANOVA.clicked.connect(self.UpdatePipelineText)
        self.checkRFE.clicked.connect(self.UpdatePipelineText)
        self.checkRelief.clicked.connect(self.UpdatePipelineText)
        self.checkFeatureSelectorAll.clicked.connect(self.SelectAllFeatureSelector)

        self.checkSVM.clicked.connect(self.UpdatePipelineText)
        self.checkLDA.clicked.connect(self.UpdatePipelineText)
        self.checkAE.clicked.connect(self.UpdatePipelineText)
        self.checkRF.clicked.connect(self.UpdatePipelineText)
        self.checkLogisticRegression.clicked.connect(self.UpdatePipelineText)
        self.checkLRLasso.clicked.connect(self.UpdatePipelineText)
        self.checkAdaboost.clicked.connect(self.UpdatePipelineText)
        self.checkDecisionTree.clicked.connect(self.UpdatePipelineText)
        self.checkNaiveBayes.clicked.connect(self.UpdatePipelineText)
        self.checkGaussianProcess.clicked.connect(self.UpdatePipelineText)
        self.checkClassifierAll.clicked.connect(self.SelectAllClassifier)

        self.radio5folder.clicked.connect(self.UpdatePipelineText)
        self.radio10Folder.clicked.connect(self.UpdatePipelineText)

        self.buttonRun.clicked.connect(self.Run)

        self.UpdatePipelineText()
        self.SetStateButtonBeforeLoading(False)

    def LoadTrainingData(self):
        dlg = QFileDialog()
        file_name, _ = dlg.getOpenFileName(self, 'Open CSV file', directory=r'C:\MyCode\FAE\Example', filter="csv files (*.csv)")
        try:
            self.training_data_container.Load(file_name)
            self.SetStateButtonBeforeLoading(True)
            self.lineEditTrainingData.setText(file_name)
            self.UpdateDataDescription()
            self.logger.info('Open CSV file ' + file_name + ' succeed.')
        except OSError as reason:
            self.logger.log('Open SCV file Error, The reason is ' + str(reason))
            print('出错啦!' + str(reason))
        except ValueError:
            self.logger.error('Open SCV file ' + file_name + ' Failed. because of value error.')
            QMessageBox.information(self, 'Error',
                                    'The selected training data mismatch.')


    def LoadTestingData(self):
        dlg = QFileDialog()
        file_name, _ = dlg.getOpenFileName(self, 'Open CSV file', filter="csv files (*.csv)")
        try:
            self.testing_data_container.Load(file_name)
            self.lineEditTestingData.setText(file_name)
            self.UpdateDataDescription()
            self.logger.info('Loading testing data ' + file_name + ' succeed.' )
        except OSError as reason:
            self.logger.log('Open SCV file Error, The reason is ' + str(reason))
            print('出错啦!' + str(reason))
        except ValueError:
            self.logger.error('Open SCV file ' + file_name + ' Failed. because of value error.')
            QMessageBox.information(self, 'Error',
                                    'The selected testing data mismatch.')

    def GenerateVerboseTest(self, normalizer_name, dimension_reduction_name, feature_selector_name, classifier_name, feature_num,
                       current_num, total_num):
        text = "Current:\n"

        text += "{:s} / ".format(normalizer_name)
        for temp in self.__process_normalizer_list:
            text += (temp.GetName() + ", ")
        text += '\n'

        text += "{:s} / ".format(dimension_reduction_name)
        for temp in self.__process_dimension_reduction_list:
            text += (temp.GetName() + ", ")
        text += '\n'

        text += "{:s} / ".format(feature_selector_name)
        for temp in self.__process_feature_selector_list:
            text += (temp.GetName() + ", ")
        text += '\n'

        text += "Feature Number: {:d} / [{:d}-{:d}]\n".format(feature_num, self.spinBoxMinFeatureNumber.value(), self.spinBoxMaxFeatureNumber.value())

        text += "{:s} / ".format(classifier_name)
        for temp in self.__process_classifier_list:
            text += (temp.GetName() + ", ")
        text += '\n'

        text += "Total process: {:d} / {:d}".format(current_num, total_num)
        return text

    def SetStateAllButtonWhenRunning(self, state):
        self.buttonLoadTrainingData.setEnabled(state)
        self.buttonLoadTestingData.setEnabled(state)
        
        self.SetStateButtonBeforeLoading(state)

    def SetStateButtonBeforeLoading(self, state):
        self.buttonRun.setEnabled(state)
        
        self.checkNormalizeUnit.setEnabled(state)
        self.checkNormalizeZeroCenter.setEnabled(state)
        self.checkNormalizeUnitWithZeroCenter.setEnabled(state)
        self.checkNormalizationAll.setEnabled(state)
        
        self.checkPCA.setEnabled(state)
        self.checkRemoveSimilarFeatures.setEnabled(state)
        self.checkPreprocessAll.setEnabled(state)
        
        self.checkANOVA.setEnabled(state)
        self.checkRFE.setEnabled(state)
        self.checkRelief.setEnabled(state)
        self.checkFeatureSelectorAll.setEnabled(state)
        
        self.spinBoxMinFeatureNumber.setEnabled(state)
        self.spinBoxMaxFeatureNumber.setEnabled(state)
        
        self.checkSVM.setEnabled(state)
        self.checkAE.setEnabled(state)
        self.checkLDA.setEnabled(state)
        self.checkRF.setEnabled(state)
        self.checkLogisticRegression.setEnabled(state)
        self.checkLRLasso.setEnabled(state)
        self.checkAdaboost.setEnabled(state)
        self.checkDecisionTree.setEnabled(state)
        self.checkNaiveBayes.setEnabled(state)
        self.checkGaussianProcess.setEnabled(state)
        self.checkClassifierAll.setEnabled(state)
        self.checkHyperParameters.setEnabled(state)

        self.radio5folder.setEnabled(state)
        self.radio10Folder.setEnabled(state)

    def Run(self):
        if self.training_data_container.IsEmpty():
            QMessageBox.about(self, '', 'Training data is empty.')
            self.logger.info('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:
                    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))
                else:
                    return

            self.textEditVerbose.setText(store_folder)
            if self.MakePipelines():
                thread = CVRun()
                thread.moveToThread(QThread())
                thread.SetProcessConnectionAndStore_folder(self, store_folder)

                thread.signal.connect(self.textEditVerbose.setPlainText)
                thread.start()
                self.SetStateAllButtonWhenRunning(False)

                hidden_file_path = os.path.join(store_folder, '.FAEresult4129074093819729087')
                with open(hidden_file_path, 'wb') as file:
                    pass
                file_hidden = os.popen('attrib +h '+ hidden_file_path)
                file_hidden.close()

            else:
                QMessageBox.about(self, 'Pipeline Error', 'Pipeline must include Classifier and CV method')
                self.logger.error('Make pipeline failed. Pipeline must include Classfier and CV method.')

    def MinFeatureNumberChange(self):
        if self.spinBoxMinFeatureNumber.value() > self.spinBoxMaxFeatureNumber.value():
            self.spinBoxMinFeatureNumber.setValue(self.spinBoxMaxFeatureNumber.value())

        self.UpdatePipelineText()

    def MaxFeatureNumberChange(self):
        if self.spinBoxMaxFeatureNumber.value() < self.spinBoxMinFeatureNumber.value():
            self.spinBoxMaxFeatureNumber.setValue(self.spinBoxMinFeatureNumber.value())

        self.UpdatePipelineText()

    def MakePipelines(self):
        self.__process_normalizer_list = []
        if self.checkNormalizeUnit.isChecked():
            self.__process_normalizer_list.append(NormalizerUnit())
        if self.checkNormalizeZeroCenter.isChecked():
            self.__process_normalizer_list.append(NormalizerZeroCenter())
        if self.checkNormalizeUnitWithZeroCenter.isChecked():
            self.__process_normalizer_list.append(NormalizerZeroCenterAndUnit())
        if (not self.checkNormalizeUnit.isChecked()) and (not self.checkNormalizeZeroCenter.isChecked()) and \
                (not self.checkNormalizeUnitWithZeroCenter.isChecked()):
            self.__process_normalizer_list.append(NormalizerNone())

        self.__process_dimension_reduction_list = []
        if self.checkPCA.isChecked():
            self.__process_dimension_reduction_list.append(DimensionReductionByPCA())
        if self.checkRemoveSimilarFeatures.isChecked():
            self.__process_dimension_reduction_list.append(DimensionReductionByPCC())

        self.__process_feature_selector_list = []
        if self.checkANOVA.isChecked():
            self.__process_feature_selector_list.append(FeatureSelectPipeline([FeatureSelectByANOVA()]))
        if self.checkRFE.isChecked():
            self.__process_feature_selector_list.append(FeatureSelectPipeline([FeatureSelectByRFE()]))
        if self.checkRelief.isChecked():
            self.__process_feature_selector_list.append(FeatureSelectPipeline([FeatureSelectByRelief()]))

        self.__process_feature_number_list = np.arange(self.spinBoxMinFeatureNumber.value(), self.spinBoxMaxFeatureNumber.value() + 1).tolist()

        self.__process_classifier_list = []
        if self.checkSVM.isChecked():
            self.__process_classifier_list.append(SVM())
        if self.checkLDA.isChecked():
            self.__process_classifier_list.append(LDA())
        if self.checkAE.isChecked():
            self.__process_classifier_list.append(AE())
        if self.checkRF.isChecked():
            self.__process_classifier_list.append(RandomForest())
        if self.checkLogisticRegression.isChecked():
            self.__process_classifier_list.append(LR())
        if self.checkLRLasso.isChecked():
            self.__process_classifier_list.append(LRLasso())
        if self.checkAdaboost.isChecked():
            self.__process_classifier_list.append(AdaBoost())
        if self.checkDecisionTree.isChecked():
            self.__process_classifier_list.append(DecisionTree())
        if self.checkGaussianProcess.isChecked():
            self.__process_classifier_list.append(GaussianProcess())
        if self.checkNaiveBayes.isChecked():
            self.__process_classifier_list.append(NaiveBayes())
        if len(self.__process_classifier_list) == 0:
            self.logger.error('Process classifier list length is zero.')
            return False

        if self.radio5folder.isChecked():
            cv = CrossValidation5Folder()
        elif self.radio10Folder.isChecked():
            cv = CrossValidation10Folder()
        else:
            return False

        self.fae.SetNormalizerList(self.__process_normalizer_list)
        self.fae.SetDimensionReductionList(self.__process_dimension_reduction_list)
        self.fae.SetFeatureSelectorList(self.__process_feature_selector_list)
        self.fae.SetFeatureNumberList(self.__process_feature_number_list)
        self.fae.SetClassifierList(self.__process_classifier_list)
        self.fae.SetCrossValition(cv)
        self.fae.GenerateMetircDict()

        return True

    def UpdateDataDescription(self):
        show_text = ""
        if self.training_data_container.GetArray().size > 0:
            show_text += "The number of training cases: {:d}\n".format(len(self.training_data_container.GetCaseName()))
            show_text += "The number of training features: {:d}\n".format(len(self.training_data_container.GetFeatureName()))
            if len(np.unique(self.training_data_container.GetLabel())) == 2:
                positive_number = len(
                    np.where(self.training_data_container.GetLabel() == np.max(self.training_data_container.GetLabel()))[0])
                negative_number = len(self.training_data_container.GetLabel()) - positive_number
                assert (positive_number + negative_number == len(self.training_data_container.GetLabel()))
                show_text += "The number of training positive samples: {:d}\n".format(positive_number)
                show_text += "The number of training negative samples: {:d}\n".format(negative_number)

        show_text += '\n'
        if self.testing_data_container.GetArray().size > 0:
            show_text += "The number of testing cases: {:d}\n".format(len(self.testing_data_container.GetCaseName()))
            show_text += "The number of testing features: {:d}\n".format(
                len(self.testing_data_container.GetFeatureName()))
            if len(np.unique(self.testing_data_container.GetLabel())) == 2:
                positive_number = len(
                    np.where(
                        self.testing_data_container.GetLabel() == np.max(self.testing_data_container.GetLabel()))[0])
                negative_number = len(self.testing_data_container.GetLabel()) - positive_number
                assert (positive_number + negative_number == len(self.testing_data_container.GetLabel()))
                show_text += "The number of testing positive samples: {:d}\n".format(positive_number)
                show_text += "The number of testing negative samples: {:d}\n".format(negative_number)

        self.textEditDescription.setText(show_text)

    def UpdatePipelineText(self):
        self.listOnePipeline.clear()

        normalization_text = 'Normalization:\n'
        normalizer_num = 0
        if self.checkNormalizeUnit.isChecked():
            normalization_text += "Normalize unit\n"
            normalizer_num += 1
        if self.checkNormalizeZeroCenter.isChecked():
            normalization_text += "Normalize zero center\n"
            normalizer_num += 1
        if self.checkNormalizeUnitWithZeroCenter.isChecked():
            normalization_text += "Normalize unit with zero center\n"
            normalizer_num += 1
        if normalizer_num == 0:
            normalizer_num = 1
        self.listOnePipeline.addItem(normalization_text)

        preprocess_test = 'Preprocess:\n'
        dimension_reduction_num = 0
        if self.checkPCA.isChecked():
            preprocess_test += "PCA\n"
            dimension_reduction_num += 1
        if self.checkRemoveSimilarFeatures.isChecked():
            preprocess_test += "Remove Similary Features\n"
            dimension_reduction_num += 1
        if dimension_reduction_num == 0:
            dimension_reduction_num = 1
        self.listOnePipeline.addItem(preprocess_test)

        feature_selection_text = "Feature Selection:\n"
        if self.spinBoxMinFeatureNumber.value() == self.spinBoxMaxFeatureNumber.value():
            feature_selection_text += "Feature Number: " + str(self.spinBoxMinFeatureNumber.value()) + "\n"
        else:
            feature_selection_text += "Feature Number range: {:d}-{:d}\n".format(self.spinBoxMinFeatureNumber.value(),
                                                                                 self.spinBoxMaxFeatureNumber.value())
        feature_num = self.spinBoxMaxFeatureNumber.value() - self.spinBoxMinFeatureNumber.value() + 1

        feature_selector_num = 0
        if self.checkANOVA.isChecked():
            feature_selection_text += "ANOVA\n"
            feature_selector_num += 1
        if self.checkRFE.isChecked():
            feature_selection_text += "RFE\n"
            feature_selector_num += 1
        if self.checkRelief.isChecked():
            feature_selection_text += "Relief\n"
            feature_selector_num += 1
        if feature_selector_num == 0:
            feature_selection_text += "None\n"
            feature_selector_num = 1
        self.listOnePipeline.addItem(feature_selection_text)


        classifier_text = 'Classifier:\n'
        classifier_num = 0
        if self.checkSVM.isChecked():
            classifier_text += "SVM\n"
            classifier_num += 1
        if self.checkLDA.isChecked():
            classifier_text += "LDA\n"
            classifier_num += 1
        if self.checkAE.isChecked():
            classifier_text += "AE\n"
            classifier_num += 1
        if self.checkRF.isChecked():
            classifier_text += "RF\n"
            classifier_num += 1
        if self.checkLogisticRegression.isChecked():
            classifier_text += "Logistic Regression\n"
            classifier_num += 1
        if self.checkLRLasso.isChecked():
            classifier_text += "Logistic Regression with Lasso\n"
            classifier_num += 1
        if self.checkAdaboost.isChecked():
            classifier_text += "Adaboost\n"
            classifier_num += 1
        if self.checkDecisionTree.isChecked():
            classifier_text += "Decision Tree\n"
            classifier_num += 1
        if self.checkGaussianProcess.isChecked():
            classifier_text += "Gaussian Process\n"
            classifier_num += 1
        if self.checkNaiveBayes.isChecked():
            classifier_text += "Naive Bayes\n"
            classifier_num += 1

        if classifier_num == 0:
            classifier_num = 1
        self.listOnePipeline.addItem(classifier_text)

        cv_method = "Cross Validation:\n"
        if self.radio5folder.isChecked():
            cv_method += "5-Folder\n"
        elif self.radio10Folder.isChecked():
            cv_method += "10-folder\n"

        self.listOnePipeline.addItem(cv_method)

        self.listOnePipeline.addItem("Total number of pipelines is:\n{:d}"
                                     .format(normalizer_num * dimension_reduction_num * feature_selector_num * feature_num * classifier_num))

    def SelectAllNormalization(self):
        if self.checkNormalizationAll.isChecked():
            self.checkNormalizeZeroCenter.setChecked(True)
            self.checkNormalizeUnitWithZeroCenter.setChecked(True)
            self.checkNormalizeUnit.setChecked(True)
        else:
            self.checkNormalizeZeroCenter.setChecked(False)
            self.checkNormalizeUnitWithZeroCenter.setChecked(False)
            self.checkNormalizeUnit.setChecked(False)

        self.UpdatePipelineText()

    def SelectAllPreprocess(self):
        if self.checkPreprocessAll.isChecked():
            self.checkPCA.setChecked(True)
            self.checkRemoveSimilarFeatures.setChecked(True)
        else:
            self.checkPCA.setChecked(False)
            self.checkRemoveSimilarFeatures.setChecked(False)

        self.UpdatePipelineText()

    def SelectAllFeatureSelector(self):
        if self.checkFeatureSelectorAll.isChecked():
            self.checkANOVA.setChecked(True)
            self.checkRFE.setChecked(True)
            self.checkRelief.setChecked(True)
        else:
            self.checkANOVA.setChecked(False)
            self.checkRFE.setChecked(False)
            self.checkRelief.setChecked(False)

        self.UpdatePipelineText()

    def SelectAllClassifier(self):
        if self.checkClassifierAll.isChecked():
            self.checkSVM.setChecked(True)
            self.checkAE.setChecked(True)
            self.checkLDA.setChecked(True)
            self.checkRF.setChecked(True)
            self.checkLogisticRegression.setChecked(True)
            self.checkLRLasso.setChecked(True)
            self.checkAdaboost.setChecked(True)
            self.checkDecisionTree.setChecked(True)
            self.checkGaussianProcess.setChecked(True)
            self.checkNaiveBayes.setChecked(True)
        else:
            self.checkSVM.setChecked(False)
            self.checkAE.setChecked(False)
            self.checkLDA.setChecked(False)
            self.checkRF.setChecked(False)
            self.checkLogisticRegression.setChecked(False)
            self.checkLRLasso.setChecked(False)
            self.checkAdaboost.setChecked(False)
            self.checkDecisionTree.setChecked(False)
            self.checkGaussianProcess.setChecked(False)
            self.checkNaiveBayes.setChecked(False)

        self.UpdatePipelineText()
Ejemplo n.º 8
0
class VisualizationConnection(QWidget, Ui_Visualization):
    def __init__(self, parent=None):
        self._root_folder = ''
        self._fae = FeatureAnalysisPipelines()
        self.sheet_dict = dict()

        super(VisualizationConnection, self).__init__(parent)
        self.setupUi(self)

        self.buttonLoadResult.clicked.connect(self.LoadAll)
        self.buttonClearResult.clicked.connect(self.ClearAll)
        self.buttonSave.clicked.connect(self.Save)

        self.__plt_roc = self.canvasROC.getFigure().add_subplot(111)
        self.__plt_plot = self.canvasPlot.getFigure().add_subplot(111)
        self.__contribution = self.canvasFeature.getFigure().add_subplot(111)

        # Update Sheet
        self.comboSheet.currentIndexChanged.connect(self.UpdateSheet)
        self.checkMaxFeatureNumber.stateChanged.connect(self.UpdateSheet)

        # Update ROC canvas
        self.comboNormalizer.currentIndexChanged.connect(self.UpdateROC)
        self.comboDimensionReduction.currentIndexChanged.connect(
            self.UpdateROC)
        self.comboFeatureSelector.currentIndexChanged.connect(self.UpdateROC)
        self.comboClassifier.currentIndexChanged.connect(self.UpdateROC)
        self.spinBoxFeatureNumber.valueChanged.connect(self.UpdateROC)
        self.checkROCCVTrain.stateChanged.connect(self.UpdateROC)
        self.checkROCCVValidation.stateChanged.connect(self.UpdateROC)
        self.checkROCTrain.stateChanged.connect(self.UpdateROC)
        self.checkROCTest.stateChanged.connect(self.UpdateROC)

        # Update Plot canvas
        self.comboPlotX.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotY.currentIndexChanged.connect(self.UpdatePlot)
        self.checkPlotMaximum.stateChanged.connect(self.UpdatePlot)
        self.comboPlotNormalizer.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotDimensionReduction.currentIndexChanged.connect(
            self.UpdatePlot)
        self.comboPlotFeatureSelector.currentIndexChanged.connect(
            self.UpdatePlot)
        self.comboPlotClassifier.currentIndexChanged.connect(self.UpdatePlot)
        self.spinPlotFeatureNumber.valueChanged.connect(self.UpdatePlot)

        self.checkPlotCVTrain.stateChanged.connect(self.UpdatePlot)
        self.checkPlotCVValidation.stateChanged.connect(self.UpdatePlot)
        self.checkPlotTrain.stateChanged.connect(self.UpdatePlot)
        self.checkPlotTest.stateChanged.connect(self.UpdatePlot)

        # Update Contribution canvas
        self.checkContributionShow.stateChanged.connect(
            self.UpdateContribution)
        self.radioContributionFeatureSelector.toggled.connect(
            self.UpdateContribution)
        self.radioContributionClassifier.toggled.connect(
            self.UpdateContribution)
        self.comboContributionFeatureSelector.currentIndexChanged.connect(
            self.UpdateContribution)
        self.comboContributionClassifier.currentIndexChanged.connect(
            self.UpdateContribution)
        self.spinFeatureSelectorFeatureNumber.valueChanged.connect(
            self.UpdateContribution)
        self.spinClassifierFeatureNumber.valueChanged.connect(
            self.UpdateContribution)

    def LoadAll(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
            if not r'.FAEresult4129074093819729087' in os.listdir(
                    self._root_folder):
                QMessageBox.about(self, 'Load Error',
                                  'This folder is not supported for import')
                return

            try:
                self.lineEditResultPath.setText(self._root_folder)
                self._fae.LoadAll(self._root_folder)
                self.SetResultDescription()
                self.SetResultTable()
                self.InitialUi()
            except Exception as ex:
                QMessageBox.about(self, "Load Error", ex.__str__())
                self.logger.log('Load Error, The reason is ' + str(ex))
                self.ClearAll()
                return

            self.buttonClearResult.setEnabled(True)
            self.buttonSave.setEnabled(True)
            self.buttonLoadResult.setEnabled(False)

    def ClearAll(self):

        self.buttonLoadResult.setEnabled(True)
        self.buttonSave.setEnabled(False)
        self.buttonClearResult.setEnabled(False)

        self.checkROCCVTrain.setChecked(False)
        self.checkROCCVValidation.setChecked(False)
        self.checkROCTrain.setChecked(False)
        self.checkROCTest.setChecked(False)
        self.checkPlotCVTrain.setChecked(False)
        self.checkPlotCVValidation.setChecked(False)
        self.checkPlotTrain.setChecked(False)
        self.checkPlotTest.setChecked(False)
        self.checkPlotMaximum.setChecked(False)
        self.checkContributionShow.setChecked(False)
        self.radioContributionFeatureSelector.setChecked(True)
        self.radioContributionFeatureSelector.setChecked(False)
        self.checkMaxFeatureNumber.setChecked(False)
        self.canvasROC.getFigure().clear()
        self.canvasPlot.getFigure().clear()
        self.canvasFeature.getFigure().clear()
        self.__plt_roc = self.canvasROC.getFigure().add_subplot(111)
        self.__plt_plot = self.canvasPlot.getFigure().add_subplot(111)
        self.__contribution = self.canvasFeature.getFigure().add_subplot(111)
        self.canvasROC.draw()
        self.canvasPlot.draw()
        self.canvasFeature.draw()

        self.textEditDescription.clear()
        self.lineEditResultPath.clear()

        self.comboSheet.clear()
        self.comboClassifier.clear()
        self.comboDimensionReduction.clear()
        self.comboNormalizer.clear()
        self.comboFeatureSelector.clear()

        self.comboPlotClassifier.clear()
        self.comboPlotDimensionReduction.clear()
        self.comboPlotFeatureSelector.clear()
        self.comboPlotNormalizer.clear()
        self.comboPlotX.clear()
        self.comboPlotY.clear()

        self.comboContributionClassifier.clear()
        self.comboContributionFeatureSelector.clear()

        self.spinBoxFeatureNumber.setValue(0)
        self.spinPlotFeatureNumber.setValue(0)
        self.spinPlotFeatureNumber.setEnabled(False)
        self.spinFeatureSelectorFeatureNumber.setValue(1)
        self.spinClassifierFeatureNumber.setValue(1)

        self.tableClinicalStatistic.clear()

        self.tableClinicalStatistic.setRowCount(0)
        self.tableClinicalStatistic.setColumnCount(0)
        self.tableClinicalStatistic.setHorizontalHeaderLabels(list([]))
        self.tableClinicalStatistic.setVerticalHeaderLabels(list([]))

        self._fae = FeatureAnalysisPipelines()
        self._root_folder = ''
        self.sheet_dict = dict()

    def Save(self):
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.DirectoryOnly)
        dlg.setOption(QFileDialog.ShowDirsOnly)

        if dlg.exec_():
            store_folder = dlg.selectedFiles()[0]
            self.canvasROC.getFigure().savefig(os.path.join(
                store_folder, 'ROC.eps'),
                                               dpi=1200)
            self.canvasROC.getFigure().savefig(os.path.join(
                store_folder, 'ROC.jpg'),
                                               dpi=300)
            self.canvasPlot.getFigure().savefig(os.path.join(
                store_folder, 'Compare.eps'),
                                                dpi=1200)
            self.canvasPlot.getFigure().savefig(os.path.join(
                store_folder, 'Compare.jpg'),
                                                dpi=300)
            self.canvasFeature.getFigure().savefig(os.path.join(
                store_folder, 'FeatureWeights.eps'),
                                                   dpi=1200)
            self.canvasFeature.getFigure().savefig(os.path.join(
                store_folder, 'FeatureWeights.jpg'),
                                                   dpi=300)

    def InitialUi(self):
        # Update ROC canvers
        for normalizer in self._fae.GetNormalizerList():
            self.comboNormalizer.addItem(normalizer.GetName())
        for dimension_reduction in self._fae.GetDimensionReductionList():
            self.comboDimensionReduction.addItem(dimension_reduction.GetName())
        for classifier in self._fae.GetClassifierList():
            self.comboClassifier.addItem(classifier.GetName())
        for feature_selector in self._fae.GetFeatureSelectorList():
            self.comboFeatureSelector.addItem(feature_selector.GetName())
        self.spinBoxFeatureNumber.setMinimum(
            int(self._fae.GetFeatureNumberList()[0]))
        self.spinBoxFeatureNumber.setMaximum(
            int(self._fae.GetFeatureNumberList()[-1]))

        # Update Plot canvars
        if len(self._fae.GetNormalizerList()) > 1:
            self.comboPlotX.addItem('Normaliaztion')
        if len(self._fae.GetDimensionReductionList()) > 1:
            self.comboPlotX.addItem('Dimension Reduction')
        if len(self._fae.GetFeatureSelectorList()) > 1:
            self.comboPlotX.addItem('Feature Selector')
        if len(self._fae.GetClassifierList()) > 1:
            self.comboPlotX.addItem('Classifier')
        if len(self._fae.GetFeatureNumberList()) > 1:
            self.comboPlotX.addItem('Feature Number')

        self.comboPlotY.addItem('AUC')

        for index in self._fae.GetNormalizerList():
            self.comboPlotNormalizer.addItem(index.GetName())
        for index in self._fae.GetDimensionReductionList():
            self.comboPlotDimensionReduction.addItem(index.GetName())
        for index in self._fae.GetFeatureSelectorList():
            self.comboPlotFeatureSelector.addItem(index.GetName())
        for index in self._fae.GetClassifierList():
            self.comboPlotClassifier.addItem(index.GetName())
        self.spinPlotFeatureNumber.setMinimum(
            int(self._fae.GetFeatureNumberList()[0]))
        self.spinPlotFeatureNumber.setMaximum(
            int(self._fae.GetFeatureNumberList()[-1]))

        # Update Contribution canvas
        # self.spinFeatureSelectorFeatureNumber.setMaximum(int(self._fae.GetFeatureNumberList()[-1]))
        self.spinClassifierFeatureNumber.setMinimum(
            int(self._fae.GetFeatureNumberList()[0]))
        self.spinClassifierFeatureNumber.setMaximum(
            int(self._fae.GetFeatureNumberList()[-1]))
        for selector in self._fae.GetFeatureSelectorList():
            self.comboContributionFeatureSelector.addItem(selector.GetName())
        for classifier in self._fae.GetClassifierList():
            specific_name = classifier.GetName() + '_coef.csv'
            if self._SearchSpecificFile(
                    int(self._fae.GetFeatureNumberList()[0]), specific_name):
                self.comboContributionClassifier.addItem(classifier.GetName())

    def UpdateROC(self):
        if (self.comboNormalizer.count() == 0) or \
                (self.comboDimensionReduction.count() == 0) or \
                (self.comboFeatureSelector.count() == 0) or \
                (self.comboClassifier.count() == 0) or \
                (self.spinBoxFeatureNumber.value() == 0):
            return

        case_name = self.comboNormalizer.currentText() + '_' + \
                    self.comboDimensionReduction.currentText() + '_' + \
                    self.comboFeatureSelector.currentText() + '_' + \
                    str(self.spinBoxFeatureNumber.value()) + '_' + \
                    self.comboClassifier.currentText()

        case_folder = os.path.join(self._root_folder, case_name)

        pred_list, label_list, name_list = [], [], []
        if self.checkROCCVTrain.isChecked():
            train_pred = np.load(os.path.join(case_folder,
                                              'train_predict.npy'))
            train_label = np.load(os.path.join(case_folder, 'train_label.npy'))
            pred_list.append(train_pred)
            label_list.append(train_label)
            name_list.append('CV Train')
        if self.checkROCCVValidation.isChecked():
            val_pred = np.load(os.path.join(case_folder, 'val_predict.npy'))
            val_label = np.load(os.path.join(case_folder, 'val_label.npy'))
            pred_list.append(val_pred)
            label_list.append(val_label)
            name_list.append('CV Validation')
        if self.checkROCTrain.isChecked():
            all_train_pred = np.load(
                os.path.join(case_folder, 'all_train_predict.npy'))
            all_train_label = np.load(
                os.path.join(case_folder, 'all_train_label.npy'))
            pred_list.append(all_train_pred)
            label_list.append(all_train_label)
            name_list.append('Train')
        if self.checkROCTest.isChecked():
            if os.path.exists(os.path.join(case_folder, 'test_label.npy')):
                test_pred = np.load(
                    os.path.join(case_folder, 'test_predict.npy'))
                test_label = np.load(
                    os.path.join(case_folder, 'test_label.npy'))
                pred_list.append(test_pred)
                label_list.append(test_label)
                name_list.append('Test')

        if len(pred_list) > 0:
            DrawROCList(pred_list,
                        label_list,
                        name_list=name_list,
                        is_show=False,
                        fig=self.canvasROC.getFigure())

        self.canvasROC.draw()

    def _UpdatePlotButtons(self, selected_index):
        index = [0, 0, 0, 0, 0]
        if self.checkPlotMaximum.isChecked():
            self.comboPlotNormalizer.setEnabled(False)
            self.comboPlotDimensionReduction.setEnabled(False)
            self.comboPlotFeatureSelector.setEnabled(False)
            self.comboPlotClassifier.setEnabled(False)
            self.spinPlotFeatureNumber.setEnabled(False)
        else:
            self.comboPlotNormalizer.setEnabled(True)
            self.comboPlotDimensionReduction.setEnabled(True)
            self.comboPlotFeatureSelector.setEnabled(True)
            self.comboPlotClassifier.setEnabled(True)
            self.spinPlotFeatureNumber.setEnabled(True)
            index[0] = self.comboPlotNormalizer.currentIndex()
            index[1] = self.comboPlotDimensionReduction.currentIndex()
            index[2] = self.comboPlotFeatureSelector.currentIndex()
            index[4] = self.comboPlotClassifier.currentIndex()
            index[3] = self.spinPlotFeatureNumber.value() - int(
                self._fae.GetFeatureNumberList()[0])

            if selected_index == 0:
                self.comboPlotNormalizer.setEnabled(False)
                index[0] = [
                    temp for temp in range(len(self._fae.GetNormalizerList()))
                ]
            elif selected_index == 1:
                self.comboPlotDimensionReduction.setEnabled(False)
                index[1] = [
                    temp for temp in range(
                        len(self._fae.GetDimensionReductionList()))
                ]
            elif selected_index == 2:
                self.comboPlotFeatureSelector.setEnabled(False)
                index[2] = [
                    temp
                    for temp in range(len(self._fae.GetFeatureSelectorList()))
                ]
            elif selected_index == 4:
                self.comboPlotClassifier.setEnabled(False)
                index[4] = [
                    temp for temp in range(len(self._fae.GetClassifierList()))
                ]
            elif selected_index == 3:
                self.spinPlotFeatureNumber.setEnabled(False)
                index[3] = [
                    temp
                    for temp in range(len(self._fae.GetFeatureNumberList()))
                ]

        return index

    def UpdatePlot(self):
        if self.comboPlotX.count() == 0:
            return

        x_ticks = []
        x_label = ''
        selected_index = -1
        if self.comboPlotX.currentText() == 'Normaliaztion':
            selected_index = 0
            x_ticks = [
                instance.GetName()
                for instance in self._fae.GetNormalizerList()
            ]
            x_label = 'Normalization Method'
        elif self.comboPlotX.currentText() == 'Dimension Reduction':
            selected_index = 1
            x_ticks = [
                instance.GetName()
                for instance in self._fae.GetDimensionReductionList()
            ]
            x_label = 'Dimension Reduction Method'
        elif self.comboPlotX.currentText() == 'Feature Selector':
            selected_index = 2
            x_ticks = [
                instance.GetName()
                for instance in self._fae.GetFeatureSelectorList()
            ]
            x_label = 'Feature Selecotr Method'
        elif self.comboPlotX.currentText() == 'Classifier':
            selected_index = 4
            x_ticks = [
                instance.GetName()
                for instance in self._fae.GetClassifierList()
            ]
            x_label = 'Classifier Method'
        elif self.comboPlotX.currentText() == 'Feature Number':
            selected_index = 3
            x_ticks = list(map(int, self._fae.GetFeatureNumberList()))
            x_label = 'Feature Number'

        max_axis_list = [0, 1, 2, 3, 4]
        max_axis_list.remove(selected_index)
        max_axis = tuple(max_axis_list)

        index = self._UpdatePlotButtons(selected_index)

        show_data = []
        show_data_std = []
        name_list = []

        if self.comboPlotY.currentText() == 'AUC':
            if self.checkPlotCVTrain.isChecked():
                temp = deepcopy(self._fae.GetAUCMetric()['train'])
                auc_std = deepcopy(self._fae.GetAUCstdMetric()['train'])
                if self.checkPlotMaximum.isChecked():
                    show_data.append(np.max(temp, axis=max_axis).tolist())
                else:
                    show_data.append(temp[tuple(index)].tolist())
                    show_data_std.append(auc_std[tuple(index)].tolist())
                name_list.append('CV Train')
            if self.checkPlotCVValidation.isChecked():
                temp = deepcopy(self._fae.GetAUCMetric()['val'])
                auc_std = deepcopy(self._fae.GetAUCstdMetric()['val'])
                if self.checkPlotMaximum.isChecked():
                    show_data.append(np.max(temp, axis=max_axis).tolist())
                else:
                    show_data.append(temp[tuple(index)].tolist())
                    show_data_std.append(auc_std[tuple(index)].tolist())
                name_list.append('CV Validation')
            if self.checkPlotTrain.isChecked():
                temp = deepcopy(self._fae.GetAUCMetric()['all_train'])
                auc_std = deepcopy(self._fae.GetAUCstdMetric()['all_train'])
                if self.checkPlotMaximum.isChecked():
                    show_data.append(np.max(temp, axis=max_axis).tolist())
                else:
                    show_data.append(temp[tuple(index)].tolist())
                    show_data_std.append(auc_std[tuple(index)].tolist())
                name_list.append('Train')
            if self.checkPlotTest.isChecked():
                temp = deepcopy(self._fae.GetAUCMetric()['test'])
                auc_std = deepcopy(self._fae.GetAUCstdMetric()['test'])
                if temp.size > 0:
                    if self.checkPlotMaximum.isChecked():
                        show_data.append(np.max(temp, axis=max_axis).tolist())
                    else:
                        show_data.append(temp[tuple(index)].tolist())
                        show_data_std.append(auc_std[tuple(index)].tolist())
                    name_list.append('Test')

        if len(show_data) > 0:
            if selected_index == 3:
                DrawCurve(x_ticks,
                          show_data,
                          show_data_std,
                          xlabel=x_label,
                          ylabel=self.comboPlotY.currentText(),
                          name_list=name_list,
                          is_show=False,
                          fig=self.canvasPlot.getFigure())
            else:
                DrawBar(x_ticks,
                        show_data,
                        ylabel=self.comboPlotY.currentText(),
                        name_list=name_list,
                        is_show=False,
                        fig=self.canvasPlot.getFigure())

        self.canvasPlot.draw()

    def UpdateContribution(self):
        if not self.checkContributionShow.isChecked():
            return

        if self.radioContributionFeatureSelector.isChecked():
            file_name = self.comboContributionFeatureSelector.currentText(
            ) + '_sort.csv'
            file_path = self._SearchSpecificFile(
                int(self._fae.GetFeatureNumberList()[0]), file_name)
            if file_path:
                df = pd.read_csv(file_path, index_col=0)

                feature_name = list(df.index)
                value = list(np.abs(df.iloc[:, 0]))

                GeneralFeatureSort(
                    feature_name,
                    value,
                    max_num=self.spinFeatureSelectorFeatureNumber.value(),
                    is_show=False,
                    fig=self.canvasFeature.getFigure())
        elif self.radioContributionClassifier.isChecked():
            specific_name = self.comboContributionClassifier.currentText(
            ) + '_coef.csv'
            feature_selector_name = self.comboContributionFeatureSelector.currentText(
            )
            file_path = self._SearchSpecificFile(
                self.spinClassifierFeatureNumber.value(), specific_name,
                feature_selector_name)
            if file_path:
                df = pd.read_csv(file_path, index_col=0)
                feature_name = list(df.index)
                value = list(np.abs(df.iloc[:, 0]))
                try:
                    SortRadiomicsFeature(feature_name,
                                         value,
                                         is_show=False,
                                         fig=self.canvasFeature.getFigure())
                except:
                    GeneralFeatureSort(feature_name,
                                       value,
                                       is_show=False,
                                       fig=self.canvasFeature.getFigure())

        self.canvasFeature.draw()

    def SetResultDescription(self):
        text = "Normalizer:\n"
        for index in self._fae.GetNormalizerList():
            text += (index.GetName() + '\n')
        text += '\n'

        text += "Dimension Reduction:\n"
        for index in self._fae.GetDimensionReductionList():
            text += (index.GetName() + '\n')
        text += '\n'

        text += "Feature Selector:\n"
        for index in self._fae.GetFeatureSelectorList():
            text += (index.GetName() + '\n')
        text += '\n'

        text += "Feature Number:\n"
        text += "{:s} - {:s}\n".format(self._fae.GetFeatureNumberList()[0],
                                       self._fae.GetFeatureNumberList()[-1])
        text += '\n'

        text += "Classifier:\n"
        for index in self._fae.GetClassifierList():
            text += (index.GetName() + '\n')
        text += '\n'

        self.textEditDescription.setPlainText(text)

    def UpdateSheet(self):
        data = np.array([])
        df = pd.DataFrame()
        data = self._fae.GetAUCMetric()
        std_data = self._fae.GetAUCstdMetric()
        self.tableClinicalStatistic.clear()
        self.tableClinicalStatistic.setSortingEnabled(False)
        if self.comboSheet.currentText() == 'Train':
            data = self._fae.GetAUCMetric()['train']
            std_data = self._fae.GetAUCstdMetric()['train']
            df = self.sheet_dict['train']
        elif self.comboSheet.currentText() == 'Validation':
            data = self._fae.GetAUCMetric()['val']
            std_data = self._fae.GetAUCstdMetric()['val']
            df = self.sheet_dict['val']
        elif self.comboSheet.currentText() == 'Test':
            data = self._fae.GetAUCMetric()['test']
            std_data = self._fae.GetAUCstdMetric()['test']
            df = self.sheet_dict['test']
        elif self.comboSheet.currentText() == 'Test On Val':
            data = self._fae.GetAUCMetric()['val']
            std_data = self._fae.GetAUCstdMetric()['val']
            df = self.sheet_dict['test']

        else:
            return

        if self.checkMaxFeatureNumber.isChecked():
            name_list = []
            for normalizer, normalizer_index in zip(
                    self._fae.GetNormalizerList(),
                    range(len(self._fae.GetNormalizerList()))):
                for dimension_reducer, dimension_reducer_index in zip(
                        self._fae.GetDimensionReductionList(),
                        range(len(self._fae.GetDimensionReductionList()))):
                    for feature_selector, feature_selector_index in zip(
                            self._fae.GetFeatureSelectorList(),
                            range(len(self._fae.GetFeatureSelectorList()))):
                        for classifier, classifier_index in zip(
                                self._fae.GetClassifierList(),
                                range(len(self._fae.GetClassifierList()))):
                            sub_auc = data[normalizer_index,
                                           dimension_reducer_index,
                                           feature_selector_index, :,
                                           classifier_index]
                            sub_auc_std = std_data[normalizer_index,
                                                   dimension_reducer_index,
                                                   feature_selector_index, :,
                                                   classifier_index]
                            one_se = max(sub_auc) - sub_auc_std[np.argmax(
                                sub_auc)]
                            for feature_number_index in range(
                                    len(self._fae.GetFeatureNumberList())):
                                if data[normalizer_index,
                                        dimension_reducer_index,
                                        feature_selector_index,
                                        feature_number_index,
                                        classifier_index] >= one_se:
                                    name = normalizer.GetName() + '_' + dimension_reducer.GetName() + '_' + \
                                    feature_selector.GetName() + '_' + str(self._fae.GetFeatureNumberList()[feature_number_index]) + '_' + \
                                    classifier.GetName()
                                    name_list.append(name)
                                    break

            df = df.loc[name_list]
        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)
        # self.tableClinicalStatistic.setVerticalHeaderLabels(list(df.index))

        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 SetResultTable(self):
        self.sheet_dict['train'] = pd.read_csv(os.path.join(
            self._root_folder, 'train_result.csv'),
                                               index_col=0)
        self.comboSheet.addItem('Train')
        self.sheet_dict['val'] = pd.read_csv(os.path.join(
            self._root_folder, 'val_result.csv'),
                                             index_col=0)
        self.comboSheet.addItem('Validation')
        if os.path.exists(os.path.join(self._root_folder, 'test_result.csv')):
            self.sheet_dict['test'] = pd.read_csv(os.path.join(
                self._root_folder, 'test_result.csv'),
                                                  index_col=0)
            self.comboSheet.addItem('Test')
            self.comboSheet.addItem('Test On Val')

        self.UpdateSheet()

    def _SearchSpecificFile(self,
                            feature_number,
                            specific_file_name,
                            specific_file_name2=''):
        for rt, folder, files in os.walk(self._root_folder):
            for file_name in files:
                # print(file_name)
                if specific_file_name2:
                    if (file_name.lower() == specific_file_name.lower()) and \
                            ('_{:d}_'.format(feature_number) in rt) and \
                            (specific_file_name2 in rt):
                        return os.path.join(rt, file_name)
                else:
                    if (file_name.lower() == specific_file_name.lower()) and (
                            '_{:d}_'.format(feature_number) in rt):
                        return os.path.join(rt, file_name)

        return ''
Ejemplo n.º 9
0
    def ClearAll(self):

        self.buttonLoadResult.setEnabled(True)
        self.buttonSave.setEnabled(False)
        self.buttonClearResult.setEnabled(False)

        self.checkROCCVTrain.setChecked(False)
        self.checkROCCVValidation.setChecked(False)
        self.checkROCTrain.setChecked(False)
        self.checkROCTest.setChecked(False)
        self.checkPlotCVTrain.setChecked(False)
        self.checkPlotCVValidation.setChecked(False)
        self.checkPlotTrain.setChecked(False)
        self.checkPlotTest.setChecked(False)
        self.checkPlotMaximum.setChecked(False)
        self.checkContributionShow.setChecked(False)
        self.radioContributionFeatureSelector.setChecked(True)
        self.radioContributionFeatureSelector.setChecked(False)
        self.checkMaxFeatureNumber.setChecked(False)
        self.canvasROC.getFigure().clear()
        self.canvasPlot.getFigure().clear()
        self.canvasFeature.getFigure().clear()
        self.__plt_roc = self.canvasROC.getFigure().add_subplot(111)
        self.__plt_plot = self.canvasPlot.getFigure().add_subplot(111)
        self.__contribution = self.canvasFeature.getFigure().add_subplot(111)
        self.canvasROC.draw()
        self.canvasPlot.draw()
        self.canvasFeature.draw()

        self.textEditDescription.clear()
        self.lineEditResultPath.clear()

        self.comboSheet.clear()
        self.comboClassifier.clear()
        self.comboDimensionReduction.clear()
        self.comboNormalizer.clear()
        self.comboFeatureSelector.clear()

        self.comboPlotClassifier.clear()
        self.comboPlotDimensionReduction.clear()
        self.comboPlotFeatureSelector.clear()
        self.comboPlotNormalizer.clear()
        self.comboPlotX.clear()
        self.comboPlotY.clear()

        self.comboContributionClassifier.clear()
        self.comboContributionFeatureSelector.clear()

        self.spinBoxFeatureNumber.setValue(0)
        self.spinPlotFeatureNumber.setValue(0)
        self.spinPlotFeatureNumber.setEnabled(False)
        self.spinFeatureSelectorFeatureNumber.setValue(1)
        self.spinClassifierFeatureNumber.setValue(1)

        self.tableClinicalStatistic.clear()

        self.tableClinicalStatistic.setRowCount(0)
        self.tableClinicalStatistic.setColumnCount(0)
        self.tableClinicalStatistic.setHorizontalHeaderLabels(list([]))
        self.tableClinicalStatistic.setVerticalHeaderLabels(list([]))

        self._fae = FeatureAnalysisPipelines()
        self._root_folder = ''
        self.sheet_dict = dict()
Ejemplo n.º 10
0
class VisualizationConnection(QWidget, Ui_Visualization):
    def __init__(self, parent=None):
        self._root_folder = ''
        self._fae = FeatureAnalysisPipelines()
        self.sheet_dict = dict()
        self.logger = eclog(os.path.split(__file__)[-1]).GetLogger()
        self.__is_ui_ready = False
        self.__is_clear = False

        super(VisualizationConnection, self).__init__(parent)
        self.setupUi(self)

        self.buttonLoadResult.clicked.connect(self.LoadAll)
        self.buttonClearResult.clicked.connect(self.ClearAll)
        self.buttonSave.clicked.connect(self.Save)
        self.buttonGenerateDescription.clicked.connect(self.GenerateDescription)

        self.__plt_roc = self.canvasROC.getFigure().add_subplot(111)
        self.__plt_plot = self.canvasPlot.getFigure().add_subplot(111)
        self.__contribution = self.canvasFeature.getFigure().add_subplot(111)

        # Update Sheet
        self.tableClinicalStatistic.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableClinicalStatistic.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.comboSheet.currentIndexChanged.connect(self.UpdateSheet)
        self.checkMaxFeatureNumber.stateChanged.connect(self.UpdateSheet)
        self.tableClinicalStatistic.itemSelectionChanged.connect(self.ShowOneResult)

        # Update ROC canvas
        self.comboNormalizer.currentIndexChanged.connect(self.UpdateROC)
        self.comboDimensionReduction.currentIndexChanged.connect(self.UpdateROC)
        self.comboFeatureSelector.currentIndexChanged.connect(self.UpdateROC)
        self.comboClassifier.currentIndexChanged.connect(self.UpdateROC)
        self.spinBoxFeatureNumber.valueChanged.connect(self.UpdateROC)
        self.checkROCCVTrain.stateChanged.connect(self.UpdateROC)
        self.checkROCCVValidation.stateChanged.connect(self.UpdateROC)
        self.checkROCTrain.stateChanged.connect(self.UpdateROC)
        self.checkROCTest.stateChanged.connect(self.UpdateROC)

        # Update Plot canvas
        self.comboPlotX.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotY.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotNormalizer.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotDimensionReduction.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotFeatureSelector.currentIndexChanged.connect(self.UpdatePlot)
        self.comboPlotClassifier.currentIndexChanged.connect(self.UpdatePlot)
        self.spinPlotFeatureNumber.valueChanged.connect(self.UpdatePlot)

        self.checkPlotCVTrain.stateChanged.connect(self.UpdatePlot)
        self.checkPlotCVValidation.stateChanged.connect(self.UpdatePlot)
        self.checkPlotTrain.stateChanged.connect(self.UpdatePlot)
        self.checkPlotOneSE.stateChanged.connect(self.UpdatePlot)
        self.checkPlotTest.stateChanged.connect(self.UpdatePlot)
       #

        # Update Contribution canvas
        self.radioContributionFeatureSelector.toggled.connect(self.UpdateContribution)
        self.radioContributionClassifier.toggled.connect(self.UpdateContribution)
        self.comboContributionNormalizor.currentIndexChanged.connect(self.UpdateContribution)
        self.comboContributionDimension.currentIndexChanged.connect(self.UpdateContribution)
        self.comboContributionFeatureSelector.currentIndexChanged.connect(self.UpdateContribution)
        self.comboContributionClassifier.currentIndexChanged.connect(self.UpdateContribution)
        self.spinContributeFeatureNumber.valueChanged.connect(self.UpdateContribution)

    def LoadAll(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
            if not r'.FAEresult4129074093819729087' in os.listdir(self._root_folder):
                QMessageBox.about(self, 'Load Error', 'This folder is not supported for import')
                return

            try:
                self.lineEditResultPath.setText(self._root_folder)
                self._fae.LoadAll(self._root_folder)
                self.SetResultDescription()
                self.SetResultTable()
                self.InitialUi()
            except Exception as ex:
                QMessageBox.about(self, "Load Error", ex.__str__())
                self.logger.log('Load Error, The reason is ' + str(ex))
                self.ClearAll()
                return

            self.buttonClearResult.setEnabled(True)
            self.buttonSave.setEnabled(True)
            self.buttonLoadResult.setEnabled(False)

    def ClearAll(self):
        self.__is_clear = True
        self.buttonLoadResult.setEnabled(True)
        self.buttonSave.setEnabled(False)
        self.buttonClearResult.setEnabled(False)

        self.checkROCCVTrain.setChecked(False)
        self.checkROCCVValidation.setChecked(False)
        self.checkROCTrain.setChecked(False)
        self.checkROCTest.setChecked(False)
        self.checkPlotCVTrain.setChecked(False)
        self.checkPlotCVValidation.setChecked(False)
        self.checkPlotTrain.setChecked(False)
        self.checkPlotOneSE.setChecked(False)
        self.checkPlotTest.setChecked(False)
        self.radioContributionFeatureSelector.setChecked(False)
        self.checkMaxFeatureNumber.setChecked(False)
        self.canvasROC.getFigure().clear()
        self.canvasPlot.getFigure().clear()
        self.canvasFeature.getFigure().clear()
        self.__plt_roc = self.canvasROC.getFigure().add_subplot(111)
        self.__plt_plot = self.canvasPlot.getFigure().add_subplot(111)
        self.__contribution = self.canvasFeature.getFigure().add_subplot(111)
        self.canvasROC.draw()
        self.canvasPlot.draw()
        self.canvasFeature.draw()

        self.textEditDescription.clear()
        self.lineEditResultPath.clear()

        self.comboSheet.clear()
        self.comboClassifier.clear()
        self.comboDimensionReduction.clear()
        self.comboNormalizer.clear()
        self.comboFeatureSelector.clear()

        self.comboPlotClassifier.clear()
        self.comboPlotDimensionReduction.clear()
        self.comboPlotFeatureSelector.clear()
        self.comboPlotNormalizer.clear()
        self.comboPlotX.clear()
        self.comboPlotY.clear()

        self.comboContributionNormalizor.clear()
        self.comboContributionDimension.clear()
        self.comboContributionClassifier.clear()
        self.comboContributionFeatureSelector.clear()

        self.spinBoxFeatureNumber.setValue(0)
        self.spinPlotFeatureNumber.setValue(0)
        self.spinPlotFeatureNumber.setEnabled(False)
        self.spinContributeFeatureNumber.setValue(1)

        self.tableClinicalStatistic.clear()
        self.tableClinicalStatistic.setRowCount(0)
        self.tableClinicalStatistic.setColumnCount(0)
        self.tableClinicalStatistic.setHorizontalHeaderLabels(list([]))
        self.tableClinicalStatistic.setVerticalHeaderLabels(list([]))

        self._fae = FeatureAnalysisPipelines()
        self._root_folder = ''
        self.sheet_dict = dict()
        self.__is_ui_ready = False
        self.__is_clear = False

    def Save(self):
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.DirectoryOnly)
        dlg.setOption(QFileDialog.ShowDirsOnly)

        if dlg.exec_():
            store_folder = dlg.selectedFiles()[0]
            try:
                self.canvasROC.getFigure().savefig(os.path.join(store_folder, 'ROC.eps'), dpi=1200)
                self.canvasROC.getFigure().savefig(os.path.join(store_folder, 'ROC.jpg'), dpi=300)
            except Exception as e:
                QMessageBox.about(self, 'Save Figure Failed', 'There is no ROC figure.\n' + e.__str__())

            try:
                self.canvasPlot.getFigure().savefig(os.path.join(store_folder, 'Compare.eps'), dpi=1200)
                self.canvasPlot.getFigure().savefig(os.path.join(store_folder, 'Compare.jpg'), dpi=300)
            except Exception as e:
                QMessageBox.about(self, 'Save Figure Failed', 'There is no AUC comparison figure.\n' + e.__str__())

            try:
                self.canvasFeature.getFigure().savefig(os.path.join(store_folder, 'FeatureWeights.eps'), dpi=1200)
                self.canvasFeature.getFigure().savefig(os.path.join(store_folder, 'FeatureWeights.jpg'), dpi=300)
            except Exception as e:
                QMessageBox.about(self, 'Save Figure Failed', 'There is no Feature Contribution figure.\n' + e.__str__())

    def InitialUi(self):
        # Update ROC canvers
        for normalizer in self._fae.GetNormalizerList():
            self.comboNormalizer.addItem(normalizer.GetName())
        for dimension_reduction in self._fae.GetDimensionReductionList():
            self.comboDimensionReduction.addItem(dimension_reduction.GetName())
        for classifier in self._fae.GetClassifierList():
            self.comboClassifier.addItem(classifier.GetName())
        for feature_selector in self._fae.GetFeatureSelectorList():
            self.comboFeatureSelector.addItem(feature_selector.GetName())
        self.spinBoxFeatureNumber.setMinimum(int(self._fae.GetFeatureNumberList()[0]))
        self.spinBoxFeatureNumber.setMaximum(int(self._fae.GetFeatureNumberList()[-1]))

        # Update Plot canvars
        if len(self._fae.GetNormalizerList()) > 1:
            self.comboPlotX.addItem('Normaliaztion')
        if len(self._fae.GetDimensionReductionList()) > 1:
            self.comboPlotX.addItem('Dimension Reduction')
        if len(self._fae.GetFeatureSelectorList()) > 1:
            self.comboPlotX.addItem('Feature Selector')
        if len(self._fae.GetClassifierList()) > 1:
            self.comboPlotX.addItem('Classifier')
        if len(self._fae.GetFeatureNumberList()) > 1:
            self.comboPlotX.addItem('Feature Number')

        self.comboPlotY.addItem('AUC')

        for index in self._fae.GetNormalizerList():
            self.comboPlotNormalizer.addItem(index.GetName())
        for index in self._fae.GetDimensionReductionList():
            self.comboPlotDimensionReduction.addItem(index.GetName())
        for index in self._fae.GetFeatureSelectorList():
            self.comboPlotFeatureSelector.addItem(index.GetName())
        for index in self._fae.GetClassifierList():
            self.comboPlotClassifier.addItem(index.GetName())
        self.spinPlotFeatureNumber.setMinimum(int(self._fae.GetFeatureNumberList()[0]))
        self.spinPlotFeatureNumber.setMaximum(int(self._fae.GetFeatureNumberList()[-1]))

        # Update Contribution canvas
        for index in self._fae.GetNormalizerList():
            self.comboContributionNormalizor.addItem(index.GetName())
        for index in self._fae.GetDimensionReductionList():
            self.comboContributionDimension.addItem(index.GetName())
        for selector in self._fae.GetFeatureSelectorList():
            self.comboContributionFeatureSelector.addItem(selector.GetName())
        for classifier in self._fae.GetClassifierList():
            specific_name = classifier.GetName() + '_coef.csv'
            if self._SearchSpecificFile(int(self._fae.GetFeatureNumberList()[0]), specific_name):
                self.comboContributionClassifier.addItem(classifier.GetName())
        self.spinContributeFeatureNumber.setMinimum(int(self._fae.GetFeatureNumberList()[0]))
        self.spinContributeFeatureNumber.setMaximum(int(self._fae.GetFeatureNumberList()[-1]))

        self.__is_ui_ready = True

    def UpdateROC(self):
        if not self.__is_ui_ready:
            return
        if (self.comboNormalizer.count() == 0) or \
                (self.comboDimensionReduction.count() == 0) or \
                (self.comboFeatureSelector.count() == 0) or \
                (self.comboClassifier.count() == 0) or \
                (self.spinBoxFeatureNumber.value() == 0):
            return

        case_name = self.comboNormalizer.currentText() + '_' + \
                    self.comboDimensionReduction.currentText() + '_' + \
                    self.comboFeatureSelector.currentText() + '_' + \
                    str(self.spinBoxFeatureNumber.value()) + '_' + \
                    self.comboClassifier.currentText()

        case_folder = os.path.join(self._root_folder, case_name)

        pred_list, label_list, name_list = [], [], []
        if self.checkROCCVTrain.isChecked():
            train_pred = np.load(os.path.join(case_folder, 'train_predict.npy'))
            train_label = np.load(os.path.join(case_folder, 'train_label.npy'))
            pred_list.append(train_pred)
            label_list.append(train_label)
            name_list.append('CV Train')
        if self.checkROCCVValidation.isChecked():
            val_pred = np.load(os.path.join(case_folder, 'val_predict.npy'))
            val_label = np.load(os.path.join(case_folder, 'val_label.npy'))
            pred_list.append(val_pred)
            label_list.append(val_label)
            name_list.append('CV Validation')
        if self.checkROCTrain.isChecked():
            all_train_pred = np.load(os.path.join(case_folder, 'all_train_predict.npy'))
            all_train_label = np.load(os.path.join(case_folder, 'all_train_label.npy'))
            pred_list.append(all_train_pred)
            label_list.append(all_train_label)
            name_list.append('Train')
        if self.checkROCTest.isChecked():
            if os.path.exists(os.path.join(case_folder, 'test_label.npy')):
                test_pred = np.load(os.path.join(case_folder, 'test_predict.npy'))
                test_label = np.load(os.path.join(case_folder, 'test_label.npy'))
                pred_list.append(test_pred)
                label_list.append(test_label)
                name_list.append('Test')

        if len(pred_list) > 0:
            DrawROCList(pred_list, label_list, name_list=name_list, is_show=False, fig=self.canvasROC.getFigure())

        self.canvasROC.draw()

    def _UpdatePlotButtons(self, selected_index):
        index = [0, 0, 0, 0, 0]

        self.comboPlotNormalizer.setEnabled(True)
        self.comboPlotDimensionReduction.setEnabled(True)
        self.comboPlotFeatureSelector.setEnabled(True)
        self.comboPlotClassifier.setEnabled(True)
        self.spinPlotFeatureNumber.setEnabled(True)
        index[0] = self.comboPlotNormalizer.currentIndex()
        index[1] = self.comboPlotDimensionReduction.currentIndex()
        index[2] = self.comboPlotFeatureSelector.currentIndex()
        index[4] = self.comboPlotClassifier.currentIndex()
        index[3] = self.spinPlotFeatureNumber.value() - int(self._fae.GetFeatureNumberList()[0])

        if selected_index == 0:
            self.comboPlotNormalizer.setEnabled(False)
            index[0] = [temp for temp in range(len(self._fae.GetNormalizerList()))]
        elif selected_index == 1:
            self.comboPlotDimensionReduction.setEnabled(False)
            index[1] = [temp for temp in range(len(self._fae.GetDimensionReductionList()))]
        elif selected_index == 2:
            self.comboPlotFeatureSelector.setEnabled(False)
            index[2] = [temp for temp in range(len(self._fae.GetFeatureSelectorList()))]
        elif selected_index == 4:
            self.comboPlotClassifier.setEnabled(False)
            index[4] = [temp for temp in range(len(self._fae.GetClassifierList()))]
        elif selected_index == 3:
            self.spinPlotFeatureNumber.setEnabled(False)
            index[3] = [temp for temp in range(len(self._fae.GetFeatureNumberList()))]

        return index

    def UpdatePlot(self):
        if (not self.__is_ui_ready) or self.__is_clear:
            return

        if self.comboPlotX.count() == 0:
            return

        x_ticks = []
        x_label = ''
        selected_index = -1
        if self.comboPlotX.currentText() == 'Normaliaztion':
            selected_index = 0
            x_ticks = [instance.GetName() for instance in self._fae.GetNormalizerList()]
            x_label = 'Normalization Method'
        elif self.comboPlotX.currentText() == 'Dimension Reduction':
            selected_index = 1
            x_ticks = [instance.GetName() for instance in self._fae.GetDimensionReductionList()]
            x_label = 'Dimension Reduction Method'
        elif self.comboPlotX.currentText() == 'Feature Selector':
            selected_index = 2
            x_ticks = [instance.GetName() for instance in self._fae.GetFeatureSelectorList()]
            x_label = 'Feature Selecotr Method'
        elif self.comboPlotX.currentText() == 'Classifier':
            selected_index = 4
            x_ticks = [instance.GetName() for instance in self._fae.GetClassifierList()]
            x_label = 'Classifier Method'
        elif self.comboPlotX.currentText() == 'Feature Number':
            selected_index = 3
            x_ticks = list(map(int, self._fae.GetFeatureNumberList()))
            x_label = 'Feature Number'

        max_axis_list = [0, 1, 2, 3, 4]
        max_axis_list.remove(selected_index)
        max_axis = tuple(max_axis_list)

        index = self._UpdatePlotButtons(selected_index)

        show_data = []
        show_data_std =[]
        name_list = []

        if self.comboPlotY.currentText() == 'AUC':
            if self.checkPlotCVTrain.isChecked():
                temp = deepcopy(self._fae.GetAUCMetric()['train'])
                auc_std = deepcopy(self._fae.GetAUCstdMetric()['train'])
                show_data.append(temp[tuple(index)].tolist())
                show_data_std.append(auc_std[tuple(index)].tolist())
                name_list.append('CV Train')
            if self.checkPlotCVValidation.isChecked():
                temp = deepcopy(self._fae.GetAUCMetric()['val'])
                auc_std = deepcopy(self._fae.GetAUCstdMetric()['val'])
                show_data.append(temp[tuple(index)].tolist())
                show_data_std.append(auc_std[tuple(index)].tolist())
                name_list.append('CV Validation')
            if self.checkPlotTrain.isChecked():
                temp = deepcopy(self._fae.GetAUCMetric()['all_train'])
                auc_std = deepcopy(self._fae.GetAUCstdMetric()['all_train'])
                show_data.append(temp[tuple(index)].tolist())
                show_data_std.append(auc_std[tuple(index)].tolist())
                name_list.append('Train')
            if self.checkPlotTest.isChecked():
                temp = deepcopy(self._fae.GetAUCMetric()['test'])
                auc_std = deepcopy(self._fae.GetAUCstdMetric()['test'])
                if temp.size > 0:
                    show_data.append(temp[tuple(index)].tolist())
                    show_data_std.append(auc_std[tuple(index)].tolist())
                    name_list.append('Test')


        if len(show_data) > 0:
            if selected_index == 3:
                DrawCurve(x_ticks, show_data, show_data_std, xlabel=x_label, ylabel=self.comboPlotY.currentText(),
                          name_list=name_list, is_show=False, one_se=self.checkPlotOneSE.isChecked(), fig=self.canvasPlot.getFigure())
            else:
                DrawBar(x_ticks, show_data, ylabel=self.comboPlotY.currentText(),
                          name_list=name_list, is_show=False, fig=self.canvasPlot.getFigure())

        self.canvasPlot.draw()

    def UpdateContribution(self):
        if (not self.__is_ui_ready) or self.__is_clear:
            return

        try:
            one_result_folder_name = self.comboContributionNormalizor.currentText() + '_' + \
                                self.comboContributionDimension.currentText() + '_' + \
                                self.comboContributionFeatureSelector.currentText() + '_' + \
                                str(self.spinContributeFeatureNumber.value()) + '_' + \
                                self.comboContributionClassifier.currentText()
            one_result_folder = os.path.join(self._root_folder, one_result_folder_name)
            # This is compatible with the previous version
            if not os.path.exists(one_result_folder):
                one_result_folder_name = self.comboContributionNormalizor.currentText() + '_Cos_' + \
                                         self.comboContributionFeatureSelector.currentText() + '_' + \
                                         str(self.spinContributeFeatureNumber.value()) + '_' + \
                                         self.comboContributionClassifier.currentText()
                one_result_folder = os.path.join(self._root_folder, one_result_folder_name)

            if self.radioContributionFeatureSelector.isChecked():
                file_name = self.comboContributionFeatureSelector.currentText() + '_sort.csv'
                file_path = os.path.join(one_result_folder, file_name)

                if not os.path.exists(file_path):
                    file_name = self.comboContributionFeatureSelector.currentText().lower() + '_sort.csv'
                    file_path = os.path.join(one_result_folder, file_name)

                if file_path:
                    df = pd.read_csv(file_path, index_col=0)
                    value = list(df.iloc[:, 0])

                    sort_by = df.columns.values[0]
                    if sort_by == 'rank':
                        reverse = False
                    elif sort_by == 'F' or sort_by == 'weight':
                        reverse = True
                    else:
                        reverse = False
                        print('Invalid feature selector sort name.')

                    #add positive and negatiove info for coef
                    processed_feature_name = list(df.index)
                    original_value = list(df.iloc[:, 0])
                    for index in range(len(original_value)):
                        if original_value[index] > 0:
                            processed_feature_name[index] = processed_feature_name[index] + ' P'
                        else:
                            processed_feature_name[index] = processed_feature_name[index] + ' N'

                    GeneralFeatureSort(processed_feature_name, value, max_num=self.spinContributeFeatureNumber.value(),
                                       is_show=False, fig=self.canvasFeature.getFigure(), reverse=reverse)

            elif self.radioContributionClassifier.isChecked():
                specific_name = self.comboContributionClassifier.currentText() + '_coef.csv'
                file_path = os.path.join(one_result_folder, specific_name)

                if not os.path.exists(file_path):
                    specific_name = self.comboContributionClassifier.currentText().lower() + '_coef.csv'
                    file_path = os.path.join(one_result_folder, specific_name)

                if file_path:
                    df = pd.read_csv(file_path, index_col=0)
                    feature_name = list(df.index)
                    value = list(np.abs(df.iloc[:, 0]))

                    #add positive and negatiove info for coef
                    processed_feature_name = list(df.index)
                    original_value = list(df.iloc[:, 0])
                    for index in range(len(original_value)):
                        if original_value[index] > 0:
                            processed_feature_name[index] = processed_feature_name[index] + ' P'
                        else:
                            processed_feature_name[index] = processed_feature_name[index] + ' N'

                    # try:
                    #     SortRadiomicsFeature(processed_feature_name, value, is_show=False, fig=self.canvasFeature.getFigure())
                    # except:
                    GeneralFeatureSort(processed_feature_name, value,
                                           is_show=False, fig=self.canvasFeature.getFigure())
            self.canvasFeature.draw()
        except Exception as e:
            content = 'In Visualization, UpdateContribution failed'
            self.logger.error('{}{}'.format(content, str(e)))
            QMessageBox.about(self, content, e.__str__())

    def SetResultDescription(self):
        text = "Normalizer:\n"
        for index in self._fae.GetNormalizerList():
            text += (index.GetName() + '\n')
        text += '\n'

        text += "Dimension Reduction:\n"
        for index in self._fae.GetDimensionReductionList():
            text += (index.GetName() + '\n')
        text += '\n'

        text += "Feature Selector:\n"
        for index in self._fae.GetFeatureSelectorList():
            text += (index.GetName() + '\n')
        text += '\n'

        text += "Feature Number:\n"
        text += "{:s} - {:s}\n".format(self._fae.GetFeatureNumberList()[0], self._fae.GetFeatureNumberList()[-1])
        text += '\n'

        text += "Classifier:\n"
        for index in self._fae.GetClassifierList():
            text += (index.GetName() + '\n')
        text += '\n'

        text += 'Cross Validation: ' + self._fae.GetCrossValidation().GetName()

        self.textEditDescription.setPlainText(text)

    def UpdateSheet(self):
        if self.__is_clear:
            self.comboSheet.setEnabled(False)
            return None


        if self.checkMaxFeatureNumber.isChecked():
            self.comboSheet.setEnabled(False)
        else:
            self.comboSheet.setEnabled(True)

        self.tableClinicalStatistic.clear()
        self.tableClinicalStatistic.setSortingEnabled(False)
        if self.comboSheet.currentText() == 'Train':
            df = self.sheet_dict['train']
        elif self.comboSheet.currentText() == 'Validation':
            df = self.sheet_dict['val']
        elif self.comboSheet.currentText() == 'Test':
            df = self.sheet_dict['test']
        else:
            return

        if self.checkMaxFeatureNumber.isChecked():
            self.sheet_dict['test'] = pd.read_csv(os.path.join(self._root_folder, 'test_result.csv'), index_col=0)
            data = self._fae.GetAUCMetric()['val']
            std_data = self._fae.GetAUCstdMetric()['val']
            df_val = self.sheet_dict['val']
            df_test = self.sheet_dict['test']
            name_list = []
            for normalizer_index, normalizer in enumerate(self._fae.GetNormalizerList()):
                for dimension_reducer_index, dimension_reducer in enumerate(self._fae.GetDimensionReductionList()):
                    for feature_selector_index, feature_selector in enumerate(self._fae.GetFeatureSelectorList()):
                        for classifier_index, classifier in enumerate(self._fae.GetClassifierList()):
                            sub_auc = data[normalizer_index, dimension_reducer_index, feature_selector_index, :,
                                      classifier_index]
                            sub_auc_std = std_data[normalizer_index, dimension_reducer_index, feature_selector_index, :,
                                      classifier_index]
                            one_se = max(sub_auc)-sub_auc_std[np.argmax(sub_auc)]
                            for feature_number_index in range(len(self._fae.GetFeatureNumberList())):
                                if data[normalizer_index, dimension_reducer_index,
                                        feature_selector_index, feature_number_index, classifier_index] >= one_se:
                                    name = normalizer.GetName() + '_' + dimension_reducer.GetName() + '_' + \
                                            feature_selector.GetName() + '_' + str(self._fae.GetFeatureNumberList()[feature_number_index]) + '_' + \
                                            classifier.GetName()
                                    name_list.append(name)
                                    break

            # choose the selected models from all test result
            df_val = df_val.loc[name_list]
            max_index = df_val['auc'].idxmax()
            sub_serise = df_val.loc[max_index]
            max_array = sub_serise.get_values().reshape(1, -1)
            max_auc_df = pd.DataFrame(data=max_array, columns=sub_serise.index.tolist(), index=[max_index])
            max_auc_95ci = max_auc_df.at[max_index, 'auc 95% CIs']

            max_auc_95ci = re.findall(r"\d+\.?\d*", max_auc_95ci)
            sub_val_df = df_val[(df_val['auc'] >= float(max_auc_95ci[0])) & (df_val['auc'] <= float(max_auc_95ci[1]))]

            index_by_val = sub_val_df.index.tolist()

            df = df_test.loc[index_by_val]

        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)
        # self.tableClinicalStatistic.setVerticalHeaderLabels(list(df.index))

        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 SetResultTable(self):
        self.sheet_dict['train'] = pd.read_csv(os.path.join(self._root_folder, 'train_result.csv'), index_col=0)
        self.comboSheet.addItem('Train')
        self.sheet_dict['val'] = pd.read_csv(os.path.join(self._root_folder, 'val_result.csv'), index_col=0)
        self.comboSheet.addItem('Validation')
        if os.path.exists(os.path.join(self._root_folder, 'test_result.csv')):
            self.sheet_dict['test'] = pd.read_csv(os.path.join(self._root_folder, 'test_result.csv'), index_col=0)
            self.comboSheet.addItem('Test')

        self.UpdateSheet()

    def _SearchSpecificFile(self, feature_number, specific_file_name, specific_file_name2=''):
        for rt, folder, files in os.walk(self._root_folder):
            for file_name in files:
                # print(file_name)
                if specific_file_name2:
                    if (file_name.lower() == specific_file_name.lower()) and \
                            ('_{:d}_'.format(feature_number) in rt) and \
                            (specific_file_name2 in rt):
                        return os.path.join(rt, file_name)
                else:
                    if (file_name.lower() == specific_file_name.lower()) and ('_{:d}_'.format(feature_number) in rt):
                        return os.path.join(rt, file_name)
        return ''

    def ShowOneResult(self):
        try:
            # for index in self.tableClinicalStatistic.selectedIndexes():
            if not self.tableClinicalStatistic.selectedIndexes():
                return None
            index = self.tableClinicalStatistic.selectedIndexes()[0]
            row = index.row()
            one_item = self.tableClinicalStatistic.item(row, 0)
            text = str(one_item.text())
            current_normalizer, current_dimension_reducer, current_feature_selector, current_feature_number, current_classifier = \
                text.split('_')

            self.comboNormalizer.setCurrentText(current_normalizer)
            self.comboDimensionReduction.setCurrentText(current_dimension_reducer)
            self.comboFeatureSelector.setCurrentText(current_feature_selector)
            self.comboClassifier.setCurrentText(current_classifier)
            self.spinBoxFeatureNumber.setValue(int(current_feature_number))
            if not (self.checkROCTrain.isChecked() or self.checkROCCVTrain.isChecked() or
                    self.checkROCCVValidation.isChecked() or self.checkROCTrain.isChecked()):
                self.checkROCCVTrain.setCheckState(True)
                self.checkROCCVValidation.setCheckState(True)
            self.UpdateROC()

            # Update the AUC versus feature number
            self.comboPlotNormalizer.setCurrentText(current_normalizer)
            self.comboPlotDimensionReduction.setCurrentText(current_dimension_reducer)
            self.comboPlotFeatureSelector.setCurrentText(current_feature_selector)
            self.comboPlotClassifier.setCurrentText(current_classifier)
            self.comboPlotX.setCurrentText('Feature Number')
            if not (self.checkPlotTrain.isChecked() or
                    self.checkPlotCVTrain.isChecked() or
                    self.checkPlotCVValidation.isChecked()):
                self.checkPlotCVValidation.setCheckState(True)
            self.UpdatePlot()


            # Update the Contribution
            self.comboContributionNormalizor.setCurrentText(current_normalizer)
            self.comboContributionDimension.setCurrentText(current_dimension_reducer)
            self.comboContributionFeatureSelector.setCurrentText(current_feature_selector)
            self.comboContributionClassifier.setCurrentText(current_classifier)
            self.spinContributeFeatureNumber.setValue(int(current_feature_number))
            self.UpdateContribution()

        except Exception as e:
            content = 'Visualization, ShowOneResult failed: '
            self.logger.error('{}{}'.format(content, str(e)))
            QMessageBox.about(self, content, e.__str__())

    def GenerateDescription(self):
        if (self.comboNormalizer.count() == 0) or \
                (self.comboDimensionReduction.count() == 0) or \
                (self.comboFeatureSelector.count() == 0) or \
                (self.comboClassifier.count() == 0) or \
                (self.spinBoxFeatureNumber.value() == 0):
            return

        case_name = self.comboNormalizer.currentText() + '_' + \
                    self.comboDimensionReduction.currentText() + '_' + \
                    self.comboFeatureSelector.currentText() + '_' + \
                    str(self.spinBoxFeatureNumber.value()) + '_' + \
                    self.comboClassifier.currentText()

        case_folder = os.path.join(self._root_folder, case_name)
        current_pipeline = OnePipeline()
        try:
            current_pipeline.LoadPipeline(os.path.join(case_folder, 'pipeline_info.csv'))
        except Exception as ex:
            QMessageBox.about(self, "In Description, Load Pipeline_info Error", ex.__str__())
            self.logger.error('Load Pipeline Error, The reason is ' + str(ex))

        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.DirectoryOnly)
        dlg.setOption(QFileDialog.ShowDirsOnly)

        if dlg.exec_():
            store_folder = dlg.selectedFiles()[0]
            roc_path = os.path.join(store_folder, 'ROC.jpg')
            self.canvasROC.getFigure().savefig(roc_path, dpi=300)

            report = Description()
            try:
                report.Run(current_pipeline, self._root_folder, store_folder)
                os.system("explorer.exe {:s}".format(os.path.normpath(store_folder)))
            except Exception as ex:
                QMessageBox.about(self, 'Description Generate Error: ', ex.__str__())
                self.logger.log('Description Generate Error:  ' + str(ex))
Ejemplo n.º 11
0
class ProcessConnection(QWidget, Ui_Process):
    def __init__(self, parent=None):
        self.__training_data_container = DataContainer()
        self.__testing_data_container = DataContainer()
        self.__fae = FeatureAnalysisPipelines()

        self.__process_normalizer_list = []
        self.__process_dimension_reduction_list = []
        self.__process_feature_selector_list = []
        self.__process_feature_number_list = []
        self.__process_classifier_list = []

        super(ProcessConnection, self).__init__(parent)
        self.setupUi(self)

        self.buttonLoadTrainingData.clicked.connect(self.LoadTrainingData)
        self.buttonLoadTestingData.clicked.connect(self.LoadTestingData)

        self.checkNormalizeUnit.clicked.connect(self.UpdatePipelineText)
        self.checkNormalizeZeroCenter.clicked.connect(self.UpdatePipelineText)
        self.checkNormalizeUnitWithZeroCenter.clicked.connect(
            self.UpdatePipelineText)

        self.checkPCA.clicked.connect(self.UpdatePipelineText)
        self.checkRemoveSimilarFeatures.clicked.connect(
            self.UpdatePipelineText)

        self.spinBoxMinFeatureNumber.valueChanged.connect(
            self.MinFeatureNumberChange)
        self.spinBoxMaxFeatureNumber.valueChanged.connect(
            self.MaxFeatureNumberChange)

        self.checkANOVA.clicked.connect(self.UpdatePipelineText)
        self.checkRFE.clicked.connect(self.UpdatePipelineText)
        self.checkRelief.clicked.connect(self.UpdatePipelineText)

        self.checkSVM.clicked.connect(self.UpdatePipelineText)
        self.checkLDA.clicked.connect(self.UpdatePipelineText)
        self.checkAE.clicked.connect(self.UpdatePipelineText)
        self.checkRF.clicked.connect(self.UpdatePipelineText)

        self.buttonRun.clicked.connect(self.Run)

        self.UpdatePipelineText()

    def LoadTrainingData(self):
        dlg = QFileDialog()
        file_name, _ = dlg.getOpenFileName(self,
                                           'Open SCV file',
                                           directory=r'C:\MyCode\FAE\Example',
                                           filter="csv files (*.csv)")
        try:
            self.__training_data_container.Load(file_name)
        except:
            print('Loading Training Data Error')

        self.lineEditTrainingData.setText(file_name)
        self.UpdateDataDescription()

    def LoadTestingData(self):
        dlg = QFileDialog()
        file_name, _ = dlg.getOpenFileName(self,
                                           'Open SCV file',
                                           filter="csv files (*.csv)")
        try:
            self.__testing_data_container.Load(file_name)
        except:
            print('Loading Testing Data Error')

        self.lineEditTestingData.setText(file_name)
        self.UpdateDataDescription()

    def SetVerboseTest(self, normalizer_name, dimension_reduction_name,
                       feature_selector_name, classifier_name, feature_num,
                       current_num, total_num):
        text = "Current:\n"

        text += "{:s} / ".format(normalizer_name)
        for temp in self.__process_normalizer_list:
            text += (temp.GetName() + ", ")
        text += '\n'

        text += "{:s} / ".format(dimension_reduction_name)
        for temp in self.__process_dimension_reduction_list:
            text += (temp.GetName() + ", ")
        text += '\n'

        text += "{:s} / ".format(feature_selector_name)
        for temp in self.__process_feature_selector_list:
            text += (temp.GetName() + ", ")
        text += '\n'

        text += "Feature Number: {:d} / [{:d}-{:d}]\n".format(
            feature_num, self.spinBoxMinFeatureNumber.value(),
            self.spinBoxMaxFeatureNumber.value())

        text += "{:s} / ".format(classifier_name)
        for temp in self.__process_classifier_list:
            text += (temp.GetName() + ", ")
        text += '\n'

        text += "Total process: {:d} / {:d}".format(current_num, total_num)

        self.textEditVerbose.setPlainText(text)

    def Run(self):
        if self.__training_data_container.IsEmpty():
            QMessageBox.about(self, '', '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:
                QMessageBox.about(self, 'The folder is not empty',
                                  'The folder is not empty')
                return

            self.textEditVerbose.setText(store_folder)
            if self.MakePipelines():
                for current_normalizer_name, current_dimension_reductor_name, \
                    current_feature_selector_name, curreent_feature_num, \
                    current_classifier_name, num, total_num\
                        in self.__fae.Run(self.__training_data_container, self.__testing_data_container, store_folder):
                    self.SetVerboseTest(current_normalizer_name,
                                        current_dimension_reductor_name,
                                        current_feature_selector_name,
                                        current_classifier_name,
                                        curreent_feature_num, num, total_num)
                    QApplication.processEvents()

                text = self.textEditVerbose.toPlainText()

                self.textEditVerbose.setPlainText(text + "\n DONE!")

                with open(store_folder + '\\.FAEresult4129074093819729087',
                          'wb') as file:
                    pass
                file_hidden = os.popen('attrib +h ' + store_folder +
                                       '\\.FAEresult4129074093819729087')
                file_hidden.close()

            else:
                QMessageBox.about(
                    self, 'Pipeline Error',
                    'Pipeline must include Classifier and CV method')

    def MinFeatureNumberChange(self):
        if self.spinBoxMinFeatureNumber.value(
        ) > self.spinBoxMaxFeatureNumber.value():
            self.spinBoxMinFeatureNumber.setValue(
                self.spinBoxMaxFeatureNumber.value())

        self.UpdatePipelineText()

    def MaxFeatureNumberChange(self):
        if self.spinBoxMaxFeatureNumber.value(
        ) < self.spinBoxMinFeatureNumber.value():
            self.spinBoxMaxFeatureNumber.setValue(
                self.spinBoxMinFeatureNumber.value())

        self.UpdatePipelineText()

    def MakePipelines(self):
        self.__process_normalizer_list = []
        if self.checkNormalizeUnit.isChecked():
            self.__process_normalizer_list.append(NormalizerUnit())
        if self.checkNormalizeZeroCenter.isChecked():
            self.__process_normalizer_list.append(NormalizerZeroCenter())
        if self.checkNormalizeUnitWithZeroCenter.isChecked():
            self.__process_normalizer_list.append(
                NormalizerZeroCenterAndUnit())
        if (not self.checkNormalizeUnit.isChecked()) and (not self.checkNormalizeZeroCenter.isChecked()) and \
                (not self.checkNormalizeUnitWithZeroCenter.isChecked()):
            self.__process_normalizer_list.append(NormalizerNone())

        self.__process_dimension_reduction_list = []
        if self.checkPCA.isChecked():
            self.__process_dimension_reduction_list.append(
                DimensionReductionByPCA())
        if self.checkRemoveSimilarFeatures.isChecked():
            self.__process_dimension_reduction_list.append(
                DimensionReductionByCos())

        self.__process_feature_selector_list = []
        if self.checkANOVA.isChecked():
            self.__process_feature_selector_list.append(
                FeatureSelectPipeline([FeatureSelectByANOVA()]))
        if self.checkRFE.isChecked():
            self.__process_feature_selector_list.append(
                FeatureSelectPipeline([FeatureSelectByRFE()]))
        if self.checkRelief.isChecked():
            self.__process_feature_selector_list.append(
                FeatureSelectPipeline([FeatureSelectByRelief()]))

        self.__process_feature_number_list = np.arange(
            self.spinBoxMinFeatureNumber.value(),
            self.spinBoxMaxFeatureNumber.value() + 1).tolist()

        self.__process_classifier_list = []
        if self.checkSVM.isChecked():
            self.__process_classifier_list.append(SVM())
        if self.checkLDA.isChecked():
            self.__process_classifier_list.append(LDA())
        if self.checkAE.isChecked():
            self.__process_classifier_list.append(AE())
        if self.checkRF.isChecked():
            self.__process_classifier_list.append(RandomForest())
        if len(self.__process_classifier_list) == 0:
            return False

        cv = CrossValidation()
        if self.radioLeaveOneOut.isChecked():
            cv.SetCV('LOO')
        elif self.radio5folder.isChecked():
            cv.SetCV('5-folder')
        elif self.radio10Folder.isChecked():
            cv.SetCV('10-folder')
        else:
            return False

        self.__fae.SetNormalizerList(self.__process_normalizer_list)
        self.__fae.SetDimensionReductionList(
            self.__process_dimension_reduction_list)
        self.__fae.SetFeatureSelectorList(self.__process_feature_selector_list)
        self.__fae.SetFeatureNumberList(self.__process_feature_number_list)
        self.__fae.SetClassifierList(self.__process_classifier_list)
        self.__fae.SetCrossValition(cv)
        self.__fae.GenerateMetircDict()

        return True

    def UpdateDataDescription(self):
        show_text = ""
        if self.__training_data_container.GetArray().size > 0:
            show_text += "The number of training cases: {:d}\n".format(
                len(self.__training_data_container.GetCaseName()))
            show_text += "The number of training features: {:d}\n".format(
                len(self.__training_data_container.GetFeatureName()))
            if len(np.unique(self.__training_data_container.GetLabel())) == 2:
                positive_number = len(
                    np.where(self.__training_data_container.GetLabel(
                    ) == np.max(self.__training_data_container.GetLabel()))[0])
                negative_number = len(self.__training_data_container.GetLabel(
                )) - positive_number
                assert (positive_number + negative_number == len(
                    self.__training_data_container.GetLabel()))
                show_text += "The number of training positive samples: {:d}\n".format(
                    positive_number)
                show_text += "The number of training negative samples: {:d}\n".format(
                    negative_number)

        show_text += '\n'
        if self.__testing_data_container.GetArray().size > 0:
            show_text += "The number of testing cases: {:d}\n".format(
                len(self.__testing_data_container.GetCaseName()))
            show_text += "The number of testing features: {:d}\n".format(
                len(self.__testing_data_container.GetFeatureName()))
            if len(np.unique(self.__testing_data_container.GetLabel())) == 2:
                positive_number = len(
                    np.where(self.__testing_data_container.GetLabel() == np.
                             max(self.__testing_data_container.GetLabel()))[0])
                negative_number = len(
                    self.__testing_data_container.GetLabel()) - positive_number
                assert (positive_number + negative_number == len(
                    self.__testing_data_container.GetLabel()))
                show_text += "The number of testing positive samples: {:d}\n".format(
                    positive_number)
                show_text += "The number of testing negative samples: {:d}\n".format(
                    negative_number)

        self.textEditDescription.setText(show_text)

    def UpdatePipelineText(self):
        self.listOnePipeline.clear()

        normalization_text = 'Normalization:\n'
        normalizer_num = 0
        if self.checkNormalizeUnit.isChecked():
            normalization_text += "Normalize unit\n"
            normalizer_num += 1
        if self.checkNormalizeZeroCenter.isChecked():
            normalization_text += "Normalize zero center\n"
            normalizer_num += 1
        if self.checkNormalizeUnitWithZeroCenter.isChecked():
            normalization_text += "Normalize unit with zero center\n"
            normalizer_num += 1
        if normalizer_num == 0:
            normalizer_num = 1
        self.listOnePipeline.addItem(normalization_text)

        preprocess_test = 'Preprocess:\n'
        if self.checkPCA.isChecked():
            preprocess_test += "PCA\n"
        if self.checkRemoveSimilarFeatures.isChecked():
            preprocess_test += "Remove Similary Features\n"
        self.listOnePipeline.addItem(preprocess_test)

        feature_selection_text = "Feature Selection:\n"
        if self.spinBoxMinFeatureNumber.value(
        ) == self.spinBoxMaxFeatureNumber.value():
            feature_selection_text += "Feature Number: " + str(
                self.spinBoxMinFeatureNumber.value()) + "\n"
        else:
            feature_selection_text += "Feature Number range: {:d}-{:d}\n".format(
                self.spinBoxMinFeatureNumber.value(),
                self.spinBoxMaxFeatureNumber.value())
        feature_num = self.spinBoxMaxFeatureNumber.value(
        ) - self.spinBoxMinFeatureNumber.value() + 1

        feature_selector_num = 0
        if self.checkANOVA.isChecked():
            feature_selection_text += "ANOVA\n"
            feature_selector_num += 1
        if self.checkRFE.isChecked():
            feature_selection_text += "RFE\n"
            feature_selector_num += 1
        if self.checkRelief.isChecked():
            feature_selection_text += "Relief\n"
            feature_selector_num += 1
        if feature_selector_num == 0:
            feature_selector_num = 1
        self.listOnePipeline.addItem(feature_selection_text)

        classifier_test = 'Classifier:\n'
        classifier_num = 0
        if self.checkSVM.isChecked():
            classifier_test += "SVM\n"
            classifier_num += 1
        if self.checkLDA.isChecked():
            classifier_test += "LDA\n"
            classifier_num += 1
        if self.checkAE.isChecked():
            classifier_test += "AE\n"
            classifier_num += 1
        if self.checkRF.isChecked():
            classifier_test += "RF\n"
            classifier_num += 1
        if classifier_num == 0:
            classifier_num = 1
        self.listOnePipeline.addItem(classifier_test)

        self.listOnePipeline.addItem(
            "Total number of pipelines is:\n{:d}".format(
                normalizer_num * feature_selector_num * feature_num *
                classifier_num))
Ejemplo n.º 12
0
class ReportConnection(QWidget, Ui_Report):
    def __init__(self, parent=None):
        self._root_folder = ''
        self._fae = FeatureAnalysisPipelines()
        self._training_data_container = DataContainer()
        self._testing_data_container = DataContainer()
        self._current_pipeline = OnePipeline()

        super(ReportConnection, self).__init__(parent)
        self.setupUi(self)

        self.buttonLoadTrainingData.clicked.connect(self.LoadTrainingData)
        self.buttonClearTrainingData.clicked.connect(self.ClearTrainingData)
        self.buttonLoadTestingData.clicked.connect(self.LoadTestingData)
        self.buttonClearTestingData.clicked.connect(self.ClearTestingData)

        self.buttonLoadResult.clicked.connect(self.LoadAll)
        self.buttonClearResult.clicked.connect(self.ClearAll)

        self.buttonGenerate.clicked.connect(self.Generate)

        self.__plt_roc = self.canvasROC.getFigure().add_subplot(111)

        # Update ROC canvas
        self.comboNormalizer.currentIndexChanged.connect(self.UpdateROC)
        self.comboDimensionReduction.currentIndexChanged.connect(
            self.UpdateROC)
        self.comboFeatureSelector.currentIndexChanged.connect(self.UpdateROC)
        self.comboClassifier.currentIndexChanged.connect(self.UpdateROC)
        self.spinBoxFeatureNumber.valueChanged.connect(self.UpdateROC)
        self.checkROCTrain.stateChanged.connect(self.UpdateROC)
        self.checkROCValidation.stateChanged.connect(self.UpdateROC)
        self.checkROCTest.stateChanged.connect(self.UpdateROC)

        self.SetPipelineStateButton(False)

    def Generate(self):
        if self._training_data_container.IsEmpty():
            QMessageBox.about(self, '', 'Load training data at least')
            return

        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.DirectoryOnly)
        dlg.setOption(QFileDialog.ShowDirsOnly)

        if dlg.exec_():
            store_folder = dlg.selectedFiles()[0]
            roc_path = os.path.join(store_folder, 'ROC.jpg')
            self.canvasROC.getFigure().savefig(roc_path, dpi=300)

            report = Report()
            try:
                report.Run(self._training_data_container,
                           self._current_pipeline, self._root_folder,
                           store_folder, self._testing_data_container)
                os.system("explorer.exe {:s}".format(
                    os.path.normpath(store_folder)))
            except Exception as ex:
                QMessageBox.about(self, 'Report Generate Error: ',
                                  ex.__str__())

    def LoadTrainingData(self):
        dlg = QFileDialog()
        file_name, _ = dlg.getOpenFileName(self,
                                           'Open SCV file',
                                           directory=r'C:\MyCode\FAE\Example',
                                           filter="csv files (*.csv)")
        try:
            self._training_data_container.Load(file_name)
            # self.SetStateButtonBeforeLoading(True)
            self.lineEditTrainingData.setText(file_name)
            self.UpdateDataDescription()
        except Exception as ex:
            QMessageBox.about(self, "Load Error", ex.__str__())

    def ClearTrainingData(self):
        self._training_data_container = DataContainer()
        # self.SetStateButtonBeforeLoading(False)
        self.lineEditTrainingData.setText("")
        self.UpdateDataDescription()

    def LoadTestingData(self):
        dlg = QFileDialog()
        file_name, _ = dlg.getOpenFileName(self,
                                           'Open SCV file',
                                           filter="csv files (*.csv)")
        try:
            self._testing_data_container.Load(file_name)
            self.lineEditTestingData.setText(file_name)
            self.UpdateDataDescription()
        except Exception as ex:
            QMessageBox.about(self, "Load Error", ex.__str__())

    def ClearTestingData(self):
        self._testing_data_container = DataContainer()
        self.lineEditTestingData.setText("")
        self.UpdateDataDescription()

    def UpdateDataDescription(self):
        show_text = ''
        if not self._training_data_container.IsEmpty():
            show_text += "The number of training cases: {:d}\n".format(
                len(self._training_data_container.GetCaseName()))
            show_text += "The number of training features: {:d}\n".format(
                len(self._training_data_container.GetFeatureName()))
            if len(np.unique(self._training_data_container.GetLabel())) == 2:
                positive_number = len(
                    np.where(self._training_data_container.GetLabel() == np.
                             max(self._training_data_container.GetLabel()))[0])
                negative_number = len(
                    self._training_data_container.GetLabel()) - positive_number
                assert (positive_number + negative_number == len(
                    self._training_data_container.GetLabel()))
                show_text += "The number of training positive samples: {:d}\n".format(
                    positive_number)
                show_text += "The number of training negative samples: {:d}\n".format(
                    negative_number)

        show_text += '\n'
        if not self._testing_data_container.IsEmpty():
            show_text += "The number of testing cases: {:d}\n".format(
                len(self._testing_data_container.GetCaseName()))
            show_text += "The number of testing features: {:d}\n".format(
                len(self._testing_data_container.GetFeatureName()))
            if len(np.unique(self._testing_data_container.GetLabel())) == 2:
                positive_number = len(
                    np.where(self._testing_data_container.GetLabel() == np.max(
                        self._testing_data_container.GetLabel()))[0])
                negative_number = len(
                    self._testing_data_container.GetLabel()) - positive_number
                assert (positive_number + negative_number == len(
                    self._testing_data_container.GetLabel()))
                show_text += "The number of testing positive samples: {:d}\n".format(
                    positive_number)
                show_text += "The number of testing negative samples: {:d}\n".format(
                    negative_number)

        self.textEditDataDescription.setText(show_text)

    def LoadAll(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
            if not r'.FAEresult4129074093819729087' in os.listdir(
                    self._root_folder):
                QMessageBox.about(self, 'Load Error',
                                  'This folder is not supported for import')
                return
            try:
                self.lineEditResultPath.setText(self._root_folder)
                self._fae.LoadAll(self._root_folder)
                self.SetResultDescription()
                self.InitialUi()
            except Exception as ex:
                QMessageBox.about(self, "Load Error", ex.__str__())
                self.ClearAll()
                return

            self.SetPipelineStateButton(True)

    def ClearAll(self):
        self.buttonLoadResult.setEnabled(True)
        self.buttonClearResult.setEnabled(False)

        self._fae = FeatureAnalysisPipelines()
        self.textEditDescription.setPlainText('')
        self.lineEditResultPath.setText('')
        self.InitialUi()

        self.checkROCTrain.setChecked(False)
        self.checkROCValidation.setChecked(False)
        self.checkROCTest.setChecked(False)

        self.spinBoxFeatureNumber.setValue(1)

        self.canvasROC.getFigure().clear()
        self.canvasROC.draw()

        self.SetPipelineStateButton(False)

    def SetPipelineStateButton(self, state):
        self.checkROCTrain.setEnabled(state)
        self.checkROCValidation.setEnabled(state)
        self.checkROCTest.setEnabled(state)

        self.comboNormalizer.setEnabled(state)
        self.comboDimensionReduction.setEnabled(state)
        self.comboFeatureSelector.setEnabled(state)
        self.comboClassifier.setEnabled(state)
        self.spinBoxFeatureNumber.setEnabled(state)

        self.buttonClearResult.setEnabled(state)
        self.buttonLoadResult.setEnabled(not state)

        self.buttonGenerate.setEnabled(state)

    def InitialUi(self):
        # Update ROC canvers
        self.comboNormalizer.clear()
        for normalizer in self._fae.GetNormalizerList():
            self.comboNormalizer.addItem(normalizer.GetName())
        self.comboDimensionReduction.clear()
        for dimension_reduction in self._fae.GetDimensionReductionList():
            self.comboDimensionReduction.addItem(dimension_reduction.GetName())
        self.comboClassifier.clear()
        for classifier in self._fae.GetClassifierList():
            self.comboClassifier.addItem(classifier.GetName())
        self.comboFeatureSelector.clear()
        for feature_selector in self._fae.GetFeatureSelectorList():
            self.comboFeatureSelector.addItem(feature_selector.GetName())

        if self._fae.GetFeatureNumberList() != []:
            self.spinBoxFeatureNumber.setMinimum(
                int(self._fae.GetFeatureNumberList()[0]))
            self.spinBoxFeatureNumber.setMaximum(
                int(self._fae.GetFeatureNumberList()[-1]))

    def SetResultDescription(self):
        text = "Normalizer:\n"
        for index in self._fae.GetNormalizerList():
            text += (index.GetName() + '\n')
        text += '\n'

        text += "Dimension Reduction:\n"
        for index in self._fae.GetDimensionReductionList():
            text += (index.GetName() + '\n')
        text += '\n'

        text += "Feature Selector:\n"
        for index in self._fae.GetFeatureSelectorList():
            text += (index.GetName() + '\n')
        text += '\n'

        text += "Feature Number:\n"
        text += "{:s} - {:s}\n".format(self._fae.GetFeatureNumberList()[0],
                                       self._fae.GetFeatureNumberList()[-1])
        text += '\n'

        text += "Classifier:\n"
        for index in self._fae.GetClassifierList():
            text += (index.GetName() + '\n')
        text += '\n'

        self.textEditDescription.setPlainText(text)

    def UpdateROC(self):
        if (self.comboNormalizer.count() == 0) or \
                (self.comboDimensionReduction.count() == 0) or \
                (self.comboFeatureSelector.count() == 0) or \
                (self.comboClassifier.count() == 0) or \
                (self.spinBoxFeatureNumber.value() == 0):
            return

        case_name = self.comboNormalizer.currentText() + '_' + \
                    self.comboDimensionReduction.currentText() + '_' + \
                    self.comboFeatureSelector.currentText() + '_' + \
                    str(self.spinBoxFeatureNumber.value()) + '_' + \
                    self.comboClassifier.currentText()

        case_folder = os.path.join(self._root_folder, case_name)
        try:
            self._current_pipeline.LoadPipeline(
                os.path.join(case_folder, 'pipeline_info.csv'))
        except Exception as ex:
            QMessageBox.about(self, "Load Error", ex.__str__())

        pred_list, label_list, name_list = [], [], []
        if self.checkROCTrain.isChecked():
            train_pred = np.load(os.path.join(case_folder,
                                              'train_predict.npy'))
            train_label = np.load(os.path.join(case_folder, 'train_label.npy'))
            pred_list.append(train_pred)
            label_list.append(train_label)
            name_list.append('train')
        if self.checkROCValidation.isChecked():
            val_pred = np.load(os.path.join(case_folder, 'val_predict.npy'))
            val_label = np.load(os.path.join(case_folder, 'val_label.npy'))
            pred_list.append(val_pred)
            label_list.append(val_label)
            name_list.append('validation')
        if self.checkROCTest.isChecked():
            if os.path.exists(os.path.join(case_folder, 'test_label.npy')):
                test_pred = np.load(
                    os.path.join(case_folder, 'test_predict.npy'))
                test_label = np.load(
                    os.path.join(case_folder, 'test_label.npy'))
                pred_list.append(test_pred)
                label_list.append(test_label)
                name_list.append('Test')

        if len(pred_list) > 0:
            DrawROCList(pred_list,
                        label_list,
                        name_list=name_list,
                        is_show=False,
                        fig=self.canvasROC.getFigure())

        self.canvasROC.draw()