对于WiFi指纹的介绍

发布于 2026-10-01 17:25 3069 字 16 min read 手写 每个字都是我自己敲的。

这里的“WiFi 指纹”不是 WiFi 密码,也不是简单判断“手机是否连接了某个 WiFi”,而是利用不同位置接收到的多个 AP 信号强度组合,推断设备所在的座位。 1. WiFi 指纹到底是什么 一个自习室通常有多个无线 AP。手机在不同座位上扫描到的 AP 信号强度不同。 例如,手机在座位 A 扫描得到: 在座位 B 可能得到: 虽然两个座位都连接同一个 WiFi,但各 AP...

这里的“WiFi 指纹”不是 WiFi 密码,也不是简单判断“手机是否连接了某个 WiFi”,而是利用不同位置接收到的多个 AP 信号强度组合,推断设备所在的座位。

1. WiFi 指纹到底是什么

一个自习室通常有多个无线 AP。手机在不同座位上扫描到的 AP 信号强度不同。

例如,手机在座位 A 扫描得到:

AP_001: -42 dBm
AP_002: -67 dBm
AP_003: -75 dBm
AP_004: -89 dBm

在座位 B 可能得到:

AP_001: -58 dBm
AP_002: -52 dBm
AP_003: -81 dBm
AP_004: -70 dBm

虽然两个座位都连接同一个 WiFi,但各 AP 的信号强度组合不同。这个组合就像该位置的“无线指纹”。

可以表示为:

F = {
    BSSID_001: -42,
    BSSID_002: -67,
    BSSID_003: -75,
    BSSID_004: -89
}

其中:

  • BSSID:某个 AP 的唯一标识;
  • RSSI:手机接收到该 AP 的信号强度;
  • RSSI 通常是负数;
  • 越接近 0,信号越强;
  • -42 dBm 通常比 -75 dBm 强。

不能只记录 WiFi 名称 SSID,因为多个 AP 可能使用同一个 SSID。应优先使用 BSSID 作为特征标识。

2. 它是如何定位座位的

WiFi 指纹定位不是通过公式直接计算距离,而是一个“采集样本、建立数据库、进行匹配”的过程。

第一步:建立指纹库

提前在每个座位采集大量样本。

例如:

座位AP_001AP_002AP_003采集时间
A-01-42-67-75上午
A-01-45-65-77上午
A-01-41-70-73下午
A-02-58-52-81上午
A-02-61-50-79下午

同一个座位不会只有一条指纹,而是会有一组指纹,因为 WiFi 信号会波动。

第二步:用户现场采集

用户进入自习室后,Android 客户端扫描当前环境:

当前观测:
AP_001: -44
AP_002: -68
AP_003: -76

第三步:和指纹库匹配

系统把当前观测与所有座位的历史指纹进行比较。

如果当前数据与 A-01 的样本最接近,则认为用户可能位于 A-01。

3. 为什么不能只看一个 AP

如果只使用一个 AP 的 RSSI,会出现很多问题:

  • 相邻座位信号差异很小;
  • 手机方向变化会影响 RSSI;
  • 人体、桌椅、墙壁会造成遮挡;
  • 某个 AP 可能暂时拥塞或失效;
  • 5 GHz 和 2.4 GHz 的传播特性不同。

因此需要使用多个 AP 的组合:

[AP_001, AP_002, AP_003, AP_004, ...]

通常 AP 越多、空间分布越合理,座位之间越容易区分。但 AP 数量不是越多越好,过弱、经常消失或变化很大的 AP 可能增加噪声。

4. 指纹数据如何预处理

原文档中提到的预处理主要解决三个问题:缺失、波动和设备差异。

4.1 AP 对齐

不同手机扫描到的 AP 集合可能不完全一样,所以要建立统一的 AP 列表:

AP_001, AP_002, AP_003, AP_004

如果某次扫描没有发现 AP_003,就需要补一个特殊值,例如:

AP_003 = -100

这里的 -100 不是实际测得的 RSSI,而是“没有检测到”的标记。实际实现时也可以额外增加一个“是否检测到”的字段,避免把缺失误认为真实弱信号。

4.2 去除异常值

例如某个 AP 平时在 -60 到 -75 之间,突然出现 -20 或 -110,就需要检查:

  • 是否扫描异常;
  • 是否 AP 发生切换;
  • 是否数据解析错误;
  • 是否设备靠近 AP;
  • 是否环境突然变化。

4.3 平滑处理

连续采样可能是:

-61, -65, -59, -70, -63

可以使用中位数:

-63

也可以使用移动平均或指数平滑,减少瞬时波动。

不过中位数、移动平均、指数平滑不一定全部叠加使用,应通过实验比较哪种效果最好。

4.4 设备差异校准

不同手机的 WiFi 芯片和天线不同。同一个位置上:

  • 手机 A 可能测到 -60;
  • 手机 B 可能测到 -67;
  • 手机 C 可能测到 -55。

因此采集指纹库时不能只使用一部手机。至少应使用 2 至 3 种 Android 设备进行测试,并分别统计准确率。

5. KNN 如何匹配座位

KNN 的基本思想是:

当前观测和哪些历史样本最接近,就把当前设备判定到这些样本所属的座位。

假设当前向量是:

X = [-44, -68, -76, -88]

某个历史样本是:

Y = [-42, -67, -75, -89]

可以计算它们的距离:

distance = sqrt(
    (-44 + 42)^2 +
    (-68 + 67)^2 +
    (-76 + 75)^2 +
    (-88 + 89)^2
)

距离越小,说明两个指纹越相似。

加权 KNN 会让距离更近的样本拥有更高权重:

权重 = 1 / (距离 + ε)

最后统计最近的若干个样本属于哪个座位。

输出可以是:

{
  "top1Seat": "A-01",
  "candidates": [
    {"seat": "A-01", "score": 0.86},
    {"seat": "A-02", "score": 0.63},
    {"seat": "B-01", "score": 0.41}
  ],
  "confidence": 0.86,
  "needManualReview": false
}

这里的 confidence 不是严格意义上的概率,而是一个用于比较和决策的可信度分数。必须在实验中进行校准,不能直接把 0.86 宣称成 86% 的真实准确率。

6. 为什么需要 Top-3,而不是只给一个座位

相邻座位的 WiFi 指纹可能非常接近。例如 A-01 和 A-02 只相差几十厘米,RSSI 变化可能小于环境噪声。

所以系统最好返回:

最可能:A-01
候选:A-02、A-03

这样可以:

  • 为推荐系统提供多个备选;
  • 在可信度低时提示用户确认;
  • 让管理员查看算法混淆情况;
  • 避免系统把一个不确定结果伪装成绝对正确。

7. WiFi 指纹能不能直接判断“人是否在座位上”

这是项目中最容易被误解的部分。

WiFi 指纹主要能判断:

某个设备当前更可能位于哪个位置。

它不能直接证明:

设备的主人此时正在座位上。

例如:

  • 用户把手机留在座位上,人已经离开;
  • 用户带着手机离开,但电脑仍然连接 WiFi;
  • 手机进入省电模式,暂时没有扫描;
  • 用户坐在座位旁边,信号被判定到相邻座位;
  • 多个人的设备同时影响无线环境。

因此,占座检测不能只依赖一次 WiFi 指纹,而应结合:

  • 用户主动开始使用;
  • 用户主动释放;
  • 连续多次定位结果;
  • 设备信号是否持续;
  • 离开持续时间;
  • 使用时长;
  • 设备是否在多个座位间快速跳转;
  • 管理员人工复核;
  • 可选的路由器连接日志。

正确的结果应该是:

设备疑似位于 A-01
→ 连续多次稳定检测
→ 判断 A-01 正在使用
→ 长时间出现异常行为
→ 标记为疑似占座
→ 管理员复核

不能写成:

检测到 WiFi 设备
→ 直接确定有人占座

8. 推荐的占用状态流程

可以使用以下状态机:

空闲
 ↓ 检测到设备
疑似使用
 ↓ 连续多次确认
使用中
 ↓ 信号短暂消失
疑似离开
 ├─ 短时间内恢复 → 使用中
 └─ 超过离开阈值 → 空闲

疑似占座流程:

使用中
 ↓ 长时间异常
疑似占座
 ↓ 管理员复核
正常使用 / 空闲

例如:

  • 连续两次识别到同一座位:进入“疑似使用”;
  • 连续 2 至 3 次结果稳定:进入“使用中”;
  • 信号消失 1 至 3 分钟:进入“疑似离开”;
  • 超过 10 分钟没有恢复:释放座位;
  • 设备仍存在但用户行为异常超过 30 至 60 分钟:标记“疑似占座”。

这些时间只是初始参数,最终必须用现场数据调整。

9. 采集指纹时应该怎么做

每个座位不能只采集一次,建议:

  • 每个座位每个时段采集 5 至 10 次;
  • 至少采集早、中、晚三个时间段;
  • 覆盖工作日和周末;
  • 使用 2 至 3 种 Android 手机;
  • 记录手机型号;
  • 记录采集方向和持握高度;
  • 记录是否有人、门窗是否打开、附近是否有遮挡;
  • 采集相邻座位和通道位置作为对照。

一个采集样本应包含:

{
  "roomId": 1,
  "seatId": "A-01",
  "deviceModel": "Pixel-6",
  "sampleTime": "2026-10-01T09:30:00",
  "wifi": [
    {"bssid": "AP_001", "rssi": -44, "frequency": 5180},
    {"bssid": "AP_002", "rssi": -68, "frequency": 2412}
  ],
  "environment": "上午,人流较少"
}

10. Android 端和路由器日志的区别

这里需要特别修正文档中的一个技术边界。

Android 主动扫描

Android 手机自己扫描周围 AP,得到:

多个 BSSID + 多个 RSSI

这最适合做 WiFi 指纹定位,也是本项目第一版推荐的方式。

路由器日志

路由器通常能提供:

  • 哪个设备连接了哪个 AP;
  • 设备连接和断开时间;
  • 有些设备能提供客户端 RSSI;
  • 部分企业级 AP 控制器能提供更多定位信息。

但普通路由器日志通常不能直接提供一组完整的“房间空间指纹”。因此:

路由器日志适合辅助判断设备是否在线,不应默认当作完整的 WiFi 指纹定位数据。

推荐采用混合方案:

Android 扫描结果
    负责座位级定位

路由器连接日志
    负责辅助判断设备在线和离线

用户操作
    负责建立使用意图

管理员复核
    负责处理疑难情况

11. 最适合本项目的实际方案

我建议第一版采用:

  1. Android 采集端在每个座位建立指纹库;
  2. Android 用户端在用户明确进入使用状态后进行受控扫描;
  3. 扫描结果上传后端;
  4. Python 服务使用加权 KNN 推断候选座位;
  5. Spring Boot 根据连续结果更新座位状态;
  6. 路由器日志只作为辅助信号;
  7. 低可信度和异常状态进入管理员复核;
  8. 所有判断保留原始事件、特征摘要和模型版本。

需要注意的是,Android 后台 WiFi 扫描受系统限制。不能假设应用被切到后台后仍然可以无限制稳定扫描,所以产品上应提供:

  • 前台采样服务;
  • 明确的采样状态;
  • 采样失败提示;
  • 手动刷新;
  • 网络断开重试;
  • 无法定位时的人工确认。

12. 应该如何评价 WiFi 指纹效果

不能只说“定位准确”,需要具体测量:

  • Top-1 准确率:第一候选就是正确座位的比例;
  • Top-3 准确率:前三个候选包含正确座位的比例;
  • 相邻座位混淆率;
  • 不同手机型号的准确率;
  • 不同时间段的准确率;
  • 有人和无人环境下的准确率;
  • AP 故障时的准确率;
  • 平均状态更新时间;
  • 正常离开被误判为占座的比例;
  • 真正占座没有被发现的比例。

数据划分不能把同一轮采样的相邻数据随机打散到训练集和测试集,否则结果可能虚高。应按日期、采集设备或采集批次划分测试数据。

13. 最重要的结论

WiFi 指纹在这个项目中适合解决:

“这个设备更可能位于哪个座位?”

它不适合单独解决:

“这个人是否一直坐在这个座位上?”

所以完整系统应该是:

WiFi 指纹定位
+ 连续时间行为
+ 用户使用会话
+ 路由器在线信息
+ 管理员人工复核

这样才能把“座位定位”和“占座检测”区分开,避免项目答辩时被质疑技术结论过度夸大。原开发文档中的算法部分基本方向正确,但“路由器日志可以直接参与完整指纹定位”这一点需要改成“Android 主动扫描负责指纹定位,路由器日志作为辅助数据”。

执笔 手写

随机文章

加载中...