2017-05-18 31 views
7

ten kod:błąd macierzy błędów, gdy wymiary tablicy mają rozmiar 3

from pandas_ml import ConfusionMatrix 
y_actu = [1,2] 
y_pred = [1,2] 
cm = ConfusionMatrix(y_actu, y_pred) 
cm.print_stats() 

drukuje:

population: 2 
P: 1 
N: 1 
PositiveTest: 1 
NegativeTest: 1 
TP: 1 
TN: 1 
FP: 0 
FN: 0 
TPR: 1.0 
TNR: 1.0 
PPV: 1.0 
NPV: 1.0 
FPR: 0.0 
FDR: 0.0 
FNR: 0.0 
ACC: 1.0 
F1_score: 1.0 
MCC: 1.0 
informedness: 1.0 
markedness: 1.0 
prevalence: 0.5 
LRP: inf 
LRN: 0.0 
DOR: inf 
FOR: 0.0 
/opt/conda/lib/python3.5/site-packages/pandas_ml/confusion_matrix/bcm.py:332: RuntimeWarning: divide by zero encountered in double_scalars 
    return(np.float64(self.TPR)/self.FPR) 

to oczekuje.

Modyfikacja kodu:

from pandas_ml import ConfusionMatrix 
y_actu = [1,2,3] 
y_pred = [1,2,3] 
cm = ConfusionMatrix(y_actu, y_pred) 
cm.print_stats() 

zmiana Zrobiłem to:

y_actu = [1,2,3] 
y_pred = [1,2,3] 

powoduje błąd:

OrderedDict([('Accuracy', 1.0), ('95% CI', (0.29240177382128668, nan)), ('No Information Rate', 'ToDo'), ('P-Value [Acc > NIR]', 0.29629629629629622), ('Kappa', 1.0), ("Mcnemar's Test P-Value", 'ToDo')]) 

ValueErrorTraceback (most recent call last) 
<ipython-input-30-d8c5dc2bea73> in <module>() 
     3 y_pred = [1,2,3] 
     4 cm = ConfusionMatrix(y_actu, y_pred) 
----> 5 cm.print_stats() 

/opt/conda/lib/python3.5/site-packages/pandas_ml/confusion_matrix/abstract.py in print_stats(self, lst_stats) 
    446   Prints statistics 
    447   """ 
--> 448   print(self._str_stats(lst_stats)) 
    449 
    450  def get(self, actual=None, predicted=None): 

/opt/conda/lib/python3.5/site-packages/pandas_ml/confusion_matrix/abstract.py in _str_stats(self, lst_stats) 
    427   } 
    428 
--> 429   stats = self.stats(lst_stats) 
    430 
    431   d_stats_str = collections.OrderedDict([ 

/opt/conda/lib/python3.5/site-packages/pandas_ml/confusion_matrix/abstract.py in stats(self, lst_stats) 
    390   d_stats = collections.OrderedDict() 
    391   d_stats['cm'] = self 
--> 392   d_stats['overall'] = self.stats_overall 
    393   d_stats['class'] = self.stats_class 
    394   return(d_stats) 

/opt/conda/lib/python3.5/site-packages/pandas_ml/confusion_matrix/cm.py in __getattr__(self, attr) 
    33   Returns (weighted) average statistics 
    34   """ 
---> 35   return(self._avg_stat(attr)) 

/opt/conda/lib/python3.5/site-packages/pandas_ml/confusion_matrix/abstract.py in _avg_stat(self, stat) 
    509    v = getattr(binary_cm, stat) 
    510    print(v) 
--> 511    s_values[cls] = v 
    512   value = (s_values * self.true).sum()/self.population 
    513   return(value) 

/opt/conda/lib/python3.5/site-packages/pandas/core/series.py in __setitem__(self, key, value) 
    771   # do the setitem 
    772   cacher_needs_updating = self._check_is_chained_assignment_possible() 
--> 773   setitem(key, value) 
    774   if cacher_needs_updating: 
    775    self._maybe_update_cacher() 

/opt/conda/lib/python3.5/site-packages/pandas/core/series.py in setitem(key, value) 
    767      pass 
    768 
--> 769    self._set_with(key, value) 
    770 
    771   # do the setitem 

/opt/conda/lib/python3.5/site-packages/pandas/core/series.py in _set_with(self, key, value) 
    809    if key_type == 'integer': 
    810     if self.index.inferred_type == 'integer': 
--> 811      self._set_labels(key, value) 
    812     else: 
    813      return self._set_values(key, value) 

/opt/conda/lib/python3.5/site-packages/pandas/core/series.py in _set_labels(self, key, value) 
    826   if mask.any(): 
    827    raise ValueError('%s not contained in the index' % str(key[mask])) 
--> 828   self._set_values(indexer, value) 
    829 
    830  def _set_values(self, key, value): 

/opt/conda/lib/python3.5/site-packages/pandas/core/series.py in _set_values(self, key, value) 
    831   if isinstance(key, Series): 
    832    key = key._values 
--> 833   self._data = self._data.setitem(indexer=key, value=value) 
    834   self._maybe_update_cacher() 
    835 

/opt/conda/lib/python3.5/site-packages/pandas/core/internals.py in setitem(self, **kwargs) 
    3166 
    3167  def setitem(self, **kwargs): 
-> 3168   return self.apply('setitem', **kwargs) 
    3169 
    3170  def putmask(self, **kwargs): 

/opt/conda/lib/python3.5/site-packages/pandas/core/internals.py in apply(self, f, axes, filter, do_integrity_check, consolidate, **kwargs) 
    3054 
    3055    kwargs['mgr'] = self 
-> 3056    applied = getattr(b, f)(**kwargs) 
    3057    result_blocks = _extend_blocks(applied, result_blocks) 
    3058 

/opt/conda/lib/python3.5/site-packages/pandas/core/internals.py in setitem(self, indexer, value, mgr) 
    685       indexer.dtype == np.bool_ and 
    686       len(indexer[indexer]) == len(value)): 
--> 687      raise ValueError("cannot set using a list-like indexer " 
    688          "with a different length than the value") 
    689 

ValueError: cannot set using a list-like indexer with a different length than the value 

Czytanie Assignment to containers in Pandas stany „Korzystanie endemiczne list nie jest dozwolone na zlecenie i nie jest to zalecane w ogóle. " czy stworzyłem endemiczną listę? Co to jest endemiczna lista?

+0

Czy próbowałeś nauki scikit? http://stackoverflow.com/questions/43697980/is-there-something-already-implemented-in-python-to-calculate-tp-tn-fp-and-fn/43698347#43698347 – Sidon

+0

@Sidon dzięki, tak I przebadał to "trochę", pandas ml oferuje wiele użytecznych statystyk zbioru danych "po wyjęciu z pudełka" za pomocą metody print_stats, która zadaje również pytanie o związany z nią plakat pytania. Dzięki za link, wizualizacje są atrakcyjne. –

Odpowiedz

4

Polecam, używając confusion_matrix z scikit-learn. Inne dane, o których wspominasz, takie jak Dokładność, Przypomnienie, Wynik F1, są również dostępne pod adresem sklearn.metrics.

>>> from sklearn.metrics import confusion_matrix 
>>> y_actu = [1,2,3] 
>>> y_pred = [1,2,3] 
>>> confusion_matrix(y_actu, y_pred) 
array([[1, 0, 0], 
     [0, 1, 0], 
     [0, 0, 1]]) 
1

Co ciekawe, gdy uruchamiam kod, nie pojawia się błąd, który otrzymałeś, a kod pobiegł doskonale. Proponuję uaktualnić pandas_ml bibliotekę uruchamiając:

pip install --upgrade pandas_ml 

Ponadto, należy uaktualnić pandy uruchamiając:

pip install --upgrade pandas 

Jeśli to nie zadziała, można użyć sama pandy, aby utworzyć macierz zamieszanie :

import pandas as pd 
y_actu = pd.Series([1, 2, 3], name='Actual') 
y_pred = pd.Series([1, 2, 3], name='Predicted') 
df_confusion = pd.crosstab(y_actu, y_pred) 
print df_confusion 

Co da ci stół, którego szukasz.

+0

dziękuję, ale nie używasz "cm = ConfusionMatrix (y_actu, y_pred)" i dlatego nie można wydrukować statystyk za pomocą 'print_stats()'? –

+0

Używając Pythona 2, udało mi się uruchomić Twój kod bezpośrednio i osiągnąć pożądane wyniki statystyk. Jakiej wersji Pythona używasz? – Ajax1234

+0

@ błękitne niebo, proszę spojrzeć na moją odpowiedź powyżej. Rozwiązałem problem, ulepszając zarówno pandy, jak i pandas_ml. ConfusionMatrix działa teraz dobrze z przykładem Multiclass [1,2,3]. –

1

wydaje się, że błąd nie jest ze względu na wymiar tablicy:

from pandas_ml import ConfusionMatrix 
y_actu = [1,2,2] 
y_pred = [1,1,2] 
cm = ConfusionMatrix(y_actu, y_pred) 
cm.print_stats() 

ten (binarny problemem klasyfikacja) działa poprawnie.

Być może macierz zamieszania problemu klasyfikacji wieloklasowej jest po prostu zepsuta.

Aktualizacja: ive właśnie uczynić kroki:

conda update pandas 

dostać pandy 0,20.1 a następnie

pip install -U pandas_ml 

teraz wszystko jest w porządku z mulsiclass matrycy zamieszanie:

from pandas_ml import ConfusionMatrix 
y_actu = [1,2,3] 
y_pred = [1,2,3] 
cm = ConfusionMatrix(y_actu, y_pred) 
cm.print_stats() 

mam wyjścia:

Class Statistics: 

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

Używam również i polecić sklearn confusion_matrix funkcję. Osobiście również zachować "pretty-print confusion matrix" funkcja przydatna z kilku dodatkowych udogodnień:

  • klasy etykiety drukowane wzdłuż matrycy zamieszanie osie
  • statystyk macierzy
  • zamieszanie znormalizowane tak, że wszystkie komórki sumują się do 1
  • kolorach zamieszanie komórek macierzy skalowane zgodnie z wartością komórki
  • Dodatkowe dane, takie jak wynik F-score itp. wydrukowane poniżej macierzy błędów.

Jak to:

enter image description here

Oto funkcja kreślenia, w dużej mierze oparte na this example from the Scikit-Learn documentation

import matplotlib.pyplot as plt 
import itertools 
from sklearn.metrics import classification_report 

def pretty_print_conf_matrix(y_true, y_pred, 
          classes, 
          normalize=False, 
          title='Confusion matrix', 
          cmap=plt.cm.Blues): 
    """ 
    Mostly stolen from: http://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py 

    Normalization changed, classification_report stats added below plot 
    """ 

    cm = confusion_matrix(y_true, y_pred) 

    # Configure Confusion Matrix Plot Aesthetics (no text yet) 
    plt.imshow(cm, interpolation='nearest', cmap=cmap) 
    plt.title(title, fontsize=14) 
    tick_marks = np.arange(len(classes)) 
    plt.xticks(tick_marks, classes, rotation=45) 
    plt.yticks(tick_marks, classes) 
    plt.ylabel('True label', fontsize=12) 
    plt.xlabel('Predicted label', fontsize=12) 

    # Calculate normalized values (so all cells sum to 1) if desired 
    if normalize: 
     cm = np.round(cm.astype('float')/cm.sum(),2) #(axis=1)[:, np.newaxis] 

    # Place Numbers as Text on Confusion Matrix Plot 
    thresh = cm.max()/2. 
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])): 
     plt.text(j, i, cm[i, j], 
       horizontalalignment="center", 
       color="white" if cm[i, j] > thresh else "black", 
       fontsize=12) 


    # Add Precision, Recall, F-1 Score as Captions Below Plot 
    rpt = classification_report(y_true, y_pred) 
    rpt = rpt.replace('avg/total', '  avg') 
    rpt = rpt.replace('support', 'N Obs') 

    plt.annotate(rpt, 
       xy = (0,0), 
       xytext = (-50, -140), 
       xycoords='axes fraction', textcoords='offset points', 
       fontsize=12, ha='left')  

    # Plot 
    plt.tight_layout() 

A oto przykład z danymi tęczówki wykorzystywanych do generowania obrazu działki:

from sklearn import datasets 
from sklearn.svm import SVC 

#get data, make predictions 
(X,y) = datasets.load_iris(return_X_y=True) 
X_train, X_test, y_train, y_test = train_test_split(X,y, train_size=0.5) 

clf = SVC() 
clf.fit(X_train,y_train) 
y_test_pred = clf.predict(X_test) 


# Plot Confusion Matrix 
plt.style.use('classic') 
plt.figure(figsize=(3,3)) 
pretty_print_conf_matrix(y_test, y_test_pred, 
         classes= ['0', '1', '2'], 
         normalize=True, 
         title='Confusion Matrix')