rasbt / mlxtend

A library of extension and helper modules for Python's data analysis and machine learning libraries.
https://rasbt.github.io/mlxtend/
Other
4.91k stars 872 forks source link

plot_decision_regions is missing the color when dealing with "-1" class labels #589

Open mhnlp opened 5 years ago

mhnlp commented 5 years ago

This code comes from this post

from mlxtend.plotting import plot_decision_regions

import numpy as np

class Perceptron(object):

    def __init__(self, eta=0.01, epochs=50):
        self.eta = eta
        self.epochs = epochs

    def train(self, X, y):

        self.w_ = np.zeros(1 + X.shape[1])
        self.errors_ = []

        for _ in range(self.epochs):
            errors = 0
            for xi, target in zip(X, y):
                update = self.eta * (target - self.predict(xi))
                self.w_[1:] +=  update * xi
                self.w_[0] +=  update
                errors += int(update != 0.0)
            self.errors_.append(errors)
        return self

    def net_input(self, X):
        return np.dot(X, self.w_[1:]) + self.w_[0]

    def predict(self, X):
        return np.where(self.net_input(X) >= 0.0, 1, -1)

import pandas as pd
df = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data', header=None)

# setosa and versicolor
y = df.iloc[0:100, 4].values
y = np.where(y == 'Iris-setosa', -1, 1)

# sepal length and petal length
X = df.iloc[0:100, [0,2]].values

%matplotlib inline
import matplotlib.pyplot as plt
from mlxtend.plotting import plot_decision_regions

ppn = Perceptron(epochs=10, eta=0.1)

ppn.train(X, y)
print('Weights: %s' % ppn.w_)
plot_decision_regions(X, y, clf=ppn)
plt.title('Perceptron')
plt.xlabel('sepal length [cm]')
plt.ylabel('petal length [cm]')
plt.show()

plt.plot(range(1, len(ppn.errors_)+1), ppn.errors_, marker='o')
plt.xlabel('Iterations')
plt.ylabel('Misclassifications')
plt.show()

mlxtend.version: '0.14.0' reproduced 100% on https://colab.research.google.com

Expected: plot a figure with 2 colored region

Actual: plot_decision_regions is missing the color of bottom region

rasbt commented 5 years ago

Hi there,

you are right. The issue comes from the fact that the plot_decision_region function expects class labels {0, 1, ...} whereas the class labels for the perceptron are {-1, 1}. I.e., do make it work, the following lines of the perceptron need to changed:

def predict(self, X):
    return np.where(self.net_input(X) >= 0.0, 1, -1)

to

def predict(self, X):
    return np.where(self.net_input(X) >= 0.5, 1, 0)

and

y = np.where(y == 'Iris-setosa', -1, 1)

to

y = np.where(y == 'Iris-setosa', 0, 1)

I think we should see if the plot_decision_regions can be "fixed" to support arbitrary class labels.