diff --git a/Cleaning_and_ML.html b/Cleaning_and_ML.html deleted file mode 100644 index 8353005..0000000 --- a/Cleaning_and_ML.html +++ /dev/null @@ -1,16370 +0,0 @@ - - -
- -pandasnumpysklearn.model_selectionsklearnpreprocessingsklearn.clustermatplotlib.pyplotscipy#importing packages
-import pandas as pd
-import numpy as np
-from sklearn.model_selection import train_test_split
-from sklearn.preprocessing import StandardScaler
-from sklearn.cluster import KMeans
-import matplotlib.pyplot as plt
-from scipy import stats
-%matplotlib inline
-Importing files from local file directory
- -from google.colab import files
-uploaded = files.upload()
-.head method was used to print the first 5 rows of the dataframe#reading from base dataset
-audioset = pd.read_csv('audioset_g.csv', sep=',')
-audioset.head()
-genre_simp¶genre_simp that simplified the numerous genre labels by assigning the genres into 4 main categoriesdef genre_simp(genre):
- if 'hip hop' in genre:
- return 'hip hop'
- elif 'metal' in genre:
- return 'classical'
- elif 'classical' in genre:
- return 'metal'
- elif 'country' in genre:
- return 'country'
- else:
- return 'None'
-genre_simp to genres¶#applying the genre simplifier function to the genres
-genre_list_simp = audioset['genre'].apply(genre_simp)
-genre¶audioset['genre'] = genre_list_simp
-audiosetg = audioset[audioset['genre'].isin(['hip hop', 'country', 'metal', 'classical'])]
-metal_setclassical_sethiphop_setcountry_set#segregate into genres, so we can sample a similar number of songs
-metal_set = audiosetg[audiosetg['genre']=='metal']
-classical_set = audiosetg[audiosetg['genre']=='classical']
-hiphop_set = audiosetg[audiosetg['genre']=='hip hop']
-country_set = audiosetg[audiosetg['genre']=='country']
-.sample method#sample an equal number of each genre
-metal_set = metal_set.sample(2000)
-classical_set = classical_set.sample(2000)
-hiphop_set = hiphop_set.sample(2000)
-country_set = country_set.sample(2000)
-genre_boxplot that plots a boxplot¶#function to print a boxplot of each metric's ability to separate by genre
-def genre_boxplot(metric):
- metal_plot = metal_set[metric]
- classical_plot = classical_set[metric]
- hiphop_plot = hiphop_set[metric]
- country_plot = country_set[metric]
- plt.boxplot([metal_plot, classical_plot, hiphop_plot, country_plot])
- plt.show()
-#genres
-# genre_boxplot('acousticness')
-genre_boxplot('danceability')
-# genre_boxplot('duration_ms')
-# genre_boxplot('energy')
-# genre_boxplot('instrumentalness')
-# genre_boxplot('key')
-# genre_boxplot('liveness')
-# genre_boxplot('loudness')
-# genre_boxplot('mode')
-# genre_boxplot('speechiness')
-# genre_boxplot('tempo')
-# genre_boxplot('time_signature')
-# genre_boxplot('valence')
-stats.shapiro function to test for assumptions of normal distributions in each song metric#test for assumption of normality
-def norm_test(genreset):
- results = [stats.shapiro(genreset['acousticness']),
- stats.shapiro(genreset['danceability']),
- stats.shapiro(genreset['duration_ms']),
- stats.shapiro(genreset['energy']),
- stats.shapiro(genreset['instrumentalness']),
- stats.shapiro(genreset['key']),
- stats.shapiro(genreset['liveness']),
- stats.shapiro(genreset['loudness']),
- stats.shapiro(genreset['mode']),
- stats.shapiro(genreset['speechiness']),
- stats.shapiro(genreset['tempo']),
- stats.shapiro(genreset['time_signature']),
- stats.shapiro(genreset['valence'])]
- return results
-norm_test(metal_set)
-# norm_test(classical_set)
-# norm_test(hiphop_set)
-# norm_test(country_set)
-stats.ks_2samp function was used#function to conduct Kolmogorov-Smirnoff test to test significant difference between genres
-def ks_test(genre1,genre2):
- results=[stats.ks_2samp(genre1['acousticness'],genre2['acousticness']),
- stats.ks_2samp(genre1['danceability'],genre2['danceability']),
- stats.ks_2samp(genre1['duration_ms'],genre2['duration_ms']),
- stats.ks_2samp(genre1['energy'],genre2['energy']),
- stats.ks_2samp(genre1['instrumentalness'],genre2['instrumentalness']),
- stats.ks_2samp(genre1['key'],genre2['key']),
- stats.ks_2samp(genre1['liveness'],genre2['liveness']),
- stats.ks_2samp(genre1['loudness'],genre2['loudness']),
- stats.ks_2samp(genre1['mode'],genre2['mode']),
- stats.ks_2samp(genre1['speechiness'],genre2['speechiness']),
- stats.ks_2samp(genre1['tempo'],genre2['tempo']),
- stats.ks_2samp(genre1['time_signature'],genre2['time_signature']),
- stats.ks_2samp(genre1['valence'],genre2['valence'])]
- return results
-# ks_test(metal_set, classical_set)
-# ks_test(metal_set, hiphop_set)
-ks_test(metal_set, country_set) #time signature cannot differentiate these
-# ks_test(classical_set, hiphop_set)
-# ks_test(classical_set, country_set) #key cannot differentiate these
-# ks_test(hiphop_set, country_set) #liveness, time_signature cannot differentiate
-#putting them into 1 dataframe
-music_set = pd.concat([metal_set, classical_set, hiphop_set, country_set])
-music_set.sample function#shuffle dataframe
-music_set = music_set.sample(frac=1)
-#isolating data and labels
-labelcol = music_set['genre']
-datacol = music_set[['acousticness', 'danceability', 'energy', 'instrumentalness', 'loudness',
- 'speechiness', 'tempo', 'valence']]
-#splitting dataset into train and test
-datacol, data_test, labelcol, label_test = train_test_split(datacol, labelcol, test_size=0.2)
-stdscale.fit function#scaling the data
-stdscale = StandardScaler()
-
-#fit on training data
-stdscale.fit(datacol)
-
-#transform both training and test
-dataset = stdscale.transform(datacol)
-data_test = stdscale.transform(data_test)
-np.array¶#transform into array for input
-train_data = np.array(dataset.astype(float))
-KMeans function#performing Kmeans
-import random
-random.seed(10)
-kmeans = KMeans(n_clusters=4, max_iter=600, algorithm = 'auto')
-kmeans.fit(train_data)
-for loop#creating the prediction cluster
-cluster = []
-for i in range(len(train_data)):
- predictor = np.array(train_data[i].astype(float))
- predictor = predictor.reshape(-1, len(predictor))
- prediction = kmeans.predict(predictor)
- cluster.append(prediction[0])
-comparison_set = pd.DataFrame(labelcol)
-comparison_set['cluster'] = cluster
-comparison_set
-Saving the clusters with dataframe to csv files as audio_clustered.csv
comparison_set.to_csv('audio_clustered.csv')
-Command to download the audio_clustered datafram
files.download('audio_clustered.csv')
-#seeing which genres are placed into which clusters
-print(comparison_set[comparison_set['genre'] == 'classical']['cluster'].mode()[0])
-print(comparison_set[comparison_set['genre'] == 'metal']['cluster'].mode()[0])
-print(comparison_set[comparison_set['genre'] == 'hip hop']['cluster'].mode()[0])
-print(comparison_set[comparison_set['genre'] == 'country']['cluster'].mode()[0])
-for loop¶#reassigning the genres to those clusters
-label_cluster = []
-for genre in labelcol:
- if genre == 'classical':
- label_cluster.append(comparison_set[comparison_set['genre'] == 'classical']['cluster'].mode()[0])
- elif genre == 'metal':
- label_cluster.append(comparison_set[comparison_set['genre'] == 'metal']['cluster'].mode()[0])
- elif genre == 'hip hop':
- label_cluster.append(comparison_set[comparison_set['genre'] == 'hip hop']['cluster'].mode()[0])
- elif genre == 'country':
- label_cluster.append(comparison_set[comparison_set['genre'] == 'country']['cluster'].mode()[0])
-correct = 0
-for i in range(len(train_data)):
- predictor = np.array(train_data[i].astype(float))
- predictor = predictor.reshape(-1, len(predictor))
- prediction = kmeans.predict(predictor)
- if prediction[0] == label_cluster[i]:
- correct += 1
-
-print("The proportion of songs correctly clustered is:", correct/len(train_data))
-#Importing packages
-from sklearn.neighbors import KNeighborsClassifier
-from sklearn import metrics
-from sklearn.metrics import confusion_matrix
-#Create KNN Classifier
-random.seed(10)
-knn = KNeighborsClassifier(n_neighbors=8)
-#Train the model using the training sets
-knn_model = knn.fit(train_data, labelcol)
-#Predict the response for test dataset
-knn_pred = knn.predict(data_test)
-#predict model accuracy
-print("Based on our current metrics, the accuracy of genre prediction is:",metrics.accuracy_score(label_test, knn_pred))
-for loop that iterates through the possible values of k¶# try K=1 through K=25 and record testing accuracy
-k_range = range(1, 30)
-
-# We can create Python dictionary using [] or dict()
-scores = []
-
-# We use a loop through the range 1 to 26
-# We append the scores in the dictionary
-for k in k_range:
- knn = KNeighborsClassifier(n_neighbors=k)
- knn.fit(train_data, labelcol)
- knn_pred = knn.predict(data_test)
- scores.append(metrics.accuracy_score(label_test, knn_pred))
-
-print("Prediction scores of varying k values:", scores)
-print("Based on the testing for maximum accuracy of genre prediction, the highest score is:", max(scores), "when k = 12")
-pred_score¶pred_score = pd.DataFrame(scores, columns = ['Prediction Score'])
-pred_score
-# import Matplotlib (scientific plotting library)
-import matplotlib.pyplot as plt
-
-# Plots the relationship between the range of K vlaues and testing accuracy
-plt.plot(k_range, scores)
-plt.xlabel('Value of K for KNN')
-plt.ylabel('Testing Accuracy')
-# changing to misclassification error
-# creating list of K for KNN
-import seaborn as sns
-
-from sklearn.model_selection import cross_val_score
-
-k_list = list(range(1,31))
-# creating list of cv scores
-cv_scores = []
-
-# perform 10-fold cross validation
-for k in k_list:
- knn = KNeighborsClassifier(n_neighbors=k)
- scores = cross_val_score(knn, train_data, labelcol, cv=30, scoring='accuracy')
- cv_scores.append(scores.mean())
-MSE = [1 - x for x in scores]
-train_data = np.array(train_data)
-labelcol = np.array(labelcol)
-plt.figure()
-plt.figure(figsize=(15,10))
-plt.title('The optimal number of neighbors', fontsize=20, fontweight='bold')
-plt.xlabel('Number of Neighbors K', fontsize=15)
-plt.ylabel('Misclassification Error', fontsize=15)
-sns.set_style("whitegrid")
-plt.plot(k_list, MSE)
-
-plt.show()
-labels = ['metal', 'classical', 'hiphop', 'country']
-cm = metrics.confusion_matrix(label_test, knn_pred)
-print(cm)
-
-fig = plt.figure()
-ax = fig.add_subplot(111)
-cax = ax.matshow(cm)
-plt.title('Confusion Matrix of the Genre Classifier', y=1.08)
-fig.colorbar(cax)
-ax.set_xticklabels([''] + labels)
-ax.set_yticklabels([''] + labels)
-plt.xlabel('Predicted')
-plt.ylabel('True')
-
-plt.show()
-precisionrecallprecision_macro_averagerecall_macro_averagedef precision(label, confusion_matrix):
- col = confusion_matrix[:, label]
- return confusion_matrix[label, label] / col.sum()
-
-def recall(label, confusion_matrix):
- row = confusion_matrix[label, :]
- return confusion_matrix[label, label] / row.sum()
-def precision_macro_average(confusion_matrix):
- rows, columns = confusion_matrix.shape
- sum_of_precisions = 0
- for label in range(rows):
- sum_of_precisions += precision(label, confusion_matrix)
- return sum_of_precisions / rows
-def recall_macro_average(confusion_matrix):
- rows, columns = confusion_matrix.shape
- sum_of_recalls = 0
- for label in range(columns):
- sum_of_recalls += recall(label, confusion_matrix)
- return sum_of_recalls / columns
-Sample output shown below
- -print("label precision recall")
-for label in range(4):
- print(f"{label:5d} {precision(label, cm):9.3f} {recall(label, cm):6.3f}")
-print("precision total:", precision_macro_average(cm))
-print("recall total:", recall_macro_average(cm))
-def accuracy(confusion_matrix):
- diagonal_sum = confusion_matrix.trace()
- sum_of_all_elements = confusion_matrix.sum()
- return diagonal_sum / sum_of_all_elements
-accuracy(cm)
-