-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwildfire_classifier.py
More file actions
113 lines (73 loc) · 4.63 KB
/
Copy pathwildfire_classifier.py
File metadata and controls
113 lines (73 loc) · 4.63 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
# -*- coding: utf-8 -*-
"""Mini Project 1 Final.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1b4AFIqz6qUi-AfI4oCGQ9VyM2nYq4hDK
# CS155 Mini Project 1
# Data Retrieval
We first obtained the training and testing data from the project github, and unzipped the files.
"""
!wget https://github.com/lakigigar/Caltech-CS155-2021/raw/main/projects/project1/WILDFIRES_TEST.zip
!wget https://github.com/lakigigar/Caltech-CS155-2021/raw/main/projects/project1/WILDFIRES_TRAIN.zip
!unzip WILDFIRES_TEST.zip
!unzip WILDFIRES_TRAIN.zip
"""We imported all of the necessary libraries and saved the data from the .csv files into Pandas dataframes. """
import pandas as pd
from sklearn import tree
from sklearn.ensemble import RandomForestClassifier
import numpy as np
from sklearn import model_selection
from sklearn import svm
from scipy import stats
from scipy.stats import uniform, truncnorm, randint
from sklearn import preprocessing
train_df = pd.read_csv('WILDFIRES_TRAIN.csv', index_col='id')
test_df = pd.read_csv('WILDFIRES_TEST.csv', index_col='id')
train_df
test_df
"""# Feature Selection
We chose to use latitude, longitude, discovery time, fire size, and month of fire as the features for our model. We decided that the FIPS name, FIPS code, and source reporting unit name were not as useful to train our model because they were essentially classification labels, and could not be easily transformed into a form understandable by the model. We assumed that the day would not be relevant because each month has roughly the same range of values for days, and it does not contribute much to the general classification of the fire. We also tested the model using only the month, only the year, and with both, but found that it performed the best using only the month. In addition, we disregarded the points in the training set with NaN values by dropping them from the dataframe, in order to prevent interference from incomplete data.
"""
train_df = train_df.drop(columns=['STATE', 'FIPS_NAME', 'FIPS_CODE', 'SOURCE_REPORTING_UNIT_NAME']).dropna()
train_df['MONTH'] = train_df['DATE'].str[5:7].astype(int)
train_df = train_df.drop(columns=['DATE'])
train_df
"""# Outlier Removal
The following plot shows the distribution of maximum z-scores for points in the training set. Since the vast majority of the points fell in the range of having a z-score less than 3, we chose to make 3 our boundary for outliers.
"""
max_zscore = pd.DataFrame(np.sort(stats.zscore(train_df)).max(axis=1))
plt = max_zscore.plot.hist(xlim=(0, 5), logy=True, bins=np.linspace(0, 5, 20))
plt.set_xlabel('Z-Score')
"""We removed outliers from our training set by removing all points with a z-score greater than 3. """
train_df = train_df[(np.abs(stats.zscore(train_df)) < 3).all(axis=1)]
train_df
"""Here, we separate the classification labels from the features. """
features = ['LATITUDE', 'LONGITUDE', 'DISCOVERY_TIME', 'FIRE_SIZE', 'MONTH']
X_train = train_df.loc[:, features].values
Y_train = train_df.loc[:,['LABEL']].values.ravel()
"""# Training the Model
After testing several models, we chose to use the RandomForestClassifier with 500 decision trees and gini impurity. To reduce overfitting, we set a minimum number of 10 samples per leaf.
"""
np.random.seed(1)
n_estimators = 500
clf = RandomForestClassifier(n_estimators = n_estimators, criterion = 'gini', min_samples_leaf=10)
clf.fit(X_train, Y_train)
"""Relative importance of features, in order of [Latitude, Longitude, Discovery Time, Fire Size, Month]. """
print(clf.feature_importances_)
"""# Formatting the Test Data
To predict the test data, we removed all of the features except for the ones we trained on. In addition, since we wanted to predict the labels of all the points in the test set, we filled all of the NaN values with the mean of that column rather than dropping them completely.
"""
test_df = test_df.drop(columns=['STATE', 'FIPS_NAME', 'FIPS_CODE', 'SOURCE_REPORTING_UNIT_NAME']).fillna(test_df.mean())
test_df['MONTH'] = test_df['DATE'].str[5:7]
test_df = test_df.drop(columns=['DATE'])
"""We used our trained model to obtain the probability that each test point was a certain class. """
test = test_df.loc[:, features].values
results = clf.predict_proba(test)
"""Finally, we outputted our results into a .csv file, listing the id of the fire followed by the probability that it was class 1, 2, 3, and 4. """
f = open("output.csv", "w")
id_index = 285382
f.write("id,P1,P2,P3,P4\n")
for point in results:
f.write("{id},{P1},{P2},{P3},{P4}\n".format(id = str(id_index), P1 = point[0], P2 = point[1], P3 = point[2], P4 = point[3]))
id_index += 1
f.close()