本文讲解的代码可在GitHub上获取

https://github.com/kyeongsoo/can405_indoor_localization

首先我们需要知道为什么要通过WIFI指纹实现室内定位,这是因为卫星定位系统在室内环境或高层建筑密集地区无法检测到卫星信号,无法满足人们对定位精度的要求。而良好的网络稳定性、高速高质量的数据传输,以及Wi-Fi通信模块在智能移动终端上的广泛应用,使得室内使用WIFI无线定位转变成一种低成本和易于实现技术。

话不多说,下面直接开始讲解代码。本文主要讲解如何预处理数据,数据集采用的UJIIndoorLoc dataset http://archive.ics.uci.edu/ml/datasets/UJIIndoorLoc

先定义训练与验证集的路径变量

path_train = '../data/UJIIndoorLoc/trainingData2.csv'
path_validation = '../data/UJIIndoorLoc/validationData2.csv'

用函数pd.read_csv读取数据,其中header=0代表第一行是标题行

    train_df = pd.read_csv(path_train, header=0) test_df = pd.read_csv(path_validation, header=0)

下面是读取数据集的结果。我们可以看到,该数据库包括19937条训练数据和1111条测试数据,实验中将原来的验证集作为测试集。一共有520个不同的无线接入点(WAP),每个无线接入点对应的接收信号强度(RSSI)范围从负整数-104dBm(极差信号)到0dBm。在本实验中,为了便于后续归一化,使用负值-110表示未检测到WAP。除了520个WiFi指纹,529个属性还包含其他指纹采集坐标和其他有用信息。

在本实验中,除了使用520个WiFi指纹外,还需要使用6个属性,即Longitude (-7695.9388~ -7299.7865),Latitude (4864745.7450~4865017.3647),Floor (建筑物内楼层的高度,整数(0 ~ 4)),BuildingID(三栋楼(0~2)),SpaceID(用于识别位置空间(办公室、走廊、教室)的内部ID号,整数),RelativePosition(相对于位置空间的相对位置(1-门内,2-门外))。

    train_dfWAP001  WAP002  WAP003  ...  USERID  PHONEID   TIMESTAMP
0        -110    -110    -110  ...       2       23  1371713733
1        -110    -110    -110  ...       2       23  1371713691...     ...     ...  ...     ...      ...         ...
19935    -110    -110    -110  ...      18       10  1371711049
19936    -110    -110    -110  ...      18       10  1371711025[19937 rows x 529 columns]test_dfWAP001  WAP002  WAP003  ...  USERID  PHONEID   TIMESTAMP
0       -110    -110    -110  ...       0        0  1380872703
1       -110    -110    -110  ...       0       13  1381155054...     ...     ...  ...     ...      ...         ...
1109    -110    -110    -110  ...       0       13  1381247807
1110    -110    -110    -110  ...       0       13  1381247836[1111 rows x 529 columns]

然后取出所有样本的520个WiFi指纹(train_AP_features),转换为float类型数组,使用函数scalescalescale对数据进行预处理。需要注意的是,这里是对每一行的数据进行标准化处理。

在此之后,添加一个新的列,它是SpaceIDSpaceIDSpaceID和RelativePositionRelativePositionRelativePosition的组合,也就是字符串内容相加。进行这一步是因为我们后面要对楼层的参考点进行编号。将SpaceIDSpaceIDSpaceID和RelativePositionRelativePositionRelativePosition结合,也就是说训练集数据中,在一个楼层里,我们将出现的不同参考点(SpaceIDSpaceIDSpaceID,RelativePositionRelativePositionRelativePosition)分别进行编号。

    train_AP_features = scale(np.asarray(train_df.iloc[:,0:520]).astype(float), axis=1) # convert integer to float and scale jointly (axis=1)train_df['REFPOINT'] = train_df.apply(lambda row: str(int(row['SPACEID'])) + str(int(row['RELATIVEPOSITION'])), axis=1) # add a new columntrain_AP_features.shape(19937, 520)train_df['REFPOINT']0        10621        1062...19935    113219936    1122Name: REFPOINT, Length: 19937, dtype: object

对于数据集中一共有几栋楼,每一栋楼有几个楼层,虽然我们可以直接在数据集的介绍中找到,但是我们一般还是选择自己从数据集中获取。np.unique函数是可以查找数组的唯一元素,因此我们可以通过该函数得到数据集中一共有三栋楼,五个楼层。

    blds = np.unique(train_df[['BUILDINGID']])flrs = np.unique(train_df[['FLOOR']])bldsarray([0, 1, 2], dtype=int64)flrsarray([0, 1, 2, 3, 4], dtype=int64)

下面的代码是将参考点映射到每个楼层,这里用到了前面的REFPOINT,即每个楼层的不同参考点用不同的id标记。然后计算各楼层的平均坐标,留着后面使用。cond代表当前选择的楼层,train_df.loc[cond,′REFPOINT′]train\_df.loc[cond, 'REFPOINT']train_df.loc[cond,′REFPOINT′]是选取当前楼层的所有参考点的值,此时得到的idx代表的就是该楼层每一个参考点编号后的id值。

    x_avg = {}y_avg = {}for bld in blds:for flr in flrs:# map reference points to sequential IDs per building-floor before building labelscond = (train_df['BUILDINGID']==bld) & (train_df['FLOOR']==flr)_, idx = np.unique(train_df.loc[cond, 'REFPOINT'], return_inverse=True) # refer to numpy.unique manualtrain_df.loc[cond, 'REFPOINT'] = idx# calculate the average coordinates of each building/floorx_avg[str(bld) + '-' + str(flr)] = np.mean(train_df.loc[cond, 'LONGITUDE'])y_avg[str(bld) + '-' + str(flr)] = np.mean(train_df.loc[cond, 'LATITUDE'])
    train_df['REFPOINT']0        131        13..19935    1519936    13Name: REFPOINT, Length: 19937, dtype: objectx_avg{'0-0': -7640.376350991143, '0-1': -7637.829042353956, '0-2': -7639.023285886209, '0-3': -7640.245117900643, '0-4': nan, '1-0': -7463.825569651152, '1-1': -7511.07230214694, '1-2': -7486.581783868335, '1-3': -7492.579508808194, '1-4': nan, '2-0': -7352.32452951861, '2-1': -7351.31601971969, '2-2': -7347.406288310243, '2-3': -7360.208989855721, '2-4': -7357.458888837215}y_avg{'0-0': 4864957.721957975, '0-1': 4864957.706202937, '0-2': 4864958.364463876, '0-3': 4864956.533051689, '0-4': nan, '1-0': 4864874.372386921, '1-1': 4864893.299521635, '1-2': 4864878.546449652, '1-3': 4864892.971830967, '1-4': nan, '2-0': 4864818.793817714, '2-1': 4864816.715084595, '2-2': 4864820.8762252545, '2-3': 4864806.658757386, '2-4': 4864822.315012857}

通过上述的操作,对于每一组数据,我们得到了520个WiFi指纹,标签就是对应的建筑,楼层,参考点的三个id,我们可以看出这是一个多标签的分类问题。对于建筑,楼层,参考点,我们可以分别采用pd.get_dummies得到对应的独热编码,然后将其合并为118位的label,其中前三位是代表建筑,接着的五位代表楼层,后面的110位是参考点。所以对于所有训练数据的label就是19937 x 118大小。

    # build labels for multi-label classificationlen_train = len(train_df)blds_all = np.asarray(pd.get_dummies(pd.concat([train_df['BUILDINGID'], test_df['BUILDINGID']]))) # for consistency in one-hot encoding for both dataframesflrs_all = np.asarray(pd.get_dummies(pd.concat([train_df['FLOOR'], test_df['FLOOR']]))) # dittoblds = blds_all[:len_train]flrs = flrs_all[:len_train]rfps = np.asarray(pd.get_dummies(train_df['REFPOINT']))train_labels = np.concatenate((blds, flrs, rfps), axis=1)# labels is an array of 19937 x 118# - 3 for BUILDINGID# - 5 for FLOOR,# - 110 for REFPOINTOUTPUT_DIM = train_labels.shape[1]
    train_labelsarray([[0, 1, 0, ..., 0, 0, 0],[0, 1, 0, ..., 0, 0, 0],[0, 1, 0, ..., 0, 0, 0],...,[0, 1, 0, ..., 0, 0, 0],[0, 1, 0, ..., 0, 0, 0],[0, 1, 0, ..., 0, 0, 0]], dtype=uint8)train_labels.shape(19937, 118)

然后我们将训练集分为训练集和验证集,其中training_ratiotraining\_ratiotraining_ratio表示训练数据与整体数据的比率,默认值为0.9。

    # split the training set into training and validation setstrain_val_split = np.random.rand(len(train_AP_features)) < training_ratio # mask index arrayx_train = train_AP_features[train_val_split]y_train = train_labels[train_val_split]x_val = train_AP_features[~train_val_split]y_val = train_labels[~train_val_split]
    x_train.shape(17955, 520)y_train.shape(17955, 118)x_val.shape(1982, 520)y_val.shape(1982, 118)

对于从文件中读取的验证集,本次实验是将其作为测试集,对WiFi指纹数据也需要进行相应的标准化。

然后得到测试集中建筑和楼层的标签,纬度和经度。

    # turn the given validation set into a testing settest_AP_features = scale(np.asarray(test_df.iloc[:,0:520]).astype(float), axis=1)  # convert integer to float and scale jointly (axis=1)x_test_utm = np.asarray(test_df['LONGITUDE'])y_test_utm = np.asarray(test_df['LATITUDE'])blds = blds_all[len_train:]flrs = flrs_all[len_train:]

至此我们已经将数据处理完毕,得到了训练集,验证集,测试集。其中训练集的WiFi指纹大小为(17955, 520),标签大小为(17955, 118)。验证集的WiFi指纹大小为(1982, 520),标签大小为(1982, 118)。测试集的WiFi指纹大小为(1111, 520),因为要评估模型的性能,因此当测试时,我们对于预测得到的标签通过训练集转换标签的对应关系得到对应预测的建筑,楼层,参考点(可以对应到经纬度坐标)与真实的相比较,评估模型的性能。

ref

  • D. Dua and C. Graff, “UCI machine learning repository,” 2017. [Online]. Available:http://archive.ics.uci.edu/ml
  • K. S. Kim, S. Lee, and K. Huang, “A scalable deep neural network architecture for multi-building and multi-floor indoor localization based on wi-fi fingerprinting,” Big Data Analytics, vol. 3, no. 1, p. 4, 2018.

本文仅供参考, 若有错误, 欢迎指出, 共同学习
欢迎关注 小玉lab 公众号

基于Wi-Fi指纹和深度神经网络的室内定位系统设计代码详解(一)相关推荐

  1. 【深度神经网络】五、GoogLeNet网络详解

    概要 本篇文章的重点就是主要介绍GoogLeNet的网络架构,这个网络架构于2014年由Google团队提出.GoogLeNet的论文为:Going deeper with convolutions. ...

  2. 基于RK3399ESP8285自动售货柜项目—MP08开发板端代码详解

    基于RK3399&ESP8285自动售货柜项目-②MP08开发板端代码详解 本系列文章将详细讲解该基于RK3399及ESP8285自动售货柜的完整实现方法,从硬件连接到网络通信再到软件实现,本 ...

  3. Keras深度学习实战(1)——神经网络基础与模型训练过程详解

    Keras深度学习实战(1)--神经网络基础与模型训练过程详解 0. 前言 1. 神经网络基础 1.1 简单神经网络的架构 1.2 神经网络的训练 1.3 神经网络的应用 2. 从零开始构建前向传播 ...

  4. 基于人工蜂群优化的BP神经网络(分类应用) - 附代码

    基于人工蜂群优化的BP神经网络(分类应用) - 附代码 文章目录 基于人工蜂群优化的BP神经网络(分类应用) - 附代码 1.鸢尾花iris数据介绍 2.数据集整理 3.人工蜂群优化BP神经网络 3. ...

  5. 基于神经网络的依存句法分析总结及代码详解

    上一篇文章CS224n之句法分析总结,介绍了句法分析以及具体的依存分析中的arc-standard算法.arc-standard系统是transition systems中最流行的一个系统之一.而本文 ...

  6. 基于哈里斯鹰优化的BP神经网络(分类应用) - 附代码

    基于哈里斯鹰优化的BP神经网络(分类应用) - 附代码 文章目录 基于哈里斯鹰优化的BP神经网络(分类应用) - 附代码 1.鸢尾花iris数据介绍 2.数据集整理 3.哈里斯鹰优化BP神经网络 3. ...

  7. 基于粒子群优化的BP神经网络(分类应用) - 附代码

    基于粒子群优化的BP神经网络(分类应用) - 附代码 文章目录 基于粒子群优化的BP神经网络(分类应用) - 附代码 1.鸢尾花iris数据介绍 2.数据集整理 3.粒子群优化BP神经网络 3.1 B ...

  8. DeepLearning tutorial(4)CNN卷积神经网络原理简介+代码详解

    FROM: http://blog.csdn.net/u012162613/article/details/43225445 DeepLearning tutorial(4)CNN卷积神经网络原理简介 ...

  9. 基于U-Net的的图像分割代码详解及应用实现

    摘要 U-Net是基于卷积神经网络(CNN)体系结构设计而成的,由Olaf Ronneberger,Phillip Fischer和Thomas Brox于2015年首次提出应用于计算机视觉领域完成语 ...

最新文章

  1. AI一分钟 | 富士康押宝人工智能,将投资21亿元用于AI研发
  2. [Python]Python操作/管理Mysql学习(一)
  3. 魔豆路由工程版体验:智能路由脱离手机的尝试
  4. Java基础笔记17
  5. python php区别-PHP,Python,Java写出来的WEB程序有什么区别?
  6. python flask route中装饰器的使用
  7. exec 和 call 用法详解
  8. v-if v-else-if v-else
  9. 史上最全java架构师技能图谱(上)
  10. 局域网在线监控设备扫描工具V1.0软件说明
  11. python读取序列5之后的数据_Python 基本功: 5. 数据序列化
  12. oracle更换年,Oracle数据库更换服务器10分钟切换方案
  13. 空间数据引擎oracle_Oracle-Spatial空间数据库基础
  14. 提取Excel中的超链接
  15. 初识Java+JDK的安装与环境变量的配置+IDEA的安装
  16. 利用串口对 89S 系列单片机编程
  17. 动画和漫画里ed、op、OVA、ost、bl、gl是什么意思?
  18. 计算机博士英文复试自我介绍,考博英语复试自我介绍7篇自我介绍
  19. 收藏 |7本 Matlab入门经典教程书籍,不可错过!
  20. Linux-常用的系统监控

热门文章

  1. 软件测试工程师薪资是多少?
  2. ​k8s常用命令 ​
  3. Android:Android系统中安装的数据文件夹在哪个位置,如何删除wps下载下来的文件
  4. python小游戏制作实验总结_20183202 实验四《python程序设计》实验报告
  5. ASP.NET 系列_08_编程指南(四)
  6. 【运维工程师必备技能之一】——英语基础
  7. 后台任务和PHP-Resque的使用
  8. Web3.0介绍与产业赛道(去中心化,金融与数字资产,应用与存储,区块链技术)
  9. Oracle概念及常用语句(一)
  10. day42 jQuery