लेबल के साथ स्केलेरन प्लॉट भ्रम की स्थिति


85

मैं क्लासिफ़ायर के प्रदर्शन की कल्पना करने के लिए एक भ्रम मैट्रिक्स की साजिश करना चाहता हूं, लेकिन यह केवल लेबल की संख्या दिखाता है, न कि लेबल:

from sklearn.metrics import confusion_matrix
import pylab as pl
y_test=['business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business', 'business']

pred=array(['health', 'business', 'business', 'business', 'business',
       'business', 'health', 'health', 'business', 'business', 'business',
       'business', 'business', 'business', 'business', 'business',
       'health', 'health', 'business', 'health'], 
      dtype='|S8')

cm = confusion_matrix(y_test, pred)
pl.matshow(cm)
pl.title('Confusion matrix of the classifier')
pl.colorbar()
pl.show()

मैं भ्रम मैट्रिक्स में लेबल (स्वास्थ्य, व्यवसाय..प्रिट) कैसे जोड़ सकता हूं?

जवाबों:


66

के रूप में में संकेत दिया इस सवाल है, तो आप "खुला" करने के लिए है निचले स्तर कलाकार एपीआई , आंकड़ा भंडारण के द्वारा और अक्ष matplotlib कार्यों आप कॉल (द्वारा पारित वस्तुओं fig, axऔर caxनीचे चर)। आप तब डिफ़ॉल्ट x- और y- अक्ष टिक्स का उपयोग कर set_xticklabels/ की जगह ले सकते हैं set_yticklabels:

from sklearn.metrics import confusion_matrix

labels = ['business', 'health']
cm = confusion_matrix(y_test, pred, labels)
print(cm)
fig = plt.figure()
ax = fig.add_subplot(111)
cax = ax.matshow(cm)
plt.title('Confusion matrix of the classifier')
fig.colorbar(cax)
ax.set_xticklabels([''] + labels)
ax.set_yticklabels([''] + labels)
plt.xlabel('Predicted')
plt.ylabel('True')
plt.show()

ध्यान दें कि मैंने यह सुनिश्चित करने के लिए labelsसूची को सूची में पारित किया confusion_matrixकि यह ठीक से क्रमबद्ध है, टिक्स से मेल खाता है।

यह निम्नलिखित आंकड़ा में परिणाम है:

यहाँ छवि विवरण दर्ज करें


3
यदि आपके पास कुछ श्रेणियों से अधिक है, तो Matplotlib कुल्हाड़ियों को गलत तरीके से लेबल करने का निर्णय लेता है - आपको इसे अपने सेल पर लेबल करने के लिए मजबूर करना होगा। from matplotlib.ticker import MultipleLocator; ax.xaxis.set_major_locator(MultipleLocator(1)); ax.yaxis.set_major_locator(MultipleLocator(1))
बचाया

एक नया होने के नाते, क्या आप मुझे बता सकते हैं कि 3 बक्से का आकार सटीकता के स्तर को प्रभावित कर रहा है या नहीं?
बोरिस

मैं उन पर संख्याओं को कैसे प्रदर्शित करूं? चूँकि रंग सभी मामलों में ज्यादा नहीं
बता

हाय ... @ मेटाकर्मीट। क्या आप बता सकते हैं कि रंगीन आकृति के अंदर की संख्या को कैसे दिखाया जाए?
हुमायूं रशीद नयन

70

अपडेट करें:

०.२२ में सीखें, सीधे भ्रम मैट्रिक्स को प्लॉट करने के लिए एक नई सुविधा है।

प्रलेखन देखें: sklearn.metrics.plot_confusion_matrix


पुराने उत्तर:

मुझे लगता है कि यह seaborn.heatmapयहाँ उपयोग के लायक है।

import seaborn as sns
import matplotlib.pyplot as plt     

ax= plt.subplot()
sns.heatmap(cm, annot=True, ax = ax); #annot=True to annotate cells

# labels, title and ticks
ax.set_xlabel('Predicted labels');ax.set_ylabel('True labels'); 
ax.set_title('Confusion Matrix'); 
ax.xaxis.set_ticklabels(['business', 'health']); ax.yaxis.set_ticklabels(['health', 'business']);

यहाँ छवि विवरण दर्ज करें


32
सुझाव: संख्याओं को वैज्ञानिक संकेतन पर जाने से रोकने के fmt='g'लिए heatmapकॉल को पास करें।
polm23

5
सुझाव: पारित cmap='Greens'करने के लिए heatmapसहज ज्ञान युक्त रंग अर्थ है करने के लिए कॉल।
एलियाडल

कैसे सुनिश्चित करें कि आप लेबल मिश्रण नहीं कर रहे हैं?
मोनिका

@RevolucionforMonica जब आप प्राप्त करते हैं confusion_matrix, तो एक्स अक्ष टिक लेबल 1, 0 और वाई अक्ष टिक लेबल 0, 1 होते हैं (धुरी मूल्यों में बढ़ता क्रम)। यदि क्लासिफायरियर है clf, तो आप क्लास ऑर्डर प्राप्त कर सकते हैं clf.classes_, जो ["health", "business"]इस मामले में मेल खाना चाहिए । (यह माना जाता है कि businessयह सकारात्मक वर्ग है)।
akilat90

29

मुझे एक फ़ंक्शन मिला जो भ्रम की मैट्रिक्स को प्लॉट कर सकता है जो इससे उत्पन्न होता है sklearn

import numpy as np


def plot_confusion_matrix(cm,
                          target_names,
                          title='Confusion matrix',
                          cmap=None,
                          normalize=True):
    """
    given a sklearn confusion matrix (cm), make a nice plot

    Arguments
    ---------
    cm:           confusion matrix from sklearn.metrics.confusion_matrix

    target_names: given classification classes such as [0, 1, 2]
                  the class names, for example: ['high', 'medium', 'low']

    title:        the text to display at the top of the matrix

    cmap:         the gradient of the values displayed from matplotlib.pyplot.cm
                  see http://matplotlib.org/examples/color/colormaps_reference.html
                  plt.get_cmap('jet') or plt.cm.Blues

    normalize:    If False, plot the raw numbers
                  If True, plot the proportions

    Usage
    -----
    plot_confusion_matrix(cm           = cm,                  # confusion matrix created by
                                                              # sklearn.metrics.confusion_matrix
                          normalize    = True,                # show proportions
                          target_names = y_labels_vals,       # list of names of the classes
                          title        = best_estimator_name) # title of graph

    Citiation
    ---------
    http://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html

    """
    import matplotlib.pyplot as plt
    import numpy as np
    import itertools

    accuracy = np.trace(cm) / np.sum(cm).astype('float')
    misclass = 1 - accuracy

    if cmap is None:
        cmap = plt.get_cmap('Blues')

    plt.figure(figsize=(8, 6))
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()

    if target_names is not None:
        tick_marks = np.arange(len(target_names))
        plt.xticks(tick_marks, target_names, rotation=45)
        plt.yticks(tick_marks, target_names)

    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]


    thresh = cm.max() / 1.5 if normalize else cm.max() / 2
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        if normalize:
            plt.text(j, i, "{:0.4f}".format(cm[i, j]),
                     horizontalalignment="center",
                     color="white" if cm[i, j] > thresh else "black")
        else:
            plt.text(j, i, "{:,}".format(cm[i, j]),
                     horizontalalignment="center",
                     color="white" if cm[i, j] > thresh else "black")


    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label\naccuracy={:0.4f}; misclass={:0.4f}'.format(accuracy, misclass))
    plt.show()

यह इस तरह दिखेगा यहाँ छवि विवरण दर्ज करें


23

आपकी रुचि https://github.com/pandas-ml/pandas-ml/ से हो सकती है

जो भ्रम मैट्रिक्स के पायथन पंडों के कार्यान्वयन को लागू करता है।

कुछ सुविधाएं:

  • साजिश भ्रम मैट्रिक्स
  • प्लॉट सामान्यीकृत भ्रम मैट्रिक्स
  • वर्ग के आँकड़े
  • समग्र आँकड़े

यहाँ एक उदाहरण है:

In [1]: from pandas_ml import ConfusionMatrix
In [2]: import matplotlib.pyplot as plt

In [3]: y_test = ['business', 'business', 'business', 'business', 'business',
        'business', 'business', 'business', 'business', 'business',
        'business', 'business', 'business', 'business', 'business',
        'business', 'business', 'business', 'business', 'business']

In [4]: y_pred = ['health', 'business', 'business', 'business', 'business',
       'business', 'health', 'health', 'business', 'business', 'business',
       'business', 'business', 'business', 'business', 'business',
       'health', 'health', 'business', 'health']

In [5]: cm = ConfusionMatrix(y_test, y_pred)

In [6]: cm
Out[6]:
Predicted  business  health  __all__
Actual
business         14       6       20
health            0       0        0
__all__          14       6       20

In [7]: cm.plot()
Out[7]: <matplotlib.axes._subplots.AxesSubplot at 0x1093cf9b0>

In [8]: plt.show()

प्लॉट भ्रम मैट्रिक्स

In [9]: cm.print_stats()
Confusion Matrix:

Predicted  business  health  __all__
Actual
business         14       6       20
health            0       0        0
__all__          14       6       20


Overall Statistics:

Accuracy: 0.7
95% CI: (0.45721081772371086, 0.88106840959427235)
No Information Rate: ToDo
P-Value [Acc > NIR]: 0.608009812201
Kappa: 0.0
Mcnemar's Test P-Value: ToDo


Class Statistics:

Classes                                 business health
Population                                    20     20
P: Condition positive                         20      0
N: Condition negative                          0     20
Test outcome positive                         14      6
Test outcome negative                          6     14
TP: True Positive                             14      0
TN: True Negative                              0     14
FP: False Positive                             0      6
FN: False Negative                             6      0
TPR: (Sensitivity, hit rate, recall)         0.7    NaN
TNR=SPC: (Specificity)                       NaN    0.7
PPV: Pos Pred Value (Precision)                1      0
NPV: Neg Pred Value                            0      1
FPR: False-out                               NaN    0.3
FDR: False Discovery Rate                      0      1
FNR: Miss Rate                               0.3    NaN
ACC: Accuracy                                0.7    0.7
F1 score                               0.8235294      0
MCC: Matthews correlation coefficient        NaN    NaN
Informedness                                 NaN    NaN
Markedness                                     0      0
Prevalence                                     1      0
LR+: Positive likelihood ratio               NaN    NaN
LR-: Negative likelihood ratio               NaN    NaN
DOR: Diagnostic odds ratio                   NaN    NaN
FOR: False omission rate                       1      0

क्या, आपको यह काम करने के लिए कैसे मिला? नवीनतम pandas_ml के साथ यह मुझे एक खाली भ्रम मैट्रिक्स (सभी 0 के) दे रहा है, और लेबल व्यवसाय और स्वास्थ्य के बजाय सही / गलत हैं।
शब्दफोर वाइज

वही, यह रिक्त है
Elham

1
मुझे एट्रीब्यूट मिल रहा है: मॉड्यूल 'sklearn.metrics' में scikit-learn version 0.23.1 और पांडा-एमएल वर्जन 0.6.1 के साथ 'jaccard_similarity_score' कोई विशेषता नहीं है। मैंने अन्य संस्करणों के साथ-साथ बिना किसी भाग्य के कोशिश की है।
पेट्रा

18
from sklearn import model_selection
test_size = 0.33
seed = 7
X_train, X_test, y_train, y_test = model_selection.train_test_split(feature_vectors, y, test_size=test_size, random_state=seed)

from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score, classification_report, confusion_matrix

model = LogisticRegression()
model.fit(X_train, y_train)
result = model.score(X_test, y_test)
print("Accuracy: %.3f%%" % (result*100.0))
y_pred = model.predict(X_test)
print("F1 Score: ", f1_score(y_test, y_pred, average="macro"))
print("Precision Score: ", precision_score(y_test, y_pred, average="macro"))
print("Recall Score: ", recall_score(y_test, y_pred, average="macro")) 

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import confusion_matrix

def cm_analysis(y_true, y_pred, labels, ymap=None, figsize=(10,10)):
    """
    Generate matrix plot of confusion matrix with pretty annotations.
    The plot image is saved to disk.
    args: 
      y_true:    true label of the data, with shape (nsamples,)
      y_pred:    prediction of the data, with shape (nsamples,)
      filename:  filename of figure file to save
      labels:    string array, name the order of class labels in the confusion matrix.
                 use `clf.classes_` if using scikit-learn models.
                 with shape (nclass,).
      ymap:      dict: any -> string, length == nclass.
                 if not None, map the labels & ys to more understandable strings.
                 Caution: original y_true, y_pred and labels must align.
      figsize:   the size of the figure plotted.
    """
    if ymap is not None:
        y_pred = [ymap[yi] for yi in y_pred]
        y_true = [ymap[yi] for yi in y_true]
        labels = [ymap[yi] for yi in labels]
    cm = confusion_matrix(y_true, y_pred, labels=labels)
    cm_sum = np.sum(cm, axis=1, keepdims=True)
    cm_perc = cm / cm_sum.astype(float) * 100
    annot = np.empty_like(cm).astype(str)
    nrows, ncols = cm.shape
    for i in range(nrows):
        for j in range(ncols):
            c = cm[i, j]
            p = cm_perc[i, j]
            if i == j:
                s = cm_sum[i]
                annot[i, j] = '%.1f%%\n%d/%d' % (p, c, s)
            elif c == 0:
                annot[i, j] = ''
            else:
                annot[i, j] = '%.1f%%\n%d' % (p, c)
    cm = pd.DataFrame(cm, index=labels, columns=labels)
    cm.index.name = 'Actual'
    cm.columns.name = 'Predicted'
    fig, ax = plt.subplots(figsize=figsize)
    sns.heatmap(cm, annot=annot, fmt='', ax=ax)
    #plt.savefig(filename)
    plt.show()

cm_analysis(y_test, y_pred, model.classes_, ymap=None, figsize=(10,10))

यहाँ छवि विवरण दर्ज करें

https://gist.github.com/hitvoice/36cf44689065ca9b927431546381a3f7 का उपयोग

ध्यान दें कि यदि आप इसका उपयोग करते हैं तो rocket_rयह रंगों को उलट देगा और किसी तरह यह नीचे की तरह अधिक प्राकृतिक और बेहतर दिखाई देगा: यहाँ छवि विवरण दर्ज करें


धन्यवाद, लेकिन rocket_rआपने जो विकल्प बताया है?
हम्मन सैमुअल

फ़ंक्शन में sns.heatmap(), cmap='rocket_r'पैमाने के रंग व्युत्क्रम के लिए तर्क पास करें
साईं प्रभंजन रेड्डी

10
    from sklearn.metrics import confusion_matrix
    import seaborn as sns
    import matplotlib.pyplot as plt
    model.fit(train_x, train_y,validation_split = 0.1, epochs=50, batch_size=4)
    y_pred=model.predict(test_x,batch_size=15)
    cm =confusion_matrix(test_y.argmax(axis=1), y_pred.argmax(axis=1))  
    index = ['neutral','happy','sad']  
    columns = ['neutral','happy','sad']  
    cm_df = pd.DataFrame(cm,columns,index)                      
    plt.figure(figsize=(10,6))  
    sns.heatmap(cm_df, annot=True)

असमंजस का जाल


8

@ Akilat90 के अपडेट के बारे में जोड़ने के लिए sklearn.metrics.plot_confusion_matrix:

आप सीधे ConfusionMatrixDisplayकक्षा का उपयोग कर सकते हैं sklearn.metricsऔर एक क्लासिफायर पास करने की आवश्यकता को दरकिनार कर सकते हैं plot_confusion_matrix। इसकी भी हैdisplay_labels तर्क , जो आपको भूखंड में प्रदर्शित लेबल को वांछित रूप से निर्दिष्ट करने की अनुमति देता है।

इसके लिए कंस्ट्रक्टर ConfusionMatrixDisplayप्लॉट के बहुत अतिरिक्त अनुकूलन करने का एक तरीका प्रदान नहीं करता है, लेकिन आप ax_इसकी plot()विधि को कॉल करने के बाद विशेषता के माध्यम से matplotlib axes obect तक पहुँच सकते हैं । मैंने इसे दिखाते हुए एक दूसरा उदाहरण जोड़ा है।

मैंने पाया कि बड़ी मात्रा में डेटा के साथ सिर्फ प्लॉट का निर्माण करने के लिए एक क्लासिफायर को फिर से चलाने के लिए परेशान होना पड़ा plot_confusion_matrix । मैं भविष्यवाणी किए गए डेटा से अन्य भूखंडों का उत्पादन कर रहा हूं, इसलिए मैं हर बार फिर से भविष्यवाणी करने के लिए अपना समय बर्बाद नहीं करना चाहता। यह उस समस्या का एक आसान समाधान भी था।

उदाहरण:

from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay

cm = confusion_matrix(y_true, y_preds, normalize='all')
cmd = ConfusionMatrixDisplay(cm, display_labels=['business','health'])
cmd.plot()

भ्रम मैट्रिक्स उदाहरण 1

उदाहरण का उपयोग कर ax_:

cm = confusion_matrix(y_true, y_preds, normalize='all')
cmd = ConfusionMatrixDisplay(cm, display_labels=['business','health'])
cmd.plot()
cmd.ax_.set(xlabel='Predicted', ylabel='True')

भ्रम मैट्रिक्स उदाहरण


1
यह उत्कृष्ट है - धन्यवाद! प्रश्न: क्या आप अक्ष लेबल के लिए 'ट्रू लेबल' और 'अनुमानित लेबल' मान को अनुकूलित कर सकते हैं?
caydin

1
मुझे यह पहले महसूस नहीं हुआ था, लेकिन आप matplotlib axes ऑब्जेक्ट के माध्यम से एक्सेस कर सकते हैं cmd.ax_, जो कि प्लॉट के बहुत नियंत्रण की अनुमति देता है। अक्ष लेबल को अनुकूलित करने के लिए कुछ इस तरह का उपयोग करें cmd.ax_.set(xlabel='foo', ylabel='bar'):। मैं अपना जवाब अपडेट करूंगा।
थिअनिनथेवुड्स

आपका बहुत बहुत धन्यवाद! लेकिन ऐसा लगता है कि यह cmd.ax_.setअक्षम है display_labels=['business','health']?
कायनात

इसके अलावा मुझे मिल रहा है AttributeError: 'ConfusionMatrixDisplay' object has no attribute 'ax_'
caydin

1
आह, तुम सही हो! उन चीजों को इंगित करने के लिए धन्यवाद। समाधान खोजने के लिए मेरे उत्साह में मैंने अपने अपडेट में कुछ गलतियां कीं। कृपया नवीनतम संस्करण देखें, इसे अभी काम करना चाहिए।
तत्कालीन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.