You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Les objets connectés envoient à des intervalles de temps réguliers des messages qui tansitent par le réseau GSM. Des antennes appelées stations de base reçoivent ces messages et sont chargées de les transmettre via un réseau filaire. Notre objectif est d'implémenter un algorithme d'apprentissage automatique pour prédire la position d'un objet à partir des messages réceptionnés par les stations de base.
print("Train set position:", train_label.shape)
train_label[:5]
Train set position: (39250, 2)
lat
lng
0
39.606690
-104.958490
1
39.606690
-104.958490
2
39.637741
-104.958554
3
39.730417
-104.968940
4
39.730417
-104.968940
print("Test set:", test.shape)
test[:5]
Test set: (29286, 8)
objid
bsid
did
nseq
rssi
time_ux
bs_lat
bs_lng
0
573be2503e952e191262c351
3578
116539.0
2.0
-111.0
1.463542e+12
39.728651
-105.163032
1
573c05f83e952e1912758013
2617
472504.0
0.0
-136.0
1.463551e+12
39.779908
-105.062479
2
573c05f83e952e1912758013
3556
472504.0
0.0
-127.0
1.463551e+12
39.780658
-105.053676
3
573c05f83e952e1912758013
3578
472504.0
0.0
-129.0
1.463551e+12
39.728651
-105.163032
4
573c05f83e952e1912758013
4058
472504.0
0.0
-105.0
1.463551e+12
39.783211
-105.088747
Exploration des données
Nombre de stations recevant un même message
data=train.groupby("objid").count()["bsid"]
data_with_3_pos=data[data>=3].count()
data_with_3_pos_less=data[data<3].count()
data_with_1_pos=data[data==1].count()
print("Messages reçus par 3 stations de base ou plus: %2.2f"%(data_with_3_pos/data.count() *100), "%")
print("Messages reçus par moins de 3 stations: %2.2f"%(data_with_3_pos_less/data.count() *100), "%")
print("Messages reçus par une station: %2.2f"%(data_with_1_pos/data.count() *100), "%")
plt.figure(figsize=(12,9))
plt.hist(data, bins=100)
plt.xlabel("Nombre de stations ayant reçues le même message")
plt.ylabel("Nombre de messages")
plt.xlim([1, 30])
plt.xticks(np.arange(1, 30+1, 1.0))
plt.show()
Messages reçus par 3 stations de base ou plus: 62.39 %
Messages reçus par moins de 3 stations: 37.61 %
Messages reçus par une station: 21.90 %
listOfBs=np.union1d(np.unique(train['bsid']), np.unique(test['bsid']))
print("Nombre de stations ayant reçues au moins un message %d"%(len(listOfBs)))
Nombre de stations ayant reçues au moins un message 259
Quelles caractéristiques chosir pour notre modèle ?
Feature Matrix construction
Message received or not
deffeat_mat_const(train, listOfBs):
messages=train["objid"].unique()
df_feat=pd.DataFrame(index=messages, columns=listOfBs).fillna(0)
# Pour chaque station recevant le message# Affecter la valeur du signal correspondantformessageinmessages:
bsids=train[train["objid"] ==message]["bsid"]
df_feat.loc[message, bsids] =1returndf_feat
Message received with rssi or not
deffeat_mat_const(train, listOfBs):
# Pour chaque station ne recevant pas de message# Affecter la plus petite valeur existante auquelle on retranchera 10min_rssi=train["rssi"].min() -10000messages=train["objid"].unique()
df_feat=pd.DataFrame(index=messages, columns=listOfBs).fillna(min_rssi)
# Pour chaque station recevant le message# Affecter la valeur du signal correspondantformessageinmessages:
bsids=train[train["objid"] ==message]["bsid"]
forbsidinbsids:
df_feat.loc[message, bsid] =train[(train["objid"] ==message) & (train["bsid"] ==bsid)]["rssi"].iloc[0]
returndf_feat
defvincenty_vec(vec_coord):
vin_vec_dist=np.zeros(vec_coord.shape[0])
ifvec_coord.shape[1] !=4:
print('ERROR: Bad number of columns (shall be = 4)')
else:
vin_vec_dist= [vincenty(vec_coord[m,0:2],vec_coord[m,2:]).metersforminrange(vec_coord.shape[0])]
returnvin_vec_dist
# evaluate distance error for each predicted pointdefEval_geoloc(y_train_lat , y_train_lng, y_pred_lat, y_pred_lng):
vec_coord=np.array([y_train_lat, y_train_lng, y_pred_lat, y_pred_lng])
err_vec=vincenty_vec(np.transpose(vec_coord))
returnerr_vec
Select hyper parameters
defregressor_and_predict_CV(reg, parameters, df_feat, ground_truth_lat, ground_truth_lng, df_test):
# train regressor and make prediction in the train set# Input: df_feat, ground_truth_lat, ground_truth_lng, df_test# Output: y_pred_lat, y_pred_lngX_train=np.array(df_feat)
reg=GridSearchCV(reg, parameters, cv=10)
reg.fit(X_train, ground_truth_lat)
y_pred_lat=reg.predict(df_test)
print("Best latitude estimator:", reg.best_estimator_)
reg.fit(X_train, ground_truth_lng)
y_pred_lng=reg.predict(df_test)
print("Best longitude estimator:", reg.best_estimator_)
returny_pred_lat, y_pred_lng
random_seed=13X_train_b, X_val, y_train, y_val=train_test_split(X_train, np.transpose([y_lat, y_lng]),
train_size=0.9, random_state=random_seed)
# Learning on a part of the training set# Predicting on another small part of the training sety_pred_lat, y_pred_lng=regressor_and_predict(X_train_b, y_train[:, 0], y_train[:, 1], X_val)
# Measuring error on the small part of the training set not used for learningerr_vec=Eval_geoloc(y_val[:, 0] , y_val[:, 1], y_pred_lat, y_pred_lng)