-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUnderstanding and Predicting Property Maintenance Fines
More file actions
408 lines (408 loc) · 19 KB
/
Understanding and Predicting Property Maintenance Fines
File metadata and controls
408 lines (408 loc) · 19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"\n",
"_You are currently looking at **version 1.1** of this notebook. To download notebooks and datafiles, as well as get help on Jupyter notebooks in the Coursera platform, visit the [Jupyter Notebook FAQ](https://www.coursera.org/learn/python-machine-learning/resources/bANLa) course resource._\n",
"\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Assignment 4 - Understanding and Predicting Property Maintenance Fines\n",
"\n",
"This assignment is based on a data challenge from the Michigan Data Science Team ([MDST](http://midas.umich.edu/mdst/)). \n",
"\n",
"The Michigan Data Science Team ([MDST](http://midas.umich.edu/mdst/)) and the Michigan Student Symposium for Interdisciplinary Statistical Sciences ([MSSISS](https://sites.lsa.umich.edu/mssiss/)) have partnered with the City of Detroit to help solve one of the most pressing problems facing Detroit - blight. [Blight violations](http://www.detroitmi.gov/How-Do-I/Report/Blight-Complaint-FAQs) are issued by the city to individuals who allow their properties to remain in a deteriorated condition. Every year, the city of Detroit issues millions of dollars in fines to residents and every year, many of these fines remain unpaid. Enforcing unpaid blight fines is a costly and tedious process, so the city wants to know: how can we increase blight ticket compliance?\n",
"\n",
"The first step in answering this question is understanding when and why a resident might fail to comply with a blight ticket. This is where predictive modeling comes in. For this assignment, your task is to predict whether a given blight ticket will be paid on time.\n",
"\n",
"All data for this assignment has been provided to us through the [Detroit Open Data Portal](https://data.detroitmi.gov/). **Only the data already included in your Coursera directory can be used for training the model for this assignment.** Nonetheless, we encourage you to look into data from other Detroit datasets to help inform feature creation and model selection. We recommend taking a look at the following related datasets:\n",
"\n",
"* [Building Permits](https://data.detroitmi.gov/Property-Parcels/Building-Permits/xw2a-a7tf)\n",
"* [Trades Permits](https://data.detroitmi.gov/Property-Parcels/Trades-Permits/635b-dsgv)\n",
"* [Improve Detroit: Submitted Issues](https://data.detroitmi.gov/Government/Improve-Detroit-Submitted-Issues/fwz3-w3yn)\n",
"* [DPD: Citizen Complaints](https://data.detroitmi.gov/Public-Safety/DPD-Citizen-Complaints-2016/kahe-efs3)\n",
"* [Parcel Map](https://data.detroitmi.gov/Property-Parcels/Parcel-Map/fxkw-udwf)\n",
"\n",
"___\n",
"\n",
"We provide you with two data files for use in training and validating your models: train.csv and test.csv. Each row in these two files corresponds to a single blight ticket, and includes information about when, why, and to whom each ticket was issued. The target variable is compliance, which is True if the ticket was paid early, on time, or within one month of the hearing data, False if the ticket was paid after the hearing date or not at all, and Null if the violator was found not responsible. Compliance, as well as a handful of other variables that will not be available at test-time, are only included in train.csv.\n",
"\n",
"Note: All tickets where the violators were found not responsible are not considered during evaluation. They are included in the training set as an additional source of data for visualization, and to enable unsupervised and semi-supervised approaches. However, they are not included in the test set.\n",
"\n",
"<br>\n",
"\n",
"**File descriptions** (Use only this data for training your model!)\n",
"\n",
" train.csv - the training set (all tickets issued 2004-2011)\n",
" test.csv - the test set (all tickets issued 2012-2016)\n",
" addresses.csv & latlons.csv - mapping from ticket id to addresses, and from addresses to lat/lon coordinates. \n",
" Note: misspelled addresses may be incorrectly geolocated.\n",
"\n",
"<br>\n",
"\n",
"**Data fields**\n",
"\n",
"train.csv & test.csv\n",
"\n",
" ticket_id - unique identifier for tickets\n",
" agency_name - Agency that issued the ticket\n",
" inspector_name - Name of inspector that issued the ticket\n",
" violator_name - Name of the person/organization that the ticket was issued to\n",
" violation_street_number, violation_street_name, violation_zip_code - Address where the violation occurred\n",
" mailing_address_str_number, mailing_address_str_name, city, state, zip_code, non_us_str_code, country - Mailing address of the violator\n",
" ticket_issued_date - Date and time the ticket was issued\n",
" hearing_date - Date and time the violator's hearing was scheduled\n",
" violation_code, violation_description - Type of violation\n",
" disposition - Judgment and judgement type\n",
" fine_amount - Violation fine amount, excluding fees\n",
" admin_fee - $20 fee assigned to responsible judgments\n",
"state_fee - $10 fee assigned to responsible judgments\n",
" late_fee - 10% fee assigned to responsible judgments\n",
" discount_amount - discount applied, if any\n",
" clean_up_cost - DPW clean-up or graffiti removal cost\n",
" judgment_amount - Sum of all fines and fees\n",
" grafitti_status - Flag for graffiti violations\n",
" \n",
"train.csv only\n",
"\n",
" payment_amount - Amount paid, if any\n",
" payment_date - Date payment was made, if it was received\n",
" payment_status - Current payment status as of Feb 1 2017\n",
" balance_due - Fines and fees still owed\n",
" collection_status - Flag for payments in collections\n",
" compliance [target variable for prediction] \n",
" Null = Not responsible\n",
" 0 = Responsible, non-compliant\n",
" 1 = Responsible, compliant\n",
" compliance_detail - More information on why each ticket was marked compliant or non-compliant\n",
"\n",
"\n",
"___\n",
"\n",
"## Evaluation\n",
"\n",
"Your predictions will be given as the probability that the corresponding blight ticket will be paid on time.\n",
"\n",
"The evaluation metric for this assignment is the Area Under the ROC Curve (AUC). \n",
"\n",
"Your grade will be based on the AUC score computed for your classifier. A model which with an AUROC of 0.7 passes this assignment, over 0.75 will recieve full points.\n",
"___\n",
"\n",
"For this assignment, create a function that trains a model to predict blight ticket compliance in Detroit using `train.csv`. Using this model, return a series of length 61001 with the data being the probability that each corresponding ticket from `test.csv` will be paid, and the index being the ticket_id.\n",
"\n",
"Example:\n",
"\n",
" ticket_id\n",
" 284932 0.531842\n",
" 285362 0.401958\n",
" 285361 0.105928\n",
" 285338 0.018572\n",
" ...\n",
" 376499 0.208567\n",
" 376500 0.818759\n",
" 369851 0.018528\n",
" Name: compliance, dtype: float32\n",
" \n",
"### Hints\n",
"\n",
"* Make sure your code is working before submitting it to the autograder.\n",
"\n",
"* Print out your result to see whether there is anything weird (e.g., all probabilities are the same).\n",
"\n",
"* Generally the total runtime should be less than 10 mins. You should NOT use Neural Network related classifiers (e.g., MLPClassifier) in this question. \n",
"\n",
"* Try to avoid global variables. If you have other functions besides blight_model, you should move those functions inside the scope of blight_model.\n",
"\n",
"* Refer to the pinned threads in Week 4's discussion forum when there is something you could not figure it out."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Notice"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"there many data speculations need to be done before writing codes. I first printed out head of each csv file and did\n",
"some operations. Then I decided to do those clean operations in the function below. The reason of choosing a Random forset\n",
"classifier: locations (state), judgement, violation type are crucial to the payment of fines.\n",
"And one can give these features an order just by computing the fines paid rate within each feature."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"\n",
"import pandas as pd\n",
"import numpy as np\n",
"from sklearn.ensemble import RandomForestClassifier\n",
"from sklearn.model_selection import GridSearchCV\n",
"def blight_model():\n",
" df = pd.read_csv('train.csv',encoding = 'ISO-8859-1' )\n",
" df = df[['state','violation_code','violation_description', 'fine_amount',\n",
" 'disposition','discount_amount',\n",
" 'clean_up_cost','compliance']] #get features and targets\n",
" df.dropna(inplace = True)\n",
" # state dictionary by the paid rate\n",
" df1 = df[['compliance','state']] \n",
" df1=df1.groupby(df1['state']).agg({'compliance':['sum','count']})\n",
" state_dict = dict(df1.iloc[:,0]/df1.iloc[:,1])\n",
" # vio_code dic by the paid rate\n",
" df1 = df[['compliance','violation_code']] \n",
" df1=df1.groupby(df1['violation_code']).agg({'compliance':['sum','count']})\n",
" vio_code_dict = dict(df1.iloc[:,0]/df1.iloc[:,1]) \n",
" #vio_des by the paid rate\n",
" df1 = df[['compliance','violation_description']] \n",
" df1=df1.groupby(df1['violation_description']).agg({'compliance':['sum','count']})\n",
" vio_des_dict = dict(df1.iloc[:,0]/df1.iloc[:,1]) \n",
" # \n",
" df1 = df[['compliance','disposition']] \n",
" df1=df1.groupby(df1['disposition']).agg({'compliance':['sum','count']})\n",
" dis_dict = dict(df1.iloc[:,0]/df1.iloc[:,1]) \n",
" dis_dict ={'Responsible (Fine Waived) by Admis': dis_dict['Responsible by Admission'],\n",
" 'Responsible (Fine Waived) by Deter': dis_dict['Responsible by Determination'],\n",
" 'Responsible - Compl/Adj by Default': dis_dict['Responsible by Default'],\n",
" 'Responsible - Compl/Adj by Determi': dis_dict['Responsible by Determination'],\n",
" 'Responsible by Admission': dis_dict['Responsible by Admission'],\n",
" 'Responsible by Default': dis_dict['Responsible by Default'],\n",
" 'Responsible by Determination': dis_dict['Responsible by Determination']}\n",
" # replace string value by rates\n",
" df.replace({'violation_description':vio_des_dict,'violation_code':vio_code_dict,\n",
" 'state':state_dict,'disposition': dis_dict }, inplace =True)\n",
" # get X_train\n",
" X_train = df.iloc[:,:-1]\n",
" # get y_train\n",
" y_train = df.iloc[:,-1]\n",
" # train model\n",
" # logreg = LogisticRegression().fit(X_train,y_train)\n",
" \n",
" rfc = RandomForestClassifier( n_estimators = 50,n_jobs = -1,random_state = 0)\n",
" rfc.fit(X_train,y_train)\n",
" # read test file\n",
" df1 = pd.read_csv('test.csv',encoding = 'ISO-8859-1' )\n",
" X_test = df1[['state','violation_code','violation_description', 'fine_amount',\n",
" 'disposition','discount_amount',\n",
" 'clean_up_cost']]\n",
" X_test.replace({'violation_description':vio_des_dict,'violation_code':vio_code_dict,\n",
" 'state':state_dict,'disposition': dis_dict}, inplace =True)\n",
" # clean state\n",
" a=[]\n",
" for i,v in X_test['state'].items():\n",
" if type(v) ==float:\n",
" a.append(v)\n",
" else:\n",
" a.append(np.nan)\n",
" X_test['state']= a\n",
" X_test['state'].fillna(0,inplace=True)\n",
" # clean vio code\n",
" a=[]\n",
" for i,v in X_test['violation_code'].items():\n",
" if type(v) ==float:\n",
" a.append(v)\n",
" else:\n",
" a.append(np.nan)\n",
" X_test['violation_code']= a\n",
" X_test['violation_code'].fillna(0,inplace=True)\n",
" #clean vio des\n",
" a=[]\n",
" for i,v in X_test['violation_description'].items():\n",
" \n",
" if type(v) ==float:\n",
" a.append(v)\n",
" else:\n",
" a.append(np.nan)\n",
" X_test['violation_description']= a\n",
" X_test['violation_description'].fillna(0,inplace=True)\n",
" # clean dis\n",
" a=[]\n",
" for i,v in X_test['disposition'].items():\n",
" if type(v) ==float:\n",
" a.append(v)\n",
" else:\n",
" a.append(np.nan)\n",
" X_test['disposition']= a\n",
" X_test['disposition'].fillna(0,inplace=True)\n",
" # pridcition\n",
" y_pro = rfc.predict_proba(X_test)[:,1]\n",
" y_re = pd.Series(y_pro , index = df1['ticket_id'])\n",
" return y_re"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/opt/conda/lib/python3.5/site-packages/IPython/core/interactiveshell.py:2827: DtypeWarning: Columns (11,12,31) have mixed types. Specify dtype option on import or set low_memory=False.\n",
" if self.run_code(code, result):\n",
"/opt/conda/lib/python3.5/site-packages/pandas/core/generic.py:3485: SettingWithCopyWarning: \n",
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
"Try using .loc[row_indexer,col_indexer] = value instead\n",
"\n",
"See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy\n",
" regex=regex)\n",
"/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:60: SettingWithCopyWarning: \n",
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
"Try using .loc[row_indexer,col_indexer] = value instead\n",
"\n",
"See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy\n",
"/opt/conda/lib/python3.5/site-packages/pandas/core/generic.py:3295: SettingWithCopyWarning: \n",
"A value is trying to be set on a copy of a slice from a DataFrame\n",
"\n",
"See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy\n",
" self._update_inplace(new_data)\n",
"/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:69: SettingWithCopyWarning: \n",
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
"Try using .loc[row_indexer,col_indexer] = value instead\n",
"\n",
"See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy\n",
"/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:79: SettingWithCopyWarning: \n",
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
"Try using .loc[row_indexer,col_indexer] = value instead\n",
"\n",
"See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy\n",
"/opt/conda/lib/python3.5/site-packages/ipykernel/__main__.py:88: SettingWithCopyWarning: \n",
"A value is trying to be set on a copy of a slice from a DataFrame.\n",
"Try using .loc[row_indexer,col_indexer] = value instead\n",
"\n",
"See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy\n"
]
},
{
"data": {
"text/plain": [
"ticket_id\n",
"284932 0.020000\n",
"285362 0.000000\n",
"285361 0.000000\n",
"285338 0.000000\n",
"285346 0.003844\n",
"285345 0.000000\n",
"285347 0.000000\n",
"285342 0.626667\n",
"285530 0.000000\n",
"284989 0.000000\n",
"285344 0.000000\n",
"285343 0.000000\n",
"285340 0.000000\n",
"285341 0.000000\n",
"285349 0.003844\n",
"285348 0.000000\n",
"284991 0.000000\n",
"285532 0.000000\n",
"285406 0.000000\n",
"285001 0.003415\n",
"285006 0.003189\n",
"285405 0.000000\n",
"285337 0.000000\n",
"285496 0.000000\n",
"285497 0.000000\n",
"285378 0.000000\n",
"285589 0.000000\n",
"285585 0.000000\n",
"285501 0.000000\n",
"285581 0.000000\n",
" ... \n",
"376367 0.008561\n",
"376366 0.000000\n",
"376362 0.010000\n",
"376363 0.125333\n",
"376365 0.008561\n",
"376364 0.000000\n",
"376228 0.000000\n",
"376265 0.000000\n",
"376286 0.043333\n",
"376320 0.000000\n",
"376314 0.000000\n",
"376327 0.043333\n",
"376385 0.043333\n",
"376435 0.060000\n",
"376370 0.010000\n",
"376434 0.000000\n",
"376459 0.060233\n",
"376478 0.000000\n",
"376473 0.000000\n",
"376484 0.000000\n",
"376482 0.000000\n",
"376480 0.000000\n",
"376479 0.000000\n",
"376481 0.000000\n",
"376483 0.000000\n",
"376496 0.000000\n",
"376497 0.000000\n",
"376499 0.003844\n",
"376500 0.003844\n",
"369851 0.000000\n",
"dtype: float64"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"blight_model()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"coursera": {
"course_slug": "python-machine-learning",
"graded_item_id": "nNS8l",
"launcher_item_id": "yWWk7",
"part_id": "w8BSS"
},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}