import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
Multi-Class Logistic Regression
$\left[ {\begin{array}{c} P(y_{1} = 1) \\ P(y_{2} = 1) \\ P(y_{3} = 1) \end{array} } \right] $
$Hardmax(\left[ {\begin{array}{c} 0.1 \\ 1.2 \\ 0.5 \end{array} } \right])$ = $\left[ {\begin{array}{c} 0 \\ 1 \\ 0 \end{array} } \right]$
def softmax(array):
return np.exp(array) / np.sum(np.exp(array), -1, keepdims=True)
a = np.arange(50)/5
b = a[::-1]
c = np.vstack([a,b]).T
pd.DataFrame(c, columns=['Increasing', 'Decreasing'])
plt.plot(softmax(c)[:,0], label='Increasing');
plt.plot(softmax(c)[:,1], label='Decreasing');
plt.xlabel('Input', fontsize=14), plt.ylabel('Output', fontsize=14)
plt.legend();
import sklearn.datasets as datasets
import time # To Track Time
iris = datasets.load_iris()
iris.keys()
print("Feature Names:\n", iris['feature_names'], "\n\nLabel Names:\n", iris['target_names'])
n_F = len(iris['feature_names'])
n_C = len(iris['target_names'])
iris['data'].shape, iris['target'].shape
df = pd.DataFrame(iris['data'], columns=iris['feature_names'])
df.head()
X = iris['data'].T
Y_class = iris['target']
X.shape, Y_class.shape
def one_hot(array, num_classes):
new_array = np.zeros((len(array), num_classes))
for i, val in enumerate(array):
new_array[i, val] = 1
return new_array
Y = one_hot(Y_class, n_C).T
Y.shape
indices = np.arange(iris['target'].shape[0])
np.random.shuffle(indices)
indices
X = X[:,indices]
Y = Y[:,indices]
Y_class = Y_class[indices]
split_ratio = 0.2
split = int(Y.shape[1] * split_ratio)
X_train = X[:, split:]
X_val = X[:, :split]
Y_train = Y[:, split:]
Y_val = Y[:, :split]
Y_class_train = Y_class[split:]
Y_class_val = Y_class[:split]
weights = np.random.randn(n_C, n_F) # Num Classes x Num Features
weights
biases = np.zeros((n_C, 1))
biases
# Activation Function
def softmax(x):
return np.exp(x)/sum(np.exp(x))
# Model
def model(biases, weights, X):
return softmax(biases + np.dot(weights, X))
model(biases, weights, X_train).shape
def cost(prediction, Y, epsilon=1e-10):
error = np.sum((Y * np.log(prediction + epsilon)) + ((1 - Y) * np.log(1 - prediction + epsilon)), -1)/Y.shape[1]
return - np.sum(error)
def train(X, Y, biases, weights, epochs=1, learning_rate=1e-2, iterations=1):
for epoch in range(epochs):
start = time.time()
for iteration in range(iterations):
# Forward Pass
pred = model(biases, weights, X)
# Calculate Loss
loss = cost(pred, Y)
# Calculate Gradients
db = np.sum((pred - Y), -1, keepdims=True) / Y.shape[1]
dw = np.dot((pred - Y), X.T) / Y.shape[1]
# Calculate Accuracy
class_pred = np.argmax(pred, 0)
class_y = np.argmax(Y, 0)
acc = np.sum(class_pred == class_y)/Y.shape[1]
# Update Biases and Weights
biases -= (learning_rate * db)
weights -= (learning_rate * dw)
print('Epoch {}:'.format(epoch+1))
print('Loss: {:.2f} | Accuracy: {:.2f}%\nTime Taken: {:.2f}s\n'.format(loss, acc*100, time.time()-start))
return biases, weights
def predict(X, Y, biases, weights):
# Forward Pass
pred = model(biases, weights, X)
# Calculate Accuracy
class_pred = np.argmax(pred, 0)
class_y = np.argmax(Y, 0)
acc = np.sum(class_pred == class_y)/Y.shape[1]
return acc, pred
biases, weights = train(X_train, Y_train, biases, weights, epochs=20, iterations=100)
acc, _ = predict(X_val, Y_val, biases, weights)
print('Accuracy of Prediction on Validation Data: {:.2f}%'.format(acc*100))
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(solver='liblinear', multi_class='ovr', verbose=1)
model.fit(X_train.T, Y_class_train)
# Training Set
model.score(X_train.T, Y_class_train)
# Validation Set
model.score(X_val.T, Y_class_val)
skpred_t = model.predict_proba(X_train.T)
skpred_v = model.predict_proba(X_val.T)
skpred = model.predict_proba(X.T)
epsilon = 1e-10
# Cross Entropy Loss
train_loss = - np.mean((Y_train.T * np.log(skpred_t + epsilon)) + ((1-Y_train.T) * np.log(1-skpred_t + epsilon)))
val_loss = - np.mean((Y_val.T * np.log(skpred_v + epsilon)) + ((1-Y_val.T) * np.log(1-skpred_v + epsilon)))
total_loss = - np.mean((Y.T * np.log(skpred + epsilon)) + ((1-Y.T) * np.log(1-skpred + epsilon)))
print('Train Set Loss: {:.4f}'.format(train_loss))
print('Validation Set Loss: {:.4f}'.format(val_loss))
print('Total Loss: {:.4f}'.format(total_loss))
from sklearn.naive_bayes import GaussianNB
NB = GaussianNB()
NB.fit(X.T, Y_class)
NB.score(X.T, Y_class)
from sklearn.tree import DecisionTreeClassifier
dec_tree = DecisionTreeClassifier()
dec_tree.fit(X.T, Y_class)
dec_tree.score(X.T, Y_class)
from sklearn.svm import SVC
SVM1 = SVC(kernel='linear')
SVM2 = SVC()
SVM1.fit(X.T, Y_class)
SVM2.fit(X.T, Y_class)
SVM1.score(X.T, Y_class), SVM2.score(X.T, Y_class)
from sklearn.ensemble import RandomForestClassifier
RFC = RandomForestClassifier()
RFC.fit(X.T, Y_class)
RFC.score(X.T, Y_class)
from sklearn.neural_network import MLPClassifier
NN1 = MLPClassifier(max_iter=1000, hidden_layer_sizes=3)
NN2 = MLPClassifier(max_iter=1000, hidden_layer_sizes=100)
NN3 = MLPClassifier(max_iter=1000, hidden_layer_sizes=300)
NN1.fit(X.T, Y_class)
NN1.score(X.T, Y_class)
NN2.fit(X.T, Y_class)
NN2.score(X.T, Y_class)
NN3.fit(X.T, Y_class)
NN3.score(X.T, Y_class)
NN4 = MLPClassifier(max_iter=1000, hidden_layer_sizes=(25,50,25))
NN4.fit(X.T, Y_class)
NN4.score(X.T, Y_class)