Exemple #1
0
def display_model_results(container, reactions=None, heading=""):
    """
    Display confusion matrices for a model container.

    Optional heading specifies prefix for the summary statistics
    (useful for when multiple model containers are built by a single script)
    """
    overall_conf_mtrcs = container.getOverallConfusionMatrices(
        reactions=reactions)
    if not overall_conf_mtrcs:
        print("No model results to display")
        return
    if len(overall_conf_mtrcs) != 1:
        raise NotImplementedError('Can only handle one response')
    for descriptor_header, conf_mtrx in overall_conf_mtrcs:
        acc = accuracy(conf_mtrx)
        bcr = BCR(conf_mtrx)
        matthews = Matthews(conf_mtrx)
        print("Confusion matrix for {}:".format(descriptor_header))
        print(confusionMatrixString(conf_mtrx))
        print("Accuracy: {:.3}".format(acc))
        print("BCR: {:.3}".format(bcr))
        print("Matthews: {:.3}".format(matthews))
    conf_mtrcs = container.getComponentConfusionMatrices(reactions=reactions)

    sum_acc = 0.0
    sum_bcr = 0.0
    sum_matthews = 0.0
    count = 0

    for model_mtrcs in conf_mtrcs:
        if len(model_mtrcs) != 1:
            raise NotImplementedError('Can only handle one response')
        for descriptor_header, conf_mtrx in model_mtrcs:
            acc = accuracy(conf_mtrx)
            bcr = BCR(conf_mtrx)
            matthews = Matthews(conf_mtrx)
            print("Confusion matrix for {}:".format(descriptor_header))
            print(confusionMatrixString(conf_mtrx))
            print("Accuracy: {:.3}".format(acc))
            print("BCR: {:.3}".format(bcr))
            print("Matthews: {:.3}".format(matthews))

            # This only works for one response. Sorry...
            # TODO XXX make this work for multiple responses
            sum_acc += acc
            sum_bcr += bcr
            sum_matthews += matthews
            count += 1

    print("{} Average accuracy: {:.3}".format(heading, sum_acc / count))
    print("{} Average BCR: {:.3}".format(heading, sum_bcr / count))
    print("{} Average Matthews: {:.3}".format(heading, sum_matthews / count))
Exemple #2
0
    def predict(self, reactions, verbose=False):
        """Make predictions from the voting for a set of provided reactions."""
        if self.built:
            resDict = {}

            num_models = self.statsmodel_set.all().count()
            num_finished = 0
            overall_start_time = datetime.datetime.now()
            for model in self.statsmodel_set.all():
                visitorOptions = json.loads(self.modelVisitorOptions)
                modelVisitor = getattr(
                    visitorModules[self.modelVisitorLibrary],
                    self.modelVisitorTool)(statsModel=model, **visitorOptions)
                if verbose:
                    logger.info(
                        "statsModel {}, saved at {}, predicting...".format(
                            model.pk, model.outputFile))
                predictions = modelVisitor.predict(reactions, verbose=verbose)
                if verbose:
                    logger.info(
                        "\t...finished predicting. Storing predictions...")
                newResDict = self._storePredictionComponents(
                    predictions, model)

                # Update the overall result-dictionary with these new counts.
                for reaction, responseDict in newResDict.items():
                    for response, outcomeDict in responseDict.items():
                        for outcome, count in outcomeDict.items():
                            if reaction not in resDict:
                                resDict[reaction] = {}
                            if response not in resDict[reaction]:
                                resDict[reaction][response] = {}

                            if outcome not in resDict[reaction][response]:
                                resDict[reaction][response][outcome] = count
                            resDict[reaction][response][outcome] += count

                if verbose:
                    logger.info("predictions stored.")
                    for response in self.outcomeDescriptors:
                        predDesc = response.predictedDescriptorType.objects.get(
                            modelContainer=self,
                            statsModel=model,
                            predictionOf=response)
                        conf_mtrx = predDesc.getConfusionMatrix(
                            reactions=reactions)

                        logger.info("Confusion matrix for {}:".format(
                            predDesc.heading))
                        logger.info(confusionMatrixString(conf_mtrx))
                        logger.info("Accuracy: {:.3}".format(
                            accuracy(conf_mtrx)))
                        logger.info("BCR: {:.3}".format(BCR(conf_mtrx)))
                        logger.info("Matthews: {:.3}".format(
                            Matthews(conf_mtrx)))
                    num_finished += 1
                    end_time = datetime.datetime.now()
                    elapsed = (end_time - overall_start_time)
                    expected_finish = datetime.timedelta(
                        seconds=(elapsed.total_seconds() *
                                 (num_models /
                                  float(num_finished)))) + overall_start_time
                    logger.info("{}. Predictions from {} of {} models.".format(
                        end_time, num_finished, num_models))
                    logger.info(
                        "Elapsed prediction time: {}. Expected completion time: {}"
                        .format(elapsed, expected_finish))

            return self._storePredictions(resDict)
        else:
            raise RuntimeError(
                'A model container cannot be used to make predictions before the build method has been called'
            )