├── finalreport.pdf ├── progress_report.pdf ├── README.md └── ips.py /finalreport.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HUbbm409/bbm406-project-wi-fi-based-indoor-positioning/HEAD/finalreport.pdf -------------------------------------------------------------------------------- /progress_report.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HUbbm409/bbm406-project-wi-fi-based-indoor-positioning/HEAD/progress_report.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bbm406-project-wi-fi-based-indoor-positioning 2 | 3 | 4 | [![video](https://i.ibb.co/nnHqHf8/b.png)](https://www.youtube.com/watch?v=Zqu3Pz22TZ0) 5 | 6 | Presentation Video: https://www.youtube.com/watch?v=Zqu3Pz22TZ0 7 | 8 | ### Wi-Fi Based Indoor Positioning Medium Stories 9 | 10 | WEEK 1 11 | 12 | https://medium.com/bbm406f18/week-1-wi-fi-based-indoor-positioning-f15cd8b52026 13 | 14 | WEEK 2 15 | 16 | https://medium.com/bbm406f18/week-2-wi-fi-based-indoor-positioning-e429bcd22734 17 | 18 | WEEK 3 19 | 20 | https://medium.com/bbm406f18/week-3-wi-fi-based-indoor-positioning-a0ecbfbcdc44 21 | 22 | WEEK 4 23 | 24 | https://medium.com/bbm406f18/week-4-wi-fi-based-indoor-positioning-d2707a244bd 25 | 26 | WEEK 5 27 | 28 | https://medium.com/bbm406f18/week-5-wi-fi-based-indoor-positioning-faa4005c44e2 29 | 30 | WEEK 6 31 | 32 | https://medium.com/bbm406f18/week-6-wi-fi-based-indoor-positioning-feb89efb5e69 33 | 34 | 35 | ### References 36 | 37 | https://www.kaggle.com/giantuji/UjiIndoorLoc 38 | 39 | http://ericjgilbert.com/wifi_locNB.nb.html 40 | 41 | https://github.com/SunnerLi 42 | -------------------------------------------------------------------------------- /ips.py: -------------------------------------------------------------------------------- 1 | from sklearn.ensemble import GradientBoostingClassifier, GradientBoostingRegressor 2 | from sklearn.ensemble import RandomForestClassifier, RandomForestRegressor 3 | from sklearn.preprocessing import MinMaxScaler 4 | from abc import ABCMeta 5 | from sklearn.svm import SVC, SVR 6 | import pandas as pd 7 | import numpy as np 8 | import matplotlib.pyplot as plt 9 | 10 | build_acc = [] 11 | floor_acc = [] 12 | 13 | long_scaler = MinMaxScaler() 14 | lat_scaler = MinMaxScaler() 15 | 16 | 17 | def load(train_path, valid_path): 18 | 19 | train_data_frame = pd.read_csv(train_path) 20 | train_data_frame = train_data_frame[(train_data_frame.LATITUDE != 0.0) & (train_data_frame.LONGITUDE != 0.0) & 21 | (train_data_frame.BUILDINGID == 2)] 22 | 23 | test_data_frame = pd.read_csv(valid_path) 24 | test_data_frame = test_data_frame[(test_data_frame.LATITUDE != 0.0) & (test_data_frame.LONGITUDE != 0.0) & 25 | (test_data_frame.BUILDINGID == 2)] 26 | 27 | rest_data_frame = train_data_frame 28 | valid_data_trame = pd.DataFrame(columns=train_data_frame.columns) 29 | valid_num = int(len(train_data_frame)/10) 30 | 31 | sample_row = rest_data_frame.sample(valid_num) 32 | rest_data_frame = rest_data_frame.drop(sample_row.index) 33 | 34 | valid_data_trame = valid_data_trame.append(sample_row) 35 | train_data_frame = rest_data_frame 36 | 37 | # Split data frame and return 38 | training_x = train_data_frame.get_values().T[:520].T 39 | training_y = train_data_frame.get_values().T[[520, 521, 522, 523], :].T 40 | 41 | validation_x = valid_data_trame.get_values().T[:520].T 42 | validation_y = valid_data_trame.get_values().T[[520, 521, 522, 523], :].T 43 | 44 | testing_x = test_data_frame.get_values().T[:520].T 45 | testing_y = test_data_frame.get_values().T[[520, 521, 522, 523], :].T 46 | 47 | return training_x, training_y, validation_x, validation_y, testing_x, testing_y 48 | 49 | 50 | def normalize_x(x_array): 51 | res = np.copy(x_array).astype(np.float) 52 | for i in range(np.shape(res)[0]): 53 | for j in range(np.shape(res)[1]): 54 | if res[i][j] == 100: 55 | res[i][j] = 0 56 | else: 57 | res[i][j] = -0.01 * res[i][j] 58 | return res 59 | 60 | 61 | def normalize_y(longs, lats): 62 | global long_scaler 63 | global lat_scaler 64 | longs = np.reshape(longs, [-1, 1]) 65 | lats = np.reshape(lats, [-1, 1]) 66 | long_scaler.fit(longs) 67 | lat_scaler.fit(lats) 68 | return np.reshape(long_scaler.transform(longs), [-1]), \ 69 | np.reshape(lat_scaler.transform(lats), [-1]) 70 | 71 | 72 | def reverse_normalizeY(longs, lats): 73 | global long_scaler 74 | global lat_scaler 75 | longs = np.reshape(longs, [-1, 1]) 76 | lats = np.reshape(lats, [-1, 1]) 77 | return np.reshape(long_scaler.inverse_transform(longs), [-1]), \ 78 | np.reshape(lat_scaler.inverse_transform(lats), [-1]) 79 | 80 | 81 | class Model( object): 82 | __metaclass__ = ABCMeta 83 | 84 | # ML model object 85 | longitude_regression_model = None 86 | latitude_regression_model = None 87 | 88 | # Training data 89 | normalize_x = None 90 | longitude_normalize_y = None 91 | latitude_normalize_y = None 92 | 93 | def __init__(self): 94 | pass 95 | 96 | def _preprocess(self, x, y): 97 | self.normalize_x = normalize_x(x) 98 | self.longitude_normalize_y, self.latitude_normalize_y = normalize_y(y[:, 0], y[:, 1]) 99 | self.floorID_y = y[:, 2] 100 | self.buildingID_y = y[:, 3] 101 | 102 | def fit(self, x, y): 103 | # Data pre-processing 104 | self._preprocess(x, y) 105 | self.longitude_regression_model.fit(self.normalize_x, self.longitude_normalize_y) 106 | self.latitude_regression_model.fit(self.normalize_x, self.latitude_normalize_y) 107 | 108 | def predict(self, x): 109 | # Testing 110 | x = normalize_x(x) 111 | predict_longitude = self.longitude_regression_model.predict(x) 112 | predict_latitude = self.latitude_regression_model.predict(x) 113 | 114 | # Reverse normalization 115 | predict_longitude, predict_latitude = reverse_normalizeY(predict_longitude, predict_latitude) 116 | 117 | # Return the result 118 | res = np.concatenate((np.expand_dims(predict_longitude, axis=-1), 119 | np.expand_dims(predict_latitude, axis=-1)), axis=-1) 120 | 121 | return res 122 | 123 | def error(self, x, y): 124 | _y = self.predict(x) 125 | dist = np.sqrt(np.square(_y[:, 0] - y[:, 0]) + np.square(_y[:, 1] - y[:, 1])) 126 | #plot_dist_error(dist) 127 | #map_plot(_y, y) 128 | print(min(dist), np.mean(dist), max(dist)) 129 | 130 | return dist 131 | 132 | 133 | class SVM(Model): 134 | def __init__(self): 135 | super().__init__() 136 | self.longitude_regression_model = SVR(verbose=True) 137 | self.latitude_regression_model = SVR(verbose=True) 138 | self.floor_classifier = SVC(verbose=True) 139 | #self.building_classifier = SVC(verbose=True) 140 | 141 | 142 | class RandomForest(Model): 143 | def __init__(self): 144 | super().__init__() 145 | self.longitude_regression_model = RandomForestRegressor() 146 | self.latitude_regression_model = RandomForestRegressor() 147 | self.floor_classifier = RandomForestClassifier() 148 | #self.building_classifier = RandomForestClassifier() 149 | 150 | 151 | class GradientBoostingDecisionTree(Model): 152 | def __init__(self): 153 | super().__init__() 154 | self.longitude_regression_model = GradientBoostingRegressor() 155 | self.latitude_regression_model = GradientBoostingRegressor() 156 | self.floor_classifier = GradientBoostingClassifier() 157 | #self.building_classifier = GradientBoostingClassifier() 158 | 159 | 160 | def plot_dist_error(dist): 161 | dist = dist.tolist() 162 | t = np.arange(0.0, len(dist), 1) 163 | y_mean = [np.mean(dist)]*len(dist) 164 | 165 | fig, ax = plt.subplots() 166 | ax.plot(t, dist, label='Error value') 167 | ax.plot(t, y_mean, label='Mean', linestyle='--', color='red') 168 | 169 | ax.set(xlabel='Data points (ID)', ylabel='Error (m)', 170 | title='Error value of points using baseline Random Forest') 171 | ax.grid() 172 | 173 | fig.savefig("error.png") 174 | plt.legend() 175 | plt.show() 176 | 177 | 178 | def map_plot(_y, y): 179 | # take the first two features 180 | h = .02 # step size in the mesh 181 | 182 | # Calculate min, max and limits 183 | x_min, x_max = y[:, 0].min() - 1, y[:, 0].max() + 1 184 | y_min, y_max = y[:, 1].min() - 1, y[:, 1].max() + 1 185 | xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) 186 | 187 | # Put the result into a color plot 188 | plt.figure() 189 | plt.scatter(y[:, 0], y[:, 1], alpha=0.5, s=7, marker='o', label='actual position') 190 | plt.scatter(_y[:, 0], _y[:, 1], alpha=0.3, s=4, marker='o', label='predicted position') 191 | plt.xlim(xx.min()-20, xx.max()+20) 192 | plt.ylim(yy.min()-20, yy.max()+20) 193 | plt.legend() 194 | plt.grid() 195 | plt.xlabel('Longitude') 196 | plt.ylabel('Latitude') 197 | plt.title("Data points") 198 | plt.tight_layout(pad=0) 199 | plt.savefig('data_points.png') 200 | plt.show() 201 | 202 | 203 | def bar_plot(lst): 204 | 205 | method = ['SVM', 'Random Forest', 'Boosting Decision Tree'] # nom = ['Obama', 'Romney', 'Johson', 'Stein'] 206 | 207 | data = lst # [51.258, 47.384, 0.992, 0.365] 208 | x_pos = [x for x in range(len(data))] 209 | 210 | 211 | fig = plt.figure() 212 | ax = fig.add_subplot(111) 213 | colorsBox = ['r', 'b', 'c', 'y', 'purple', 'green', 'k', 'magenta', 'firebrick'] 214 | 215 | for x in range(len(data)): 216 | ax.bar(x_pos[x], data[x], color=colorsBox[x], label=method[x], align='center') 217 | 218 | #plt.xlabel('Nominees') 219 | plt.title("Floor classification for buildingID=2") 220 | plt.ylabel('Accuracy(%)') 221 | plt.ylim(bottom=50, top=100) 222 | plt.xticks(x_pos, method) 223 | plt.legend() 224 | plt.tight_layout() 225 | plt.savefig('floor.pdf', bbox_inches=None) 226 | plt.close() 227 | 228 | 229 | if __name__ == '__main__': 230 | 231 | train_csv_path = 'TrainingData.csv' 232 | valid_csv_path = 'ValidationData.csv' 233 | train_x, train_y, valid_x, valid_y, test_x, test_y = load(train_csv_path, valid_csv_path) 234 | # Training 235 | SVM = SVM() 236 | SVM.fit(train_x, train_y) 237 | 238 | RF = RandomForest() 239 | RF.fit(train_x, train_y) 240 | 241 | GBDT = GradientBoostingDecisionTree() 242 | GBDT.fit(train_x, train_y) 243 | 244 | RF.error(test_x, test_y) 245 | --------------------------------------------------------------------------------