import pandas as pd
import os
from sklearn.tree import DecisionTreeClassifier
from sklearn import preprocessing
from sklearn.metrics import accuracy_score
from sklearn.cross_validation import train_test_split
print pd.__version__
0.20.3
/usr/local/lib/python2.7/dist-packages/sklearn/cross_validation.py:41: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20. "This module will be removed in 0.20.", DeprecationWarning)
# reading data to pandas dataframe
DATA_DIR = '../data'
df = pd.read_table(
os.path.abspath(os.path.join(DATA_DIR, 'day11/credit.csv')),
sep=',',
header=None
)
df.head(5)
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | b | 30.83 | 0.000 | u | g | w | v | 1.25 | t | t | 1 | f | g | 00202 | 0 | + |
1 | a | 58.67 | 4.460 | u | g | q | h | 3.04 | t | t | 6 | f | g | 00043 | 560 | + |
2 | a | 24.50 | 0.500 | u | g | q | h | 1.50 | t | f | 0 | f | g | 00280 | 824 | + |
3 | b | 27.83 | 1.540 | u | g | w | v | 3.75 | t | t | 5 | t | g | 00100 | 3 | + |
4 | b | 20.17 | 5.625 | u | g | w | v | 1.71 | t | f | 0 | f | s | 00120 | 0 | + |
# (rows, columns)
df.shape
(690, 16)
# checking for NaN in the entire df
df.isnull().sum()
# None of the columns have missing values in them
0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 0 10 0 11 0 12 0 13 0 14 0 15 0 dtype: int64
# object in pandas means string; we need to convert all to numerical
df.dtypes
0 object 1 object 2 float64 3 object 4 object 5 object 6 object 7 float64 8 object 9 object 10 int64 11 object 12 object 13 object 14 int64 15 object dtype: object
# but here is something we found unusual; a '?' we will prune out all the rows
# where in any of the column if '?' exists
# figuring out all the columns where '?' exists
for columns in range(16):
if '?' in df[columns].unique().tolist():
df = df[df[columns]!='?']
# new data after removing the rows having '?' in them
df.shape
(653, 16)
# we will now encode the objects to float dtype for features
# 0, 3, 4, 5, 6, 8, 9, 11
for column in [0, 3, 4, 5, 6, 8, 9, 11, 12]:
possible_values = df[column].unique().tolist()
encoded_inp = {v:idx for idx, v in enumerate(possible_values)}
df[column].replace(encoded_inp, inplace=True)
# we will now encode the objects to float dtype for target
# 15
encoded_inp = {'+':1, '-':0}
df[15].replace(encoded_inp, inplace=True)
# we will not convert the remaining object dtypes to float dtype
# 1, 13; i am not sure what 13 column is about; will drop it for now
df.drop([13], axis = 1, inplace = True)
df[1] = df[1].astype(float)
X = df.iloc[:, :-1].values
Y = df.iloc[:, -1].values
# ideal practice is to use test as 20% - 30% of training data
# defined by test_size in train_test_split()
# random_state is required to avoid sequential biasness in the data distribution
def data_split(X, Y):
X_train, X_test, Y_train, Y_test = train_test_split( X, Y, test_size=0.2, random_state = 10)
return X_train, X_test, Y_train, Y_test
X_train, X_test, Y_train, Y_test = data_split(X, Y)
X_train.shape, X_test.shape
((522, 14), (131, 14))
class DecisionTrees(object):
def __init__(self):
self.classifier = DecisionTreeClassifier(random_state=10)
def train(self, X_train, Y_train):
model = self.classifier.fit(X_train, Y_train)
return model
def predict(self, model, X_test):
return model.predict(X_test)
def evaluate(self, Y_test, Y_pred):
return accuracy_score(Y_test, Y_pred)*100
# train the model and tuning depth paramater of the classifier over validation set
dtree = DecisionTrees()
model_dtree = dtree.train(X_train, Y_train)
predictions = dtree.predict(model_dtree, X_test)
print dtree.evaluate(Y_test, predictions)
81.67938931297711