Machine Learning - week 4 Assignment:
THE MOVIE DATASET.
TASK- IS to check which cluster perform best and to check and compare the statistics of each cluster( Ratings, Revenue, Votes , Budget, Average Vote count, Movie Title and Popularity)
#Check if rows contain any null values data_numeric.isnull().sum()
# -*- coding: utf-8 -*-
from pandas import Series, DataFrame import pandas as pd import numpy as np import matplotlib.pylab as plt from sklearn.cross_validation import train_test_split from sklearn import preprocessing from sklearn.cluster import KMeans
#
Read the movies metadata csv file
âââ Data Management âââ data = pd.read_csv(âmovies_metadata.csvâ)
#upper-case all DataFrame column names
data.columns = map(str.upper, data.columns)
#Only keep the numeric columns for our analysis. However, weâll keep titles also #to interpret the results at the end of clustering. Note that this title column will #not be used in the analysis.
data.drop(data.index[19730],inplace=True) data.drop(data.index[29502],inplace=True) data.drop(data.index[35585],inplace=True)
data.columns
data_numeric = data[[âBUDGETâ,'POPULARITYâ,'REVENUEâ,'RUNTIMEâ,'VOTE_AVERAGEâ,'VOTE_COUNTâ,'TITLEâ]]
data_numeric.head()
#Check if rows contain any null values
data_numeric.isnull().sum()
# Data Management #Drop all the rows with null values
data_clean = data_numeric.dropna()
# subset clustering variables cluster=data_clean cluster.describe()
#Letâs see the statistics for the votes counts for the movies data cluster['VOTE_COUNTâ].describe()
#We see that a half of movies have been rated less than 10 times. For easier interpretability,
#letâs take only the movies that have more than 30 votes, i.e. top 26% of the movies.
cluster['VOTE_COUNTâ].quantile(np.arange(.74,1,0.01))
cluster = cluster[cluster['VOTE_COUNTâ]>30]
cluster.shape
cluster.columns
# standardize clustering variables to have mean=0 and sd=1 #Data Normalization
clustervar=cluster.copy() clustervar = clustervar.drop(columns='TITLEâ) clustervar['BUDGETâ]=preprocessing.scale(clustervar['BUDGETâ].astype('float64â)) clustervar['POPULARITYâ]=preprocessing.scale(clustervar['POPULARITYâ].astype('float64â)) clustervar['REVENUEâ]=preprocessing.scale(clustervar['REVENUEâ].astype('float64â)) clustervar['RUNTIMEâ]=preprocessing.scale(clustervar['RUNTIMEâ].astype('float64â)) clustervar['VOTE_AVERAGEâ]=preprocessing.scale(clustervar['VOTE_AVERAGEâ].astype('float64â)) clustervar['VOTE_COUNTâ]=preprocessing.scale(clustervar['VOTE_COUNTâ].astype('float64â))
clustervar.head()
Apply K-Means Clustering
What k to choose?
Letâs fit cluster size 1 to 20 on our data and take a look at the corresponding score value. Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â
from scipy.spatial.distance import cdist clusters=range(1,20) meandist=[]
for k in clusters: Â model=KMeans(n_clusters=k) Â model.fit(clustervar) Â clusassign=model.predict(clustervar) Â meandist.append(sum(np.min(cdist(clustervar, model.cluster_centers_, 'euclideanâ), axis=1)) Â / clus_train.shape[0])
These MeanDist signify how far our observations are from the cluster center. A large positive or a large negative value would indicate that the cluster center is far from the observations.
Based on these MeanDist, we plot an Elbow curve to decide which cluster size is optimal. Note that we are dealing with tradeoff between cluster size(hence the computation required) and the relative accuracy.
âââ
Plot average distance from observations from the cluster centroid to use the Elbow Method to identify number of clusters to choose âââ
plt.plot(clusters, meandist) plt.xlabel('Number of clustersâ) plt.ylabel('Average distanceâ) plt.title('Selecting k with the Elbow Methodâ)
Our Elbow point is around cluster size of 5. We will use k=5 to further interpret our clustering result.
# Interpret 5 cluster solution
model3=KMeans(n_clusters=5) model3.fit(clustervar) clusassign=model3.predict(clustervar)
# plot clusters
from sklearn.decomposition import PCA pca_2 = PCA(2) plot_columns = pca_2.fit_transform(clustervar) plt.scatter(x=plot_columns[:,0], y=plot_columns[:,1], c=model3.labels_,) plt.xlabel('Canonical variable 1â) plt.ylabel('Canonical variable 2â) plt.title('Scatterplot of Canonical Variables for 3 Clustersâ) plt.show()
As a result of clustering, we have the clustering label. Letâs put these labels back into the original numeric data frame.
len(model3.labels_)
cluster['clusterâ] = model3.labels_
cluster.head()
Interpret clustering results
#Letâs see cluster sizes first.
import seaborn as sns plt.figure(figsize=(12,7)) axis = sns.barplot(x=np.arange(0,5,1),y=cluster.groupby(['clusterâ]).count()['BUDGETâ].values) x=axis.set_xlabel(âCluster Numberâ) x=axis.set_ylabel(âNumber of moviesâ)
We clearly see that one cluster is the largest and one cluster has the fewest number of movies.
Letâs look at the cluster statistics.
cluster.groupby(['clusterâ]).mean()
We see that one cluster which is also the smallest, is the cluster of movies that received maximum number of votes(in terms of counts) and also have very high popularity and total runtime and net revenue. Letâs see some of the movies that belong to this cluster.
size_array = list(cluster.groupby(['clusterâ]).count()['BUDGETâ].values)
cluster[cluster['clusterâ]==size_array.index(sorted(size_array)[0])].sample(5)
We see many big movie names in this cluster. So the results are intuitive.
Cluster that is the second smallest cluster in the results, has 2nd highest votes count and the most highly rated movies.
The runtime for these movies is on the higher end and popularity score is also good.
Letâs see some of the movie names from this cluster.
cluster[cluster['clusterâ]==size_array.index(sorted(size_array)[1])].sample(5)
Lastly, letâs take a look at the least successful movies. This cluster represents the movies that received least number of votes and also has the smallest run-time, revenue and popularity score.
cluster[cluster['clusterâ]==size_array.index(sorted(size_array)[-1])].sample(5)
As we can see this cluster also includes the movies for which our dataset has no information about the budget and revenue, hence there corresponding fields have 0 value in it. This pulls down the net revenue of the whole cluster. If we keep the cluster size slightly larger, we might get to see these movies clustered separately.













