<jupyter_start><jupyter_text>Perceptron<jupyter_code>import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

%matplotlib inline
def load_dataset(filename: str) -> pd.DataFrame:
    '''Load and return the content of `filename` into a Pandas DataFrame'''
    
    
    return pd.read_csv(filename, delim_whitespace=True)
def split_dataset(dataset: pd.DataFrame) -> (list, list, list, list):
    '''Split the `dataset` into 4 lists: 2 for training and 2 to test the prediction'''
    
    
    labels_train = dataset.values[:,-1]
    training_samples = dataset.values[:,:-1]

    theta = np.ones((labels_train.size, 1))
    training_samples = np.concatenate((training_samples, theta), axis=1)
    
    return training_samples, training_samples[:], labels_train, labels_train[:]
def accuracy_score(labels_test: list, prediction: list) -> float:
    '''
    Return the calculated accuracy score, in other words, the number of `right`
    predictions divided by `all` predictions
    '''


    if len(labels_test) != len(prediction):
        raise ValueError('Both `labels_test` and `predictions` must have \
                         the same length')

    test_samples = zip(prediction, labels_test)
    return sum([1 for p, l in  test_samples if p == l]) / len(labels_test)
class Perceptron(object):
    '''Implements the single neuron (perceptron) Artificial Neural Network (ANN)'''


    def __init__(self: object):
        '''
        Naive initializations
        '''


        self.weights = []
        self.errors = []
        self.converged = False


    def fit(self: object, training_samples: list, labels_train: list,
            learning_rate=.1, max_iterations=int(1e4), error=1e-2) -> None:
        '''
        Operate over the training set until the cost function produces a square
        error lesser than the (optional) given param `error`. Or until hit the
        (optional) given param `max_iterations`
        '''


        self.converged = False
        self.errors = []
        self.weights = np.array(np.random.random(training_samples[0].size))

        for iteration in range(max_iterations):
            squared_error = 0
            for training_sample, label in zip(training_samples, labels_train):
                diff = label - self.neuron_output(training_sample)
                squared_error += diff ** 2
                self.weights = self.weights - learning_rate * (2 * diff * -training_sample)
            if iteration < max_iterations:
                self.errors.append(squared_error)
            if squared_error / len(training_samples) < error:
                self.converged = True
                break


    def predict(self: object, test_samples: list) -> list:
        '''
        Make a prediction to the given param `test_samples`
        '''


        return [self.neuron_output(test_sample) for test_sample in test_samples]


    def neuron_output(self: object, sample: list, threshold=.5) -> float:
        '''
        Calculate the output of the ANN when presented with the values of the
        given param `feature_sample`


        Returns: The result of the activation function with the pondered
        weights applied to the values of `feature_sample`

        Returns
            1 - If the given param `input_value` is greater or equal than the
                (optional given param `threshold`.
            0 - Otherwise.
        '''


        return 0 if np.dot(sample, self.weights) < threshold else 1


    def plot_errors(self: object) -> None:
        '''
        Generate a plot with the error curve obtained during the last training
        of the perceptron
        '''


        plt.xlabel("$Iterations$")
        plt.ylabel("$Error - (MSE)$")
        plt.plot(
            self.errors, "b{}-".format("o" if len(self.errors) < 25 else ""),
            label="Mean Square Error (MSE) in the first {} iterations".
            format(len(self.errors))
        )
        plt.legend(loc="upper right")
        plt.axis([-.1, len(self.errors), -.1, max(self.errors) + .5])
        plt.grid(True)
        plt.show()<jupyter_output><empty_output><jupyter_text>First Example, the ```And``` case  Display the Dataset<jupyter_code>dataset = load_dataset("and.dat")
dataset.head()<jupyter_output><empty_output><jupyter_text>Plot of the Dataset<jupyter_code>dataset.plot();
training_samples, testing_samples, labels_train, labels_test = split_dataset(dataset)

colors = ["red" if label == 0 else "blue" for label in labels_train]

plt.figure()
plt.scatter(training_samples[:, 0], training_samples[:, 1], s=170, color=colors)

plt.xlabel("$X$")
plt.ylabel("$Y$")
plt.title("Plot of AND")

plt.show()
clf = Perceptron()
clf.fit(training_samples, labels_train)
pred = clf.predict(testing_samples)
accuracy = accuracy_score(labels_test, pred)
print('Convergence: {}\nAccuracy: {}%\n'.format("Succeed" if clf.converged else "Fail", 100 * accuracy))
clf.weights
pd.DataFrame.from_items([('Expected', labels_test), ('Obtained', pred)])
clf.plot_errors()<jupyter_output><empty_output><jupyter_text>-------------------------------  Second Example, the ```OR``` case  Display the Dataset<jupyter_code>dataset = load_dataset("or.dat")
dataset.head()<jupyter_output><empty_output><jupyter_text>Plot of the Dataset<jupyter_code>dataset.plot();
training_samples, testing_samples, labels_train, labels_test = split_dataset(dataset)

colors = ["red" if label == 0 else "blue" for label in labels_train]

plt.figure()
plt.scatter(training_samples[:, 0], training_samples[:, 1], s=170, color=colors)

plt.xlabel("$X$")
plt.ylabel("$Y$")
plt.title("Plot of OR")

plt.show()
clf = Perceptron()
clf.fit(training_samples, labels_train)
pred = clf.predict(testing_samples)
accuracy = accuracy_score(labels_test, pred)
print('Convergence: {}\nAccuracy: {}%\n'.format("Succeed" if clf.converged else "Fail", 100 * accuracy))
clf.weights
pd.DataFrame.from_items([('Expected', labels_test), ('Obtained', pred)])
clf.plot_errors()<jupyter_output><empty_output><jupyter_text>----------------------  Third Example, the ```And with 3 entries``` case  Display the Dataset<jupyter_code>dataset = load_dataset("3_and.dat")
dataset.head(10)<jupyter_output><empty_output><jupyter_text>Plot of the Dataset<jupyter_code>dataset.plot();
training_samples, testing_samples, labels_train, labels_test = split_dataset(dataset)

colors = ["red" if label == 0 else "blue" for label in labels_train]

plt.figure()
plt.scatter(training_samples[:, 0], training_samples[:, 1], s=170, color=colors)
plt.xlabel("$X$")
plt.ylabel("$Y$")
plt.title("Plot of 3_AND")

plt.show()
clf = Perceptron()
clf.fit(training_samples, labels_train)
pred = clf.predict(testing_samples)
accuracy = accuracy_score(labels_test, pred)
print('Convergence: {}\nAccuracy: {}%\n'.format("Succeed" if clf.converged else "Fail", 100 * accuracy))
clf.weights
pd.DataFrame.from_items([('Expected', labels_test), ('Obtained', pred)])
clf.plot_errors()<jupyter_output><empty_output><jupyter_text>-------------------------------  Last Example, the ```10 entries example``` case  Display the Dataset<jupyter_code>dataset = load_dataset("10_example.dat")
dataset.head()<jupyter_output><empty_output><jupyter_text>Plot of the Dataset<jupyter_code>training_samples, testing_samples, labels_train, labels_test = split_dataset(dataset)

colors = ["red" if label == 0 else "blue" for label in labels_train]

plt.close()
plt.figure()
plt.scatter(range(1024), [label for label in labels_train], color=colors)
plt.xlabel("$X$")
plt.ylabel("$Y$")
plt.title("Plot of an example with 10 entries")

plt.show()
clf = Perceptron()
clf.fit(training_samples, labels_train, error=1e-3)
pred = clf.predict(testing_samples)
accuracy = accuracy_score(labels_test, pred)
print('Convergence: {}\nAccuracy: {}%\n'.format("Succeed" if clf.converged else "Fail", 100 * accuracy))
clf.weights
plt.rcParams["figure.figsize"] = [4 * 4, 3 * 2]
clf.plot_errors()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13895531780994336, 'fraction_numerical': 0.009943360604153555, 'mean_word_length': 3.693443591258122, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 44, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '180675', 'license': 'Apache-2.0', 'n_tokens_mistral': 2625, 'n_tokens_neox': 2466, 'n_words': 628, 'path': 'techniques/ANN/Perceptron/perceptron.ipynb', 'repo_name': 'jhonatancasale/learning-machine-learning', 'size': '7945'}