forked from jjkatara1/CS35
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathiris5.py
More file actions
293 lines (239 loc) · 8.71 KB
/
iris5.py
File metadata and controls
293 lines (239 loc) · 8.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#
# read iris data
#
import numpy as np
import pandas as pd
from sklearn import tree # for decision trees
from sklearn import ensemble # for random forests
from collections import Counter
try: # different imports for different versions of scikit-learn
from sklearn.model_selection import cross_val_score # simpler cv this week
except ImportError:
try:
from sklearn.cross_validation import cross_val_score
except:
print("No cross_val_score!")
#
# Here are the correct answers to the csv's "unknown" flowers
#
answers = [ 'virginica', # index 0 (row 1 in the csv)
'virginica', # index 1 (row 2 in the csv)
'versicolor', # and so on...
'versicolor',
'setosa',
'setosa',
'virginica',
'versicolor',
'setosa']
print("+++ Start of pandas' datahandling +++\n")
# df is a "dataframe":
df = pd.read_csv('iris5.csv', header=0) # read the file w/header row #0
# Now, let's take a look at a bit of the dataframe, df:
df.head() # first five lines
df.info() # column details
# One important feature is the conversion from string to numeric datatypes!
# For _input_ features, numpy and scikit-learn need numeric datatypes
# You can define a transformation function, to help out...
def transform(s):
""" from string to number
setosa -> 0
versicolor -> 1
virginica -> 2
"""
d = { 'unknown':-1, 'setosa':0, 'versicolor':1, 'virginica':2 }
return d[s]
#
# this applies the function transform to a whole column
#
# df['irisname'] = df['irisname'].map(transform) # apply the function to the column
print("\n+++ End of pandas +++\n")
print("+++ Start of numpy/scikit-learn +++\n")
print(" +++++ Decision Trees +++++\n\n")
# Data needs to be in numpy arrays - these next two lines convert to numpy arrays
X_all = df.iloc[:,0:4].values # iloc == "integer locations" of rows/cols
y_all = df[ 'irisname' ].values # individually addressable columns (by name)
#print("y_ALL", y_all)
X_labeled = X_all[9:,:] # make the 10 into 0 to keep all of the data
y_labeled = y_all[9:] # same for this line
#
# we can scramble the data - but only the labeled data!
#
indices = np.random.permutation(len(X_labeled)) # this scrambles the data each time
X_data_full = X_labeled[indices]
y_data_full = y_labeled[indices]
X_train = X_data_full
y_train = y_data_full
#
# some labels to make the graphical trees more readable...
#
print("Some labels for the graphical tree:")
feature_names = ['sepallen', 'sepalwid', 'petallen', 'petalwid']
target_names = ['setosa', 'versicolor', 'virginica']
#
# show the creation of three tree files (at three max_depths)
#
for max_depth in [1,2,3]:
# the DT classifier
dtree = tree.DecisionTreeClassifier(max_depth=max_depth)
# train it (build the tree)
dtree = dtree.fit(X_train, y_train)
# write out the dtree to tree.dot (or another filename of your choosing...)
filename = 'tree' + str(max_depth) + '.dot'
tree.export_graphviz(dtree, out_file=filename, # the filename constructed above...!
feature_names=feature_names, filled=True,
rotate=False, # LR vs UD
class_names=target_names,
leaves_parallel=True ) # lots of options!
#
# Visualize the resulting graphs (the trees) at www.webgraphviz.com
#
print("Wrote the file", filename)
#
#
# cross-validation and scoring to determine parameter: max_depth
#
for max_depth in range(1,12):
# create our classifier
dtree = tree.DecisionTreeClassifier(max_depth=max_depth)
#
# cross-validate to tune our model (this week, all-at-once)
#
scores = cross_val_score(dtree, X_train, y_train, cv=5)
average_cv_score = scores.mean()
print("For depth=", max_depth, "average CV score = ", average_cv_score)
# print(" Scores:", scores)
# import sys
# print("bye!")
# sys.exit(0)
MAX_DEPTH = 3 # choose a MAX_DEPTH based on cross-validation...
print("\nChoosing MAX_DEPTH =", MAX_DEPTH, "\n")
#
# now, train the model with ALL of the training data... and predict the unknown labels
#
X_unknown = X_all[0:9,0:4] # the final testing data
X_train = X_all[9:,0:4] # the training data
y_unknown = y_all[0:9] # the final testing outputs/labels (unknown)
y_train = y_all[9:] # the training outputs/labels (known)
# our decision-tree classifier...
dtree = tree.DecisionTreeClassifier(max_depth=MAX_DEPTH)
dtree = dtree.fit(X_train, y_train)
#
# and... Predict the unknown data labels
#
print("Decision-tree predictions:\n")
predicted_labels = dtree.predict(X_unknown)
answer_labels = answers
#
# formatted printing! (docs.python.org/3/library/string.html#formatstrings)
#
s = "{0:<11} | {1:<11}".format("Predicted","Answer")
# arg0: left-aligned, 11 spaces, string, arg1: ditto
print(s)
s = "{0:<11} | {1:<11}".format("-------","-------")
print(s)
# the table...
for p, a in zip( predicted_labels, answer_labels ):
s = "{0:<11} | {1:<11}".format(p,a)
print(s)
#
# feature importances!
#
print()
print("dtree.feature_importances_ are\n ", dtree.feature_importances_)
print("Order:", feature_names[0:4])
#
# now, show off Random Forests!
#
print("\n\n")
print(" +++++ Random Forests +++++\n\n")
#
# The data is already in good shape -- let's start from the original dataframe:
#
X_all = df.iloc[:,0:4].values # iloc == "integer locations" of rows/cols
y_all = df[ 'irisname' ].values # individually addressable columns (by name)
X_labeled = X_all[9:,:] # just the input features, X, that HAVE output labels
y_labeled = y_all[9:] # here are the output labels, y, for X_labeled
#
# we can scramble the data - but only the labeled data!
#
indices = np.random.permutation(len(X_labeled)) # this scrambles the data each time
X_data_full = X_labeled[indices]
y_data_full = y_labeled[indices]
# X_train = X_data_full
# y_train = y_data_full
#
# cross-validation to determine the Random Forest's parameters (max_depth and n_estimators)
#
#
# Lab task! Your goal:
# + loop over a number of values of max_depth (m)
# + loop over different numbers of trees/n_estimators (n)
# -> to find a pair of values that results in a good average CV score
#
# use the decision-tree code above as a template for this...
#
# here is a _single_ example call to build a RF:
#m = 2
#n = 10
count = 0
# stores a count of all 'm' values to see what the optimal one was
# mnVal = []
# totalMN = 0
# for m in range(99, 100, 1):
# print("m:", m)
# totalN = 0
# nVal = 0
# for n in range(10, 27, 1):
# print("[m:", m, ",n:", str(n) + "]")
# rforest = ensemble.RandomForestClassifier(max_depth=m, n_estimators=n)
#
# # an example call to run 5x cross-validation on the labeled data
# scores = cross_val_score(rforest, X_train, y_train, cv=5)
# #print("CV scores:", scores)
# #print("CV scores' average:", scores.mean())
# if totalN <= scores.mean():
# totalN = scores.mean()
# nVal = n
#
# if totalMN < totalN:
# mnVal = [m, nVal]
# totalMN = totalN
#
# print("Best Values:", mnVal)
# print("Score:", totalMN)
#
# now, train the model with ALL of the training data... and predict the labels of the test set
#
X_test = X_all[0:9,0:4] # the final testing data
X_train = X_all[9:,0:4] # the training data
y_test = y_all[0:9] # the final testing outputs/labels (unknown)
y_train = y_all[9:] # the training outputs/labels (known)
# these next lines is where the full training data is used for the model
MAX_DEPTH = 42
NUM_TREES = 27
print()
print("Using MAX_DEPTH=", MAX_DEPTH, "and NUM_TREES=", NUM_TREES)
rforest = ensemble.RandomForestClassifier(max_depth=MAX_DEPTH, n_estimators=NUM_TREES)
rforest = rforest.fit(X_train, y_train)
# here are some examples, printed out:
print("Random-forest predictions:\n")
predicted_labels = rforest.predict(X_test)
answer_labels = answers # note that we're "cheating" here!
#
# formatted printing again (see above for reference link)
#
s = "{0:<11} | {1:<11}".format("Predicted","Answer")
# arg0: left-aligned, 11 spaces, string, arg1: ditto
print(s)
s = "{0:<11} | {1:<11}".format("-------","-------")
print(s)
# the table...
for p, a in zip( predicted_labels, answer_labels ):
s = "{0:<11} | {1:<11}".format(p,a)
print(s)
#
# feature importances
#
print("\nrforest.feature_importances_ are\n ", rforest.feature_importances_)
print("Order:", feature_names[0:4])
# The individual trees are in rforest.estimators_ [a list of decision trees!]