<jupyter_start><jupyter_text>1.) rank of A is C-1<jupyter_code>import sys, itertools
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
from mpl_toolkits.mplot3d import Axes3D
import random
from sklearn import svm
import csv
import numpy as np
from sklearn.metrics import confusion_matrix
labelcol = 18

def drop_col(data, col):
    return data.drop(data.columns[[col]], axis = 1)


def contribution_map(eigenValues):
  #Summing the real and imaginary parts for the calculation of contribution percentage
  total_sum = np.sum(np.sum([np.real(eigenValues), np.imag(eigenValues)]))
  #print(total_sum)
  for i in eigenValues:
    contr_percent = round(((np.sum([np.real(i),np.imag(i)]) / total_sum) * 100),2)
    print("Eigen Values {} with contribution {}%".format(i, contr_percent))

# Function estimates the LDA parameters
def LDA(data, labels):
    
    # no. of classes
    # group data by label column
    data = pd.concat([data, labels.T], axis=1, join='inner')
    grouped = data.groupby(data.iloc[:, labelcol])
    classes = [c for c in grouped.groups.keys()]
    classwise = {} 
    for c in classes:
      classwise[c] = drop_col(grouped.get_group(c), labelcol)

    # calculate means for each class
    means = {}
    for c in classes:
        means[c] = np.array(classwise[c].mean(axis = 0))

    # calculate the overall mean of all the data
    overall_mean = np.array(drop_col(data, labelcol).mean(axis = 0))

    # calculate between class covariance matrix
    # S_B = \sigma{N_i (m_i - m) (m_i - m).T}
    S_B = np.zeros((data.shape[1] - 1, data.shape[1] - 1))
    for c in means.keys():
        S_B += np.multiply(len(classwise[c]), np.outer((means[c] - overall_mean), (means[c] - overall_mean)))

    # calculate within class covariance matrix
    # S_W = \sigma{S_i}
    S_W = 0
    for key, values in classwise.items():
      S_W = S_W + np.cov(values.T)

    # find eigenvalue, eigenvector pairs for inv(S_W).S_B
    mat = np.dot(np.linalg.pinv(S_W), S_B)
    eig_vals, eig_vecs = np.linalg.eig(mat)
    contribution_map(eig_vals)
    
    eiglist = [(eig_vals[i], eig_vecs[:, i]) for i in range(len(eig_vals))]

    # sort the eig_vals in decreasing order
    eiglist = sorted(eiglist, key = lambda x : x[0], reverse = True)

    # only first two eigenvalues are important as their contribution percentage are high
    # two eigenvectors
    u = np.array([eiglist[i][1] for i in range(2)])

    # two eigenvalues
    L = np.array([eiglist[i][0] for i in range(2)])

    projections = np.dot(drop_col(data, labelcol), u.T)

    return u, L, projections
def read_csv(file):
  with open(file, 'r') as f:
      data = pd.read_csv(f, delimiter=',',dtype="float64")
      labels = data.iloc[:, -1]
      featureData = data.iloc[:, 0:-1]
      return featureData, labels
train_data, train_labels = read_csv('train.csv')
coefficient, latent, new_data = LDA(train_data, train_labels)
new_data = np.real(new_data) + np.imag(new_data)
classifier = svm.SVC(gamma="scale", kernel="rbf")
classifier.fit(new_data, train_labels)
def plot_contour(data, labels, classifier, title):

  # make mesh grid
  x = np.arange(data[:,0].min(), data[:,0].max(), 0.02)
  y = np.arange(data[:,1].min(), data[:,1].max(), 0.02)
  X, Y = np.meshgrid(x, y)

  # plot contour and data scatter
  plt.figure()
  ax = plt.axes()
  Z = classifier.predict(np.c_[X.ravel(), Y.ravel()])
  Z = Z.reshape(X.shape)
  ax.contour(X, Y, Z, cmap='viridis' , alpha=0.9)
  ax.contourf(X, Y, Z, cmap='viridis' , alpha=0.9)
  scatter = ax.scatter(data[:,0], data[:,1], c=labels, cmap='viridis', s=25, edgecolors='k', linewidth=1)
  ax.set_xlim(X.min(), X.max())
  ax.set_ylim(Y.min(), Y.max())
  ax.set_xlabel('LDA 1')
  ax.set_ylabel('LDA 2')
  ax.set_title(title)
  # produce a legend with the unique colors from the scatter
  ax.legend(handles=scatter.legend_elements(num=[1,2,3,4])[0], labels=['1: OPEL','2: SAAB','3: BUS','4: VAN'])
  plt.show()
plot_contour(new_data, train_labels, classifier, "Training")
test_data, test_labels = read_csv('test.csv')
test_data_proj = np.dot(test_data, coefficient.T)
test_data_proj = np.real(test_data_proj) + np.imag(test_data_proj)
predicted_labels = classifier.predict(test_data_proj)
confusion_matrix(test_labels, predicted_labels)
plot_contour(test_data_proj, test_labels, classifier, "Testing")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1488828089375285, 'fraction_numerical': 0.013451892384860921, 'mean_word_length': 4.101162790697674, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '383584', 'license': 'Apache-2.0', 'n_tokens_mistral': 1680, 'n_tokens_neox': 1623, 'n_words': 395, 'path': 'PR/Assignment07/PRAssignment07.ipynb', 'repo_name': 'jhinga-la-la/pattern-recognition-course', 'size': '4386'}