**数据集介绍**
本实验采集的是广播信号,x,y坐标,是GPS采集的经纬度坐标。88000KHz、90400KHz、93100KHz分别是三个广播电台的频段。这3个广播电台是独立的,在建模时可以认为相互之间没有关系。其下数据是该点的电磁场强度,该数据从某地的郊区和市区采集的,通过车载设备,边开车边采集。
根据采集的数据,推算出附近地点没有采集的数据。具体方法,可以从现在数据中,任意选择10%作为测试数据,90%作为训练数据建模
def show_data(y, y_pred, title):
plt.figure(figsize=(7, 6), facecolor='w')
plt.plot(y, 'r-', lw=3, label='Actual')
plt.plot(y_pred, 'g.', markersize=2, label='Predict', alpha=0.2)
plt.grid(b=True, ls=':', color='#606060')
plt.xlabel('Samples', fontsize=15)
plt.ylabel('Field Intensity', fontsize=15)
plt.legend(loc='upper left')
plt.title(title, fontsize=18)
plt.tight_layout()
if __name__ == '__main__':
pd.set_option('display.width', 500)
data = pd.read_csv('FieldIntensity_19w.csv', header=0)
print(data)
x = MinMaxScaler().fit_transform(data[['x', 'y']])
y = data['88000KHz'].values
# 绘图
mpl.rcParams['font.sans-serif'] = 'SimHei'
mpl.rcParams['axes.unicode_minus'] = False
idx = np.arange(x.shape[0])
np.random.shuffle(idx)
idx = idx[:1500]
plt.figure(figsize=(7, 7), facecolor='w')
ax = plt.subplot(111, projection='3d')
ax.scatter(data['x'][idx], data['y'][idx], data['88000KHz'][idx], c=data['88000KHz'][idx],
marker='.', edgecolors='#404040', s=100, cmap=cm.bwr)
ax.set_xlabel(u'X')
ax.set_ylabel(u'Y')
ax.set_zlabel(u'Field Intensity')
plt.title(u'场强衰减值', fontsize=18)
plt.tight_layout(0.5)
plt.show()
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.1, random_state=0)
# model = GridSearchCV(rf, param_grid={'max_depth': np.arange(8, 18), 'min_samples_split': np.arange(3, 15, 2)})
model = RandomForestRegressor(n_estimators=100, criterion='mse', max_depth=15, min_samples_split=3)
print('正在训练...')
t_start = time()
model.fit(x_train, y_train)
t_end = time()
print('耗时:%.3f秒。' % (t_end - t_start))
# 按照训练集的y值排序
order = y_train.argsort(axis=0)
x_train = x_train[order]
y_train = y_train[order]
y_train_pred = model.predict(x_train)
print('训练集R2 =', r2_score(y_train, y_train_pred))
mse_train = mean_squared_error(y_train, y_train_pred)
mae_train = mean_absolute_error(y_train, y_train_pred)
print('\t训练集MSE = %.3f, RMSE = %.3f, MAE = %.3f' % (mse_train, np.sqrt(mse_train), mae_train))
order = y_test.argsort(axis=0)
x_test = x_test[order]
y_test = y_test[order]
y_test_pred = model.predict(x_test)
print('测试集R2 =', r2_score(y_test, y_test_pred))
mse_test = mean_squared_error(y_test, y_test_pred)
mae_test = mean_absolute_error(y_test, y_test_pred)
print('\t测试集MSE = %.3f, RMSE = %.3f, MAE = %.3f' % (mse_test, np.sqrt(mse_test), mae_test))
show_data(y_train, y_train_pred, 'Train Data')
show_data(y_test, y_test_pred, 'Test Data')
plt.show()
针对同一个经纬度,可以把功率dbm做平均处理。
数据一共有191709个点,如果同一个经纬度的功率dbm做平均,就只有4847个点。或者在两个GPS点之间,让这些值平均分布,相当于汽车是匀速运动,在两个GPS点之间画一条直线,让这次监测的场强值,按照顺序依次分布在这条线上。
某经纬度的场强值,每行是一个三元组(x,y,d),其中x和y为经纬度坐标,d为该点的场强值,共有19万条数据。如下图所示。最终输出未知区域的场强。
使用均方误差平方根RMSE和绝对值误差MAE作为模型预测的判别依据。在测试集上,RMSE=3.81,MAE=2.73,精度相当高。
无线电随机森林模型训练集和测试集预测效果:
(更详细源码在github上,本文不做更新,仅供学习)