代码之家  ›  专栏  ›  技术社区  ›  Kleyson Rios

Python混淆矩阵matplotlib基于类别数的自动图形大小

  •  0
  • Kleyson Rios  · 技术社区  · 7 年前

    我使用以下函数生成混淆矩阵:

    def plot_confusion_matrix(cm, classes, normalize=False, cmap=cm.Blues, png_output=None, show=True):
        """
        This function prints and plots the confusion matrix.
        Normalization can be applied by setting `normalize=True`.
        """
        if normalize:
            cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
            title='Normalized confusion matrix'
        else:
            title='Confusion matrix'
    
        f = plt.figure()
    
        plt.imshow(cm, interpolation='nearest', cmap=cmap)
        plt.title(title)
        plt.colorbar()
        tick_marks = np.arange(len(classes))
        plt.xticks(tick_marks, classes, rotation=45)
        plt.yticks(tick_marks, classes)
    
        fmt = '.2f' if normalize else 'd'
        thresh = cm.max() / 2.
        for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
            plt.text(j, i, format(cm[i, j], fmt),
                    horizontalalignment="center",
                    color="white" if cm[i, j] > thresh else "black")
    
        plt.tight_layout()
        plt.ylabel('True label')
        plt.xlabel('Predicted label')
    
        if png_output is not None:
            os.makedirs(png_output, exist_ok=True)
            f.savefig(os.path.join(png_output,'confusion_matrix.png'), bbox_inches='tight')
    
        if show:
            plt.show()
            plt.close(f)
        else:
            plt.close(f)
    

    当我有几节课的时候,我会得到一张整洁的图表,像这样:

    enter image description here

    enter image description here

    我尝试使用与此解决方案相同的方法 Python boxplot matplotlib automatic figure size based on the number of categories

    我怎样才能让我的混淆矩阵根据类的数量来调整它的大小呢?

    更新1

    包括记号位置和动态宽度之后

    enter image description here

    def plot_confusion_matrix(y_true,y_pred, classes, normalize=False, cmap=cm.Blues, png_output=None, show=True):
        """
        This function prints and plots the confusion matrix.
        Normalization can be applied by setting `normalize=True`.
        """
    
        cm = confusion_matrix(y_true,y_pred)
    
        if normalize:
            cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
            title='Normalized confusion matrix'
        else:
            title='Confusion matrix'
    
        # Calculate chart area size
        leftmargin = 0.5 # inches
        rightmargin = 0.5 # inches
        categorysize = 0.5 # inches
        figwidth = leftmargin + rightmargin + (len(classes) * categorysize)           
    
        f = plt.figure(figsize=(figwidth, figwidth))
    
        # Create an axes instance and ajust the subplot size
        ax = f.add_subplot(111)
        ax.set_aspect(1)
        f.subplots_adjust(left=leftmargin/figwidth, right=1-rightmargin/figwidth, top=0.94, bottom=0.1)
    
        res = ax.imshow(cm, interpolation='nearest', cmap=cmap)
    
        plt.title(title)
        plt.colorbar(res)
        ax.set_xticks(range(len(classes)))
        ax.set_yticks(range(len(classes)))
        ax.set_xticklabels(classes, rotation=45, ha='right')
        ax.set_yticklabels(classes)
    
        fmt = '.2f' if normalize else 'd'
        thresh = cm.max() / 2.
        for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
            ax.text(j, i, format(cm[i, j], fmt),
                    horizontalalignment="center",
                    color="white" if cm[i, j] > thresh else "black")
    
        # plt.tight_layout()
        plt.ylabel('True label')
        plt.xlabel('Predicted label')
    
        if png_output is not None:
            os.makedirs(png_output, exist_ok=True)
            f.savefig(os.path.join(png_output,'confusion_matrix.png'), bbox_inches='tight')
    
        if show:
            plt.show()
            plt.close(f)
        else:
            plt.close(f)
    

    克莱森·里奥斯。

    0 回复  |  直到 7 年前
        1
  •  0
  •   Kleyson Rios    7 年前

    现在使用@ImportanceOfBeingErnest获取正确的图表很有帮助。

    enter image description here

    在最终代码下面:

       def plot_confusion_matrix(cm, classes, normalize=False, cmap=cm.Blues, png_output=None, show=True):
            """
            This function prints and plots the confusion matrix.
            Normalization can be applied by setting `normalize=True`.
            """
            if normalize:
                cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
                title='Normalized confusion matrix'
            else:
                title='Confusion matrix'
    
            # Calculate chart area size
            leftmargin = 0.5 # inches
            rightmargin = 0.5 # inches
            categorysize = 0.5 # inches
            figwidth = leftmargin + rightmargin + (len(classes) * categorysize)           
    
            f = plt.figure(figsize=(figwidth, figwidth))
    
            # Create an axes instance and ajust the subplot size
            ax = f.add_subplot(111)
            ax.set_aspect(1)
            f.subplots_adjust(left=leftmargin/figwidth, right=1-rightmargin/figwidth, top=0.94, bottom=0.1)
    
            res = ax.imshow(cm, interpolation='nearest', cmap=cmap)
    
            plt.title(title)
            plt.colorbar(res)
            ax.set_xticks(range(len(classes)))
            ax.set_yticks(range(len(classes)))
            ax.set_xticklabels(classes, rotation=45, ha='right')
            ax.set_yticklabels(classes)
    
            fmt = '.2f' if normalize else 'd'
            thresh = cm.max() / 2.
            for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
                ax.text(j, i, format(cm[i, j], fmt),
                        horizontalalignment="center",
                        color="white" if cm[i, j] > thresh else "black")
    
            # plt.tight_layout()
            plt.ylabel('True label')
            plt.xlabel('Predicted label')
    
            if png_output is not None:
                os.makedirs(png_output, exist_ok=True)
                f.savefig(os.path.join(png_output,'confusion_matrix.png'), bbox_inches='tight')
    
            if show:
                plt.show()
                plt.close(f)
            else:
                plt.close(f)