├── Breast_cancer_data.csv
├── K-means Clustering.ipynb
├── KNN Classification + Regression.ipynb
├── README.md
├── airfoil_noise_data.csv
├── decision tree classification.ipynb
├── decision tree regression.ipynb
├── linear regression.ipynb
├── logistic regression.ipynb
├── naive bayes.ipynb
└── sgd.ipynb
/Breast_cancer_data.csv:
--------------------------------------------------------------------------------
1 | mean_radius,mean_texture,mean_perimeter,mean_area,mean_smoothness,diagnosis
2 | 17.99,10.38,122.8,1001.0,0.1184,0
3 | 20.57,17.77,132.9,1326.0,0.08474,0
4 | 19.69,21.25,130.0,1203.0,0.1096,0
5 | 11.42,20.38,77.58,386.1,0.1425,0
6 | 20.29,14.34,135.1,1297.0,0.1003,0
7 | 12.45,15.7,82.57,477.1,0.1278,0
8 | 18.25,19.98,119.6,1040.0,0.09463,0
9 | 13.71,20.83,90.2,577.9,0.1189,0
10 | 13.0,21.82,87.5,519.8,0.1273,0
11 | 12.46,24.04,83.97,475.9,0.1186,0
12 | 16.02,23.24,102.7,797.8,0.08206,0
13 | 15.78,17.89,103.6,781.0,0.0971,0
14 | 19.17,24.8,132.4,1123.0,0.0974,0
15 | 15.85,23.95,103.7,782.7,0.08401,0
16 | 13.73,22.61,93.6,578.3,0.1131,0
17 | 14.54,27.54,96.73,658.8,0.1139,0
18 | 14.68,20.13,94.74,684.5,0.09867,0
19 | 16.13,20.68,108.1,798.8,0.117,0
20 | 19.81,22.15,130.0,1260.0,0.09831,0
21 | 13.54,14.36,87.46,566.3,0.09779,1
22 | 13.08,15.71,85.63,520.0,0.1075,1
23 | 9.504,12.44,60.34,273.9,0.1024,1
24 | 15.34,14.26,102.5,704.4,0.1073,0
25 | 21.16,23.04,137.2,1404.0,0.09428,0
26 | 16.65,21.38,110.0,904.6,0.1121,0
27 | 17.14,16.4,116.0,912.7,0.1186,0
28 | 14.58,21.53,97.41,644.8,0.1054,0
29 | 18.61,20.25,122.1,1094.0,0.0944,0
30 | 15.3,25.27,102.4,732.4,0.1082,0
31 | 17.57,15.05,115.0,955.1,0.09847,0
32 | 18.63,25.11,124.8,1088.0,0.1064,0
33 | 11.84,18.7,77.93,440.6,0.1109,0
34 | 17.02,23.98,112.8,899.3,0.1197,0
35 | 19.27,26.47,127.9,1162.0,0.09401,0
36 | 16.13,17.88,107.0,807.2,0.104,0
37 | 16.74,21.59,110.1,869.5,0.0961,0
38 | 14.25,21.72,93.63,633.0,0.09823,0
39 | 13.03,18.42,82.61,523.8,0.08983,1
40 | 14.99,25.2,95.54,698.8,0.09387,0
41 | 13.48,20.82,88.4,559.2,0.1016,0
42 | 13.44,21.58,86.18,563.0,0.08162,0
43 | 10.95,21.35,71.9,371.1,0.1227,0
44 | 19.07,24.81,128.3,1104.0,0.09081,0
45 | 13.28,20.28,87.32,545.2,0.1041,0
46 | 13.17,21.81,85.42,531.5,0.09714,0
47 | 18.65,17.6,123.7,1076.0,0.1099,0
48 | 8.196,16.84,51.71,201.9,0.086,1
49 | 13.17,18.66,85.98,534.6,0.1158,0
50 | 12.05,14.63,78.04,449.3,0.1031,1
51 | 13.49,22.3,86.91,561.0,0.08752,1
52 | 11.76,21.6,74.72,427.9,0.08637,1
53 | 13.64,16.34,87.21,571.8,0.07685,1
54 | 11.94,18.24,75.71,437.6,0.08261,1
55 | 18.22,18.7,120.3,1033.0,0.1148,0
56 | 15.1,22.02,97.26,712.8,0.09056,0
57 | 11.52,18.75,73.34,409.0,0.09524,1
58 | 19.21,18.57,125.5,1152.0,0.1053,0
59 | 14.71,21.59,95.55,656.9,0.1137,0
60 | 13.05,19.31,82.61,527.2,0.0806,1
61 | 8.618,11.79,54.34,224.5,0.09752,1
62 | 10.17,14.88,64.55,311.9,0.1134,1
63 | 8.598,20.98,54.66,221.8,0.1243,1
64 | 14.25,22.15,96.42,645.7,0.1049,0
65 | 9.173,13.86,59.2,260.9,0.07721,1
66 | 12.68,23.84,82.69,499.0,0.1122,0
67 | 14.78,23.94,97.4,668.3,0.1172,0
68 | 9.465,21.01,60.11,269.4,0.1044,1
69 | 11.31,19.04,71.8,394.1,0.08139,1
70 | 9.029,17.33,58.79,250.5,0.1066,1
71 | 12.78,16.49,81.37,502.5,0.09831,1
72 | 18.94,21.31,123.6,1130.0,0.09009,0
73 | 8.888,14.64,58.79,244.0,0.09783,1
74 | 17.2,24.52,114.2,929.4,0.1071,0
75 | 13.8,15.79,90.43,584.1,0.1007,0
76 | 12.31,16.52,79.19,470.9,0.09172,1
77 | 16.07,19.65,104.1,817.7,0.09168,0
78 | 13.53,10.94,87.91,559.2,0.1291,1
79 | 18.05,16.15,120.2,1006.0,0.1065,0
80 | 20.18,23.97,143.7,1245.0,0.1286,0
81 | 12.86,18.0,83.19,506.3,0.09934,1
82 | 11.45,20.97,73.81,401.5,0.1102,1
83 | 13.34,15.86,86.49,520.0,0.1078,1
84 | 25.22,24.91,171.5,1878.0,0.1063,0
85 | 19.1,26.29,129.1,1132.0,0.1215,0
86 | 12.0,15.65,76.95,443.3,0.09723,1
87 | 18.46,18.52,121.1,1075.0,0.09874,0
88 | 14.48,21.46,94.25,648.2,0.09444,0
89 | 19.02,24.59,122.0,1076.0,0.09029,0
90 | 12.36,21.8,79.78,466.1,0.08772,1
91 | 14.64,15.24,95.77,651.9,0.1132,1
92 | 14.62,24.02,94.57,662.7,0.08974,1
93 | 15.37,22.76,100.2,728.2,0.092,0
94 | 13.27,14.76,84.74,551.7,0.07355,1
95 | 13.45,18.3,86.6,555.1,0.1022,1
96 | 15.06,19.83,100.3,705.6,0.1039,0
97 | 20.26,23.03,132.4,1264.0,0.09078,0
98 | 12.18,17.84,77.79,451.1,0.1045,1
99 | 9.787,19.94,62.11,294.5,0.1024,1
100 | 11.6,12.84,74.34,412.6,0.08983,1
101 | 14.42,19.77,94.48,642.5,0.09752,0
102 | 13.61,24.98,88.05,582.7,0.09488,0
103 | 6.981,13.43,43.79,143.5,0.117,1
104 | 12.18,20.52,77.22,458.7,0.08013,1
105 | 9.876,19.4,63.95,298.3,0.1005,1
106 | 10.49,19.29,67.41,336.1,0.09989,1
107 | 13.11,15.56,87.21,530.2,0.1398,0
108 | 11.64,18.33,75.17,412.5,0.1142,1
109 | 12.36,18.54,79.01,466.7,0.08477,1
110 | 22.27,19.67,152.8,1509.0,0.1326,0
111 | 11.34,21.26,72.48,396.5,0.08759,1
112 | 9.777,16.99,62.5,290.2,0.1037,1
113 | 12.63,20.76,82.15,480.4,0.09933,1
114 | 14.26,19.65,97.83,629.9,0.07837,1
115 | 10.51,20.19,68.64,334.2,0.1122,1
116 | 8.726,15.83,55.84,230.9,0.115,1
117 | 11.93,21.53,76.53,438.6,0.09768,1
118 | 8.95,15.76,58.74,245.2,0.09462,1
119 | 14.87,16.67,98.64,682.5,0.1162,0
120 | 15.78,22.91,105.7,782.6,0.1155,0
121 | 17.95,20.01,114.2,982.0,0.08402,0
122 | 11.41,10.82,73.34,403.3,0.09373,1
123 | 18.66,17.12,121.4,1077.0,0.1054,0
124 | 24.25,20.2,166.2,1761.0,0.1447,0
125 | 14.5,10.89,94.28,640.7,0.1101,1
126 | 13.37,16.39,86.1,553.5,0.07115,1
127 | 13.85,17.21,88.44,588.7,0.08785,1
128 | 13.61,24.69,87.76,572.6,0.09258,0
129 | 19.0,18.91,123.4,1138.0,0.08217,0
130 | 15.1,16.39,99.58,674.5,0.115,1
131 | 19.79,25.12,130.4,1192.0,0.1015,0
132 | 12.19,13.29,79.08,455.8,0.1066,1
133 | 15.46,19.48,101.7,748.9,0.1092,0
134 | 16.16,21.54,106.2,809.8,0.1008,0
135 | 15.71,13.93,102.0,761.7,0.09462,1
136 | 18.45,21.91,120.2,1075.0,0.0943,0
137 | 12.77,22.47,81.72,506.3,0.09055,0
138 | 11.71,16.67,74.72,423.6,0.1051,1
139 | 11.43,15.39,73.06,399.8,0.09639,1
140 | 14.95,17.57,96.85,678.1,0.1167,0
141 | 11.28,13.39,73.0,384.8,0.1164,1
142 | 9.738,11.97,61.24,288.5,0.0925,1
143 | 16.11,18.05,105.1,813.0,0.09721,0
144 | 11.43,17.31,73.66,398.0,0.1092,1
145 | 12.9,15.92,83.74,512.2,0.08677,1
146 | 10.75,14.97,68.26,355.3,0.07793,1
147 | 11.9,14.65,78.11,432.8,0.1152,1
148 | 11.8,16.58,78.99,432.0,0.1091,0
149 | 14.95,18.77,97.84,689.5,0.08138,1
150 | 14.44,15.18,93.97,640.1,0.0997,1
151 | 13.74,17.91,88.12,585.0,0.07944,1
152 | 13.0,20.78,83.51,519.4,0.1135,1
153 | 8.219,20.7,53.27,203.9,0.09405,1
154 | 9.731,15.34,63.78,300.2,0.1072,1
155 | 11.15,13.08,70.87,381.9,0.09754,1
156 | 13.15,15.34,85.31,538.9,0.09384,1
157 | 12.25,17.94,78.27,460.3,0.08654,1
158 | 17.68,20.74,117.4,963.7,0.1115,0
159 | 16.84,19.46,108.4,880.2,0.07445,1
160 | 12.06,12.74,76.84,448.6,0.09311,1
161 | 10.9,12.96,68.69,366.8,0.07515,1
162 | 11.75,20.18,76.1,419.8,0.1089,1
163 | 19.19,15.94,126.3,1157.0,0.08694,0
164 | 19.59,18.15,130.7,1214.0,0.112,0
165 | 12.34,22.22,79.85,464.5,0.1012,1
166 | 23.27,22.04,152.1,1686.0,0.08439,0
167 | 14.97,19.76,95.5,690.2,0.08421,1
168 | 10.8,9.71,68.77,357.6,0.09594,1
169 | 16.78,18.8,109.3,886.3,0.08865,0
170 | 17.47,24.68,116.1,984.6,0.1049,0
171 | 14.97,16.95,96.22,685.9,0.09855,1
172 | 12.32,12.39,78.85,464.1,0.1028,1
173 | 13.43,19.63,85.84,565.4,0.09048,0
174 | 15.46,11.89,102.5,736.9,0.1257,0
175 | 11.08,14.71,70.21,372.7,0.1006,1
176 | 10.66,15.15,67.49,349.6,0.08792,1
177 | 8.671,14.45,54.42,227.2,0.09138,1
178 | 9.904,18.06,64.6,302.4,0.09699,1
179 | 16.46,20.11,109.3,832.9,0.09831,0
180 | 13.01,22.22,82.01,526.4,0.06251,1
181 | 12.81,13.06,81.29,508.8,0.08739,1
182 | 27.22,21.87,182.1,2250.0,0.1094,0
183 | 21.09,26.57,142.7,1311.0,0.1141,0
184 | 15.7,20.31,101.2,766.6,0.09597,0
185 | 11.41,14.92,73.53,402.0,0.09059,1
186 | 15.28,22.41,98.92,710.6,0.09057,0
187 | 10.08,15.11,63.76,317.5,0.09267,1
188 | 18.31,18.58,118.6,1041.0,0.08588,0
189 | 11.71,17.19,74.68,420.3,0.09774,1
190 | 11.81,17.39,75.27,428.9,0.1007,1
191 | 12.3,15.9,78.83,463.7,0.0808,1
192 | 14.22,23.12,94.37,609.9,0.1075,0
193 | 12.77,21.41,82.02,507.4,0.08749,1
194 | 9.72,18.22,60.73,288.1,0.0695,1
195 | 12.34,26.86,81.15,477.4,0.1034,0
196 | 14.86,23.21,100.4,671.4,0.1044,0
197 | 12.91,16.33,82.53,516.4,0.07941,1
198 | 13.77,22.29,90.63,588.9,0.12,0
199 | 18.08,21.84,117.4,1024.0,0.07371,0
200 | 19.18,22.49,127.5,1148.0,0.08523,0
201 | 14.45,20.22,94.49,642.7,0.09872,0
202 | 12.23,19.56,78.54,461.0,0.09586,1
203 | 17.54,19.32,115.1,951.6,0.08968,0
204 | 23.29,26.67,158.9,1685.0,0.1141,0
205 | 13.81,23.75,91.56,597.8,0.1323,0
206 | 12.47,18.6,81.09,481.9,0.09965,1
207 | 15.12,16.68,98.78,716.6,0.08876,0
208 | 9.876,17.27,62.92,295.4,0.1089,1
209 | 17.01,20.26,109.7,904.3,0.08772,0
210 | 13.11,22.54,87.02,529.4,0.1002,1
211 | 15.27,12.91,98.17,725.5,0.08182,1
212 | 20.58,22.14,134.7,1290.0,0.0909,0
213 | 11.84,18.94,75.51,428.0,0.08871,1
214 | 28.11,18.47,188.5,2499.0,0.1142,0
215 | 17.42,25.56,114.5,948.0,0.1006,0
216 | 14.19,23.81,92.87,610.7,0.09463,0
217 | 13.86,16.93,90.96,578.9,0.1026,0
218 | 11.89,18.35,77.32,432.2,0.09363,1
219 | 10.2,17.48,65.05,321.2,0.08054,1
220 | 19.8,21.56,129.7,1230.0,0.09383,0
221 | 19.53,32.47,128.0,1223.0,0.0842,0
222 | 13.65,13.16,87.88,568.9,0.09646,1
223 | 13.56,13.9,88.59,561.3,0.1051,1
224 | 10.18,17.53,65.12,313.1,0.1061,1
225 | 15.75,20.25,102.6,761.3,0.1025,0
226 | 13.27,17.02,84.55,546.4,0.08445,1
227 | 14.34,13.47,92.51,641.2,0.09906,1
228 | 10.44,15.46,66.62,329.6,0.1053,1
229 | 15.0,15.51,97.45,684.5,0.08371,1
230 | 12.62,23.97,81.35,496.4,0.07903,1
231 | 12.83,22.33,85.26,503.2,0.1088,0
232 | 17.05,19.08,113.4,895.0,0.1141,0
233 | 11.32,27.08,71.76,395.7,0.06883,1
234 | 11.22,33.81,70.79,386.8,0.0778,1
235 | 20.51,27.81,134.4,1319.0,0.09159,0
236 | 9.567,15.91,60.21,279.6,0.08464,1
237 | 14.03,21.25,89.79,603.4,0.0907,1
238 | 23.21,26.97,153.5,1670.0,0.09509,0
239 | 20.48,21.46,132.5,1306.0,0.08355,0
240 | 14.22,27.85,92.55,623.9,0.08223,1
241 | 17.46,39.28,113.4,920.6,0.09812,0
242 | 13.64,15.6,87.38,575.3,0.09423,1
243 | 12.42,15.04,78.61,476.5,0.07926,1
244 | 11.3,18.19,73.93,389.4,0.09592,1
245 | 13.75,23.77,88.54,590.0,0.08043,1
246 | 19.4,23.5,129.1,1155.0,0.1027,0
247 | 10.48,19.86,66.72,337.7,0.107,1
248 | 13.2,17.43,84.13,541.6,0.07215,1
249 | 12.89,14.11,84.95,512.2,0.0876,1
250 | 10.65,25.22,68.01,347.0,0.09657,1
251 | 11.52,14.93,73.87,406.3,0.1013,1
252 | 20.94,23.56,138.9,1364.0,0.1007,0
253 | 11.5,18.45,73.28,407.4,0.09345,1
254 | 19.73,19.82,130.7,1206.0,0.1062,0
255 | 17.3,17.08,113.0,928.2,0.1008,0
256 | 19.45,19.33,126.5,1169.0,0.1035,0
257 | 13.96,17.05,91.43,602.4,0.1096,0
258 | 19.55,28.77,133.6,1207.0,0.0926,0
259 | 15.32,17.27,103.2,713.3,0.1335,0
260 | 15.66,23.2,110.2,773.5,0.1109,0
261 | 15.53,33.56,103.7,744.9,0.1063,0
262 | 20.31,27.06,132.9,1288.0,0.1,0
263 | 17.35,23.06,111.0,933.1,0.08662,0
264 | 17.29,22.13,114.4,947.8,0.08999,0
265 | 15.61,19.38,100.0,758.6,0.0784,0
266 | 17.19,22.07,111.6,928.3,0.09726,0
267 | 20.73,31.12,135.7,1419.0,0.09469,0
268 | 10.6,18.95,69.28,346.4,0.09688,1
269 | 13.59,21.84,87.16,561.0,0.07956,1
270 | 12.87,16.21,82.38,512.2,0.09425,1
271 | 10.71,20.39,69.5,344.9,0.1082,1
272 | 14.29,16.82,90.3,632.6,0.06429,1
273 | 11.29,13.04,72.23,388.0,0.09834,1
274 | 21.75,20.99,147.3,1491.0,0.09401,0
275 | 9.742,15.67,61.5,289.9,0.09037,1
276 | 17.93,24.48,115.2,998.9,0.08855,0
277 | 11.89,17.36,76.2,435.6,0.1225,1
278 | 11.33,14.16,71.79,396.6,0.09379,1
279 | 18.81,19.98,120.9,1102.0,0.08923,0
280 | 13.59,17.84,86.24,572.3,0.07948,1
281 | 13.85,15.18,88.99,587.4,0.09516,1
282 | 19.16,26.6,126.2,1138.0,0.102,0
283 | 11.74,14.02,74.24,427.3,0.07813,1
284 | 19.4,18.18,127.2,1145.0,0.1037,0
285 | 16.24,18.77,108.8,805.1,0.1066,0
286 | 12.89,15.7,84.08,516.6,0.07818,1
287 | 12.58,18.4,79.83,489.0,0.08393,1
288 | 11.94,20.76,77.87,441.0,0.08605,1
289 | 12.89,13.12,81.89,515.9,0.06955,1
290 | 11.26,19.96,73.72,394.1,0.0802,1
291 | 11.37,18.89,72.17,396.0,0.08713,1
292 | 14.41,19.73,96.03,651.0,0.08757,1
293 | 14.96,19.1,97.03,687.3,0.08992,1
294 | 12.95,16.02,83.14,513.7,0.1005,1
295 | 11.85,17.46,75.54,432.7,0.08372,1
296 | 12.72,13.78,81.78,492.1,0.09667,1
297 | 13.77,13.27,88.06,582.7,0.09198,1
298 | 10.91,12.35,69.14,363.7,0.08518,1
299 | 11.76,18.14,75.0,431.1,0.09968,0
300 | 14.26,18.17,91.22,633.1,0.06576,1
301 | 10.51,23.09,66.85,334.2,0.1015,1
302 | 19.53,18.9,129.5,1217.0,0.115,0
303 | 12.46,19.89,80.43,471.3,0.08451,1
304 | 20.09,23.86,134.7,1247.0,0.108,0
305 | 10.49,18.61,66.86,334.3,0.1068,1
306 | 11.46,18.16,73.59,403.1,0.08853,1
307 | 11.6,24.49,74.23,417.2,0.07474,1
308 | 13.2,15.82,84.07,537.3,0.08511,1
309 | 9.0,14.4,56.36,246.3,0.07005,1
310 | 13.5,12.71,85.69,566.2,0.07376,1
311 | 13.05,13.84,82.71,530.6,0.08352,1
312 | 11.7,19.11,74.33,418.7,0.08814,1
313 | 14.61,15.69,92.68,664.9,0.07618,1
314 | 12.76,13.37,82.29,504.1,0.08794,1
315 | 11.54,10.72,73.73,409.1,0.08597,1
316 | 8.597,18.6,54.09,221.2,0.1074,1
317 | 12.49,16.85,79.19,481.6,0.08511,1
318 | 12.18,14.08,77.25,461.4,0.07734,1
319 | 18.22,18.87,118.7,1027.0,0.09746,0
320 | 9.042,18.9,60.07,244.5,0.09968,1
321 | 12.43,17.0,78.6,477.3,0.07557,1
322 | 10.25,16.18,66.52,324.2,0.1061,1
323 | 20.16,19.66,131.1,1274.0,0.0802,0
324 | 12.86,13.32,82.82,504.8,0.1134,1
325 | 20.34,21.51,135.9,1264.0,0.117,0
326 | 12.2,15.21,78.01,457.9,0.08673,1
327 | 12.67,17.3,81.25,489.9,0.1028,1
328 | 14.11,12.88,90.03,616.5,0.09309,1
329 | 12.03,17.93,76.09,446.0,0.07683,1
330 | 16.27,20.71,106.9,813.7,0.1169,0
331 | 16.26,21.88,107.5,826.8,0.1165,0
332 | 16.03,15.51,105.8,793.2,0.09491,0
333 | 12.98,19.35,84.52,514.0,0.09579,1
334 | 11.22,19.86,71.94,387.3,0.1054,1
335 | 11.25,14.78,71.38,390.0,0.08306,1
336 | 12.3,19.02,77.88,464.4,0.08313,1
337 | 17.06,21.0,111.8,918.6,0.1119,0
338 | 12.99,14.23,84.08,514.3,0.09462,1
339 | 18.77,21.43,122.9,1092.0,0.09116,0
340 | 10.05,17.53,64.41,310.8,0.1007,1
341 | 23.51,24.27,155.1,1747.0,0.1069,0
342 | 14.42,16.54,94.15,641.2,0.09751,1
343 | 9.606,16.84,61.64,280.5,0.08481,1
344 | 11.06,14.96,71.49,373.9,0.1033,1
345 | 19.68,21.68,129.9,1194.0,0.09797,0
346 | 11.71,15.45,75.03,420.3,0.115,1
347 | 10.26,14.71,66.2,321.6,0.09882,1
348 | 12.06,18.9,76.66,445.3,0.08386,1
349 | 14.76,14.74,94.87,668.7,0.08875,1
350 | 11.47,16.03,73.02,402.7,0.09076,1
351 | 11.95,14.96,77.23,426.7,0.1158,1
352 | 11.66,17.07,73.7,421.0,0.07561,1
353 | 15.75,19.22,107.1,758.6,0.1243,0
354 | 25.73,17.46,174.2,2010.0,0.1149,0
355 | 15.08,25.74,98.0,716.6,0.1024,0
356 | 11.14,14.07,71.24,384.6,0.07274,1
357 | 12.56,19.07,81.92,485.8,0.0876,1
358 | 13.05,18.59,85.09,512.0,0.1082,1
359 | 13.87,16.21,88.52,593.7,0.08743,1
360 | 8.878,15.49,56.74,241.0,0.08293,1
361 | 9.436,18.32,59.82,278.6,0.1009,1
362 | 12.54,18.07,79.42,491.9,0.07436,1
363 | 13.3,21.57,85.24,546.1,0.08582,1
364 | 12.76,18.84,81.87,496.6,0.09676,1
365 | 16.5,18.29,106.6,838.1,0.09686,1
366 | 13.4,16.95,85.48,552.4,0.07937,1
367 | 20.44,21.78,133.8,1293.0,0.0915,0
368 | 20.2,26.83,133.7,1234.0,0.09905,0
369 | 12.21,18.02,78.31,458.4,0.09231,1
370 | 21.71,17.25,140.9,1546.0,0.09384,0
371 | 22.01,21.9,147.2,1482.0,0.1063,0
372 | 16.35,23.29,109.0,840.4,0.09742,0
373 | 15.19,13.21,97.65,711.8,0.07963,1
374 | 21.37,15.1,141.3,1386.0,0.1001,0
375 | 20.64,17.35,134.8,1335.0,0.09446,0
376 | 13.69,16.07,87.84,579.1,0.08302,1
377 | 16.17,16.07,106.3,788.5,0.0988,1
378 | 10.57,20.22,70.15,338.3,0.09073,1
379 | 13.46,28.21,85.89,562.1,0.07517,1
380 | 13.66,15.15,88.27,580.6,0.08268,1
381 | 11.08,18.83,73.3,361.6,0.1216,0
382 | 11.27,12.96,73.16,386.3,0.1237,1
383 | 11.04,14.93,70.67,372.7,0.07987,1
384 | 12.05,22.72,78.75,447.8,0.06935,1
385 | 12.39,17.48,80.64,462.9,0.1042,1
386 | 13.28,13.72,85.79,541.8,0.08363,1
387 | 14.6,23.29,93.97,664.7,0.08682,0
388 | 12.21,14.09,78.78,462.0,0.08108,1
389 | 13.88,16.16,88.37,596.6,0.07026,1
390 | 11.27,15.5,73.38,392.0,0.08365,1
391 | 19.55,23.21,128.9,1174.0,0.101,0
392 | 10.26,12.22,65.75,321.6,0.09996,1
393 | 8.734,16.84,55.27,234.3,0.1039,1
394 | 15.49,19.97,102.4,744.7,0.116,0
395 | 21.61,22.28,144.4,1407.0,0.1167,0
396 | 12.1,17.72,78.07,446.2,0.1029,1
397 | 14.06,17.18,89.75,609.1,0.08045,1
398 | 13.51,18.89,88.1,558.1,0.1059,1
399 | 12.8,17.46,83.05,508.3,0.08044,1
400 | 11.06,14.83,70.31,378.2,0.07741,1
401 | 11.8,17.26,75.26,431.9,0.09087,1
402 | 17.91,21.02,124.4,994.0,0.123,0
403 | 11.93,10.91,76.14,442.7,0.08872,1
404 | 12.96,18.29,84.18,525.2,0.07351,1
405 | 12.94,16.17,83.18,507.6,0.09879,1
406 | 12.34,14.95,78.29,469.1,0.08682,1
407 | 10.94,18.59,70.39,370.0,0.1004,1
408 | 16.14,14.86,104.3,800.0,0.09495,1
409 | 12.85,21.37,82.63,514.5,0.07551,1
410 | 17.99,20.66,117.8,991.7,0.1036,0
411 | 12.27,17.92,78.41,466.1,0.08685,1
412 | 11.36,17.57,72.49,399.8,0.08858,1
413 | 11.04,16.83,70.92,373.2,0.1077,1
414 | 9.397,21.68,59.75,268.8,0.07969,1
415 | 14.99,22.11,97.53,693.7,0.08515,1
416 | 15.13,29.81,96.71,719.5,0.0832,0
417 | 11.89,21.17,76.39,433.8,0.09773,1
418 | 9.405,21.7,59.6,271.2,0.1044,1
419 | 15.5,21.08,102.9,803.1,0.112,0
420 | 12.7,12.17,80.88,495.0,0.08785,1
421 | 11.16,21.41,70.95,380.3,0.1018,1
422 | 11.57,19.04,74.2,409.7,0.08546,1
423 | 14.69,13.98,98.22,656.1,0.1031,1
424 | 11.61,16.02,75.46,408.2,0.1088,1
425 | 13.66,19.13,89.46,575.3,0.09057,1
426 | 9.742,19.12,61.93,289.7,0.1075,1
427 | 10.03,21.28,63.19,307.3,0.08117,1
428 | 10.48,14.98,67.49,333.6,0.09816,1
429 | 10.8,21.98,68.79,359.9,0.08801,1
430 | 11.13,16.62,70.47,381.1,0.08151,1
431 | 12.72,17.67,80.98,501.3,0.07896,1
432 | 14.9,22.53,102.1,685.0,0.09947,0
433 | 12.4,17.68,81.47,467.8,0.1054,1
434 | 20.18,19.54,133.8,1250.0,0.1133,0
435 | 18.82,21.97,123.7,1110.0,0.1018,0
436 | 14.86,16.94,94.89,673.7,0.08924,1
437 | 13.98,19.62,91.12,599.5,0.106,0
438 | 12.87,19.54,82.67,509.2,0.09136,1
439 | 14.04,15.98,89.78,611.2,0.08458,1
440 | 13.85,19.6,88.68,592.6,0.08684,1
441 | 14.02,15.66,89.59,606.5,0.07966,1
442 | 10.97,17.2,71.73,371.5,0.08915,1
443 | 17.27,25.42,112.4,928.8,0.08331,0
444 | 13.78,15.79,88.37,585.9,0.08817,1
445 | 10.57,18.32,66.82,340.9,0.08142,1
446 | 18.03,16.85,117.5,990.0,0.08947,0
447 | 11.99,24.89,77.61,441.3,0.103,1
448 | 17.75,28.03,117.3,981.6,0.09997,0
449 | 14.8,17.66,95.88,674.8,0.09179,1
450 | 14.53,19.34,94.25,659.7,0.08388,1
451 | 21.1,20.52,138.1,1384.0,0.09684,0
452 | 11.87,21.54,76.83,432.0,0.06613,1
453 | 19.59,25.0,127.7,1191.0,0.1032,0
454 | 12.0,28.23,76.77,442.5,0.08437,1
455 | 14.53,13.98,93.86,644.2,0.1099,1
456 | 12.62,17.15,80.62,492.9,0.08583,1
457 | 13.38,30.72,86.34,557.2,0.09245,1
458 | 11.63,29.29,74.87,415.1,0.09357,1
459 | 13.21,25.25,84.1,537.9,0.08791,1
460 | 13.0,25.13,82.61,520.2,0.08369,1
461 | 9.755,28.2,61.68,290.9,0.07984,1
462 | 17.08,27.15,111.2,930.9,0.09898,0
463 | 27.42,26.27,186.9,2501.0,0.1084,0
464 | 14.4,26.99,92.25,646.1,0.06995,1
465 | 11.6,18.36,73.88,412.7,0.08508,1
466 | 13.17,18.22,84.28,537.3,0.07466,1
467 | 13.24,20.13,86.87,542.9,0.08284,1
468 | 13.14,20.74,85.98,536.9,0.08675,1
469 | 9.668,18.1,61.06,286.3,0.08311,1
470 | 17.6,23.33,119.0,980.5,0.09289,0
471 | 11.62,18.18,76.38,408.8,0.1175,1
472 | 9.667,18.49,61.49,289.1,0.08946,1
473 | 12.04,28.14,76.85,449.9,0.08752,1
474 | 14.92,14.93,96.45,686.9,0.08098,1
475 | 12.27,29.97,77.42,465.4,0.07699,1
476 | 10.88,15.62,70.41,358.9,0.1007,1
477 | 12.83,15.73,82.89,506.9,0.0904,1
478 | 14.2,20.53,92.41,618.4,0.08931,1
479 | 13.9,16.62,88.97,599.4,0.06828,1
480 | 11.49,14.59,73.99,404.9,0.1046,1
481 | 16.25,19.51,109.8,815.8,0.1026,0
482 | 12.16,18.03,78.29,455.3,0.09087,1
483 | 13.9,19.24,88.73,602.9,0.07991,1
484 | 13.47,14.06,87.32,546.3,0.1071,1
485 | 13.7,17.64,87.76,571.1,0.0995,1
486 | 15.73,11.28,102.8,747.2,0.1043,1
487 | 12.45,16.41,82.85,476.7,0.09514,1
488 | 14.64,16.85,94.21,666.0,0.08641,1
489 | 19.44,18.82,128.1,1167.0,0.1089,0
490 | 11.68,16.17,75.49,420.5,0.1128,1
491 | 16.69,20.2,107.1,857.6,0.07497,0
492 | 12.25,22.44,78.18,466.5,0.08192,1
493 | 17.85,13.23,114.6,992.1,0.07838,1
494 | 18.01,20.56,118.4,1007.0,0.1001,0
495 | 12.46,12.83,78.83,477.3,0.07372,1
496 | 13.16,20.54,84.06,538.7,0.07335,1
497 | 14.87,20.21,96.12,680.9,0.09587,1
498 | 12.65,18.17,82.69,485.6,0.1076,1
499 | 12.47,17.31,80.45,480.1,0.08928,1
500 | 18.49,17.52,121.3,1068.0,0.1012,0
501 | 20.59,21.24,137.8,1320.0,0.1085,0
502 | 15.04,16.74,98.73,689.4,0.09883,1
503 | 13.82,24.49,92.33,595.9,0.1162,0
504 | 12.54,16.32,81.25,476.3,0.1158,1
505 | 23.09,19.83,152.1,1682.0,0.09342,0
506 | 9.268,12.87,61.49,248.7,0.1634,1
507 | 9.676,13.14,64.12,272.5,0.1255,1
508 | 12.22,20.04,79.47,453.1,0.1096,1
509 | 11.06,17.12,71.25,366.5,0.1194,1
510 | 16.3,15.7,104.7,819.8,0.09427,1
511 | 15.46,23.95,103.8,731.3,0.1183,0
512 | 11.74,14.69,76.31,426.0,0.08099,1
513 | 14.81,14.7,94.66,680.7,0.08472,1
514 | 13.4,20.52,88.64,556.7,0.1106,0
515 | 14.58,13.66,94.29,658.8,0.09832,1
516 | 15.05,19.07,97.26,701.9,0.09215,0
517 | 11.34,18.61,72.76,391.2,0.1049,1
518 | 18.31,20.58,120.8,1052.0,0.1068,0
519 | 19.89,20.26,130.5,1214.0,0.1037,0
520 | 12.88,18.22,84.45,493.1,0.1218,1
521 | 12.75,16.7,82.51,493.8,0.1125,1
522 | 9.295,13.9,59.96,257.8,0.1371,1
523 | 24.63,21.6,165.5,1841.0,0.103,0
524 | 11.26,19.83,71.3,388.1,0.08511,1
525 | 13.71,18.68,88.73,571.0,0.09916,1
526 | 9.847,15.68,63.0,293.2,0.09492,1
527 | 8.571,13.1,54.53,221.3,0.1036,1
528 | 13.46,18.75,87.44,551.1,0.1075,1
529 | 12.34,12.27,78.94,468.5,0.09003,1
530 | 13.94,13.17,90.31,594.2,0.1248,1
531 | 12.07,13.44,77.83,445.2,0.11,1
532 | 11.75,17.56,75.89,422.9,0.1073,1
533 | 11.67,20.02,75.21,416.2,0.1016,1
534 | 13.68,16.33,87.76,575.5,0.09277,1
535 | 20.47,20.67,134.7,1299.0,0.09156,0
536 | 10.96,17.62,70.79,365.6,0.09687,1
537 | 20.55,20.86,137.8,1308.0,0.1046,0
538 | 14.27,22.55,93.77,629.8,0.1038,0
539 | 11.69,24.44,76.37,406.4,0.1236,1
540 | 7.729,25.49,47.98,178.8,0.08098,1
541 | 7.691,25.44,48.34,170.4,0.08668,1
542 | 11.54,14.44,74.65,402.9,0.09984,1
543 | 14.47,24.99,95.81,656.4,0.08837,1
544 | 14.74,25.42,94.7,668.6,0.08275,1
545 | 13.21,28.06,84.88,538.4,0.08671,1
546 | 13.87,20.7,89.77,584.8,0.09578,1
547 | 13.62,23.23,87.19,573.2,0.09246,1
548 | 10.32,16.35,65.31,324.9,0.09434,1
549 | 10.26,16.58,65.85,320.8,0.08877,1
550 | 9.683,19.34,61.05,285.7,0.08491,1
551 | 10.82,24.21,68.89,361.6,0.08192,1
552 | 10.86,21.48,68.51,360.5,0.07431,1
553 | 11.13,22.44,71.49,378.4,0.09566,1
554 | 12.77,29.43,81.35,507.9,0.08276,1
555 | 9.333,21.94,59.01,264.0,0.0924,1
556 | 12.88,28.92,82.5,514.3,0.08123,1
557 | 10.29,27.61,65.67,321.4,0.0903,1
558 | 10.16,19.59,64.73,311.7,0.1003,1
559 | 9.423,27.88,59.26,271.3,0.08123,1
560 | 14.59,22.68,96.39,657.1,0.08473,1
561 | 11.51,23.93,74.52,403.5,0.09261,1
562 | 14.05,27.15,91.38,600.4,0.09929,1
563 | 11.2,29.37,70.67,386.0,0.07449,1
564 | 15.22,30.62,103.4,716.9,0.1048,0
565 | 20.92,25.09,143.0,1347.0,0.1099,0
566 | 21.56,22.39,142.0,1479.0,0.111,0
567 | 20.13,28.25,131.2,1261.0,0.0978,0
568 | 16.6,28.08,108.3,858.1,0.08455,0
569 | 20.6,29.33,140.1,1265.0,0.1178,0
570 | 7.76,24.54,47.92,181.0,0.05263,1
571 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ML_from_Scratch
2 | Trying to implement basic ml algorithms from scratch in python. I have also made videos explaining these algorithms...
3 |
4 | ## Gradient Descent
5 | [](https://youtu.be/36zkIAAUcZ4)
6 | [](https://youtu.be/41BiBUZbg9U)
7 |
8 |
9 | ## Linear Regression
10 | [](https://youtu.be/fnDO1s4fzi4)
11 |
12 | ## Logistic Regression
13 | [](https://youtu.be/NtjAeXppomA)
14 |
15 | ## Stochastic Gradient Descent
16 | [](https://youtu.be/V8InSDYHG4s)
17 |
18 | ## KNN
19 | [](https://youtu.be/0RwM2BaLNkE)
20 |
21 | ## K-means
22 | [](https://youtu.be/IB9WfafBmjk)
23 |
24 | ## Decision Tree Classification
25 | [](https://youtu.be/ZVR2Way4nwQ)
26 | [](https://youtu.be/sgQAhG5Q7iY)
27 |
28 |
29 | ## Decision Tree Regression
30 | [](https://youtu.be/UhY5vPfQIrA)
31 | [](https://youtu.be/P2ZB8c5Ha1Q)
32 |
33 | ## Naive Bayes Classification
34 | [](https://youtu.be/lFJbZ6LVxN8)
35 | [](https://youtu.be/3I8oX3OUL6I)
36 |
37 | ## Data source
38 | - airfoil_noise_data.csv (converted from the .dat file available at https://archive.ics.uci.edu/ml/datasets/airfoil+self-noise)
39 |
40 | Donor:
41 | Dr Roberto Lopez
42 | robertolopez '@' intelnics.com
43 | Intelnics
44 |
45 | Creators:
46 | Thomas F. Brooks, D. Stuart Pope and Michael A. Marcolini
47 | NASA
48 |
49 | - Breast_cancer_data.csv (taken from https://www.kaggle.com/merishnasuwal/breast-cancer-prediction-dataset)
50 |
--------------------------------------------------------------------------------
/decision tree classification.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Import tools"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import numpy as np\n",
17 | "import pandas as pd"
18 | ]
19 | },
20 | {
21 | "cell_type": "markdown",
22 | "metadata": {},
23 | "source": [
24 | "## Get the data"
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": 2,
30 | "metadata": {
31 | "scrolled": false
32 | },
33 | "outputs": [
34 | {
35 | "data": {
36 | "text/html": [
37 | "
\n",
38 | "\n",
51 | "
\n",
52 | " \n",
53 | " \n",
54 | " | \n",
55 | " sepal_length | \n",
56 | " sepal_width | \n",
57 | " petal_length | \n",
58 | " petal_width | \n",
59 | " type | \n",
60 | "
\n",
61 | " \n",
62 | " \n",
63 | " \n",
64 | " 0 | \n",
65 | " 5.1 | \n",
66 | " 3.5 | \n",
67 | " 1.4 | \n",
68 | " 0.2 | \n",
69 | " 0 | \n",
70 | "
\n",
71 | " \n",
72 | " 1 | \n",
73 | " 4.9 | \n",
74 | " 3.0 | \n",
75 | " 1.4 | \n",
76 | " 0.2 | \n",
77 | " 0 | \n",
78 | "
\n",
79 | " \n",
80 | " 2 | \n",
81 | " 4.7 | \n",
82 | " 3.2 | \n",
83 | " 1.3 | \n",
84 | " 0.2 | \n",
85 | " 0 | \n",
86 | "
\n",
87 | " \n",
88 | " 3 | \n",
89 | " 4.6 | \n",
90 | " 3.1 | \n",
91 | " 1.5 | \n",
92 | " 0.2 | \n",
93 | " 0 | \n",
94 | "
\n",
95 | " \n",
96 | " 4 | \n",
97 | " 5.0 | \n",
98 | " 3.6 | \n",
99 | " 1.4 | \n",
100 | " 0.2 | \n",
101 | " 0 | \n",
102 | "
\n",
103 | " \n",
104 | " 5 | \n",
105 | " 5.4 | \n",
106 | " 3.9 | \n",
107 | " 1.7 | \n",
108 | " 0.4 | \n",
109 | " 0 | \n",
110 | "
\n",
111 | " \n",
112 | " 6 | \n",
113 | " 4.6 | \n",
114 | " 3.4 | \n",
115 | " 1.4 | \n",
116 | " 0.3 | \n",
117 | " 0 | \n",
118 | "
\n",
119 | " \n",
120 | " 7 | \n",
121 | " 5.0 | \n",
122 | " 3.4 | \n",
123 | " 1.5 | \n",
124 | " 0.2 | \n",
125 | " 0 | \n",
126 | "
\n",
127 | " \n",
128 | " 8 | \n",
129 | " 4.4 | \n",
130 | " 2.9 | \n",
131 | " 1.4 | \n",
132 | " 0.2 | \n",
133 | " 0 | \n",
134 | "
\n",
135 | " \n",
136 | " 9 | \n",
137 | " 4.9 | \n",
138 | " 3.1 | \n",
139 | " 1.5 | \n",
140 | " 0.1 | \n",
141 | " 0 | \n",
142 | "
\n",
143 | " \n",
144 | "
\n",
145 | "
"
146 | ],
147 | "text/plain": [
148 | " sepal_length sepal_width petal_length petal_width type\n",
149 | "0 5.1 3.5 1.4 0.2 0\n",
150 | "1 4.9 3.0 1.4 0.2 0\n",
151 | "2 4.7 3.2 1.3 0.2 0\n",
152 | "3 4.6 3.1 1.5 0.2 0\n",
153 | "4 5.0 3.6 1.4 0.2 0\n",
154 | "5 5.4 3.9 1.7 0.4 0\n",
155 | "6 4.6 3.4 1.4 0.3 0\n",
156 | "7 5.0 3.4 1.5 0.2 0\n",
157 | "8 4.4 2.9 1.4 0.2 0\n",
158 | "9 4.9 3.1 1.5 0.1 0"
159 | ]
160 | },
161 | "execution_count": 2,
162 | "metadata": {},
163 | "output_type": "execute_result"
164 | }
165 | ],
166 | "source": [
167 | "col_names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'type']\n",
168 | "data = pd.read_csv(\"iris.csv\", skiprows=1, header=None, names=col_names)\n",
169 | "data.head(10)"
170 | ]
171 | },
172 | {
173 | "cell_type": "markdown",
174 | "metadata": {},
175 | "source": [
176 | "## Node class"
177 | ]
178 | },
179 | {
180 | "cell_type": "code",
181 | "execution_count": 3,
182 | "metadata": {},
183 | "outputs": [],
184 | "source": [
185 | "class Node():\n",
186 | " def __init__(self, feature_index=None, threshold=None, left=None, right=None, info_gain=None, value=None):\n",
187 | " ''' constructor ''' \n",
188 | " \n",
189 | " # for decision node\n",
190 | " self.feature_index = feature_index\n",
191 | " self.threshold = threshold\n",
192 | " self.left = left\n",
193 | " self.right = right\n",
194 | " self.info_gain = info_gain\n",
195 | " \n",
196 | " # for leaf node\n",
197 | " self.value = value"
198 | ]
199 | },
200 | {
201 | "cell_type": "markdown",
202 | "metadata": {},
203 | "source": [
204 | "## Tree class"
205 | ]
206 | },
207 | {
208 | "cell_type": "code",
209 | "execution_count": 4,
210 | "metadata": {},
211 | "outputs": [],
212 | "source": [
213 | "class DecisionTreeClassifier():\n",
214 | " def __init__(self, min_samples_split=2, max_depth=2):\n",
215 | " ''' constructor '''\n",
216 | " \n",
217 | " # initialize the root of the tree \n",
218 | " self.root = None\n",
219 | " \n",
220 | " # stopping conditions\n",
221 | " self.min_samples_split = min_samples_split\n",
222 | " self.max_depth = max_depth\n",
223 | " \n",
224 | " def build_tree(self, dataset, curr_depth=0):\n",
225 | " ''' recursive function to build the tree ''' \n",
226 | " \n",
227 | " X, Y = dataset[:,:-1], dataset[:,-1]\n",
228 | " num_samples, num_features = np.shape(X)\n",
229 | " \n",
230 | " # split until stopping conditions are met\n",
231 | " if num_samples>=self.min_samples_split and curr_depth<=self.max_depth:\n",
232 | " # find the best split\n",
233 | " best_split = self.get_best_split(dataset, num_samples, num_features)\n",
234 | " # check if information gain is positive\n",
235 | " if best_split[\"info_gain\"]>0:\n",
236 | " # recur left\n",
237 | " left_subtree = self.build_tree(best_split[\"dataset_left\"], curr_depth+1)\n",
238 | " # recur right\n",
239 | " right_subtree = self.build_tree(best_split[\"dataset_right\"], curr_depth+1)\n",
240 | " # return decision node\n",
241 | " return Node(best_split[\"feature_index\"], best_split[\"threshold\"], \n",
242 | " left_subtree, right_subtree, best_split[\"info_gain\"])\n",
243 | " \n",
244 | " # compute leaf node\n",
245 | " leaf_value = self.calculate_leaf_value(Y)\n",
246 | " # return leaf node\n",
247 | " return Node(value=leaf_value)\n",
248 | " \n",
249 | " def get_best_split(self, dataset, num_samples, num_features):\n",
250 | " ''' function to find the best split '''\n",
251 | " \n",
252 | " # dictionary to store the best split\n",
253 | " best_split = {}\n",
254 | " max_info_gain = -float(\"inf\")\n",
255 | " \n",
256 | " # loop over all the features\n",
257 | " for feature_index in range(num_features):\n",
258 | " feature_values = dataset[:, feature_index]\n",
259 | " possible_thresholds = np.unique(feature_values)\n",
260 | " # loop over all the feature values present in the data\n",
261 | " for threshold in possible_thresholds:\n",
262 | " # get current split\n",
263 | " dataset_left, dataset_right = self.split(dataset, feature_index, threshold)\n",
264 | " # check if childs are not null\n",
265 | " if len(dataset_left)>0 and len(dataset_right)>0:\n",
266 | " y, left_y, right_y = dataset[:, -1], dataset_left[:, -1], dataset_right[:, -1]\n",
267 | " # compute information gain\n",
268 | " curr_info_gain = self.information_gain(y, left_y, right_y, \"gini\")\n",
269 | " # update the best split if needed\n",
270 | " if curr_info_gain>max_info_gain:\n",
271 | " best_split[\"feature_index\"] = feature_index\n",
272 | " best_split[\"threshold\"] = threshold\n",
273 | " best_split[\"dataset_left\"] = dataset_left\n",
274 | " best_split[\"dataset_right\"] = dataset_right\n",
275 | " best_split[\"info_gain\"] = curr_info_gain\n",
276 | " max_info_gain = curr_info_gain\n",
277 | " \n",
278 | " # return best split\n",
279 | " return best_split\n",
280 | " \n",
281 | " def split(self, dataset, feature_index, threshold):\n",
282 | " ''' function to split the data '''\n",
283 | " \n",
284 | " dataset_left = np.array([row for row in dataset if row[feature_index]<=threshold])\n",
285 | " dataset_right = np.array([row for row in dataset if row[feature_index]>threshold])\n",
286 | " return dataset_left, dataset_right\n",
287 | " \n",
288 | " def information_gain(self, parent, l_child, r_child, mode=\"entropy\"):\n",
289 | " ''' function to compute information gain '''\n",
290 | " \n",
291 | " weight_l = len(l_child) / len(parent)\n",
292 | " weight_r = len(r_child) / len(parent)\n",
293 | " if mode==\"gini\":\n",
294 | " gain = self.gini_index(parent) - (weight_l*self.gini_index(l_child) + weight_r*self.gini_index(r_child))\n",
295 | " else:\n",
296 | " gain = self.entropy(parent) - (weight_l*self.entropy(l_child) + weight_r*self.entropy(r_child))\n",
297 | " return gain\n",
298 | " \n",
299 | " def entropy(self, y):\n",
300 | " ''' function to compute entropy '''\n",
301 | " \n",
302 | " class_labels = np.unique(y)\n",
303 | " entropy = 0\n",
304 | " for cls in class_labels:\n",
305 | " p_cls = len(y[y == cls]) / len(y)\n",
306 | " entropy += -p_cls * np.log2(p_cls)\n",
307 | " return entropy\n",
308 | " \n",
309 | " def gini_index(self, y):\n",
310 | " ''' function to compute gini index '''\n",
311 | " \n",
312 | " class_labels = np.unique(y)\n",
313 | " gini = 0\n",
314 | " for cls in class_labels:\n",
315 | " p_cls = len(y[y == cls]) / len(y)\n",
316 | " gini += p_cls**2\n",
317 | " return 1 - gini\n",
318 | " \n",
319 | " def calculate_leaf_value(self, Y):\n",
320 | " ''' function to compute leaf node '''\n",
321 | " \n",
322 | " Y = list(Y)\n",
323 | " return max(Y, key=Y.count)\n",
324 | " \n",
325 | " def print_tree(self, tree=None, indent=\" \"):\n",
326 | " ''' function to print the tree '''\n",
327 | " \n",
328 | " if not tree:\n",
329 | " tree = self.root\n",
330 | "\n",
331 | " if tree.value is not None:\n",
332 | " print(tree.value)\n",
333 | "\n",
334 | " else:\n",
335 | " print(\"X_\"+str(tree.feature_index), \"<=\", tree.threshold, \"?\", tree.info_gain)\n",
336 | " print(\"%sleft:\" % (indent), end=\"\")\n",
337 | " self.print_tree(tree.left, indent + indent)\n",
338 | " print(\"%sright:\" % (indent), end=\"\")\n",
339 | " self.print_tree(tree.right, indent + indent)\n",
340 | " \n",
341 | " def fit(self, X, Y):\n",
342 | " ''' function to train the tree '''\n",
343 | " \n",
344 | " dataset = np.concatenate((X, Y), axis=1)\n",
345 | " self.root = self.build_tree(dataset)\n",
346 | " \n",
347 | " def predict(self, X):\n",
348 | " ''' function to predict new dataset '''\n",
349 | " \n",
350 | " preditions = [self.make_prediction(x, self.root) for x in X]\n",
351 | " return preditions\n",
352 | " \n",
353 | " def make_prediction(self, x, tree):\n",
354 | " ''' function to predict a single data point '''\n",
355 | " \n",
356 | " if tree.value!=None: return tree.value\n",
357 | " feature_val = x[tree.feature_index]\n",
358 | " if feature_val<=tree.threshold:\n",
359 | " return self.make_prediction(x, tree.left)\n",
360 | " else:\n",
361 | " return self.make_prediction(x, tree.right)"
362 | ]
363 | },
364 | {
365 | "cell_type": "markdown",
366 | "metadata": {},
367 | "source": [
368 | "## Train-Test split"
369 | ]
370 | },
371 | {
372 | "cell_type": "code",
373 | "execution_count": 5,
374 | "metadata": {},
375 | "outputs": [],
376 | "source": [
377 | "X = data.iloc[:, :-1].values\n",
378 | "Y = data.iloc[:, -1].values.reshape(-1,1)\n",
379 | "from sklearn.model_selection import train_test_split\n",
380 | "X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=.2, random_state=41)"
381 | ]
382 | },
383 | {
384 | "cell_type": "markdown",
385 | "metadata": {},
386 | "source": [
387 | "## Fit the model"
388 | ]
389 | },
390 | {
391 | "cell_type": "code",
392 | "execution_count": 6,
393 | "metadata": {},
394 | "outputs": [
395 | {
396 | "name": "stdout",
397 | "output_type": "stream",
398 | "text": [
399 | "X_2 <= 1.9 ? 0.33741385372714494\n",
400 | " left:0.0\n",
401 | " right:X_3 <= 1.5 ? 0.427106638180289\n",
402 | " left:X_2 <= 4.9 ? 0.05124653739612173\n",
403 | " left:1.0\n",
404 | " right:2.0\n",
405 | " right:X_2 <= 5.0 ? 0.019631171921475288\n",
406 | " left:X_1 <= 2.8 ? 0.20833333333333334\n",
407 | " left:2.0\n",
408 | " right:1.0\n",
409 | " right:2.0\n"
410 | ]
411 | }
412 | ],
413 | "source": [
414 | "classifier = DecisionTreeClassifier(min_samples_split=3, max_depth=3)\n",
415 | "classifier.fit(X_train,Y_train)\n",
416 | "classifier.print_tree()"
417 | ]
418 | },
419 | {
420 | "cell_type": "markdown",
421 | "metadata": {},
422 | "source": [
423 | "## Test the model"
424 | ]
425 | },
426 | {
427 | "cell_type": "code",
428 | "execution_count": 7,
429 | "metadata": {},
430 | "outputs": [
431 | {
432 | "data": {
433 | "text/plain": [
434 | "0.9333333333333333"
435 | ]
436 | },
437 | "execution_count": 7,
438 | "metadata": {},
439 | "output_type": "execute_result"
440 | }
441 | ],
442 | "source": [
443 | "Y_pred = classifier.predict(X_test) \n",
444 | "from sklearn.metrics import accuracy_score\n",
445 | "accuracy_score(Y_test, Y_pred)"
446 | ]
447 | }
448 | ],
449 | "metadata": {
450 | "kernelspec": {
451 | "display_name": "Python 3",
452 | "language": "python",
453 | "name": "python3"
454 | },
455 | "language_info": {
456 | "codemirror_mode": {
457 | "name": "ipython",
458 | "version": 3
459 | },
460 | "file_extension": ".py",
461 | "mimetype": "text/x-python",
462 | "name": "python",
463 | "nbconvert_exporter": "python",
464 | "pygments_lexer": "ipython3",
465 | "version": "3.8.5"
466 | }
467 | },
468 | "nbformat": 4,
469 | "nbformat_minor": 4
470 | }
471 |
--------------------------------------------------------------------------------
/decision tree regression.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Import tools"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import numpy as np\n",
17 | "import pandas as pd"
18 | ]
19 | },
20 | {
21 | "cell_type": "markdown",
22 | "metadata": {},
23 | "source": [
24 | "## Get the data"
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": 2,
30 | "metadata": {},
31 | "outputs": [
32 | {
33 | "data": {
34 | "text/html": [
35 | "\n",
36 | "\n",
49 | "
\n",
50 | " \n",
51 | " \n",
52 | " | \n",
53 | " x0 | \n",
54 | " x1 | \n",
55 | " x2 | \n",
56 | " x3 | \n",
57 | " x4 | \n",
58 | " y | \n",
59 | "
\n",
60 | " \n",
61 | " \n",
62 | " \n",
63 | " 0 | \n",
64 | " 800 | \n",
65 | " 0.0 | \n",
66 | " 0.3048 | \n",
67 | " 71.3 | \n",
68 | " 0.002663 | \n",
69 | " 126.201 | \n",
70 | "
\n",
71 | " \n",
72 | " 1 | \n",
73 | " 1000 | \n",
74 | " 0.0 | \n",
75 | " 0.3048 | \n",
76 | " 71.3 | \n",
77 | " 0.002663 | \n",
78 | " 125.201 | \n",
79 | "
\n",
80 | " \n",
81 | " 2 | \n",
82 | " 1250 | \n",
83 | " 0.0 | \n",
84 | " 0.3048 | \n",
85 | " 71.3 | \n",
86 | " 0.002663 | \n",
87 | " 125.951 | \n",
88 | "
\n",
89 | " \n",
90 | " 3 | \n",
91 | " 1600 | \n",
92 | " 0.0 | \n",
93 | " 0.3048 | \n",
94 | " 71.3 | \n",
95 | " 0.002663 | \n",
96 | " 127.591 | \n",
97 | "
\n",
98 | " \n",
99 | " 4 | \n",
100 | " 2000 | \n",
101 | " 0.0 | \n",
102 | " 0.3048 | \n",
103 | " 71.3 | \n",
104 | " 0.002663 | \n",
105 | " 127.461 | \n",
106 | "
\n",
107 | " \n",
108 | "
\n",
109 | "
"
110 | ],
111 | "text/plain": [
112 | " x0 x1 x2 x3 x4 y\n",
113 | "0 800 0.0 0.3048 71.3 0.002663 126.201\n",
114 | "1 1000 0.0 0.3048 71.3 0.002663 125.201\n",
115 | "2 1250 0.0 0.3048 71.3 0.002663 125.951\n",
116 | "3 1600 0.0 0.3048 71.3 0.002663 127.591\n",
117 | "4 2000 0.0 0.3048 71.3 0.002663 127.461"
118 | ]
119 | },
120 | "execution_count": 2,
121 | "metadata": {},
122 | "output_type": "execute_result"
123 | }
124 | ],
125 | "source": [
126 | "data = pd.read_csv(\"airfoil_noise_data.csv\")\n",
127 | "data.head(5)"
128 | ]
129 | },
130 | {
131 | "cell_type": "markdown",
132 | "metadata": {},
133 | "source": [
134 | "## Node class"
135 | ]
136 | },
137 | {
138 | "cell_type": "code",
139 | "execution_count": 3,
140 | "metadata": {},
141 | "outputs": [],
142 | "source": [
143 | "class Node():\n",
144 | " def __init__(self, feature_index=None, threshold=None, left=None, right=None, var_red=None, value=None):\n",
145 | " ''' constructor ''' \n",
146 | " \n",
147 | " # for decision node\n",
148 | " self.feature_index = feature_index\n",
149 | " self.threshold = threshold\n",
150 | " self.left = left\n",
151 | " self.right = right\n",
152 | " self.var_red = var_red\n",
153 | " \n",
154 | " # for leaf node\n",
155 | " self.value = value"
156 | ]
157 | },
158 | {
159 | "cell_type": "markdown",
160 | "metadata": {},
161 | "source": [
162 | "## Tree class"
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": 4,
168 | "metadata": {},
169 | "outputs": [],
170 | "source": [
171 | "class DecisionTreeRegressor():\n",
172 | " def __init__(self, min_samples_split=2, max_depth=2):\n",
173 | " ''' constructor '''\n",
174 | " \n",
175 | " # initialize the root of the tree \n",
176 | " self.root = None\n",
177 | " \n",
178 | " # stopping conditions\n",
179 | " self.min_samples_split = min_samples_split\n",
180 | " self.max_depth = max_depth\n",
181 | " \n",
182 | " def build_tree(self, dataset, curr_depth=0):\n",
183 | " ''' recursive function to build the tree '''\n",
184 | " \n",
185 | " X, Y = dataset[:,:-1], dataset[:,-1]\n",
186 | " num_samples, num_features = np.shape(X)\n",
187 | " best_split = {}\n",
188 | " # split until stopping conditions are met\n",
189 | " if num_samples>=self.min_samples_split and curr_depth<=self.max_depth:\n",
190 | " # find the best split\n",
191 | " best_split = self.get_best_split(dataset, num_samples, num_features)\n",
192 | " # check if information gain is positive\n",
193 | " if best_split[\"var_red\"]>0:\n",
194 | " # recur left\n",
195 | " left_subtree = self.build_tree(best_split[\"dataset_left\"], curr_depth+1)\n",
196 | " # recur right\n",
197 | " right_subtree = self.build_tree(best_split[\"dataset_right\"], curr_depth+1)\n",
198 | " # return decision node\n",
199 | " return Node(best_split[\"feature_index\"], best_split[\"threshold\"], \n",
200 | " left_subtree, right_subtree, best_split[\"var_red\"])\n",
201 | " \n",
202 | " # compute leaf node\n",
203 | " leaf_value = self.calculate_leaf_value(Y)\n",
204 | " # return leaf node\n",
205 | " return Node(value=leaf_value)\n",
206 | " \n",
207 | " def get_best_split(self, dataset, num_samples, num_features):\n",
208 | " ''' function to find the best split '''\n",
209 | " \n",
210 | " # dictionary to store the best split\n",
211 | " best_split = {}\n",
212 | " max_var_red = -float(\"inf\")\n",
213 | " # loop over all the features\n",
214 | " for feature_index in range(num_features):\n",
215 | " feature_values = dataset[:, feature_index]\n",
216 | " possible_thresholds = np.unique(feature_values)\n",
217 | " # loop over all the feature values present in the data\n",
218 | " for threshold in possible_thresholds:\n",
219 | " # get current split\n",
220 | " dataset_left, dataset_right = self.split(dataset, feature_index, threshold)\n",
221 | " # check if childs are not null\n",
222 | " if len(dataset_left)>0 and len(dataset_right)>0:\n",
223 | " y, left_y, right_y = dataset[:, -1], dataset_left[:, -1], dataset_right[:, -1]\n",
224 | " # compute information gain\n",
225 | " curr_var_red = self.variance_reduction(y, left_y, right_y)\n",
226 | " # update the best split if needed\n",
227 | " if curr_var_red>max_var_red:\n",
228 | " best_split[\"feature_index\"] = feature_index\n",
229 | " best_split[\"threshold\"] = threshold\n",
230 | " best_split[\"dataset_left\"] = dataset_left\n",
231 | " best_split[\"dataset_right\"] = dataset_right\n",
232 | " best_split[\"var_red\"] = curr_var_red\n",
233 | " max_var_red = curr_var_red\n",
234 | " \n",
235 | " # return best split\n",
236 | " return best_split\n",
237 | " \n",
238 | " def split(self, dataset, feature_index, threshold):\n",
239 | " ''' function to split the data '''\n",
240 | " \n",
241 | " dataset_left = np.array([row for row in dataset if row[feature_index]<=threshold])\n",
242 | " dataset_right = np.array([row for row in dataset if row[feature_index]>threshold])\n",
243 | " return dataset_left, dataset_right\n",
244 | " \n",
245 | " def variance_reduction(self, parent, l_child, r_child):\n",
246 | " ''' function to compute variance reduction '''\n",
247 | " \n",
248 | " weight_l = len(l_child) / len(parent)\n",
249 | " weight_r = len(r_child) / len(parent)\n",
250 | " reduction = np.var(parent) - (weight_l * np.var(l_child) + weight_r * np.var(r_child))\n",
251 | " return reduction\n",
252 | " \n",
253 | " def calculate_leaf_value(self, Y):\n",
254 | " ''' function to compute leaf node '''\n",
255 | " \n",
256 | " val = np.mean(Y)\n",
257 | " return val\n",
258 | " \n",
259 | " def print_tree(self, tree=None, indent=\" \"):\n",
260 | " ''' function to print the tree '''\n",
261 | " \n",
262 | " if not tree:\n",
263 | " tree = self.root\n",
264 | "\n",
265 | " if tree.value is not None:\n",
266 | " print(tree.value)\n",
267 | "\n",
268 | " else:\n",
269 | " print(\"X_\"+str(tree.feature_index), \"<=\", tree.threshold, \"?\", tree.var_red)\n",
270 | " print(\"%sleft:\" % (indent), end=\"\")\n",
271 | " self.print_tree(tree.left, indent + indent)\n",
272 | " print(\"%sright:\" % (indent), end=\"\")\n",
273 | " self.print_tree(tree.right, indent + indent)\n",
274 | " \n",
275 | " def fit(self, X, Y):\n",
276 | " ''' function to train the tree '''\n",
277 | " \n",
278 | " dataset = np.concatenate((X, Y), axis=1)\n",
279 | " self.root = self.build_tree(dataset)\n",
280 | " \n",
281 | " def make_prediction(self, x, tree):\n",
282 | " ''' function to predict new dataset '''\n",
283 | " \n",
284 | " if tree.value!=None: return tree.value\n",
285 | " feature_val = x[tree.feature_index]\n",
286 | " if feature_val<=tree.threshold:\n",
287 | " return self.make_prediction(x, tree.left)\n",
288 | " else:\n",
289 | " return self.make_prediction(x, tree.right)\n",
290 | " \n",
291 | " def predict(self, X):\n",
292 | " ''' function to predict a single data point '''\n",
293 | " \n",
294 | " preditions = [self.make_prediction(x, self.root) for x in X]\n",
295 | " return preditions"
296 | ]
297 | },
298 | {
299 | "cell_type": "markdown",
300 | "metadata": {},
301 | "source": [
302 | "## Train-Test split"
303 | ]
304 | },
305 | {
306 | "cell_type": "code",
307 | "execution_count": 5,
308 | "metadata": {},
309 | "outputs": [],
310 | "source": [
311 | "X = data.iloc[:, :-1].values\n",
312 | "Y = data.iloc[:, -1].values.reshape(-1,1)\n",
313 | "from sklearn.model_selection import train_test_split\n",
314 | "X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=.2, random_state=41)"
315 | ]
316 | },
317 | {
318 | "cell_type": "markdown",
319 | "metadata": {},
320 | "source": [
321 | "## Fit the model"
322 | ]
323 | },
324 | {
325 | "cell_type": "code",
326 | "execution_count": 6,
327 | "metadata": {},
328 | "outputs": [
329 | {
330 | "name": "stdout",
331 | "output_type": "stream",
332 | "text": [
333 | "X_0 <= 3150.0 ? 7.132048702017748\n",
334 | " left:X_4 <= 0.033779199999999995 ? 3.5903305690676675\n",
335 | " left:X_3 <= 55.5 ? 1.1789899981318328\n",
336 | " left:X_4 <= 0.00251435 ? 1.614396721819876\n",
337 | " left:128.9919833333333\n",
338 | " right:125.90953579676673\n",
339 | " right:X_1 <= 15.4 ? 2.2342245360792994\n",
340 | " left:129.39160280373832\n",
341 | " right:123.80422222222222\n",
342 | " right:X_0 <= 1250.0 ? 9.970884020498875\n",
343 | " left:X_4 <= 0.0483159 ? 6.355275159824863\n",
344 | " left:124.38024528301887\n",
345 | " right:118.30039999999998\n",
346 | " right:X_3 <= 39.6 ? 5.036286657241022\n",
347 | " left:113.58091666666667\n",
348 | " right:118.07284615384614\n",
349 | " right:X_4 <= 0.00146332 ? 29.082992105065273\n",
350 | " left:X_0 <= 8000.0 ? 11.886497073996967\n",
351 | " left:X_2 <= 0.0508 ? 7.608945827689513\n",
352 | " left:134.04247500000002\n",
353 | " right:127.33581818181818\n",
354 | " right:X_4 <= 0.00076193 ? 10.622919322400815\n",
355 | " left:128.94078571428574\n",
356 | " right:122.4076875\n",
357 | " right:X_4 <= 0.022902799999999997 ? 5.638575922510647\n",
358 | " left:X_0 <= 6300.0 ? 5.985051045988911\n",
359 | " left:120.04740816326529\n",
360 | " right:114.67370491803278\n",
361 | " right:X_4 <= 0.0368233 ? 8.63874479304644\n",
362 | " left:113.83169565217393\n",
363 | " right:107.6395833333333\n"
364 | ]
365 | }
366 | ],
367 | "source": [
368 | "regressor = DecisionTreeRegressor(min_samples_split=3, max_depth=3)\n",
369 | "regressor.fit(X_train,Y_train)\n",
370 | "regressor.print_tree()"
371 | ]
372 | },
373 | {
374 | "cell_type": "markdown",
375 | "metadata": {},
376 | "source": [
377 | "## Test the model"
378 | ]
379 | },
380 | {
381 | "cell_type": "code",
382 | "execution_count": 7,
383 | "metadata": {},
384 | "outputs": [
385 | {
386 | "data": {
387 | "text/plain": [
388 | "4.851358097184457"
389 | ]
390 | },
391 | "execution_count": 7,
392 | "metadata": {},
393 | "output_type": "execute_result"
394 | }
395 | ],
396 | "source": [
397 | "Y_pred = regressor.predict(X_test) \n",
398 | "from sklearn.metrics import mean_squared_error\n",
399 | "np.sqrt(mean_squared_error(Y_test, Y_pred))"
400 | ]
401 | }
402 | ],
403 | "metadata": {
404 | "kernelspec": {
405 | "display_name": "Python 3",
406 | "language": "python",
407 | "name": "python3"
408 | },
409 | "language_info": {
410 | "codemirror_mode": {
411 | "name": "ipython",
412 | "version": 3
413 | },
414 | "file_extension": ".py",
415 | "mimetype": "text/x-python",
416 | "name": "python",
417 | "nbconvert_exporter": "python",
418 | "pygments_lexer": "ipython3",
419 | "version": "3.8.5"
420 | }
421 | },
422 | "nbformat": 4,
423 | "nbformat_minor": 4
424 | }
425 |
--------------------------------------------------------------------------------
/linear regression.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Generating Fake Data"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 16,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "from sklearn.datasets.samples_generator import make_regression\n",
17 | "X, y = make_regression(n_samples=200, n_features=1, n_informative=1, noise=6, bias=30, random_state=200)\n",
18 | "m = 200"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "## Visualizing the Data"
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": 25,
31 | "metadata": {},
32 | "outputs": [
33 | {
34 | "data": {
35 | "image/png": "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\n",
36 | "text/plain": [
37 | ""
38 | ]
39 | },
40 | "metadata": {},
41 | "output_type": "display_data"
42 | }
43 | ],
44 | "source": [
45 | "from matplotlib import pyplot as plt\n",
46 | "plt.scatter(X,y, c = \"red\",alpha=.5, marker = 'o')\n",
47 | "plt.xlabel(\"X\")\n",
48 | "plt.ylabel(\"Y\")\n",
49 | "plt.show()"
50 | ]
51 | },
52 | {
53 | "cell_type": "markdown",
54 | "metadata": {},
55 | "source": [
56 | "## Linear Model"
57 | ]
58 | },
59 | {
60 | "cell_type": "code",
61 | "execution_count": 18,
62 | "metadata": {},
63 | "outputs": [],
64 | "source": [
65 | "import numpy as np\n",
66 | "def h(X,w):\n",
67 | " return (w[1]*np.array(X[:,0])+w[0])"
68 | ]
69 | },
70 | {
71 | "cell_type": "markdown",
72 | "metadata": {},
73 | "source": [
74 | "## Cost Function"
75 | ]
76 | },
77 | {
78 | "cell_type": "code",
79 | "execution_count": 19,
80 | "metadata": {},
81 | "outputs": [],
82 | "source": [
83 | "def cost(w,X,y):\n",
84 | " return (.5/m) * np.sum(np.square(h(X,w)-np.array(y)))"
85 | ]
86 | },
87 | {
88 | "cell_type": "markdown",
89 | "metadata": {},
90 | "source": [
91 | "## Gradient Descent "
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "execution_count": 20,
97 | "metadata": {},
98 | "outputs": [],
99 | "source": [
100 | "def grad(w,X,y):\n",
101 | " g = [0]*2\n",
102 | " g[0] = (1/m) * np.sum(h(X,w)-np.array(y))\n",
103 | " g[1] = (1/m) * np.sum((h(X,w)-np.array(y))*np.array(X[:,0]))\n",
104 | " return g\n"
105 | ]
106 | },
107 | {
108 | "cell_type": "code",
109 | "execution_count": 21,
110 | "metadata": {},
111 | "outputs": [],
112 | "source": [
113 | "def descent(w_new, w_prev, lr):\n",
114 | " print(w_prev)\n",
115 | " print(cost(w_prev,X,y))\n",
116 | " j=0\n",
117 | " while True:\n",
118 | " w_prev = w_new\n",
119 | " w0 = w_prev[0] - lr*grad(w_prev,X,y)[0]\n",
120 | " w1 = w_prev[1] - lr*grad(w_prev,X,y)[1]\n",
121 | " w_new = [w0, w1]\n",
122 | " print(w_new)\n",
123 | " print(cost(w_new,X,y))\n",
124 | " if (w_new[0]-w_prev[0])**2 + (w_new[1]-w_prev[1])**2 <= pow(10,-6):\n",
125 | " return w_new\n",
126 | " if j>500: \n",
127 | " return w_new\n",
128 | " j+=1 "
129 | ]
130 | },
131 | {
132 | "cell_type": "markdown",
133 | "metadata": {},
134 | "source": [
135 | "## Initializing Parameters"
136 | ]
137 | },
138 | {
139 | "cell_type": "code",
140 | "execution_count": 22,
141 | "metadata": {},
142 | "outputs": [],
143 | "source": [
144 | "w = [0,-1]"
145 | ]
146 | },
147 | {
148 | "cell_type": "markdown",
149 | "metadata": {},
150 | "source": [
151 | "## Training the Model"
152 | ]
153 | },
154 | {
155 | "cell_type": "code",
156 | "execution_count": 23,
157 | "metadata": {},
158 | "outputs": [
159 | {
160 | "name": "stdout",
161 | "output_type": "stream",
162 | "text": [
163 | "[0, -1]\n",
164 | "540.5360663843456\n",
165 | "[3.0956308633447547, 0.11442770988081663]\n",
166 | "437.91139336428444\n",
167 | "[5.873446610978822, 1.1023454281382854]\n",
168 | "355.5039050187037\n",
169 | "[8.366165526017987, 1.9778657783247602]\n",
170 | "289.3267499184995\n",
171 | "[10.603129563187093, 2.753547324958939]\n",
172 | "236.1799750745718\n",
173 | "[12.610653489037027, 3.440564026385428]\n",
174 | "193.49509649539323\n",
175 | "[14.412337853388406, 4.048856351454087]\n",
176 | "159.2103901995911\n",
177 | "[16.0293495446536, 4.587266032213945]\n",
178 | "131.6708284668908\n",
179 | "[17.480673291820082, 5.063656213710697]\n",
180 | "109.54778810165583\n",
181 | "[18.7833371265594, 5.485018573380515]\n",
182 | "91.77462156224563\n",
183 | "[19.952614505935692, 5.857568814053481]\n",
184 | "77.49495508304668\n",
185 | "[21.002205515744066, 6.186831784078626]\n",
186 | "66.02119816099949\n",
187 | "[21.944399323224108, 6.4777173436470505]\n",
188 | "56.801246289923824\n",
189 | "[22.79021982273288, 6.734587976310905]\n",
190 | "49.39175789964725\n",
191 | "[23.549556216205993, 6.961319037445921]\n",
192 | "43.436706577550574\n",
193 | "[24.23128008944935, 7.1613524356181975]\n",
194 | "38.6501664442448\n",
195 | "[24.843350383306017, 7.337744457271138]\n",
196 | "34.802494555336104\n",
197 | "[25.39290751357782, 7.493208368754656]\n",
198 | "31.709239459080347\n",
199 | "[25.88635776349851, 7.630152361500887]\n",
200 | "29.22223761683571\n",
201 | "[26.329448955986066, 7.750713345236864]\n",
202 | "27.22246575546644\n",
203 | "[26.727338308440384, 7.85678703973609]\n",
204 | "25.614302554322332\n",
205 | "[27.084653279240058, 7.950054767051352]\n",
206 | "24.320921533807876\n",
207 | "[27.405546131200424, 8.032007302818467]\n",
208 | "23.280591944370723\n",
209 | "[27.69374286207346, 8.10396610651881]\n",
210 | "22.443708530267372\n",
211 | "[27.952587084793493, 8.167102216040767]\n",
212 | "21.77040640846802\n",
213 | "[28.1850793797893, 8.222453061042739]\n",
214 | "21.22864568158778\n",
215 | "[28.393912587566714, 8.270937422096216]\n",
216 | "20.792673176173675\n",
217 | "[28.581503461264624, 8.313368738022628]\n",
218 | "20.44178697219165\n",
219 | "[28.75002105541824, 8.350466941915155]\n",
220 | "20.159344055135406\n",
221 | "[28.901412188203544, 8.382868986773879]\n",
222 | "19.93196319200716\n",
223 | "[29.03742427951789, 8.411138204226754]\n",
224 | "19.74888457866804\n",
225 | "[29.159625835953786, 8.435772624233959]\n",
226 | "19.601455387770752\n",
227 | "[29.2694248256702, 8.45721236977788]\n",
228 | "19.482716431969585\n",
229 | "[29.368085161021078, 8.475846228144906]\n",
230 | "19.387070041859424\n",
231 | "[29.45674148426251, 8.492017489347575]\n",
232 | "19.310013179228125\n",
233 | "[29.536412431457247, 8.506029132372674]\n",
234 | "19.24792295396926\n",
235 | "[29.60801253158606, 8.518148431144402]\n",
236 | "19.19788424005612\n",
237 | "[29.672362881642048, 8.528611044246796]\n",
238 | "19.157551114830053\n",
239 | "[29.73020072393229, 8.537624645454327]\n",
240 | "19.125035474814123\n",
241 | "[29.782188038766204, 8.545372145882025]\n",
242 | "19.09881748922257\n",
243 | "[29.828919254015993, 8.552014553005522]\n",
244 | "19.077673602614112\n",
245 | "[29.87092816255075, 8.557693506843796]\n",
246 | "19.06061864154971\n",
247 | "[29.90869412914744, 8.562533529178292]\n",
248 | "19.046859257450855\n",
249 | "[29.942647660055936, 8.566644017743355]\n",
250 | "19.035756481849372\n",
251 | "[29.97317540084111, 8.57012101381262]\n",
252 | "19.026795607153897\n",
253 | "[30.000624621352255, 8.573048768478005]\n",
254 | "19.019561957024997\n",
255 | "[30.025307240597662, 8.57550113013079]\n",
256 | "19.013721392385282\n",
257 | "[30.047503438857856, 8.577542773171217]\n",
258 | "19.009004625587373\n",
259 | "[30.067464899489234, 8.579230285760998]\n",
260 | "19.005194597236063\n",
261 | "[30.085417718492856, 8.580613132462974]\n",
262 | "19.00211631637512\n",
263 | "[30.101565015998244, 8.581734505857439]\n",
264 | "18.99962868224005\n",
265 | "[30.11608928029284, 8.582632079662158]\n",
266 | "18.99761790019706\n",
267 | "[30.12915447187187, 8.583338674491873]\n",
268 | "18.995992180371438\n",
269 | "[30.14090791215345, 8.583882846154577]\n",
270 | "18.994677468461337\n",
271 | "[30.151481978966018, 8.584289405279359]\n",
272 | "18.993614007260764\n",
273 | "[30.160995628639302, 8.58457987608947]\n",
274 | "18.99275356682987\n",
275 | "[30.169555762489143, 8.584772901261081]\n",
276 | "18.992057212939287\n",
277 | "[30.177258453655917, 8.584884599031389]\n",
278 | "18.991493508895633\n",
279 | "[30.184190048614877, 8.584928878028586]\n",
280 | "18.991037066345022\n",
281 | "[30.190428156204195, 8.584917714681556]\n",
282 | "18.99066737713041\n",
283 | "[30.196042535696083, 8.584861397520429]\n",
284 | "18.99036787153328\n",
285 | "[30.201095894251807, 8.584768742193141]\n",
286 | "18.990125158892102\n",
287 | "[30.205644603039065, 8.58464728059093]\n",
288 | "18.989928415168315\n",
289 | "[30.20973934033721, 8.584503427091704]\n",
290 | "18.98976888893204\n",
291 | "[30.21342566910097, 8.58434262458882]\n",
292 | "18.98963950279431\n",
293 | "[30.216744555686475, 8.584169472669567]\n",
294 | "18.989534531782173\n",
295 | "[30.219732835755565, 8.58398784003826]\n",
296 | "18.9894493437512\n",
297 | "[30.22242363275721, 8.583800963039536]\n",
298 | "18.989380189826502\n",
299 | "[30.22484673383125, 8.583611531925033]\n",
300 | "18.989324035195228\n",
301 | "[30.227028927482966, 8.583421766317985]\n",
302 | "18.989278422451623\n",
303 | "[30.228994306931416, 8.583233481162887]\n",
304 | "18.98924136120799\n",
305 | "[30.23076454263459, 8.583048144298838]\n",
306 | "18.98921123890338\n",
307 | "[30.23235912713573, 8.582866926663364]\n",
308 | "18.98918674872298\n",
309 | "[30.233795595053294, 8.582690746016727]\n",
310 | "18.98916683133221\n",
311 | "[30.235089720748128, 8.582520304973011]\n",
312 | "18.989150627766747\n",
313 | "[30.23625569594233, 8.582356124032495]\n",
314 | "18.98913744133326\n",
315 | "[30.237306289331627, 8.582198570228412]\n",
316 | "18.989126706789886\n",
317 | "[30.238252990024396, 8.582047881929046]\n",
318 | "18.98911796540923\n",
319 | "[30.238252990024396, 8.582047881929046]\n"
320 | ]
321 | }
322 | ],
323 | "source": [
324 | "w = descent(w,w,.1)\n",
325 | "print(w)"
326 | ]
327 | },
328 | {
329 | "cell_type": "markdown",
330 | "metadata": {},
331 | "source": [
332 | "## Visualizing the Result"
333 | ]
334 | },
335 | {
336 | "cell_type": "code",
337 | "execution_count": 24,
338 | "metadata": {},
339 | "outputs": [
340 | {
341 | "data": {
342 | "image/png": "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\n",
343 | "text/plain": [
344 | ""
345 | ]
346 | },
347 | "metadata": {},
348 | "output_type": "display_data"
349 | }
350 | ],
351 | "source": [
352 | "def graph(formula, x_range): \n",
353 | " x = np.array(x_range) \n",
354 | " y = formula(x) \n",
355 | " plt.plot(x, y) \n",
356 | " \n",
357 | "def my_formula(x):\n",
358 | " return w[0]+w[1]*x\n",
359 | "\n",
360 | "plt.scatter(X,y, c = \"red\",alpha=.5, marker = 'o')\n",
361 | "graph(my_formula, range(-5,5))\n",
362 | "plt.xlabel('X')\n",
363 | "plt.ylabel('Y')\n",
364 | "plt.show()"
365 | ]
366 | }
367 | ],
368 | "metadata": {
369 | "kernelspec": {
370 | "display_name": "Python 3",
371 | "language": "python",
372 | "name": "python3"
373 | },
374 | "language_info": {
375 | "codemirror_mode": {
376 | "name": "ipython",
377 | "version": 3
378 | },
379 | "file_extension": ".py",
380 | "mimetype": "text/x-python",
381 | "name": "python",
382 | "nbconvert_exporter": "python",
383 | "pygments_lexer": "ipython3",
384 | "version": "3.6.5"
385 | }
386 | },
387 | "nbformat": 4,
388 | "nbformat_minor": 2
389 | }
390 |
--------------------------------------------------------------------------------
/logistic regression.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Creating Fake Data"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 26,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "from sklearn.datasets.samples_generator import make_blobs\n",
17 | "X, Y = make_blobs(n_samples=200, centers=2, n_features=2, cluster_std=5, random_state=11)\n",
18 | "m = 200"
19 | ]
20 | },
21 | {
22 | "cell_type": "markdown",
23 | "metadata": {},
24 | "source": [
25 | "## Visualizing the Data"
26 | ]
27 | },
28 | {
29 | "cell_type": "code",
30 | "execution_count": 28,
31 | "metadata": {},
32 | "outputs": [
33 | {
34 | "data": {
35 | "image/png": "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\n",
36 | "text/plain": [
37 | ""
38 | ]
39 | },
40 | "metadata": {},
41 | "output_type": "display_data"
42 | }
43 | ],
44 | "source": [
45 | "from matplotlib import pyplot as plt\n",
46 | "from pandas import DataFrame \n",
47 | "df = DataFrame(dict(x=X[:,0], y=X[:,1], label=Y))\n",
48 | "colors = {0:'blue', 1:'orange'}\n",
49 | "fig, ax = plt.subplots()\n",
50 | "grouped = df.groupby('label')\n",
51 | "for key, group in grouped:\n",
52 | " group.plot(ax=ax, kind='scatter', x='x', y='y', label=key, color=colors[key])\n",
53 | "plt.xlabel('X_0')\n",
54 | "plt.ylabel('X_1')\n",
55 | "plt.show()"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "metadata": {},
61 | "source": [
62 | "## Logistic Model"
63 | ]
64 | },
65 | {
66 | "cell_type": "code",
67 | "execution_count": 6,
68 | "metadata": {},
69 | "outputs": [],
70 | "source": [
71 | "import numpy as np\n",
72 | "def sigmoid(z):\n",
73 | " return 1 / (1 + np.exp(-z))"
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": 7,
79 | "metadata": {},
80 | "outputs": [],
81 | "source": [
82 | "def hx(w,X):\n",
83 | " z = np.array(w[0] + w[1]*np.array(X[:,0]) + w[2]*np.array(X[:,1]))\n",
84 | " return sigmoid(z)"
85 | ]
86 | },
87 | {
88 | "cell_type": "markdown",
89 | "metadata": {},
90 | "source": [
91 | "## Cost Function - Binary Cross Entropy "
92 | ]
93 | },
94 | {
95 | "cell_type": "code",
96 | "execution_count": 8,
97 | "metadata": {},
98 | "outputs": [],
99 | "source": [
100 | "def cost(w, X, Y):\n",
101 | " y_pred = hx(w,X)\n",
102 | " return -1 * sum(Y*np.log(y_pred) + (1-Y)*np.log(1-y_pred))"
103 | ]
104 | },
105 | {
106 | "cell_type": "markdown",
107 | "metadata": {},
108 | "source": [
109 | "## Gradient Descent"
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": 9,
115 | "metadata": {},
116 | "outputs": [],
117 | "source": [
118 | "def grad(w, X, Y):\n",
119 | " y_pred = hx(w,X)\n",
120 | " g = [0]*3\n",
121 | " g[0] = -1 * sum(Y*(1-y_pred) - (1-Y)*y_pred)\n",
122 | " g[1] = -1 * sum(Y*(1-y_pred)*X[:,0] - (1-Y)*y_pred*X[:,0])\n",
123 | " g[2] = -1 * sum(Y*(1-y_pred)*X[:,1] - (1-Y)*y_pred*X[:,1])\n",
124 | " return g"
125 | ]
126 | },
127 | {
128 | "cell_type": "code",
129 | "execution_count": 37,
130 | "metadata": {},
131 | "outputs": [],
132 | "source": [
133 | "def descent(w_new, w_prev, lr):\n",
134 | " print(w_prev)\n",
135 | " print(cost(w_prev, X, Y))\n",
136 | " j=0\n",
137 | " while True:\n",
138 | " w_prev = w_new\n",
139 | " w0 = w_prev[0] - lr*grad(w_prev, X, Y)[0]\n",
140 | " w1 = w_prev[1] - lr*grad(w_prev, X, Y)[1]\n",
141 | " w2 = w_prev[2] - lr*grad(w_prev, X, Y)[2]\n",
142 | " w_new = [w0, w1, w2]\n",
143 | " print(w_new)\n",
144 | " print(cost(w_new, X, Y))\n",
145 | " if (w_new[0]-w_prev[0])**2 + (w_new[1]-w_prev[1])**2 + (w_new[2]-w_prev[2])**2 100: \n",
149 | " return w_new\n",
150 | " j+=1"
151 | ]
152 | },
153 | {
154 | "cell_type": "markdown",
155 | "metadata": {},
156 | "source": [
157 | "## Initializing Parameters"
158 | ]
159 | },
160 | {
161 | "cell_type": "code",
162 | "execution_count": 38,
163 | "metadata": {},
164 | "outputs": [],
165 | "source": [
166 | "w=[1,1,1] "
167 | ]
168 | },
169 | {
170 | "cell_type": "markdown",
171 | "metadata": {},
172 | "source": [
173 | "## Training the Model"
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": 39,
179 | "metadata": {},
180 | "outputs": [
181 | {
182 | "name": "stdout",
183 | "output_type": "stream",
184 | "text": [
185 | "[1, 1, 1]\n",
186 | "126.96627984087802\n",
187 | "[1.2539422898588644, -0.5512710240837779, 1.1843328109648115]\n",
188 | "112.81815690482537\n",
189 | "[1.2400289717256012, 1.3365539538600526, 1.3041857280167006]\n",
190 | "168.5749357223354\n",
191 | "[1.496038556709955, -0.26091766794801896, 1.498589948744304]\n",
192 | "75.77036936925771\n",
193 | "[1.552998152697941, 0.5805338886016641, 1.2059963033700993]\n",
194 | "67.88063552779857\n",
195 | "[1.7129970823802407, -0.12884219161477717, 0.9205552719943874]\n",
196 | "49.631255078140065\n",
197 | "[1.721522374547689, 0.8081464107255731, 0.784948881261807]\n",
198 | "84.65164447415044\n",
199 | "[1.9318934810214365, -0.5853214217947893, 0.9260582355386137]\n",
200 | "137.02236299684375\n",
201 | "[1.792209433897121, 2.259519445068961, 1.8717281361304319]\n",
202 | "296.375960910099\n",
203 | "[2.0717704014100984, 0.4671501798576154, 2.2375086018139254]\n",
204 | "96.21982855549399\n",
205 | "[2.2275891867070294, 0.17556932949773574, 1.7757719140648793]\n",
206 | "66.93614685472798\n",
207 | "[2.34635073219192, 0.10042351859759649, 1.3377088708014218]\n",
208 | "47.88369966457564\n",
209 | "[2.420814222298708, 0.2006649466226462, 0.9803329461122527]\n",
210 | "35.74059972551982\n",
211 | "[2.47109414690982, 0.15761477718705647, 0.7206148121331153]\n",
212 | "31.156227520259954\n",
213 | "[2.4669494157236738, 0.33368915465087157, 0.6530382051207929]\n",
214 | "31.825794017269445\n",
215 | "[2.5018185122166057, 0.052068234061564855, 0.5947139224875355]\n",
216 | "37.13648828690444\n",
217 | "[2.4168290256808196, 0.8618663362335011, 0.8721726092434906]\n",
218 | "77.31322559093016\n",
219 | "[2.596954895024072, -0.39576768312727784, 0.9305031886901464]\n",
220 | "97.53803980330012\n",
221 | "[2.4680716616586964, 1.8009384856190926, 1.4733863829082396]\n",
222 | "210.1650208652238\n",
223 | "[2.7256313646387795, 0.10398042243284711, 1.7582377785757068]\n",
224 | "60.930800473556\n",
225 | "[2.8139079434551295, 0.18042029298994794, 1.356581836503274]\n",
226 | "44.87910324512945\n",
227 | "[2.8764378665294585, 0.18788023515027294, 1.0240956114450044]\n",
228 | "35.1115767203633\n",
229 | "[2.9004091563475756, 0.25373283853477424, 0.8052448292395792]\n",
230 | "31.203934623682823\n",
231 | "[2.905564316215357, 0.23573784244902107, 0.6972405539065145]\n",
232 | "30.64594404630533\n",
233 | "[2.884978695284491, 0.3156866373830539, 0.7013654663287641]\n",
234 | "30.87299094573297\n",
235 | "[2.8899757309235032, 0.18571374355707734, 0.662108112619276]\n",
236 | "31.58765075793203\n",
237 | "[2.8456086105455767, 0.44695414312741255, 0.7472822400464028]\n",
238 | "34.997339236852504\n",
239 | "[2.8946903864992204, 0.0311385451581056, 0.652724208526957]\n",
240 | "41.16553917784135\n",
241 | "[2.78333314375564, 1.0205125031757631, 0.9858502424130702]\n",
242 | "90.41042650497221\n",
243 | "[2.970171901127539, -0.2925927602835001, 1.054289078329687]\n",
244 | "77.28627608547319\n",
245 | "[2.8765338440725268, 1.3870481637289969, 1.2593201244024514]\n",
246 | "137.884699579421\n",
247 | "[3.096205693561861, -0.09815951484676533, 1.3875700666825428]\n",
248 | "55.28433950652438\n",
249 | "[3.091222620686947, 0.691357878366354, 1.1851902704372872]\n",
250 | "54.56897648020144\n",
251 | "[3.197031648206172, 0.04853253754001363, 0.9522363399023503]\n",
252 | "38.879877723561194\n",
253 | "[3.152849114551307, 0.6705086356955698, 0.9042855300104767]\n",
254 | "47.42326651334623\n",
255 | "[3.249401718635574, -0.05586144519042935, 0.7968950006624693]\n",
256 | "50.77734982683568\n",
257 | "[3.1265348460183477, 1.2297186855362119, 1.1081714720550426]\n",
258 | "111.36985561835434\n",
259 | "[3.326563756861511, -0.1791741101134301, 1.2218462740483753]\n",
260 | "62.108694704750796\n",
261 | "[3.269128921912794, 1.0293263482837012, 1.2008084141382773]\n",
262 | "82.99082598516479\n",
263 | "[3.433600163161756, -0.10416961202267583, 1.1426909126167342]\n",
264 | "53.969099415361306\n",
265 | "[3.372434392083106, 0.9606133194736919, 1.1258764505552485]\n",
266 | "73.24867011604414\n",
267 | "[3.5227671344926526, -0.10541269443776047, 1.0639829014706683]\n",
268 | "54.95877911862518\n",
269 | "[3.4402314176940667, 1.0678781146572354, 1.1359656744505753]\n",
270 | "84.39209613357035\n",
271 | "[3.6053162123525917, -0.1094419475498285, 1.1193961332548408]\n",
272 | "55.78053131843188\n",
273 | "[3.5284998867311446, 1.035838685329749, 1.1603344516799623]\n",
274 | "79.31512100875807\n",
275 | "[3.6850794814765253, -0.0823331021711422, 1.117327385696941]\n",
276 | "53.365825253435844\n",
277 | "[3.6094245208717335, 0.990136688364013, 1.1479057502919368]\n",
278 | "73.00073094363131\n",
279 | "[3.7550639240710013, -0.06190456364194685, 1.0874826200950347]\n",
280 | "51.85370536629623\n",
281 | "[3.6740149106228186, 0.9863883933259856, 1.1383256238195103]\n",
282 | "71.6077027550773\n",
283 | "[3.816365454730692, -0.053415680920452235, 1.079972647866281]\n",
284 | "51.512482717018116\n",
285 | "[3.7321415001226725, 0.9874518828741854, 1.1419582058166857]\n",
286 | "70.91147940312463\n",
287 | "[3.8721953817202945, -0.040975086743274325, 1.0817922008147334]\n",
288 | "50.68840558905084\n",
289 | "[3.7880511473342113, 0.9676622239349191, 1.1410140920986547]\n",
290 | "68.11602429098141\n",
291 | "[3.9218160093807857, -0.02032252700940551, 1.069864113475001]\n",
292 | "49.12965800771219\n",
293 | "[3.8372555826614154, 0.9397003151318558, 1.1301065005574003]\n",
294 | "64.66526827228455\n",
295 | "[3.963079147188273, 0.0015189750142303726, 1.048002481200122]\n",
296 | "47.55953959619178\n",
297 | "[3.8768575558853064, 0.9161026456599739, 1.116464165382025]\n",
298 | "61.870753988367085\n",
299 | "[3.995752432150913, 0.019597576030487285, 1.027414752411626]\n",
300 | "46.36190019402692\n",
301 | "[3.907745460549524, 0.89829389197684, 1.1055063163003485]\n",
302 | "59.82357707095895\n",
303 | "[4.0211666051250194, 0.03440304270300665, 1.0117153695411087]\n",
304 | "45.42762114954028\n",
305 | "[3.932061436494771, 0.8820448670623741, 1.0967233693735197]\n",
306 | "58.07265242127726\n",
307 | "[4.040538211472588, 0.0486222507940266, 0.9980600115598323]\n",
308 | "44.528626105329884\n",
309 | "[3.95104075816509, 0.8635822178845587, 1.087464778932447]\n",
310 | "56.25191093140636\n",
311 | "[4.0542064633885655, 0.06390897971924736, 0.9830845369826282]\n",
312 | "43.560297250359895\n",
313 | "[3.9647146116297285, 0.8419896969170714, 1.0762339319145042]\n",
314 | "54.28859760963312\n",
315 | "[4.061974777022511, 0.08010117719043697, 0.9658476947904583]\n",
316 | "42.55609321933739\n",
317 | "[3.9726570293297416, 0.8185528342778258, 1.0632653646122094]\n",
318 | "52.30757518813522\n",
319 | "[4.063741047353516, 0.09591304118161548, 0.9474917553090927]\n",
320 | "41.60869408164448\n",
321 | "[3.9746698824165576, 0.7955306511635729, 1.0497944865210715]\n",
322 | "50.49160062072334\n",
323 | "[4.0598875620346835, 0.10973094543337403, 0.929938489713735]\n",
324 | "40.807102034142616\n",
325 | "[3.9710681877912237, 0.7754202550430537, 1.0373138237663093]\n",
326 | "49.006821287773285\n",
327 | "[4.051367062032833, 0.120083598318384, 0.9149680408447317]\n",
328 | "40.21376802733146\n",
329 | "[3.9626934207233138, 0.7605664236412619, 1.027175552319945]\n",
330 | "47.97972673492794\n",
331 | "[4.03960146305846, 0.1258626202000106, 0.9038701158750538]\n",
332 | "39.8665848590012\n",
333 | "[3.9508175989838605, 0.7529117846030396, 1.0204483002710898]\n",
334 | "47.49986495259877\n",
335 | "[4.026319016314264, 0.12633822832598507, 0.8975122703008471]\n",
336 | "39.79309105387893\n",
337 | "[3.937022647315148, 0.7539702241394387, 1.0179583095352271]\n",
338 | "47.64232237902202\n",
339 | "[4.013431600037268, 0.12097838008325779, 0.8966869188055052]\n",
340 | "40.03060914399324\n",
341 | "[3.9231193858382776, 0.7650499798316024, 1.0204780871163988]\n",
342 | "48.50370516914084\n",
343 | "[4.0030116224672625, 0.10920033650354244, 0.9025652832558652]\n",
344 | "40.647028942768124\n",
345 | "[3.911168807082645, 0.7874617085157639, 1.0289496414232508]\n",
346 | "50.233655133405684\n",
347 | "[3.9973475854531766, 0.09037455328475408, 0.9170124097333662]\n",
348 | "41.74920834355003\n",
349 | "[3.9036347048532614, 0.8219989928942072, 1.0444815131818708]\n",
350 | "53.00756665023323\n",
351 | "[3.998896442510712, 0.06491278493707686, 0.9421306486550264]\n",
352 | "43.414481126056494\n",
353 | "[3.903578932273919, 0.8658652317559935, 1.0673333907773224]\n",
354 | "56.743118405663786\n",
355 | "[4.009605120891904, 0.03790132000571389, 0.9771595777097101]\n",
356 | "45.367245465512056\n",
357 | "[3.9142374607656074, 0.9053571447819756, 1.0933903406414625]\n",
358 | "60.26445149748922\n",
359 | "[4.028982704706953, 0.022311918251399665, 1.0115367561804436]\n",
360 | "46.56452396428107\n",
361 | "[3.936118279261484, 0.9161216408470005, 1.1107981056735687]\n",
362 | "61.119030592288695\n",
363 | "[4.05221859760455, 0.029367074818002936, 1.0249045662087954]\n",
364 | "46.03001820966252\n",
365 | "[3.962804479787527, 0.890313219168536, 1.1082732172211933]\n",
366 | "58.54793332826261\n",
367 | "[4.071694739617031, 0.05576987084898566, 1.0076561457699287]\n",
368 | "44.146310350361176\n",
369 | "[3.9843650919995444, 0.8441134205516451, 1.087132296857637]\n",
370 | "54.38313567139385\n",
371 | "[4.081221437775141, 0.08935078570508614, 0.9713207459960232]\n",
372 | "42.00179619891018\n",
373 | "[3.9945804561228613, 0.7946114356824799, 1.058305857789166]\n",
374 | "50.363531876210516\n",
375 | "[4.078719695444127, 0.11976411937445264, 0.9330027012706759]\n",
376 | "40.284159514532284\n",
377 | "[3.992398365094767, 0.7520453654158086, 1.0315755035230465]\n",
378 | "47.27452627208367\n",
379 | "[4.065870596044042, 0.14186053507189011, 0.9025860178561832]\n",
380 | "39.138492702670455\n",
381 | "[3.9799787694173245, 0.7210735715432988, 1.0111931600659616]\n",
382 | "45.255334753917104\n",
383 | "[4.0460976445817955, 0.15448991706397763, 0.8819752531296552]\n",
384 | "38.48142071458852\n",
385 | "[3.960514974560398, 0.7030948526309135, 0.9977984989102618]\n",
386 | "44.1983732970012\n",
387 | "[4.022890960756249, 0.1583065776331426, 0.8696992149881329]\n",
388 | "38.21770810120381\n",
389 | "[3.937085053426291, 0.6982103483166531, 0.9909832248890901]\n",
390 | "43.98944447469072\n",
391 | "[3.937085053426291, 0.6982103483166531, 0.9909832248890901]\n"
392 | ]
393 | }
394 | ],
395 | "source": [
396 | "w = descent(w,w,.0099)\n",
397 | "print(w)"
398 | ]
399 | },
400 | {
401 | "cell_type": "markdown",
402 | "metadata": {},
403 | "source": [
404 | "## Visualizing the Result"
405 | ]
406 | },
407 | {
408 | "cell_type": "code",
409 | "execution_count": 40,
410 | "metadata": {},
411 | "outputs": [
412 | {
413 | "data": {
414 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYsAAAELCAYAAAAoUKpTAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJztnXmYVOWZ6H9f7w1NszZrd3WDIiKg7I1rFFCMMXFJNEAzVyOJeidxkswkcclMkjveJM5kIblxIprBbNAQjQsGFRWMMol20w2IgIqi9AYIxb51N718949TJdXVtdc5dc6pen/PU09VnapzzntOdX/v972r0lojCIIgCJHIslsAQRAEwfmIshAEQRCiIspCEARBiIooC0EQBCEqoiwEQRCEqIiyEARBEKIiykIQBEGIiigLQRAEISqiLARBEISo5NgtgFkMGTJEV1RU2C2GIAiCq9i0adNBrXVJtO+ljbKoqKigvr7ebjEEQRBchVKqMZbviRlKEARBiIooC0EQBCEqoiwEQRCEqKSNz0IQBMEuOjo6aGlpoa2tzW5RwlJQUEBpaSm5ubkJ7S/KQhAEIUlaWlro168fFRUVKKXsFqcXWmsOHTpES0sLo0ePTugYYoYSBEFIkra2NgYPHuxIRQGglGLw4MFJrXxsVxZKqceVUgeUUtsDtv1AKbVHKfWW73GdnTIKgiBEw6mKwk+y8tmuLIDfAdeG2L5Eaz3Z93ghxTIJTqTNC4fqjGdBEFKK7cpCa70BOGy3HILDaVgJq8vh1auN54aVdkskCI5i7dq1jBs3jnPPPZeHHnrI9OPbriwi8DWl1Ns+M9XAUF9QSt2plKpXStV7vTLbTFvavFC7GLpaoeOY8Vy7WFYYguCjq6uLr371q7z44ou88847rFy5knfeecfUczhVWTwCnANMBvYBPwv1Ja31Y1rr6Vrr6SUlUUubCG7lVANk5fXclpVrbBcEl+L1Ql2d8ZwsGzdu5Nxzz2XMmDHk5eUxf/58Vq9enfyBA3CkstBa79dad2mtu4HfADPtlkmwkb4V0H2m57buDmO7ILiQlSuhvByuvtp4XpmkVXXPnj2UlZV98r60tJQ9e/YkKWVPHKkslFIjAt7eBGwP910hAygogcplkF0IucXGc+UyY3smIw5/V+L1wuLF0NoKx44Zz4sXJ7fC0Fr32mZ2dJbtSXlKqZXAlcAQpVQL8H3gSqXUZEADDcBdtgkoOIOKBTB8rmF66lshiqJhpeG3ycozVl2Vy4x7JDiehgbIyzOUhJ/cXGN7otb00tJSmpubP3nf0tLCyJEjk5IzGNuVhdY61F/4spQLIjifghJREtDT4d/lG3FqFxvKVO6P46mogDNBVtWODmN7osyYMYMPPviA3bt3M2rUKFatWkV1dXUyYvbCkWYoQRAiIA5/V1NSAsuWQWEhFBcbz8uWJb6qAMjJyeHhhx9m3rx5jB8/nltvvZUJEyaYJzQOWFkIghAn4vB3PQsWwNy5humpoiI5ReHnuuuu47rrrCt2ISsLQXAb4vBPC0pKYMYMcxRFKpCVhZDZtHntcZone15x+AspRpRFumLXIOgm7Ioo8p9X5RjnnfZLGBsQ8BfrbycOfyGFiLJIRySsMjp2RRQFntdP3d3G89i7UvPbyURCSADxWaQbUkcpNuyKKDrVYKwogqm/Bw783frfTgoyCgkiyiLdkLDK2LAroijUeQF0B7w620hDDcTM304mEkISiLJINySsMjbsiigqKDF8FKHoPgPdrUHbTPztZCKR1txxxx0MHTqUiRMnWnJ8URbphoRVxk7FArihEWavM55T5dcZexfMWAoqt/dnwYP5mMXm/XYykUhrbr/9dtauXWvZ8UVZpCN2DYJupKAEBs9IvTIdexdctxWy8ntuDx7MP1pmnplIJhLOwuRCkFdccQWDBg0y5VihkGiodEXCKp1P//Ew67e+6Kdc6GoHsnqaovxmIrN+S8nPcAYujFgUZSEIdhI4eOcUwdppPT+3wkwkEwl7cWkhSDFDCYLd+E1h/ccbPopAEvFZWNnnQnpoJI9LAw1EWQiCU2jzGj6KQOL1WViZRyE5Gubg0kADURaC4BSSnXGanUcRuIo49i7UfCn1ORrpuJKxKNBgwYIFXHzxxezcuZPS0lKWLTO3LZD4LATBKSQ74/Qrmy4THOSBDtjO08Y23dHzO2Y73yPJ4BIncMxYEGiwMtlG3lGwfWWhlHpcKXVAKbU9YNsgpdQrSqkPfM8D7ZRREFJCsjNOs8wbwSsU3dFbUSR67ERlSMdsc7vCthPEdmUB/A64NmjbfcB6rfVYYL3vvSV0dWs+8p606vCCEB/J5MiYZd4IZQ4LJivf2hwNlzqB0xnbzVBa6w1KqYqgzTcAV/pe/x54DbjXivO/+t4BvvKHei45ZzCLZpVz9QXDyM12gg4VMpZkQlvNMG+Eq1/lJysfPr3FiN4yG39F3Jwi1zmBtdYopewWIyxaBxceiw+njorDtNb7AHzPQ0N9SSl1p1KqXilV7/Umtjyd4hnAt+eNo/HQaf5xxWYueehVfvbyTvYebY2+syA4kWTNG8ErFJVrzPL9q5VZv7VGUQRGW62dZoQNuyTbvKCggEOHDiU9IFuF1ppDhw5RUFCQ8DGUEy7Ot7JYo7We6Ht/VGs9IODzI1rriH6L6dOn6/r6+oRl6OrWvP7+AVbUNPHqzgMoYPb5Q6maVc4VY0vIznLujEEQLCGw7wVYm/Xd5jUURaBzPrsQrt0EnScdn23e0dFBS0sLbW1tdosSloKCAkpLS8nN7VmTTCm1SWs9Pdr+tpuhwrBfKTVCa71PKTUCOGD1CbOzFLPPH8bs84fRcuQ0qzY2s6qumXXv1lE6sJCFlR5unV7GkKL86AcThHQg2Bxm5WAdLpKr86SxSnI4ubm5jB492m4xLMWpZqjngNt8r28DVqfy5KUD+/CteeN4477ZPLxwCmUD+/Cfa3dy8Y/Xc8/KLdR+5NzlZtqSjvH2wllcmqiWSdhuhlJKrcRwZg8B9gPfB54FngA8QBNwi9b6cKTjJGuGisauAydZUdvIU5taON7WydihRVRVerh5WinFBSFKTQvmkc7x9plCLK1cP/mdcw1FIb9zSojVDGW7sjALq5WFn9YzXfzl7b2sqGlka8sxCnOz+dxFI1k0q5xJpf0tP3/GEc6WfUOjo23YQgDxKHvpD55yRFmkgG0tx1hR28jqt/bS2tHFhaX9WVRZzmcvGklhXnZKZUlbDtUZ0TEdx85uyy028hBcYMvOeETZO55YlYVTfRauYFJpfx76/IXUfncO/+dzE2g908V3nnqbmT9axw+e28GuAyfsFtH9pNqWnWrfSLqfT5Lr0ganRkO5iuKCXG67pIL/dXE5G3cfZkVtEytqG/ndGw1Ujh7EolnlzJswnLwc0c1x44/5D7ZlWzErTbVvJN3PB+K4TiPEDGURB0+282R9C9UbG2k+3MqQojxunV7Ggpkeygb1sVs892G1LTvV5pJ0P18g4rh2NG7Ps3A9Q4ry+d9XnsNdV4xhwwdeltc0sfT1D3nk9Q+5atxQqio9XDluqCT7xUoiJTDiUTBmVmwNJUNOUc/ksnjOZ4aitOr6YiFSCRJxaLsGURYWk5WluHLcUK4cN5S9R1tZtbGJlXXNLP59PaMGFLJgZhm3zihjaL/E0/CFEMRrcrHCXOKXQWP01c4uNLZXLjMGz1jOZ5bpyG5zUChlLyHRrkLMUDbQ0dXNK+/sZ0VtI3/fdYicLMW8icOpqvRw8ZjBqS1Glo4zu0RNLmaaS0LJECzLx+sin89s01Ey12f234lESTkGMUM5mNzsLK6bNILrJo3gQ+9Jqmub+POmFp5/ex9jSvpSVVnOF6aW0r+Pxcl+6TqzS9TkYmZDmlAyBMsS7XynGoxVSSBaR7+OcAN7LNcXal8r/k7sNIsJCSErC4fQ1tHFmrf3sbymkbeaj5Kfk8Vnfcl+F5X2N3+1kU4zu+ABzgnXFsvKIposx96F5y/ovf0z74Sv+prMwB5q3+FzrbmXoe5PVgHc2OS+vz+XI3kWLqMgN5svTCvl2a9eypp7LuPmqaW8sG0fN/7X3/nsw39j5cYmTp/pNO+E6RL/HljWenW58d6iHsdxEShDls8flV0YnyydJ8/6OfxkFxrbQ5FMd7lw+x7eYs3fycfroDv477nb2C44EjFDOZCJo/rz45sn8cB15/Pslj0sr2ni/qe38aPn3+WmqaNYNKuc84b1S+4kdjs8zSBwgPPPUGsXG7NhC3ocx02gDMHRULEQ7rcItz0Z0064fRXm/534f7fgVq3dZ87+frK6cByysnAw/Qpy+YeLK1j7jcv5890XM2f8UFZtbOaaJRu4dembrH5rD+2dXYkdPNTse+oSY9BwS2XXaKsjs3ocJ5P17Jeh//iessRyzHhXSMlMAMLtO3CK+au0SG1b3bi6zRDEZ+EyDp86w5P1zVRvbKLx0GkG9c3jlumlVM0sxzM4gWQ/v73/8GbY/E13ObtT4ZsI5wNIJjooXr9CPOdKJuIp0r6JXG+4fWL158R6znSM6EshUkgwzenu1vxt10GW1zSy7t39aOCKsSVUVXqYff5QcuLpI+4Eh3CiWJUd3OY17PUbboDugO5n/hVYooo1Ffc6mcHTrIE3mkL8JAdFG/c3MAelYkHsCjVdI/pSiCiLDGLfsVZfZ78m9h9vZ0T/AubP8DB/ZhnDimNI9nN7ZVczZ5ZtXvjgUdjxQ8jKhs5TPT/PKTKUUnf72W3xDPZuv9exEKtCDJfdHs/+bp3kOAjJs8ggRvQv5JtXn8fXZp/L+nf3s6K2iSXr3uf/vfoB11wwjKrKci45ZzBZ4UqLuN3ZHa0USKzKxD9L9Q8+3SG+093hm8UGKIt48gPcfq9jIZKj3f+5/7cIdc9iddRLrkZKcbSyUEo1ACeALqAzFu2XyeRmZ3HtxBFcO3EEDQdPUb2xiSfrm3lx+8eMHtKXqkoPX5hWyoA+Qc7FVFZ2TTWxmikCI6tCkd0X6D5rggoknsHeLfc6mdVaOIV4eDOs+1T03yJWhZoJitdBONoM5VMW07XWB6N9N5PNUJFo6+jixe37WF7TxKbGI+TlZHH9hSNYNKucKWUDeib7pZujMB4zRSjzUOA+VzxrRAYVlJjjJ3HyvTbDDxB8j/xKNlaTUaz3WCraJk1a+CxEWZjLu/uOs6K2kWc27+HUmS4uGFFM1SwPN04eRd98Ry8yEyMe/0C4CJ2sApj1eO8ByImDvRkymekHCJTnVEP438L/eaIVaZ34W7iIdFEWu4EjGBVyHtVaPxbuu6IsYudkeyer3zKS/d7dd5yi/BxumjKKqlkezh9ebLd45hHvwNewEmpuDzBtZMOM/4Kxd6VC2rMkMvgluhoIPpdVDvhwv0UykWWCKaSLshiptd6rlBoKvALco7XeEPD5ncCdAB6PZ1pjY6NNkroTrTVbmo+yvKaRNW/v40xnN9PLB1I1y8OnJ46gIDcN+ojHY6Zo88Kznt6hsqmMrvHLq3KMwXPaL6Mrq6Sr7KagFlSP8yVomgqHrCySIi2URSBKqR8AJ7XWPw31uawskuPIqTM8tbmFFbVN7D54ioF9crllehkLZ3qoGNI3voM57Z83VnnsDmsNZwqbsTSywkhE7kgKJlrp9GSI1TQV6/2WPIukcX3orFKqL5CltT7he30N8O82i5W2DOybx5cvH8Mdl47mjQ8PsaK2kWV/281jGz7i8rFDqKosZ+74GJL9nPjPG2uXPbuja041GCuKYDZ9HcpuNrfMR6SwU6vqaoVS2snc70i1wZwwSUkzHKssgGHAM75onRygWmu91l6R0p+sLMVlY4dw2dgh7D/e9kmy393LNzGsOJ/5MzwsmOlheP8QyX5u/+e1O6w11KAP0XMHEpE7moJJpI1tJMJNIpK535JnkVJcY4aKhpihrKOzq5tX3zvAitomNnzgJUsp5o4fSlVlOZedO+Rssp/dZhyzsNOM9sGjUHd3z22x2vHjlTtVYafRfCqJ3m/J4DYF15uhBOeQk53FNROGc82E4TQdOk31xiaeqG/mpR37KR/ch4UzPdwyvYxBdptxzMLsWXU8+H0Tm75uDOK6K/JsO3igjUfuVJVxj7YCSPR+270SzDBkZSEkRHtnF2u3f8yKmiY2NhwmLyeLz0waQZXnfaY13o7KliSppIg02463UrDdAQdWrwDsvj6Xk3bRUNEQZWEf7+8/wYqaRp7evIcT7Z2cP7SQqguzuXH6OPoNGG63eOlFYGht54men4UagJ0ScJCoyUsUgeWIshBSzqn2Tv6ydS/LaxvZvuc4ffOyuWHKKKoqPUwY2d9u8SLjhEEpmgyR+kBAb/+QFTP6QBkhvnuWsE/FQZF1aYj4LISU0zc/h/kzPXxxRhlbW46xvKaRpza1UF3bxBTPAKoqy7n+Qgcm+zlhUIolGS+U7T+QYP+Q2dFCgfep8zQoZSifWO9ZPL4Jt0fWpSHSVlUwHaUUk8sG8NNbLqL2gTn82/UXcKy1g289uZVZP17P/13zDrsPnop8kGRamcZD4KDUccx4rl2c2taygTJ0njDKn9fdbURGBRIutDanKHS7UzMDDoLvk+4wjp3MPYv0G0drmSukHFEWgqUM6JPH4stGs/6fP0X1Vyq59Jwh/O6NBq766WtU/XcNL27bR0dXUOOIhpWG+eTVq43nhpXWCeiEQSlSMl7gQBqqJ/eMpTDnVcO0FDyzj7eHdzQZw/XNhvjvWbTf2KrIulRNQtIQ8VkIKefA8TaeqG9m5cZm9hxtZWi/fObPKGP+TA8jC05aa2cPFVlkd6x+mxeeLevZUAkgpx/MWR+6Qq6VvoJwx4jkL4nnnsV6z83OA3GCudGBiINbcDxd3ZrXdh5geU0jr73vRQGzz8ljEQ9yReHfyFK+v81kEvtiGSA+8RdkG4OS31+QSqd3Msl4obBC9sDBu7PV57MoiH8gj7d0vBnX4YRJgUMRB7fgeLKzFHPGD2PO+GE0Hz7Nyo1NPFHXyLpT91KWdxsLB73IrYNeYXC2CXb2SE7SigXQcdyXCJdn5C4c3Q4fLUvdLLRHMl4e6M7ETUZWzaCDk/ggsYE8HhOTWQmSUhokaWRlITiKM53dvPTaUyyv2U3tyQnkqQ6uPQcWzbmCGRUDe3b2i0asM9hoJhZI3Sw02Zm0W2bQqe5w55b7YgOyshBcSV5OFp+dewufvczLrqZdLN+Ry1NbD/Hco29y3rAiqirLuWnqKIoLcqMfLNYZbLSQVEjdLDTZmbRbZtCpKjXiR0qDJI2sLATH03qmi79s3cuK2ka2thyjMDebGyaPpKqynEmlUZL9YpnBHnsXXpzS28EciKws0gMnJF86DHFwC2nJNl+y3+qte2jr6Oai0v5UVZbz2YtGUpgXJtkv0gDhVyYa6G41BlaAMYt9PosU1rgyy9eQahOP4GpEWQhpzbHWDp7xdfb74MBJigty+Py0UqoqPZw7tF9sBwk1C8/Kh09vgf7jUzsLNXNF0OaFI1sMBThoisygQVYUERCfhZDW9C/M5fZLR3PbJRVs3H2Y5bVNLK9p5Ld/b2DWmEFUVZYzb8Jw8nIi5J2Gsu9n50PnSeN1KkuVm+VrCF6dTF0Cg6Zm1iAZrBgkv8IURFkIrkYpReWYwVSOGczBkxfwRH0z1bVN3LNyC0OK8vnijFLmz/BQNqhP751DOcC72o3yGanGjIzlUKHCdXcbyX3+UNx0HyRDKcvN35QaUybg6HIfSqlrlVI7lVK7lFL32S2P4GyGFOXzj1eey4ZvX8VvvzSDyWX9eeS1D7niJ3/ljt/V8ep7++nqDjC7BpbD8PsqyIK106wtMRIKM0pzhCvJ0XnCnppXqSZUna9NX+9dSkVqTCWEY30WSqls4H3gaqAFqAMWaK3fCfV98VkIodhztJVVG5tYVdeM90Q7owYUsrDSw63Tyyjpl298KVQ0lJURRLE0NkrEbBRvCfN0I1ReTU6RsUJL1W/rQmL1WTh5ZTET2KW1/khrfQZYBdxgs0yCyxg1oJB/uWYcb9w3m19XTaV8cB9+8tJOLnloPV+t3sybHx5Cd5wwylYEYtXsM1oBvYISYzBPps1odqFhegrGjS1u4yGUKU93GeVbzCimmOE42WcxCmgOeN8CVNoki+Bm2rzknmrgurEVXDdpFh96T1Jd28SfN7Xw/Nv7OGdIAVX5c/n8gLX0z/aVTrdiYI1QfsR7ooSGBqiogJJkxrHAZLdP2q5mSBJauMS7igVQdrNEQyWJk81QtwDztNZf9r3/B2Cm1vqegO/cCdwJ4PF4pjU2Ntoiq+BgIkTCtHV0sebtfSyvaeSt5qMUqHbm9XuThQPW0jngAS5dGOQMTsBE5PVyVglkhS4/8lLHOm768gzy8uDMGVi2DBbE64cOJ1smhoxm4jUngevzLJRSFwM/0FrP872/H0Br/eNQ3xefhdCLNi/62XJUd+TcBa8Xzpl+jH4X7iR33EHI0XTs788PFnmounwkffJyEgq/XLkSFi/mEyWw/L+93Jzd06egswop/6dGmr1n5SkshMbGOFYYEhoqJEE6+CzqgLFKqdFKqTxgPvCczTIJLuKlpxs4fjJ6Y6OGBsg61p+9a2bS9KurOfTyBLJyuvnhK9uo/OF6vv90He+/9v24uul5vYaiaG2FY8eM50VfLuH4+J4RTx+VLOP4mZ5aITfXkCkmUtHpTxoGCTjYZ6G17lRKfQ14CcgGHtda77BZLMFphDE5eL3wlW9U8N5/9HR46q4OVJAvoqLCmPkD6DO5nNxSQdd75az++xGe39nIyk17+X3XEmb23UbVoBe5tv8b5OdGTphraDBWFK0Bi5rcXNjZvoAZN5wtoFd8ouSTc/vp6DBkigmTkvl6mMsCd5NVi+DDySsLtNYvaK3P01qfo7X+od3yCA4jQmRRQwMcP1PCHY8t43R7IcdOF3P6jDGTDx5ES0oMP0FhIRQXG8/LlimunjKIX8yfwpv/PIX7Rv6RjzuG8PXm73DJu7/jP1puofnMiLCiBSogP58ogYCIp9DnjsMEZUIy38qVUF4OV19tPK/030Yn9CcXHINjfRbxIj6LOEgHB2CUWkperzHwtbbCkH5eKkoa2H+igk07SsIOxGFn1wANK+mu+TL/c3IqK7yzWXd8BhrFp84roaqynNnnDyU7q2evDb/PIjfXUBSRHNcRzx2NBAsHer2wZQvceGPPFdAnPpMwDvm0ztXIQFzv4I4XURYxki5mhRgaG8UzWMdEgJLd117Eqo3NrKprYv/xdkb2L2DBTA9fnFHG0OKzORuBSgCSUAhxyBbLBMB/b7Ky4NSpnp8VF8O6dTBjkpQ7zwREWQi9cXivg3Cz61DbD+7xMnBDOdk6eqSTZQM00NHVzfp397Oiton/+eAgOVmKayYMo6qynEvOGfxJZ7/Awbm72wTFlQSBq65Q9IjGknLnaY9UnRV64+AuasFhpv7BNNR2gMWLS5h/8TIeXrSYnPxc8rJDJ52VlMSpJOKcoedmZ3HtxBFcO3EEuw+eorq2kSc3tfDCto8ZM6QvCys9XFleyu235/XwYdx+O8yda40Ci0Yo5ztA375nFdkncqW6o53gWGRlkSF4vdCyy8vkxuh5B3bIFjzTLSyETZtg2rSe2wsKQKmz24b083J+aQPPvFLBkFFJXoNJJrq2ji5e2GYk+21uOkpuVhZHto7kxFsezuwdABirjZdegmuuCXUAa31Koe53QQGsXg1TptijwMKSDv41hyMrC+ETzs7OS/jcRct4/K7F5OQ6pwREuDDTjRt7b88OaoZ38EQJb+8pYfdeGDIqCSFCleKouQPyBsfdQKggN5ubp5Zy89RS3tl7nP94qpG/tu6haFILZ/YXc2JLOafeGUnIf78U+JT8EVjB/pyQiisVhFMI0pvDUcjKIs0JNYssK/Gy9Y0GBpZWOOKfLpmVhf+7cWU8hyKUwxzozu6L7u7m1IRlFF+Y2KDt9UJpRSd55+2h35RG8oaeoLs9h1tnjuIrV5Uzbriv6F+KfUpW+3NiIpxyDFdBN5N6c6SIdMjgFkzAP2sP5Fh7CbuOJFjZ1ALC5RqMH997++OPJ5mXEI5Q+QpAVtcpsnUrOZsW83R1YvkFJSXwu//OofO9co4/cTmH/3QJ04YP47kdzcz7xQa+8MgbPLtlD23HdvfuR2Fh74WSEpgxw0ZFESmPI9N7czgQWVmkGf7YeTDszxB61p70TNwC4omGsmRW7J/lkoXuOkVg1sSx08Vc//N1PP36jITPFyzzkVNn+POmFlbUNtJw6DSD+uRwS9FTLBz4F8rzPzZ2coBPyTIihT/3rcjs3hwpxPLQWaXU1VrrVxLa2QJEWRi+idtvP5s5nJsLv/+98drUfIN0ps0LR7bQ/dqNZAWE5Z4+U8jCR57l+7+YwpSLzR24u7s1b3x4iBW1jby8Yx9dWnF58dssGryWOVffTc6YNP2xopnd/Mpb5RgrikDSWYmmmFQoiyattSehnS0g05VFuNj5ggJoajJe226fdhHH315JzqbFdHTlUpDbBmjaOvpQXHQGNcs6e/n+422seuM9Vtbv4+OT3QwvLmD+zDLmz/AwvH9B9AO4jWh5HH6TVKjeHOKzMAVTlIVSKlyVVwXM1lr3TVA+08l0ZVFXB1dd1Tsbt29f+OtfDdu0EB9PV3t5/GdbeOKeG+iT13b2A7NntSGigTq7uln/3gFW1Dax4X0v2VmKueOHUlVZzmXnDiErqLSIq4k1PDaW70mobdyYFTp7ObAIOBl8fIy2p4JDqKgwEqqC6eqKo4Kp0IObF5Zw1cyB5NXnQ3eAsog3kTHSABYmGignO4t5E4Yzb8JwGg+donpjE0/UNfPSjv1UDO7DwkoPt0wrY2DfEE5gt1FQEtu9jPa9dCll41CirSxeBP5Ta/3XEJ9t0FpfYaVw8ZDpKwsI77MQ/0QSJBvOGmkAi/PYbR1drN3+MStqG6lrOEJeThafmTSCRbM8TPUM/KS0SEbi8FI2TsaUlYXW+tMRPnOMohAMFiwwSkgERkOJfyJJwvV1jmUAitBzm4KSuMuvFORmc+OUUdw4ZRTvfXyc6tomnt68h2csAd6bAAAduklEQVS27OH84f2omlXOTVNGUZSfgbm2Di5lky6YEjqrlHpTa32xCfIkjKwsBEtJxBYerTJutNlwDOc81d7Jc1v3srymkR17j9M3z1AoVZXlXDCyOMGLdSGyskiYVJf7SMMwDUEIIFa7eiDRGhNFWrXEaH/vm5/Dgpke5s8oY2vLMZbXNPpyN5o4b9AAqirL+eIlIyjIze61b1qRzApQiAmzVhabtdZTTZDHf7wfAF8B/CmaD2itX4i0j6wsBEcSS4nvNi8c3mKEjQz0ZVImMUte9sczfOeRPfSZ1Ej2wFMUZuey6JJSFlaWM3qIYwIYrUGioeImHQoJLtFa/9RuIdyII2r+mIjZ15PS+xNLie+P1/VcRVzwQML2d68X7rkrj9bW0Rx+s4ICzyH6T2/icd3Ab/5nN5edO4SqSg9zLxhGbnYaVPsJVg6JrACFmIj416KUKovw2eWBb02TSEiKsP2UXYrZ12PL/Qnoud2LUPWRdvww4b7aPWuBKdqahtC6biqPXDubf7n6PD7ynuR/r9jMpQ+9ys9f3sneo2HKabiBCD3YBfOJFjr7EbAU+LnWutO3bRjwM2Cc1nqGb9tErfV204QyzFC3A8eBeuBftNZHIu3jRjOUFTNmt9SBigWzr8eR9yecE3z8t2HHjxLqqx3pGru6NX997wAraht57X0vCpgzfhhVlR6uGFvinmQ/cWibhllVZ6cB5wBblFKzlVJfBzYCbwKV/i8loiiUUuuUUttDPG4AHvGddzKwD0M5hTrGnUqpeqVUvdfrrgqUVsxwQ1WYzc01tieC12tkhqf61vrPu2WLuddj9v0xhXBO8HPvMga+2euM5xiTy8JV8PUrw+wsxdwLhvHbL81kw7ev4q5PncPmxiPc/ts6rvzpayx9/UMOnWw39xqtIFRVWgsr9AoxOrh9SmIJsBeYpbVusVqwgHNXAGu01hMjfc9NKwurZrhmHjdcm1OrCTxve7uRlR7YjjTtVhZgSZ/reFat7Z1dvLRjPytqGqndfZi87Cw+PWk4VZXlzKhwaLKfrCxMI9aVBVrrsA9gAPAo8BZwDfALYBtGXaiI+ybzAEYEvP4msCraPtOmTdNuYeNGrfv31xrOPoqLje3JUl2tdWGhcbzCQuN9vBw4YOwbKF9hobHdSkKdNzc3+esJxIz7YwmtB7Q+uNF4tvGc7398XH9/9XY98ftrdfm9a/Q1P39d//6N3fp465nUyRUru6u1XlWo9RPFxvNup/yY7gKo1zGMy7H4LH4N/EKf9VlM9m1r1FpbMtdUSv0RwwSlgQbgLq31vkj7yMqi5/GT8YXU1RnmsWMBZvTiYli3zpyChOHkC3feJ5+EgQPdEw3limi0KHkcp8908pete1le08S2Pcfok5fNDZNHUlVZzsRR/W0UPAgJlU0as6rOluowJiel1Fe01r9JQkZTcZOygLPmFif2mLBSmUUybznWTBQHdpnv4iJOE87bLUdZXtPIc1v30tbRzUVlA1hU6eH6C0dSmJfmyX4ZgOX9LJyG25QFOHsGaoUyi0UZOFmJRsM1yi5aGZIwHDvdwdNbWlhe08iH3lMUF+TwhWllVM3ycE5JUQoEF6wgHZLy0p6SEocNIgH4ixKaqcz80UiBg6k/Gsl//HjO6zRlG8v1OYJoZUjC0L9PLl+6dDS3X1JB7e7DLK9p5I81DTz+991cPGYwi2aVc82ENEn2E3ohykIIi9nKrKKiZ2QTGKuH4H4bsZzXieaecNdXVGT4Y5JVaqYpxyTrKCmlmDVmMLPGDMZ7op0n6puprm3iq9WbKemXzxenl7Gg0sOoAYVJCCk4DTFDCSklmpkplgHRyeae4OtbvNi4xmSVmiXK0UTncFe3ZsP7XpbXNPLqzgNGK83zjc5+V5xXQrZbkv0yEPFZCI4lnEKIdUC0OlorXoKvx/++qAimTUteqTlZOYai5chpVm1sZlVdMwdPtlM6sJAFMz3cOr2Mkn75dosnBGFWBrcgmE5JiTGoBw50Xq+hKFpbDSXQ2mq8D5U9Hqs5KxWEysT3X9/Jk+ZkjIfKPM/OtjnzPAKlA/vwrXnjeOO+2fzXwqmUDezDT17aySUPredr1Zup+egQ6TJJzSTEZyE4gnicw/6SFsHmrMBZfSqc3oEKzi/34sUwebKhKIqKzFFqoZTjyZOwebM1Kymz7mFeThafuXAEn7lwBLsOnKS6tok/b2pmzdv7OHdoEVWVHm6eWkr/wlyzRBesJJbMPTc83JTBLfQmkazxAweMrHf/d5Yu1To/X+t+/VKTnR0qE7+w0JChf3/j9de+Zk7G+NKlPc9jVVa9P8PdL7/Z9/B0e6f+U12T/tzDf9Pl967R4/71Bf3tJ9/SW5uPmHsiIWYwI4PbTYjPwt14vfDoo/CjHyWWY/Hoo3D33T23WW3X93ph1ChD1nAUFsKmTcZKIJmZel0dzJkDJ06c3Wa2nybVvpFtLcdYUdvI6rf20trRxaRR/Vk0y8NnLxpJnzwxeqQK8VkIrsFv9//pT40587e/bQxQsSoKrxe+/vXe23NyQtv1zaymG63GXm6uoSiCfTTxUlEBnZ09t5ntp0l1Vd5Jpf156PMXUvvdOfyfz02graOLe5/aRuWP1vOD53aw68CJ6AcRUoYoizTFrvLi8RLs2G5rM1YX8RBqkAPDzh88mJpZGr6hwXA0R8KsAT1a6XEzsCtwoLggl9suqeDlb17BE3ddzFXjhrKitpG5P9/AFx99k79s3cuZzm5rhRCiImu9NMSJCWvhMCPrOdSsG+CXvwwfcRXokJ47N/S5ojl6i4p6yu2noMC4pkDHuxlYkVUfSKTAgVSglGLm6EHMHD2Igycv4Mn6Fqo3NnLPyi0MKcrj1ullLJjpoWxQn9QIJPRAfBZphpl251REFoWSt6AAVq+GKVNiP+/KlXD77Wdnxjk58Ic/9FSS8eRnBCvcJUtg6tSe96KuDj71qdCyB1bJdVpZkmg4Sd7ubs2GD7ysqG1i/bv70cCV55WwaFY5V44bKsl+JmBKPws3PSQaysCsXhlWR8WEOldxsdG/Ii8v/vMeOKB1QUHkaKFYIq4OHND6pZd6HwuMKKuCAq0ffND4XizHS+V9THf2HDmtf/byTj3j/76iy+9doy/58Xr9q/Xv6/3HW+0WzdUQYzSU7YO8WQ9RFgZmNC6yo/mRf5BO9LwbNxqDeTQl6R+8i4qMENelS3t/1rdvb0URKmy1ujp8M6VwSifU9QSHAAuROdPZpV/ctldX/aZGl9+7Rp9z//P6H5dv0n//wKu7u7vtFs91xKosxGeRZphhd7ajempJiWG6SfS8mzf3DCuF0M7ZBQvg+HEjeiovD775TcMUNXfuWX9GLPgzzBsbjUeg2cZvwsrKMhz2gQReT2C4sBv8S04hNzuLayeO4NqJI9h98BTVtY08uamF57ftY8yQviys9PCFaaUM6BMi6kFIGPFZpCnJ2J3D+RGamqy1YSfqbwm1H8DSpXDXXbGd49ln4dZbe/oz/J+FUyCh/B3hZAm+nnXr4I47eisTJ9d8cjJtHV28sG0fy2sa2dx0lPycLK6/cCSLZnmYXDbAmX3EHYLj8yyUUrcopXYopbqVUtODPrtfKbVLKbVTKTXPLhndTKj6S36ihdX6Vye5AVUYuruNAS4ZYj1vYHjokiWG0osUAhwqdLZfP8MhHct3/dcZHDbqVyJLlxrKMphQK5dwYbx9+54NdwVj5RGsKPyyOLXmk1lYEdZdkJvNzVNLefofL+WFf7qcz08r5cXt+7jp129w/a/+RnVtE6faQ4TMCbETi63KigcwHhgHvAZMD9h+AbAVyAdGAx8C2dGOJz6L2IjV4WqW78Nvi4/H0evfb+lS82WN9N1w/gf/fg8+GN4/4b/OcMd/6aWz8oQKQvA/8vLS23eRSof/8dYz+g9vNuh5S17X5feu0RO+t1b/6zPb9Hv7jlt3UheCWxzcIZTF/cD9Ae9fAi6OdhxRFtGJZ1BNNKoq3ECfmxuf4olXWUUa6OP5bjRnc/DnoQa/aLKEujb/Izc3fZWFHYETWmvd3d2t6xsO6W+s2qLHPvCCLr93jf78r/+un9ncots6Oq09uQuIVVk40cE9CqgJeN/i2yYkSTyO60Syef2O3Zycs87mcLb7SI5rrxdeeKF3dnSkfeJJWIv03Whd+gI/D5fkF8rpHXyMZcvgS1+C9vaenxUWOrANq0nY1XZWKcW08kFMKx/Ev11/AX/e1MyK2ia+8ae3+Pc1edwyvZSFMz2UD+5rnRBpgKXKQim1Dhge4qPvaq1Xh9stxLaQXnil1J3AnQAejychGTOJeBRAvFFVgQNnLIQ7r1/haN3bph9NWcXTBtaMlrGRBr9otaAWLDBKmU+Z0lNh2NWXIxU4oQ/JoL553HnFOXz5sjH8/cODLK9p5L//ZzePvv4RV5xXwqJKD7PPH0qO9BHvhaXKQms9N4HdWoCygPelwN4wx38MeAyMaKgEzpVRxKsA4pmthxo4A8nLM0JJI5XBiKZwlixx1ow72cFv/Hj47W/tK6+RauwuJxJIVpbi8rElXD62hI+PtbGqrolVG5u584+bGNG/gPkzPMyfWcaw4hCRDRmK7aGzSqnXgG9pret97ycA1cBMYCSwHhirte6KdBwJnY0dK8o5hAsZLSqCri5jUIimeF5+GW6+GU6d6v1ZURG8+qo9bVMjEa2neCw4qbxGKnDq9XZ2dbP+vQOsqG1iw/tesrMUV48fxqJZ5VxyzmCy0rS0iON7cCulbgJ+BZQAR4G3tNbzfJ99F7gD6AS+obV+MdrxRFnYT/DAGaqeUqR9Q+Ud+Ek2/8DKASpVg59TB9l0pPHQKaprm3iivpkjpzsYPaQvC2cayX4D+6ZXsp/jlYXZiLJwBokMaJES2QoLjedkMpvdVIU3HOlwDW6kraOLtds/ZnlNI/WNR8jLyeL6SSOomuVhqmdgWiT7ibIQXEOoarB9+8Ljj8Po0bEpnnBKKtXd36wgHa4hHXjv4+OsqGnimS17ONneyfnD+7FoVjk3ThlFUb4TA0tjw/EZ3IK7sLKZUihHcXc3XHVVbB3mwjU08ofg5gT9H7stSzrVHeyE0Jw/vJgHb5xI7QNz+NFNk8hSin99djuVP1zHd5/Zxrv7jtstoqXIykKISqwmkGRs6ok6isPNupcsMYoEBuZ8BH7uplm5rCycidaat5qPsrymiTVv76W9s5upngEsmlXOdZNGUJAbpY2iQxAzlGAKsQ5UZtjUI5mSwimhujqYM6enQujXz5AhOOGtXz+jo54b7f1mRF0J1nH09Bn+vKmF6tomPjp4igF9crllWikLK8sZPcTZyX6iLARTiKW7nJUz32hK6NFH4e67e+6Tn298P1CBFBXBww/Ddde5dzYu0VDOR2vNmx8eYnltIy/v2E9nt+ayc4ewaJaHueOHOTLZT5SFYAqxKIJ42pWaee5wUVQ/+Ql873tithHs5cDxNv5U18zKjU3sPdbGsOJ8vjjDw4KZZYzoX2i3eJ8gDm7BFEKVDQ/OurWqjEM0x264cuBtbdFlFgSrGVpcwD1zxrLhO1fxm/81nfEjivnVqx9w6UOv8pU/1PP6+166u90zWZeVRRqQCvNEtHNYYVNPdGXhb9QEzjLbiBlJaDp0muqNTTxZ38yhU2fwDOrDwkoPt0wrZXBRvi0yycoiQwgXNmo2JSXGIBeuEdGCBWc7wDU2muN8jbaqKSmBBx7ovV9e3tlKpn4zWLiwXytCgkMdM9bfycoQZcF+PIP7cN+nz+eN+2fzy/mTGd6/gIdefI+Lf/wq31i1hbqGwzh2Ah9LHXM3PDKxn4XZDYoikcqmNcFEkvHAAa0LCsLfg0hyW3FNoY4Z6+9k5z0W7GPnx8f1957dpid+b60uv3eNvubnr+s/vLFbH289k5Lz45bmR2Y9MlFZJNqgyE8qu+ZZSbhmQ5HktuKaInXJi/Y7Of0eC9Zzqr1Dr6xt1J/5fxt0+b1r9Ph/e1Hf99Tbevueo5aeN1Zl4d4cdSEpx3K4xj1z5/a2p9vVtCZWwpVSjyQ3mH9N4c4H0X8np99jwXr65OUwf6aH+TM9bG0+yoraRp7Z0sLKjU1MLjOS/a6/0L5kP/FZuJhYIpXCEU8JCSc0rYmG3z8Ra5SWFdcU7phTplgXUeYmH4ebZLWbi8oG8J9fuIja++fy/c9ewIm2Dr715FYqf7SeB9e8w4fek6kXKpblhxsemWiG8hOr3yF4H6t6XCdCItcQC5HktuKakunvHa88bvJxuElWJ9Ld3a3f2HVQf3XFJn3uA8/r8nvX6AWPvamff3uvPtPZldSxidEMJaGzGUy84a5WhX5aXX47ktxWNYJK9Jix7uumelFuktUNeE+080R9M9W1Tew52kpJv3z+ac5Y/mFWeULHkwxuISbsjv2XgSQxwmXNP/kkDBzorFwOqzL8M52ubs3r7x9gRU0TV44r4R8urkjoOLEqC3FwZzglJfYOKpno2DVDQYfycbS2wo03Oq9Bkht8Xm4kO0sx+/xhzD5/WErOZ5uDWyl1i1Jqh1KqWyk1PWB7hVKqVSn1lu+x1C4ZM5lUOSMzbSAxK4kyOLihoACUMhTGsWPG8+LFznAmJxOIITgHO6OhtgM3AxtCfPah1nqy73F3iM8FC0lVVji4cyBJVJEGhivHO6CHOmdg1vzq1Wdb0PpxUoMkKzL8hdRim7LQWr+rtd5p1/kFg+BBKJkBLVHcNJAko0gT7XgX6Zz+kOEpU2JfodkVwhoqvFlwD07NsxitlNqilHpdKXW53cKkK6EGIbtaeLphIElWkSZicov1nLGu0FK5ahTSC0uVhVJqnVJqe4jHDRF22wd4tNZTgH8GqpVSxWGOf6dSql4pVe91gnE2xSQzQww3CBUVZZYPIR6SVaSJmNziOWe0FZodq0YhfbA0GkprPTeBfdqBdt/rTUqpD4HzgF5xsVrrx4DHwAidTU5ad5FsbkK4KKSTJ41jBedfOHXGn8rQXzOc8eFKk5h1zkjRbZkYeSaYh+PMUEqpEqVUtu/1GGAs8JG9UjkLM2aIkQYht/gQUm1SMcsZH2xyi7RCNDMAINMizwSTiSXN24oHcBPQgrGK2A+85Nv+eWAHsBXYDHw2luNlUrmPZKvN+rG6hIeV2Fml1czSJPFU/jXjnG7+zQVrQMp9pC9mZj3bncGdKOmQFWxX9rpbf3PBGqRTXhpjpmnCDVFIoUgHk4pEngluQpSFS3GLX8Eq3JjMF0w6KDwhc5DaUC7G7rpOdhNvZJHT8Cs8t0SeCZmNKAvB1bhdYbpd4QmZgygLQbAZtys8ITMQn4WQlkgLT0EwF1EWQtoh9Y8EwXxEWQhphdQ/EgRrEGXhYsTU0hu7chcEId0RZeFSxNQSGsldEARrEGXhQsTUEp50SNYTBCciobMuREpNR8ZpuQtSi0lIB2Rl4ULE1BIdp9Q/EnOhkC6IsnAhYmpxB2IuFNIJMUO5FKeZWqKRiaYYMRcK6YSsLFyMU0wt0chUU4yYC4V0QpSFYCmZbIrJFHOh5PtkBrYpC6XUT5RS7yml3lZKPaOUGhDw2f1KqV1KqZ1KqXl2ySgkT6YnyaV735FMXTVmInauLF4BJmqtLwTeB+4HUEpdAMwHJgDXAr9WSmXbJqWQFGKKcY+5MF4yedWYidimLLTWL2utO31va4BS3+sbgFVa63at9W5gFzDTDhmF5MkUU0wmkumrxkzDKdFQdwB/8r0ehaE8/LT4tgkuxW2RW0JsyKoxs7BUWSil1gHDQ3z0Xa31at93vgt0Aiv8u4X4vg5z/DuBOwE8Hk/S8grWIQ1+0g9pC5tZWKostNZzI32ulLoNuB6Yo7X2K4QWoCzga6XA3jDHfwx4DGD69OkhFYogCNYhq8bMwTYzlFLqWuBe4FNa69MBHz0HVCulfg6MBMYCG20QURCEGJBVY2Zgp8/iYSAfeEUpBVCjtb5ba71DKfUE8A6GeeqrWusuG+UUBEHIeGxTFlrrcyN89kPghykURxAEQYiAZHALgiAIURFlIQiCIERFlIUgCIIQFVEWgiAIQlREWQiCIAhREWUhCIIgREWUhSAIghAVURaC45BmOoLgPERZCI5CmukIgjMRZSE4BmmmIwjORZSF4BikmY4gOBdRFoJjkGY6guBcRFkIjkFasAqCc3FKW1VBAKSZjiA4FVEWguOQZjqC4DzEDCUIgiBERZSFIAiCEBVRFoIgCEJURFkIgiAIURFlIQiCIERFaa3tlsEUlFJeoDHB3YcAB00UJxWIzKnBbTK7TV4QmVNFOJnLtdZR4w/TRlkkg1KqXms93W454kFkTg1uk9lt8oLInCqSlVnMUIIgCEJURFkIgiAIURFlYfCY3QIkgMicGtwms9vkBZE5VSQls/gsBEEQhKjIykIQBEGISkYrC6XUT5RS7yml3lZKPaOUGhDw2f1KqV1KqZ1KqXl2yhmIUuoWpdQOpVS3Ump6wPYKpVSrUuot32OpnXIGEk5m32eOvM9+lFI/UErtCbiv19ktUziUUtf67uMupdR9dssTC0qpBqXUNt+9rbdbnlAopR5XSh1QSm0P2DZIKfWKUuoD3/NAO2UMJozMSf0tZ7SyAF4BJmqtLwTeB+4HUEpdAMwHJgDXAr9WSmXbJmVPtgM3AxtCfPah1nqy73F3iuWKREiZHX6fA1kScF9fsFuYUPju238BnwYuABb47q8buMp3b50aivo7jL/PQO4D1mutxwLrfe+dxO/oLTMk8bec0cpCa/2y1rrT97YGKPW9vgFYpbVu11rvBnYBM+2QMRit9bta6512yxEPEWR27H12ITOBXVrrj7TWZ4BVGPdXSBKt9QbgcNDmG4Df+17/HrgxpUJFIYzMSZHRyiKIO4AXfa9HAc0Bn7X4tjmd0UqpLUqp15VSl9stTAy45T5/zWeqfNxp5oYA3HIvg9HAy0qpTUqpO+0WJg6Gaa33Afieh9osT6wk/Lec9s2PlFLrgOEhPvqu1nq17zvfBTqBFf7dQnw/ZWFjscgcgn2AR2t9SCk1DXhWKTVBa33cMkEDSFBmW+/zJ0JEkB14BHgQQ64HgZ9hTCychiPuZQJcqrXeq5QaCryilHrPNysWzCepv+W0VxZa67mRPldK3QZcD8zRZ+OIW4CygK+VAnutkbA30WQOs0870O57vUkp9SFwHpASp2EiMmPzffYTq+xKqd8AaywWJ1EccS/jRWu91/d8QCn1DIY5zQ3KYr9SaoTWep9SagRwwG6BoqG13u9/ncjfckaboZRS1wL3Ap/TWp8O+Og5YL5SKl8pNRoYC2y0Q8ZYUUqV+J3DSqkxGDJ/ZK9UUXH8ffYNBH5uwnDWO5E6YKxSarRSKg8jcOA5m2WKiFKqr1Kqn/81cA3Ovb/BPAfc5nt9GxBu9ewYkv1bTvuVRRQeBvIxlr8ANVrru7XWO5RSTwDvYJinvqq17rJRzk9QSt0E/AooAZ5XSr2ltZ4HXAH8u1KqE+gC7tZam+rgSpRwMjv5Pgfwn0qpyRhL9wbgLnvFCY3WulMp9TXgJSAbeFxrvcNmsaIxDHjG97+XA1RrrdfaK1JvlFIrgSuBIUqpFuD7wEPAE0qpxUATcIt9EvYmjMxXJvO3LBncgiAIQlQy2gwlCIIgxIYoC0EQBCEqoiwEQRCEqIiyEARBEKIiykIQBEGIiigLQRAEISqiLAQhSZRSZUqp3UqpQb73A33vy8N8/zZfaesPfBUEBMHxSJ6FIJiAUuo7wLla6zuVUo8CDVrrH4f43iCMEizTMZKjNgHTtNZHUiqwIMSJrCwEwRyWALOUUt8ALsMo0haKecArWuvDPgXxCqH7DgiCo8j0ch+CYApa6w6l1LeBtcA1vp4SoXBrKXEhw5GVhSCYx6cxSsVPjPAdt5YSFzIcURaCYAK+Am1XA7OAbwZV+AzElaXEBUEc3IKQJMoom/oG8D2t9StKqXuAWVrrqhDfHYTh1J7q27QZw8HtiArBghAOWVkIQvJ8BWjSWr/ie/9r4Hyl1KeCv+hTCg9i9J+oA/5dFIXgBmRlIQiCIERFVhaCIAhCVCR0VhAsQCk1Cfhj0OZ2rXWlHfIIQrKIGUoQBEGIipihBEEQhKiIshAEQRCiIspCEARBiIooC0EQBCEqoiwEQRCEqPx/fxWWoJ4UOvQAAAAASUVORK5CYII=\n",
415 | "text/plain": [
416 | ""
417 | ]
418 | },
419 | "metadata": {},
420 | "output_type": "display_data"
421 | }
422 | ],
423 | "source": [
424 | "def graph(formula, x_range): \n",
425 | " x = np.array(x_range) \n",
426 | " y = formula(x) \n",
427 | " plt.plot(x, y) \n",
428 | " \n",
429 | "def my_formula(x):\n",
430 | " return (-w[0]-w[1]*x)/w[2]\n",
431 | "\n",
432 | "from matplotlib import pyplot as plt\n",
433 | "from pandas import DataFrame \n",
434 | "df = DataFrame(dict(x=X[:,0], y=X[:,1], label=Y))\n",
435 | "colors = {0:'blue', 1:'orange'}\n",
436 | "fig, ax = plt.subplots()\n",
437 | "grouped = df.groupby('label')\n",
438 | "for key, group in grouped:\n",
439 | " group.plot(ax=ax, kind='scatter', x='x', y='y', label=key, color=colors[key])\n",
440 | "graph(my_formula, range(-20,15))\n",
441 | "plt.xlabel('X_0')\n",
442 | "plt.ylabel('X_1')\n",
443 | "plt.show()"
444 | ]
445 | }
446 | ],
447 | "metadata": {
448 | "kernelspec": {
449 | "display_name": "Python 3",
450 | "language": "python",
451 | "name": "python3"
452 | },
453 | "language_info": {
454 | "codemirror_mode": {
455 | "name": "ipython",
456 | "version": 3
457 | },
458 | "file_extension": ".py",
459 | "mimetype": "text/x-python",
460 | "name": "python",
461 | "nbconvert_exporter": "python",
462 | "pygments_lexer": "ipython3",
463 | "version": "3.6.5"
464 | }
465 | },
466 | "nbformat": 4,
467 | "nbformat_minor": 2
468 | }
469 |
--------------------------------------------------------------------------------
/sgd.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "## Creating Fake Data"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import numpy as np\n",
17 | "from sklearn.utils import shuffle\n",
18 | "from sklearn.datasets.samples_generator import make_blobs\n",
19 | "X, Y = make_blobs(n_samples=300, centers=2, n_features=2, cluster_std=5, random_state=11)"
20 | ]
21 | },
22 | {
23 | "cell_type": "markdown",
24 | "metadata": {},
25 | "source": [
26 | "## Visualizing the Data"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 3,
32 | "metadata": {},
33 | "outputs": [
34 | {
35 | "data": {
36 | "image/png": "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\n",
37 | "text/plain": [
38 | ""
39 | ]
40 | },
41 | "metadata": {},
42 | "output_type": "display_data"
43 | }
44 | ],
45 | "source": [
46 | "from matplotlib import pyplot as plt\n",
47 | "from pandas import DataFrame \n",
48 | "df = DataFrame(dict(x=X[:,0], y=X[:,1], label=Y))\n",
49 | "colors = {0:'blue', 1:'orange'}\n",
50 | "fig, ax = plt.subplots()\n",
51 | "grouped = df.groupby('label')\n",
52 | "for key, group in grouped:\n",
53 | " group.plot(ax=ax, kind='scatter', x='x', y='y', label=key, color=colors[key])\n",
54 | "plt.xlabel('X_1')\n",
55 | "plt.ylabel('X_2')\n",
56 | "plt.show()"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {},
62 | "source": [
63 | "## Splitting into batches"
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": 4,
69 | "metadata": {},
70 | "outputs": [],
71 | "source": [
72 | "def next_batch(X, Y, batch_size):\n",
73 | " for i in np.arange(0, X.shape[0], batch_size):\n",
74 | " yield (X[i:i + batch_size], Y[i:i + batch_size])"
75 | ]
76 | },
77 | {
78 | "cell_type": "markdown",
79 | "metadata": {},
80 | "source": [
81 | "## Adding column of 1's "
82 | ]
83 | },
84 | {
85 | "cell_type": "code",
86 | "execution_count": 5,
87 | "metadata": {},
88 | "outputs": [
89 | {
90 | "data": {
91 | "text/plain": [
92 | "(300, 3)"
93 | ]
94 | },
95 | "execution_count": 5,
96 | "metadata": {},
97 | "output_type": "execute_result"
98 | }
99 | ],
100 | "source": [
101 | "X = np.c_[np.ones((X.shape[0])), X]\n",
102 | "X.shape"
103 | ]
104 | },
105 | {
106 | "cell_type": "markdown",
107 | "metadata": {},
108 | "source": [
109 | "## Logistic Model"
110 | ]
111 | },
112 | {
113 | "cell_type": "code",
114 | "execution_count": 6,
115 | "metadata": {},
116 | "outputs": [],
117 | "source": [
118 | "import numpy as np\n",
119 | "def sigmoid(z):\n",
120 | " return 1 / (1 + np.exp(-z))"
121 | ]
122 | },
123 | {
124 | "cell_type": "code",
125 | "execution_count": 7,
126 | "metadata": {},
127 | "outputs": [],
128 | "source": [
129 | "def hx(W,X):\n",
130 | " return sigmoid(np.dot(X,W))"
131 | ]
132 | },
133 | {
134 | "cell_type": "markdown",
135 | "metadata": {},
136 | "source": [
137 | "## Cost Function - Binary Cross Entropy "
138 | ]
139 | },
140 | {
141 | "cell_type": "code",
142 | "execution_count": 8,
143 | "metadata": {},
144 | "outputs": [],
145 | "source": [
146 | "def cost(W, X, Y):\n",
147 | " y_pred = hx(W,X)\n",
148 | " return -1 * sum(Y*np.log(y_pred) + (1-Y)*np.log(1-y_pred))"
149 | ]
150 | },
151 | {
152 | "cell_type": "markdown",
153 | "metadata": {},
154 | "source": [
155 | "## Stochastic Gradient Descent"
156 | ]
157 | },
158 | {
159 | "cell_type": "code",
160 | "execution_count": 9,
161 | "metadata": {},
162 | "outputs": [],
163 | "source": [
164 | "def grad(W, X, Y):\n",
165 | " y_pred = hx(W,X)\n",
166 | " A = (Y*(1-y_pred) - (1-Y)*y_pred)\n",
167 | " g = -1* np.dot(A.T,X)\n",
168 | " return g"
169 | ]
170 | },
171 | {
172 | "cell_type": "code",
173 | "execution_count": 10,
174 | "metadata": {},
175 | "outputs": [],
176 | "source": [
177 | "def sgd(W_new, W_prev, lr, batch_size, epochs):\n",
178 | " X_, Y_ = shuffle(X, Y, random_state=0)\n",
179 | " for e in range(epochs):\n",
180 | " epoch_loss = []\n",
181 | " X_, Y_ = shuffle(X_, Y_, random_state=0)\n",
182 | " for (batchX, batchY) in next_batch(X_, Y_, batch_size):\n",
183 | " W_prev = W_new\n",
184 | " epoch_loss.append(cost(W_prev, batchX, batchY))\n",
185 | " gradients = grad(W_prev, batchX, batchY)\n",
186 | " W_new = W_prev - lr*gradients\n",
187 | " print(np.average(epoch_loss))\n",
188 | " return W_new"
189 | ]
190 | },
191 | {
192 | "cell_type": "markdown",
193 | "metadata": {},
194 | "source": [
195 | "## Initializing Weights & Bias"
196 | ]
197 | },
198 | {
199 | "cell_type": "code",
200 | "execution_count": 11,
201 | "metadata": {},
202 | "outputs": [
203 | {
204 | "data": {
205 | "text/plain": [
206 | "(3,)"
207 | ]
208 | },
209 | "execution_count": 11,
210 | "metadata": {},
211 | "output_type": "execute_result"
212 | }
213 | ],
214 | "source": [
215 | "W = np.random.uniform(size=(X.shape[1],))\n",
216 | "W.shape"
217 | ]
218 | },
219 | {
220 | "cell_type": "markdown",
221 | "metadata": {},
222 | "source": [
223 | "## Training the Model"
224 | ]
225 | },
226 | {
227 | "cell_type": "code",
228 | "execution_count": 12,
229 | "metadata": {},
230 | "outputs": [
231 | {
232 | "name": "stdout",
233 | "output_type": "stream",
234 | "text": [
235 | "[0.79618896 0.4163837 0.42391672]\n",
236 | "6.277384446178855\n",
237 | "5.743854541290189\n",
238 | "5.639645113634937\n",
239 | "5.470853335391083\n",
240 | "5.667962099033007\n",
241 | "5.28981499238036\n",
242 | "5.271342725834096\n",
243 | "5.060368761481374\n",
244 | "5.446976524735743\n",
245 | "5.066447704414417\n",
246 | "5.09547652563199\n",
247 | "5.027047324020139\n",
248 | "5.231413878163542\n",
249 | "4.988553649645022\n",
250 | "5.045966239495252\n",
251 | "5.114093205881277\n",
252 | "5.24313649711587\n",
253 | "5.3309800879511595\n",
254 | "5.2369933729138705\n",
255 | "4.931357222546931\n",
256 | "5.141072913940974\n",
257 | "4.865177946360237\n",
258 | "5.159259956251705\n",
259 | "4.9850013574989935\n",
260 | "5.075992543432262\n",
261 | "5.257537980731875\n",
262 | "5.15220734911969\n",
263 | "5.376113028226739\n",
264 | "5.01790696023796\n",
265 | "4.91743150129637\n",
266 | "5.155592756181093\n",
267 | "4.778496875740468\n",
268 | "5.170830308497642\n",
269 | "4.982057737386109\n",
270 | "5.065383224896023\n",
271 | "5.130301783329287\n",
272 | "5.0560422794900335\n",
273 | "4.751542045996459\n",
274 | "5.044836198314092\n",
275 | "5.200065208594642\n",
276 | "5.285956700133218\n",
277 | "4.69607623817095\n",
278 | "5.1110131343684895\n",
279 | "4.929261653440459\n",
280 | "5.508577234972032\n",
281 | "4.9295442093408335\n",
282 | "5.35853341436791\n",
283 | "5.109882297828997\n",
284 | "5.268900506923824\n",
285 | "5.0553568625861995\n",
286 | "5.127108057053507\n",
287 | "5.256180863878795\n",
288 | "5.2017470229439295\n",
289 | "5.29706022610866\n",
290 | "4.842578732589242\n",
291 | "5.216497984078021\n",
292 | "5.167172158840554\n",
293 | "5.030913544155235\n",
294 | "4.9208154561894215\n",
295 | "5.0286895579435775\n",
296 | "5.254927983516582\n",
297 | "5.01657084246088\n",
298 | "4.902782163580072\n",
299 | "4.952060238428389\n",
300 | "4.9191214387250035\n",
301 | "5.027098170280329\n",
302 | "5.077946337475286\n",
303 | "4.880098287861289\n",
304 | "4.944972140093644\n",
305 | "5.052666303168795\n",
306 | "5.081615975832211\n",
307 | "5.182569862898558\n",
308 | "4.9697239615921625\n",
309 | "5.056706134894904\n",
310 | "5.110368058329958\n",
311 | "4.996883358551884\n",
312 | "4.989696640078847\n",
313 | "4.858898302441649\n",
314 | "4.930715531754518\n",
315 | "5.009314794537656\n",
316 | "5.127984153485331\n",
317 | "5.0231049124602825\n",
318 | "5.254008279820028\n",
319 | "5.014073801135062\n",
320 | "4.97986671455312\n",
321 | "5.05243719762335\n",
322 | "5.0420997708089415\n",
323 | "5.069451589063102\n",
324 | "5.150257226697879\n",
325 | "5.164400634677876\n",
326 | "5.039134823534483\n",
327 | "4.9883474157043795\n",
328 | "5.132433782589542\n",
329 | "4.891167385232467\n",
330 | "5.062085674381252\n",
331 | "5.2087055067642165\n",
332 | "4.955120478076216\n",
333 | "4.88214965225135\n",
334 | "4.935119155279668\n",
335 | "5.4527388101645755\n",
336 | "4.902647474574163\n",
337 | "4.973218626980669\n",
338 | "4.969125747240431\n",
339 | "5.034819845305565\n",
340 | "5.11158072777152\n",
341 | "5.052709686640736\n",
342 | "4.968840505649011\n",
343 | "5.088612053925859\n",
344 | "4.915818444090352\n",
345 | "5.093157727293972\n",
346 | "5.033660011718062\n",
347 | "5.223412724166921\n",
348 | "5.1077816665230475\n",
349 | "5.135494856877415\n",
350 | "4.989777059244171\n",
351 | "5.165527490515357\n",
352 | "5.327764783138228\n",
353 | "5.019080784749545\n",
354 | "5.0239554594473805\n",
355 | "5.026682139880581\n",
356 | "5.159710856114193\n",
357 | "5.027795318281852\n",
358 | "4.988648104694423\n",
359 | "5.012928309587274\n",
360 | "5.081666714554431\n",
361 | "5.272117622609143\n",
362 | "4.851869972177484\n",
363 | "4.956969286562633\n",
364 | "5.025160410234134\n",
365 | "4.993677569943672\n",
366 | "5.099870584911604\n",
367 | "5.096181311604027\n",
368 | "5.236923964162504\n",
369 | "4.903674873885619\n",
370 | "5.075807820064275\n",
371 | "4.701673307737802\n",
372 | "5.299083765240716\n",
373 | "5.112201692629844\n",
374 | "5.057198863500682\n",
375 | "5.213612968874003\n",
376 | "5.1198465312517225\n",
377 | "4.928097399784619\n",
378 | "4.991964359552881\n",
379 | "4.994824548764347\n",
380 | "5.049272339126923\n",
381 | "4.942713247937617\n",
382 | "4.91913758023255\n",
383 | "5.43143326229052\n",
384 | "5.116114463071936\n",
385 | "4.9625898877661445\n",
386 | "5.042137105313292\n",
387 | "5.157805681662321\n",
388 | "5.04896325685934\n",
389 | "5.018982423826876\n",
390 | "5.185034061711793\n",
391 | "5.032465453425752\n",
392 | "4.897108003638827\n",
393 | "4.95421678149162\n",
394 | "5.259006286037971\n",
395 | "5.182717981721985\n",
396 | "4.884826442197778\n",
397 | "5.156842877561891\n",
398 | "5.047645060816286\n",
399 | "5.050121866311711\n",
400 | "4.869794749038038\n",
401 | "4.9957190876138835\n",
402 | "5.022988953794398\n",
403 | "5.002839753440677\n",
404 | "4.881319490767778\n",
405 | "5.055591006717888\n",
406 | "5.015670050297785\n",
407 | "5.013392499945725\n",
408 | "4.989724363452584\n",
409 | "4.880412359751283\n",
410 | "5.416224099805669\n",
411 | "5.2867392415724135\n",
412 | "5.11414942585176\n",
413 | "5.079966239068073\n",
414 | "4.925427043815789\n",
415 | "5.145176957835869\n",
416 | "5.130160451160554\n",
417 | "5.024814422423505\n",
418 | "4.958769936817604\n",
419 | "4.81843182784822\n",
420 | "5.34842232805925\n",
421 | "5.279335054775109\n",
422 | "5.107921381756868\n",
423 | "5.15079791674754\n",
424 | "5.096406330816437\n",
425 | "5.00585692466524\n",
426 | "5.200218860079871\n",
427 | "4.96229644142354\n",
428 | "4.937523034036624\n",
429 | "5.174090668819386\n",
430 | "5.1400977102309175\n",
431 | "5.1319926651455186\n",
432 | "5.048127875476851\n",
433 | "5.416048064604175\n",
434 | "5.057120736099771\n",
435 | "4.864273959307718\n",
436 | "[2.38150361 0.22263106 0.53666744]\n"
437 | ]
438 | }
439 | ],
440 | "source": [
441 | "print(W)\n",
442 | "W = sgd(W, W, .009, 32, 200)\n",
443 | "print(W)"
444 | ]
445 | },
446 | {
447 | "cell_type": "markdown",
448 | "metadata": {},
449 | "source": [
450 | "## Visualizing the Result"
451 | ]
452 | },
453 | {
454 | "cell_type": "code",
455 | "execution_count": 13,
456 | "metadata": {},
457 | "outputs": [
458 | {
459 | "data": {
460 | "image/png": "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\n",
461 | "text/plain": [
462 | ""
463 | ]
464 | },
465 | "metadata": {},
466 | "output_type": "display_data"
467 | }
468 | ],
469 | "source": [
470 | "def graph(formula, x_range): \n",
471 | " x = np.array(x_range) \n",
472 | " y = formula(x) \n",
473 | " plt.plot(x, y) \n",
474 | " \n",
475 | "def my_formula(x):\n",
476 | " return (-W[0]-W[1]*x)/W[2]\n",
477 | "\n",
478 | "from matplotlib import pyplot as plt\n",
479 | "from pandas import DataFrame \n",
480 | "df = DataFrame(dict(x=X[:,1], y=X[:,2], label=Y))\n",
481 | "colors = {0:'blue', 1:'orange'}\n",
482 | "fig, ax = plt.subplots()\n",
483 | "grouped = df.groupby('label')\n",
484 | "for key, group in grouped:\n",
485 | " group.plot(ax=ax, kind='scatter', x='x', y='y', label=key, color=colors[key])\n",
486 | "graph(my_formula, range(-20,15))\n",
487 | "plt.xlabel('X_1')\n",
488 | "plt.ylabel('X_2')\n",
489 | "plt.show()"
490 | ]
491 | }
492 | ],
493 | "metadata": {
494 | "kernelspec": {
495 | "display_name": "Python 3",
496 | "language": "python",
497 | "name": "python3"
498 | },
499 | "language_info": {
500 | "codemirror_mode": {
501 | "name": "ipython",
502 | "version": 3
503 | },
504 | "file_extension": ".py",
505 | "mimetype": "text/x-python",
506 | "name": "python",
507 | "nbconvert_exporter": "python",
508 | "pygments_lexer": "ipython3",
509 | "version": "3.6.5"
510 | }
511 | },
512 | "nbformat": 4,
513 | "nbformat_minor": 2
514 | }
515 |
--------------------------------------------------------------------------------