Challenge

Implementing Clustering and Predicting the Class of Car from "Car Dataset"

Implementing Clustering and Predicting the Class of Car from "Car Dataset"

Importing libraries

import pandas as pd
import numpy as np
import seaborn as sn
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import  MinMaxScaler
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import sklearn.cluster as cluster
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
import sklearn.metrics as metrics
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LinearRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report

Importing the dataset

df=pd.read_csv("cars.csv")
df.head()

Information on the dataset

df.info()

Replacing "?" with NaN values

df.replace("?", np.nan, inplace = True)

Saving the changes to a new dataset "cars_dataset"

df.to_csv("cars_dataset.csv", index=False)

Importing the new dataset

df2 = pd.read_csv('cars_dataset.csv')
df2.head()

Count of all the null values

df2.isnull().sum()

Observation:

We can see that the "?" were replaced by NaN. Now this can be easily replaced by values.

Replacing null values of normalized-loss, bore, stroke, horespower, peak-rpm with the median of their respective columns

a_n = df2["normalized-losses"].astype("float").median(axis=0)
print("Average of normalized-losses: ", a_n)

a_b = df2['bore'].astype('float').median(axis=0)
print("Average of bore: ", a_b)

a_s = df2["stroke"].astype("float").median(axis = 0)
print("Average of stroke:", a_s)

a_h = df2['horsepower'].astype('float').median(axis=0)
print("Average horsepower:", a_h)

a_p = df2['peak-rpm'].astype('float').median(axis=0)
print("Average peak rpm:", a_p)
Average of normalized-losses:  115.0
Average of bore:  3.31
Average of stroke: 3.29
Average horsepower: 95.0
Average peak rpm: 5200.0
df2["normalized-losses"].replace(np.nan, a_n, inplace=True)
df2["stroke"].replace(np.nan, a_s, inplace = True)
df2["bore"].replace(np.nan, a_b, inplace=True)
df2['horsepower'].replace(np.nan, a_h, inplace=True)
df2['peak-rpm'].replace(np.nan, a_p, inplace=True)
df2[df2['num-of-doors'].isna()]

Information on the new dataset

df2.info()

Since most of the sedan type cars are four doors,assuming that the both sedan cars have four doors

df2["num-of-doors"].replace(np.nan,"four", inplace=True)

Finding the price using Random Forest Regressor

def encoder(datatype):
    t = LabelEncoder()
    for i in datatype:
        if datatype[i].dtype == "object":
            datatype[i] = t.fit_transform(datatype[i])
encoder(df2)
df2.head()

Scaling the dataset using MinMaxScaler

scaler=MinMaxScaler()
df2=pd.DataFrame(scaler.fit_transform(df2), columns=df2.columns)

Filtering the null value price rows

m_p = df2[df2['price'].isna()]
m_p

Removing the null value price rows

df2.dropna(subset=["price"], axis=0, inplace=True)
df2.reset_index(drop=True, inplace=True)
X = df2[df2.columns.drop(['price'])]
Y = df2['price']

Splitting the dataset into test and train dataset

X_train, X_test, y_train, y_test = train_test_split(X,Y,test_size = 0.4, random_state=90)
RF = RandomForestRegressor()
RF.fit(X_train,y_train)
Y_pred = RF.predict(X_test)

print(Y_pred)
[0.31379177 0.6594963  0.10796481 0.11735713 0.04875676 0.05798669
 0.05820913 0.01216151 0.04276103 0.68375552 0.10995941 0.10865076
 0.19176779 0.1968224  0.05484062 0.07174619 0.11174979 0.10200611
 0.19873467 0.02918673 0.39471302 0.07897696 0.0166176  0.71101758
 0.12547043 0.02645003 0.04965667 0.01424656 0.20127352 0.21185691
 0.77121841 0.34967876 0.29633186 0.11822191 0.11624448 0.27342845
 0.10701058 0.10898499 0.38818927 0.12648789 0.03851398 0.07122859
 0.05344943 0.12032372 0.24321906 0.2029075  0.29578919 0.38569659
 0.03856958 0.0882759  0.65348592 0.11823461 0.09118341 0.36920783
 0.26553299 0.01969192 0.12416944 0.28137195 0.2187091  0.12871589
 0.14655156 0.11254245 0.03696763 0.21488605 0.12124721 0.35277568
 0.03856958 0.20575791 0.5814463  0.23937863 0.23679708 0.28243955
 0.11105895 0.12310892 0.2308587  0.08609776 0.23725336 0.15435281
 0.0589864  0.59251502 0.11302741]
rf = RF.score(X_test,y_test)
print(rf)
0.9088761544334404
X1 = m_p[m_p.columns.drop(['price'])]

Predicting the null-value price using random forest regressor

p = RF.predict(X1)
p
array([0.3214756 , 0.02299787, 0.0290564 , 0.7026245 ])
index = [200,201,202,203]
final_Array = []
c = 0
for l in index:
    if c<len(index):
        for j in p:         
            final_Array.append(((l, j)))
            j+=1
            l+=1
            c+=1
data = pd.DataFrame(final_Array,columns=['index','price'])
data.head()

Reseting the index

X1.reset_index(drop=True, inplace=True)

Joining the new price with the existing column

f = pd.concat([X1,data], axis=1)

Setting index

f.set_index("index", inplace=True)
f

Combining the missing price dataset with df2

df2 = pd.concat([df2,f])
df2.isnull().sum()

Plotting

plt.figure(figsize=(17,17))
sn.heatmap(data=df2.corr(),annot=True) # corretalional 
plt.show()

Performing PCA on the dataset

pca = PCA(n_components=3)
d_pca = pd.DataFrame(pca.fit_transform(df2),columns=['pc1','pc2','pc3'])
d_pca

Implementing K-means to form class column

k_range=range(1,20)
sse=[]
for k in k_range:
    km=KMeans(n_clusters=k)
    km.fit(d_pca)
    sse.append(km.inertia_)
print(sse)
plt.plot(k_range, sse, '-+')
plt.xlabel('K value')
plt.ylabel('SSE')
plt.title('Elbow plot (To determine best K value)')
plt.show()
[182.734723477616, 114.60985735648904, 81.85969283379508, 56.99943652748497, 
35.56070361085253, 29.54146540722608, 25.416432975144257, 21.352301605932805,
18.945979843146944, 16.58388640195327, 15.10720189601353, 13.602270043948335,
12.034749354562923, 11.489623078880674, 10.406934622932779, 9.415576706325817,
8.518812489508145, 7.893105020717661, 6.850086945580614]


Since elbow curve doesn't help to choose correct k values silhoutte score is used
for i in range(2,13):
    labels=cluster.KMeans(n_clusters=i).fit(d_pca).labels_
    print ("Silhouette score for k(clusters) = "+str(i)+" is "+str(metrics.silhouette_score(d_pca,labels,metric="euclidean")))
Silhouette score for k(clusters) = 2 is 0.40391133552680836
Silhouette score for k(clusters) = 3 is 0.4537742123882564
Silhouette score for k(clusters) = 4 is 0.4543734446698324
Silhouette score for k(clusters) = 5 is 0.5049600066530242
Silhouette score for k(clusters) = 6 is 0.5168513332218838
Silhouette score for k(clusters) = 7 is 0.47178574773325727
Silhouette score for k(clusters) = 8 is 0.4419244701735852
Silhouette score for k(clusters) = 9 is 0.4447355418092978
Silhouette score for k(clusters) = 10 is 0.4658308691009421
Silhouette score for k(clusters) = 11 is 0.4841685602067468
Silhouette score for k(clusters) = 12 is 0.4643317491683399


Based on silhouette score number of cluster is chosen as 6
kmeans = KMeans(n_clusters = 6)
y1 = pd.Series(kmeans.fit_predict(d_pca))
d_pca['class'] = y1
y1.value_counts()

d_pca.head(10)

sn.pairplot(d_pca, hue="class")
plt.show()



Using Classifier
1. KNN Classifier
X = d_pca[d_pca.columns.drop(['class'])]
y = d_pca['class']
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.3, random_state =90) 
kn = KNeighborsClassifier(n_neighbors=6)
kn.fit(X_train,y_train)
y_pred = kn.predict(X_test)
y_pred
array([2, 2, 2, 0, 5, 0, 4, 2, 0, 4, 1, 2, 2, 0, 1, 2, 4, 1, 4, 4, 2, 1,
       0, 0, 2, 1, 2, 4, 2, 1, 4, 3, 2, 2, 2, 1, 0, 4, 0, 0, 0, 2, 1, 2,
       2, 2, 2, 2, 4, 5, 1, 2, 5, 1, 2, 0, 4, 5, 4, 0, 2, 0])
knt = kn.score(X_test,y_test)
print(knt)
0.9838709677419355
cm = confusion_matrix(y_test, y_pred)
print(cm)
[[12  0  0  0  0  0]
 [ 0 10  0  0  0  0]
 [ 0  0 23  0  0  0]
 [ 0  0  0  1  0  0]
 [ 1  0  0  0 11  0]
 [ 0  0  0  0  0  4]]
print(classification_report(y_test, y_pred))
precision    recall  f1-score   support

           0       0.92      1.00      0.96        12
           1       1.00      1.00      1.00        10
           2       1.00      1.00      1.00        23
           3       1.00      1.00      1.00         1
           4       1.00      0.92      0.96        12
           5       1.00      1.00      1.00         4

    accuracy                           0.98        62
   macro avg       0.99      0.99      0.99        62
weighted avg       0.99      0.98      0.98        62
plt.figure(figsize=(15,10))
categories = np.unique(y)
df_cm = pd.DataFrame(cm, index = [i for i in categories], columns = [i for i in categories])
sn.heatmap(df_cm,annot=True)
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.show()

2. Decision Tree

X = d_pca[d_pca.columns.drop(['class'])]
y = d_pca['class']
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.3, random_state =90) 
DC = DecisionTreeClassifier()
DC.fit(X_train,y_train)
y_pred = DC.predict(X_test)
y_pred
array([2, 2, 2, 4, 5, 0, 4, 2, 0, 4, 1, 2, 2, 0, 1, 2, 4, 1, 4, 4, 2, 1,
       0, 0, 2, 1, 2, 4, 2, 1, 4, 3, 2, 2, 2, 1, 0, 4, 0, 0, 0, 2, 1, 2,
       2, 2, 2, 2, 4, 5, 1, 2, 5, 1, 2, 0, 4, 5, 4, 0, 2, 0])
Dc = DC.score(X_test,y_test)
print(Dc)

1.0

print(classification_report(y_test, y_pred))
precision    recall  f1-score   support

           0       1.00      1.00      1.00        12
           1       1.00      1.00      1.00        10
           2       1.00      1.00      1.00        23
           3       1.00      1.00      1.00         1
           4       1.00      1.00      1.00        12
           5       1.00      1.00      1.00         4

    accuracy                           1.00        62
   macro avg       1.00      1.00      1.00        62
weighted avg       1.00      1.00      1.00        62
cm = confusion_matrix(y_test, y_pred)
print(cm)
[[12  0  0  0  0  0]
 [ 0 10  0  0  0  0]
 [ 0  0 23  0  0  0]
 [ 0  0  0  1  0  0]
 [ 0  0  0  0 12  0]
 [ 0  0  0  0  0  4]]
plt.figure(figsize=(15,10))
categories = np.unique(y)
df_cm = pd.DataFrame(cm, index = [i for i in categories], columns = [i for i in categories])
sn.heatmap(df_cm,annot=True)
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.show()


3. Random Forest
X = d_pca[d_pca.columns.drop(['class'])]
y = d_pca['class']
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.3, random_state = 90) 
Rtc = RandomForestClassifier()
Rtc.fit(X_train,y_train)
y_pred = Rtc.predict(X_test)
y_pred
array([2, 2, 2, 4, 5, 0, 4, 2, 0, 4, 1, 2, 2, 0, 1, 2, 4, 1, 4, 4, 2, 1,
       0, 0, 2, 1, 2, 4, 2, 1, 4, 3, 2, 2, 2, 1, 0, 4, 0, 0, 0, 2, 1, 2,
       2, 2, 2, 2, 4, 5, 1, 2, 5, 1, 2, 0, 4, 5, 4, 0, 2, 0])
rc = Rtc.score(X_test,y_test)
print(rc)

1.0

print(classification_report(y_test, y_pred))
precision    recall  f1-score   support

           0       1.00      1.00      1.00        12
           1       1.00      1.00      1.00        10
           2       1.00      1.00      1.00        23
           3       1.00      1.00      1.00         1
           4       1.00      1.00      1.00        12
           5       1.00      1.00      1.00         4

    accuracy                           1.00        62
   macro avg       1.00      1.00      1.00        62
weighted avg       1.00      1.00      1.00        62
cm = confusion_matrix(y_test, y_pred)
print(cm)
[[12  0  0  0  0  0]
 [ 0 10  0  0  0  0]
 [ 0  0 23  0  0  0]
 [ 0  0  0  1  0  0]
 [ 0  0  0  0 12  0]
 [ 0  0  0  0  0  4]]
plt.figure(figsize=(15,10))
categories = np.unique(y)
df_cm = pd.DataFrame(cm, index = [i for i in categories], columns = [i for i in categories])
sn.heatmap(df_cm,annot=True)
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.show()

4. SVM
X = d_pca[d_pca.columns.drop(['class'])]
y = d_pca['class']
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.3, random_state =90) 
SVM = SVC()
SVM.fit(X_train,y_train)
y_pred = SVM.predict(X_test)
y_pred
array([2, 2, 2, 0, 5, 0, 4, 2, 0, 4, 1, 2, 2, 0, 1, 2, 4, 1, 4, 4, 2, 1,
       0, 0, 2, 1, 2, 4, 2, 1, 4, 3, 2, 2, 2, 1, 0, 4, 0, 0, 0, 2, 1, 2,
       2, 2, 2, 2, 4, 5, 1, 2, 5, 1, 2, 0, 4, 5, 4, 0, 2, 0])
svm = SVM.score(X_test,y_test)
print(svm)
0.9838709677419355
print(classification_report(y_test, y_pred))
precision    recall  f1-score   support

           0       0.92      1.00      0.96        12
           1       1.00      1.00      1.00        10
           2       1.00      1.00      1.00        23
           3       1.00      1.00      1.00         1
           4       1.00      0.92      0.96        12
           5       1.00      1.00      1.00         4

    accuracy                           0.98        62
   macro avg       0.99      0.99      0.99        62
weighted avg       0.99      0.98      0.98        62
cm = confusion_matrix(y_test, y_pred)
print(cm)
[[12  0  0  0  0  0]
 [ 0 10  0  0  0  0]
 [ 0  0 23  0  0  0]
 [ 0  0  0  1  0  0]
 [ 1  0  0  0 11  0]
 [ 0  0  0  0  0  4]]
plt.figure(figsize=(15,10))
categories = np.unique(y)
df_cm = pd.DataFrame(cm, index = [i for i in categories], columns = [i for i in categories])
sn.heatmap(df_cm,annot=True)
plt.xlabel("Predicted")
plt.ylabel("Actual")
plt.show()

Comparing the Classifier Models

df5 = pd.DataFrame([["KNN",knt],["Decision Tree",Dc],["Random Forest",rc],["SVM",svm]],columns=["models","accuracy"])
df5

e = pd.DataFrame(df5.groupby('models')['accuracy'].mean())
e.plot.bar(title='models vs accuracy')
plt.xlabel("models")
plt.ylabel("accuracy")
plt.grid(linestyle='-.')

Observation

Random forest predicts the class of car with highest accuracy among the classifiers.



Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.