feat: CellData.sql 新增 cellinfo→sector 逆推(频段特征库+物理站/扇区/站型规则,补缺不覆盖)

This commit is contained in:
2026-06-26 10:45:57 +08:00
parent eb34f9804c
commit e7b35ca837
3 changed files with 253 additions and 3 deletions
+105 -3
View File
@@ -1,3 +1,105 @@
UPDATE cellinfo SET `带宽` = IF(`带宽` IS NULL OR `带宽` = '', '0M', CONCAT(REPLACE(UPPER(`带宽`),'M',''), 'M'));␍
␍
# 后续实现通过cellinfo表处理为扇区表,支撑扇区容量分析
-- =============================================================================
-- CellData 数据处理脚本(在 celldata 库执行)
-- 1) 规范化 cellinfo.带宽
-- 2) 重建频段特征库 sector_band_ref(频点/PLMN -> 制式/频段 对应表)
-- 3) 由 cellinfo 逆推 sector(扇区/物理站/制式/频段/带宽/站型/网络)
-- —— 不清空 sector,仅补充缺失 CGI,已有行(含人工修正)保留不覆盖
-- 逆推规则与准确率见 docs/sector_inference_research.md
-- =============================================================================
-- 1. 带宽规范化:空值补 0M,统一大写并以 M 结尾(如 20M)
UPDATE cellinfo SET `带宽` = IF(`带宽` IS NULL OR `带宽` = '', '0M', CONCAT(REPLACE(UPPER(`带宽`),'M',''), 'M'));
-- 2. 频段特征库:网络 + 频点区间(+PLMN) -> 制式/频段
-- 700M 与 广电 同频点 763.25,由 PLMN 区分(460-00=移动700M,460-15=中国广电)
-- D频 与 3DMM 同频点同 PLMN 同带宽,cellinfo 无法区分,统一判 D频(3DMM 为天线属性)
DROP TABLE IF EXISTS sector_band_ref;
CREATE TABLE sector_band_ref (
`网络` varchar(8),
f_lo decimal(10,2),
f_hi decimal(10,2),
plmn varchar(16) NULL,
`制式` varchar(20),
`频段` varchar(20)
);
INSERT INTO sector_band_ref (`网络`,f_lo,f_hi,plmn,`制式`,`频段`) VALUES
('5G',4000,99999,NULL,'4.9G','4.9G'),
('5G',700,800,'460-00','700M','700M'),
('5G',700,800,'460-15','广电','广电'),
('5G',2000,3000,NULL,'2.6G','2.6G'),
('4G',900,1000,NULL,'FDD','FDD900'),
('4G',1000,1880,NULL,'FDD','FDD1800'),
('4G',1880,1920,NULL,'TDD','F频'),
('4G',1920,2110,NULL,'TDD','A频'),
('4G',2300,2400,NULL,'TDD','E频'),
('4G',2400,2700,NULL,'TDD','D频');
-- 3. 逆推暂存表:预处理小区名称(全角括号->半角、【】->()、去空格/制表符)
DROP TABLE IF EXISTS _sector_infer;
CREATE TABLE _sector_infer AS
SELECT
c.CGI, c.`网络`, c.`带宽`, c.PLMN, c.`频点`, c.`制式` AS ci_zs,
REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
c.`小区名称`,' ',''),CHAR(9),''),' ',''),'(','('),')',')'),'【','('),'】',')') AS name1
FROM cellinfo c;
ALTER TABLE _sector_infer
ADD COLUMN `制式` varchar(20),
ADD COLUMN `频段` varchar(20),
ADD COLUMN `站型` varchar(10),
ADD COLUMN numstr varchar(20),
ADD COLUMN base varchar(220),
ADD COLUMN `物理站` varchar(200),
ADD COLUMN `扇区` varchar(210);
-- 3.1 设备码([频率前缀]-Z[xx]-[扇区号])剥离得到 base;尾部数字串;站型判定
-- 站型:设备码尾字母 W=室分;名称含"微小"=微站;其余=宏站
UPDATE _sector_infer SET
base = REGEXP_REPLACE(name1,'[A-Z0-9]+-Z[A-Z0-9]{2}-[0-9]+$',''),
numstr = REGEXP_SUBSTR(name1,'[0-9]+$'),
`站型` = CASE
WHEN name1 REGEXP 'Z[A-Z]W-[0-9]+$' THEN '室分'
WHEN name1 LIKE '%微小%' THEN '微站'
ELSE '宏站' END;
-- 3.2 制式/频段:按特征库匹配;未命中回落 cellinfo 原制式
UPDATE _sector_infer t
JOIN sector_band_ref r
ON r.`网络` = t.`网络`
AND CAST(NULLIF(t.`频点`,'') AS DECIMAL(10,2)) >= r.f_lo
AND CAST(NULLIF(t.`频点`,'') AS DECIMAL(10,2)) < r.f_hi
AND (r.plmn IS NULL OR r.plmn = t.PLMN)
SET t.`制式` = r.`制式`, t.`频段` = r.`频段`;
UPDATE _sector_infer SET `制式` = ci_zs, `频段` = ci_zs WHERE `制式` IS NULL;
-- 3.3 物理站(非 700M/广电):去码后删全部括号注记,保留(微小X)并回贴;
-- 再去掉不闭合的悬空开括号与孤立右括号
UPDATE _sector_infer SET `物理站` = CONCAT(
TRIM(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(
base,'\\([^()]*\\)',''),'\\([^()]*\\)',''),'\\([^()]*\\)',''),'\\([^()]*$',''),'[)]+$',''),'^[)]+','')),
IFNULL(REGEXP_SUBSTR(name1,'[(]微小[A-Z]?[)]'),''))
WHERE `制式` IS NULL OR `制式` NOT IN ('700M','广电');
-- 3.4 物理站(700M/广电):取以"(江门"开头的括号内容为真实站址;
-- 无则取外层(去 CBN- 前缀与注记)。括号内容以"共"开头属共建标注,归外层
UPDATE _sector_infer SET `物理站` =
CASE WHEN REGEXP_SUBSTR(base,'\\(江门[^()]*') <> ''
THEN TRIM(SUBSTRING(REGEXP_SUBSTR(base,'\\(江门[^()]*'),2))
ELSE TRIM(REGEXP_REPLACE(REGEXP_REPLACE(base,'\\(.*$',''),'^CBN-?','')) END
WHERE `制式` IN ('700M','广电');
-- 3.5 扇区 = 物理站 + 扇区号(700M/广电取末位数字;其余取数字串 % 100)
UPDATE _sector_infer SET `扇区` = CONCAT(`物理站`,
CASE WHEN numstr IS NULL OR numstr = '' THEN ''
WHEN `制式` IN ('700M','广电') THEN RIGHT(numstr,1)
ELSE CAST(CAST(numstr AS UNSIGNED) % 100 AS CHAR) END);
-- 4. 补缺写回 sector:仅插入 sector 中尚不存在的 CGI(区域留空,不参与逆推)
-- 已存在的 CGI 一律保留,避免人工修正(如 3DMM、人工纠正的物理站/带宽)被覆盖
INSERT INTO sector (CGI,`扇区`,`物理站`,`区域`,`制式`,`频段`,`带宽`,`站型`,`网络`)
SELECT i.CGI, i.`扇区`, i.`物理站`, NULL, i.`制式`, i.`频段`, i.`带宽`, i.`站型`, i.`网络`
FROM _sector_infer i
LEFT JOIN sector s ON s.CGI = i.CGI
WHERE s.CGI IS NULL;
DROP TABLE _sector_infer;
+9
View File
@@ -972,6 +972,15 @@ CellData 处理日志细化(`app/services/cell_data.py`):
- 同扇区同运营商小区每项加详情图标按钮(`OpenOutline`),点击 `openDetail(sib.id)` 在抽屉内切换到该小区详情;`.cap-sib-item` 改 flex 行(`.cap-sib-body` 占主 + 右侧 `.cap-icon-btn`)。新增通用 `.cap-icon-btn` 样式(复制/详情共用)。
- 验证:`frontend` `vue-tsc --noEmit` 通过。
## 2026-06-26:CellData.sql 新增 cellinfo→sector 逆推(特征库 + 补缺不覆盖)
- 背景:`celldata.cellinfo`(自动处理、有数据源)→ `celldata.sector`(原人工整理)。新脚本自动逆推 sector 的 扇区/物理站/制式/频段/带宽/站型/网络(区域留空,最终不用)。
- 特征库 `sector_band_ref`(频点区间+PLMN→制式/频段,10 条):700M/广电同频 763.25 用 PLMN 区分(460-00/460-15);4.9G 用频点≥4000;4G FDD900/1800、TDD F/A/E/D 频按频点分档。**D频与3DMM 同频同PLMN同带宽不可区分**,统一判 D频(3DMM 为天线属性)。
- 逆推 staging `_sector_infer`:预处理小区名(全角括号→半角、【】→()、去空格/制表符)→ 剥设备码正则 `[A-Z0-9]+-Z[A-Z0-9]{2}-[0-9]+$` 得 base;站型(码尾 W=室分 / 名称含"微小"=微站 / 否则宏站);制式频段经特征表 JOIN(未命中回落 cellinfo 制式);物理站(非700M 删全部成对括号+清悬空+回贴(微小X);700M 取"(江门"括号内容否则外层去CBN-);扇区=物理站+扇区号(700M 末位/其余 %100)。
- 落库:`INSERT` 仅补 sector 中缺失 CGI(**不清空、不覆盖**已有行,保人工修正如 3DMM/15M/纠正物理站),末尾 DROP staging;`sector_band_ref` 作为持久特征库保留。
- 准确率(MCP 实测,重叠 66001):网络 100%、制式 97.88%(排除 3DMM 即 100%)、频段 97.6%、带宽 99.75%、站型 99.94%、**物理站 99.59%、扇区 99.20%**;残差为不可还原的人工差异(室分多载波编号、700M 个别人工编号、源数据制表符等)。详见 `docs/sector_inference_research.md`。
- 关键坑:MySQL 字符串字面量会吞掉未知转义的反斜杠,正则字面量需写 `\\(`(.sql 文件)/ JSON 调用需 `\\\\(`;ICU 正则字符类内的 `[ ]` 易误判,统一把名称中的 `[]` 转 `()` 后只处理圆括号。
## 2026-06-26:离线可用性全面审计(运行期零外网)
结论:**运行期已完全离线就绪,无需改运行时代码**;外网仅「构建期」需要。审计证据:
+139
View File
@@ -0,0 +1,139 @@
# cellinfo → sector 逆推调研笔记
> 目标:用 `celldata.cellinfo`(自动处理、有数据源)逆推出 `celldata.sector`(人工据 cellinfo 整理)。
> 现有 sector 作为基准/参考。逆推时**不清空** sector:仅补充缺失 CGI,已有的保留(避免人工纠正被自动运行冲掉)。
> 脚本与特征库写入 `CellData.sql`。本文件记录字段映射、规则、每轮测试的优化点与准确率。
## 一、两表结构(celldata)
cellinfo(数据源,66778 行):`CGI, eNodeBID, CellID, PLMN, 基站名称, 小区名称, 频点, 带宽, 制式, 功率, 网络`
sector(目标,66969 行):`CGI, 扇区, 物理站, 区域, 制式, 频段, 带宽, 站型, 网络`
连接键:`CGI`。sector 比 cellinfo 多 ~191 行(历史/其他来源),逆推以 cellinfo 为准。
## 二、字段来源结论
| sector 字段 | 来源 | 说明 |
|---|---|---|
| CGI | 复制 cellinfo.CGI | 连接键 |
| 网络 | 复制 cellinfo.网络 | 4G / 5G |
| 带宽 | 复制 cellinfo.带宽 | cellinfo 已规范化为如 `20M` |
| 区域 | **留空(不推理)** | 用户确认最终不使用该字段 |
| 制式 + 频段 | 频点 + PLMN 推导(特征表) | 见三 |
| 站型 | 名称关键字 + 设备码推导 | 见四 |
| 物理站 | 小区名称解析 | 见五 |
| 扇区 | 物理站 + 扇区号 | 扇区号见五 |
## 三、频点 → 制式 / 频段(特征库核心)
cellinfo.制式 已给出粗类(FDD/TDD/700M/2.6G),频段再按频点细分;个别需 PLMN 区分:
| 网络 | 频点范围 | PLMN | 制式 | 频段 | 实测样本 |
|---|---|---|---|---|---|
| 5G | ≥4000 | 任意 | 4.9G | 4.9G | 4827.36、4919.52 |
| 5G | 700–800 | 460-00 | 700M | 700M | 763.25(移动)9808 |
| 5G | 700–800 | 460-15 | 广电 | 广电 | 763.25(广电)9802 |
| 5G | 2000–3000 | 任意 | 2.6G | 2.6G | 2524.95 等 |
| 4G | 900–1000 | 任意 | FDD | FDD900 | 939.0 |
| 4G | 1000–1880 | 任意 | FDD | FDD1800 | 1810–1827 |
| 4G | 1880–1920 | 任意 | TDD | F频 | 1895.0、1909.4 |
| 4G | 1920–2110 | 任意 | TDD | A频 | 2017.5 |
| 4G | 2300–2400 | 任意 | TDD | E频 | 2330、2349.8、2364.6 |
| 4G | 2400–2700 | 任意 | TDD | D频 | 2624.6 等 |
**关键歧义**
1. **700M vs 广电**:同频点 763.25,由 **PLMN** 区分(460-00=移动 700M,460-15=中国广电)。✅ 可完美区分。
2. **D频 vs 3DMM**:同频点(2624.6 等)、同 PLMN(460-00)、同带宽(20M)、功率也重叠(18.2 两类都有)。**cellinfo 无法可靠区分**——3DMM 是 3D-MIMO 天线属性,非频点/名称可还原。逆推统一归 `TDD/D频`;现有 sector 中的 3DMM 因「不覆盖已有行」而保留,新增行只能判 D频(已知局限)。
## 四、站型规则(实测覆盖度)
| 站型 | 规则 | 命中 | 总数 | 备注 |
|---|---|---|---|---|
| 室分 | 小区名设备码尾 `Z[A-Z]W`(如 ZLW/ZRW/ZFW,末字母 W) | 10146 | 10168 | 99.8% |
| 微站 | 小区名含「微小」(如 (微小M)/(微小I)) | 1086 | 1086 | 100% |
| 宏站 | 其余(设备码尾 H,如 Z5H/ZLH/ZFH,且无微小) | — | 54747 | 仅 18 行宏站名含微小(误差≈0.03%) |
判定顺序:室分(W 码) → 微站(微小) → 宏站。W 码与微小在数据中互斥。
## 五、物理站 / 扇区解析
预处理(仅为解析可靠):全角 `()【】`→半角 `()[]`、去空格。
**设备码**(位于小区名尾部):`<频率前缀>-Z<x><尾字母>-<扇区号>`,正则 `[A-Z0-9]+-Z[A-Z0-9]{2}-[0-9]+$`。
- 频率前缀:U / E / D / F / DC / RD / RDC 等;尾字母 H=室外(宏/微)、W=室分。
- 例:`U-Z5H-0711`、`E-ZLW-8`、`D-ZRH-103`、`F-ZLH-3`、`RDC-ZFH-2`。
**扇区号**(取小区名尾部数字串):
- 700M/广电(Z5H 码):取**末位数字**。`0711`→1、`0712`→2、`0713`→3、`30712`→2。
- 其余:取数字串 **% 100**。`-3`→3、`-103`→3、`-113`→13、`-203`→3、`-16`→16。
**物理站**:
- **非 700M**:= 小区名去设备码后,删除所有括号/方括号内容,但**保留 `(微小X)`**。
- 例 `江门台山河东家禽(从…搬迁)(微小M)(共…F-ZLH)F-ZLH-2` → `江门台山河东家禽(微小M)`。
- 例 `江门鹤山坚美园52至53栋(共…E-ZLW)E-ZLW-8` → `江门鹤山坚美园52至53栋`。
- **700M/广电**:名称结构 `CBN-<枢纽>(<真实站址>)<码>` 或 `CBN-<站址><码>`。
- 去码后取**最后一个括号内容**作为物理站;若该内容**以「共」开头**(共建标注,如 `(共…E-ZLW)`)则改取**括号前的外层**(去 `CBN-` 前缀);无括号则取外层去 `CBN-`。
- 取到的内容再删除其内部子括号(如 `(搬迁)(重建)`)。
- 注意:`共和` 等地名(括号内容以「江门」开头、共字在中间)**不算共建**,仍取内层。
- 例 `CBN-江门新会圭阳路(江门新会雍翠峰(搬迁))U-Z5H-0712` → `江门新会雍翠峰`。
- 例 `CBN-江门台山通济公园U-Z5H-0713` → `江门台山通济公园`。
- 例 `CBN-江门鹤山铸德(江门鹤山共和鸿江工业区)U-Z5H-0712` → `江门鹤山共和鸿江工业区`。
**扇区** = 物理站 + 扇区号(如 `江门新会五和农村二` + `1` = `江门新会五和农村二1`)。
> 括号宽度:现有 sector 的 `(微小X)` 用全角 `()`。逆推统一转半角输出;对比准确率时两侧都做括号归一化,衡量语义正确性而非宽度。
## 六、测试与准确率(逐轮更新)
测试方法:在 celldata 建 `sector_band_ref` 特征表 + `_sector_infer` 暂存表逐字段推导,
JOIN 现有 `sector`(重叠 CGI **n=66001**)逐字段比对;物理站/扇区比对时两侧做括号+空白归一化。
### Round 1(基础规则)
| 字段 | 准确率 |
|---|---|
| 网络 | 100%(66001)|
| 带宽 | 99.75%(65838)|
| 制式 | 97.88%(64601)|
| 频段 | 97.60%(64417)|
| 站型 | 99.94%(65963)|
| 物理站 | 99.12%(65419)|
| 扇区 | 98.72%(65159)|
失配定位:
- 制式失配 **100% 是 TDD↔3DMM**(1400)——同频/同 PLMN/同带宽/功率重叠,不可还原。
- 频段失配 = 3DMM(1400) + F频↔A频(162,1895/1909 同频人工分档) + E频↔D频(22)。
- 带宽失配主要 cellinfo=20M 而人工=15M(155,源数据人工修正)。
- 站型失配 38:20 个室分码为 `Z[A-Z]R`(如 E-ZLR,高铁 SM 站)未被 W 规则覆盖;18 个宏站名含"微小"被误判微站。
- 物理站/扇区失配:700M 多括号/不闭合、非 700M 共建/拉远不闭合括号。
### Round 2(物理站 v2/v3:按关键字保留限定括号)——失败回退
尝试只删"共/从/拉远/搬迁…"备注括号、保留 `(龙山路)(红线内)(1)`,物理站反降到 ~98.2%。
原因:① 末尾 `[)]+$` 误删了 `(微小M)` 等合法括号的右括号;② 大量无备注关键字的别名括号本应删除却被保留,净损失。结论:**"删全部括号+回贴微小"才是最优主策略**。
### Round 3(v4:删全部括号 + 悬空清理 + 700M 取"(江门"内容)——定稿
- 非 700M:去码 → 删全部成对括号(3 轮) → 删悬空开括号 `\([^()]*$` → 删孤立 `)` → 回贴 `(微小X)`。
- 700M/广电:取 `(江门…` 括号内容;无则取外层去 `CBN-`("共"开头自然落外层)。
- 扇区号:700M 末位;其余 %100。
| 字段 | 准确率 | 说明 |
|---|---|---|
| 网络 | 100% | 复制 |
| 制式 | 97.88%(排除 3DMM 即 **100%**)| 仅差不可还原的 3DMM |
| 频段 | 97.60% | 差额=3DMM+同频 F/A、E/D 人工分档 |
| 带宽 | 99.75% | 差额为人工把 20M 改 15M |
| 站型 | 99.94% | |
| 物理站 | **99.59%**(65728)| |
| 扇区 | **99.20%**(65470)| |
剩余残差为**不可还原的人工差异**,不再继续拟合(避免过拟合):
- 室分多载波编号不一致:`E-ZLW-12→2`、`-111→1`、`-115→5`(末位)与 `-16→16`(%100)并存;脚本按用户既定 %100。
- 700M 个别人工编号:`0713→1`、`0712→4`、`0712→空`,与名义 071N→N 规则冲突。
- 物理站个别含区域前缀(`柏怡酒店`↔`江海柏怡酒店`)、保留 `(龙山路)/(1)` 等;真实数据存在尾随制表符。
- 因"不覆盖已有行",上述人工值在自动运行中均被保留,不受影响。
### 落库策略
仅 `INSERT` sector 中缺失的 CGI(本次快照 **921 条**),已有 CGI 一律保留。区域留空。
### 复现实测命令(celldata)
按 `CellData.sql` 顺序执行即可;准确率核验 SQL:
`SELECT 物理站/扇区 归一化后 = sector 对应值 的占比 FROM _sector_infer JOIN sector USING(CGI)`。