北邮 AI无线通信 | 基于KNN的调制模式识别(3)依托于Jupyter Notebook对样本信号调制模式识别的仿真设计(modulation_recognition_module)

📅 2026/6/30 23:24:59
北邮 AI无线通信 | 基于KNN的调制模式识别(3)依托于Jupyter Notebook对样本信号调制模式识别的仿真设计(modulation_recognition_module)
目录一、什么是KNN二、为什么要在OSI的物理层中引入KNN三、基于KNN算法的调制识别技术建模四、数据生成部分仿真设计五、调制识别部分仿真设计5.0、摘要及项目文件结构5.0.1、摘要5.0.2、项目文件结构5.1、环境依赖5.1.1、conda生态5.1.2、anaconda的安装5.1.3、常见conda指令的使用5.2、虚拟环境的创建与配置5.3、开发工具与集成开发环境5.4、IDEPycharm Jetbrains5.5、IDEJupyter Notebook5.6、IDEVisual Studio Code5.6.1、插件的安装5.6.2、为Jupyter注册kernel5.6.3、为.ipynb文件选择内核5.7、仿真设计5.8、基于四阶累积量五个特征的仿真5.8.1、cell1导入包及数据部分5.8.2、cell2生成KNN分类器5.8.3、cell3BPSKModulationClassTest5.8.4、cell4QPSKModulationClassTest5.8.5、cell516QAM ModulationClassTest5.8.6、运行结果六、变参对比七、高阶累积量下的训练一、什么是KNN北邮 AI无线通信 | 基于KNN的调制模式识别1理论基础仿真建模二、为什么要在OSI的物理层中引入KNN北邮 AI无线通信 | 基于KNN的调制模式识别1理论基础仿真建模三、基于KNN算法的调制识别技术建模北邮 AI无线通信 | 基于KNN的调制模式识别1理论基础仿真建模四、数据生成部分仿真设计北邮 AI无线通信 | 基于KNN的调制模式识别2依托于MatlabR2023b对调制信号训练数据生成部分的仿真设计data_generation_module五、调制识别部分仿真设计本模块采用Pycharm实现负责加载数据、训练 KNN 分类器并在不同 SNR 条件下对四种调制方式进行分类识别与性能评估并绘制一个信噪比SINR与识别成功率的对应关系图。5.0、摘要及项目文件结构5.0.1、摘要针对四种典型数字调制方式的自动识别问题本文设计了一套基于K近邻算法的仿真实验方案。实验以信号高阶累积量的归一化幅度作为五维特征向量在纯净信号特征上训练分类器其中近邻数取十采用欧氏距离与多数表决机制。测试阶段采用差异化的信噪比扫描策略低阶调制从负信噪比起步评估高阶调制则扩展至更高信噪比范围并放宽步进以匹配不同调制阶数对噪声的敏感程度。每个信噪比点加载千个经高斯白噪声信道污染的样本逐样本预测并统计四分类混淆分布最终绘制识别准确率随信噪比变化的曲线同时记录误判流向为分析不同调制方式间的特征混淆边界提供了依据。5.0.2、项目文件结构首先应将上述digits文件夹下新生成的所有数据文件拷贝到本模块的data文件夹中故拷贝后本模块的文件结构如下modulation_recognition/ │ ├── fuc1.py # 核心KNN 分类器实现 可视化 │ ├── main.ipynb # Jupyter Notebook 主程序 │ │ ├── data/ # 数据文件与 data_generation/digits/ 内容相同 │ ├── sample.dat # 训练集4类 × 10条 40行 │ │ │ ├── testBPSK--4.dat ~ testBPSK-10.dat # BPSK 测试8个SNR-4~10dB │ ├── testQPSK--4.dat ~ testQPSK-10.dat # QPSK 测试8个SNR-4~10dB │ └── test16QAM-0.dat ~ test16QAM-40.dat # 16QAM 测试9个SNR0~40dB │ └── .ipynb_checkpoints/ └── main-checkpoint.ipynb # Notebook 自动检查点5.1、环境依赖5.1.1、conda生态15分钟彻底搞懂Anaconda Miniconda conda-forge miniforge Mamba历史上官方python包管理器pip曾对于跨语言依赖支持很不友好很多常用的库根本没法用一句简单的pip install 安装好。为了解决这个问题Continuum Analytics公司将python和各种常见的数学库打包成了一个超大的安装包这就是anaconda distribution的原型。anaconda distribution的第一版只是一个把所有依赖打包在一起的大杂烩而已而我们今天熟悉的conda命令在当时甚至还没有出现随着第一版的使用有关库更新、稀缺库安装、多余库删除的问题逐渐成为主要矛盾故而anaconda公司不久后就新增了一个命令行工具用来专门解决这些问题可以通过conda install/uninstall pkg_name来添加/删除包这就是conda指令原型。为此anaconda公司专门维护了一个自己的软件包仓库收录了几千个软件包。anaconda公司为每个支持的系统都提前编译好了对应的二进制版本并且精心处理好了各种复杂的依赖所以虽然conda和pip的功能类似但通过conda下载下来的包往往是可以开箱即用的少了很多对不同系统兼容的折腾。当然了无论怎么维护能够做到包和包之间100%兼容还是很困难的比如一个项目需要numpy2.3另外一个项目需要numpy1.26无论安装哪个版本都会影响另一个项目python官方的解决方法是使用venv创建虚拟环境每个项目都拥有自己一套独立的依赖互不影响conda也采用了类似的机制可以用conda create -n venv_name来创建不同的conda环境用conda activate/deactivate来激活/去激活在虚拟环境激活状态下采用conda install 来安装包就会安装在本虚拟环境中。如果在conda install之前没有执行conda activate的话安装的包将会被安装在base环境即conda自身运行环境中这是不推荐的。anaconda随后贡献了他们的软件托管平台但是为了保证其他用户不影响到他们原本已经维护好的仓库故而推出了一个名为binstar的平台后来改名为ANACONDA.ORG用户可以在这个平台上创建自己的软件仓库自己上传包、自己维护、自己负责兼容性的问题在anaconda.org上这样的仓库被称为channels而anaconda官方维护的仓库被命名为defaultsmainRmsys2三个channels当我们执行conda install 时默认下载源就是defaults。由于anaconda.org的出现人们更倾向于最小化自己的conda仓库故而anaconda公司推出了miniconda只包含conda命令和运行conda所需要的最基本的环境依赖所以体积比anaconda distribution小得多。当然现在的anaconda distribution也不仅仅是conda命令和各种包的集合了它还内置了很多其他的工具比如图形化的包管理界面anaconda navigator等这些在miniconda中是完全没有的。至此是conda的全部官方生态发展史下面我们来介绍conda的开源社区。【conda-forge】虽然conda的defaults已经收录了几千个常见的软件包但归根结底是由一家公司进行维护的精力有限。为了发展包罗万象的软件仓库由于有了anaconda.org这个非常成熟的托管平台开源社区在上面创造了一个叫做conda-forge的channelconda-forge是完全由开源社区共同维护的任何人都可以申请上传自己搭好的软件包审核通过之后就可以共享给所有人了。发展到现在conda-forge已经是anaconda.org上最大的channel了它包含了3w多个软件包如果算上不同操作系统的版本总量或超10w。conda-forge的内容完全由社区维护anaconda公司只负责提供anaconda.org平台进行托管。conda-forge在兼容性上可能比anaconda官方的defaults略逊一筹但是在大部分场景下是完全够用的而且conda-forge最大的优点是软件包数量极多更新非常快最重要的一点anaconda提供的defaults渠道从2020年之后对商业用途就开始收费了因此目前绝大多数开发者用的都是conda-forge在conda中使用conda-forge的方法是conda create -n nev_name -c conda-forge其中-c是-channel的缩写。无论是创建环境还是后续安装包-c conda-forge参数都要带上否则conda会默认从defaults进行下载可能引发一系列问题。【miniforge】由于每次使用conda-forge下载依赖都必须加-c conda-forge这一操作过于繁琐所以conda-forge开源社区的开发者参考miniconda自己打包了一个conda安装包修改了配置文件把默认的channel改成了conda-forge命名为miniforge。miniforge的安装效果和miniconda基本一样但miniforge的默认配置指向免费的conda-forge channel而miniconda则指向收费的defaults channel。5.1.2、anaconda的安装anaconda下载地址Index of /archiveanaconda安装教程2026最新版 Anaconda 下载与安装全流程详解超详细图文教程5.1.3、常见conda指令的使用如果已经安装了anaconda distribution就应该有anaconda prompt这个conda终端。你可以直接在电脑文件检索框中输入anaconda prompt就可以找到。①创建虚拟环境conda create -n name python3.12其中name是你虚拟环境的名字python可以指定任何版本也可以不指定。②删除虚拟环境conda env remove -n name其中name是你虚拟环境的名字。③列出所有虚拟环境conda env list④激活虚拟环境conda activate name其中name是你虚拟环境的名字。⑤退出当前虚拟环境conda deactivate⑥列出某一虚拟环境中的所有安装包conda list -n name其中name是你虚拟环境的名字如果你已经激活了该虚拟环境则可简化为conda list。⑦在某虚拟环境中安装某依赖库conda install library_name其中library_name是依赖库名称。⑧在某虚拟环境中删除某依赖库conda uninstall library_name其中library_name是依赖库名称。⑨查看依赖库版本conda list -n environment_name library_name其中environment_name是虚拟环境名library_name是待查询依赖库名如果已经激活了虚拟环境则直接conda list library_name即可。如果需要查看所有依赖库版本则直接conda list即可。5.2、虚拟环境的创建与配置基于对python项目的严谨管理建议新建虚拟环境并安装所需依赖库。本仿真模块基于KNN算法同时需要矩阵运算和绘图所以python应选3.8及以上版本同时安装所需库具体操作如下全部运行在管理员模式下的powershell中①创建虚拟环境conda create -n jupyter_309 python3.9②激活虚拟环境conda activate jupyter_309③添加所需库conda install numpy scikit-learn matplotlib ipykernel④检查所需库是否已经添加依次执行conda list numpy、conda list scikit-learn、conda list matplotlib、conda list ipykernel看是否有正确版本号输出。⑤退出虚拟环境conda deactivate5.3、开发工具与集成开发环境由于对未知样本的调试模式识别模块操作时具有时序逻辑即按照时间先后顺序应依次进行导入包及数据、生成KNN分类器、BPSK调制分类测试、QPSK调制分类测试、16QAM调制分类测试五个部分且需要断点检测每个部分的输出所以传统的python运行文件.py不能很好地操作因此本模块采用python语言编写的Interactive Python Notebook文件来仿真执行。对于传统的.py文件使用pycharm community这个IDE即可执行。但是该IDE无法执行.ipynb这种交互式文件所以无法选用pycharm community作为本仿真模块的集成开发环境。下面介绍几种常用的能够编译执行.ipynb文件的开发环境其中包括Pycharm Jetbrains、Notebook、VSCode。5.4、IDEPycharm Jetbrains社区版Pycharm是没法运行.ipynb文件的只有专业版Pycharm Jetbrains才可以而专业版软件要交钱所以大家要么动用钞能力要么花点时间跟着博主crack一下。想使用破解的pycharm jetbrains 2019 的朋友可以参考我的文章【保姆级】手把手教你下载专业版JetBrains Pycharm基于Anaconda环境其中需要的各种软件包可以私信和我要配置过程比较繁琐需要有一定基础的朋友耐心操作。配置成功打开后点击屏幕右上角配置python解释器同时点击Install Jupyter package让它自己默默安装就好选择ADD…选择conda environmentexisting environmentjupyter_309其余配置如下OK后如图所示点击OK并等待Jetbrains运行完所有的配置。然后就可以运行了。5.5、IDEJupyter Notebook【Jupyter Notebook简介】Jupyter Notebook 是一个基于浏览器架构的交互式计算平台最初源于 IPython 项目如今已发展为数据科学与科学计算领域最广泛使用的工具之一。其核心设计理念是以文档为中心将可执行代码、文本注释、数学公式、数据可视化图表与富媒体内容整合在同一个以单元格为基本组成单元的线性文档中。每个单元格可以独立编写和运行计算结果会在单元格下方即时呈现并持久保存这使得用户能够以分步探索的方式逐步推进分析任务而非像传统脚本那样需要一次性执行全部逻辑。Jupyter Notebook 的核心架构由前端浏览器界面和后端计算内核两部分组成。前端负责呈现文档结构、渲染富文本与图表并接收用户的编辑和运行指令。后端内核是与具体编程语言交互的执行引擎默认采用 Python 内核但也支持 R、Julia、Scala 等超过四十种编程语言。内核维护着持续运行的会话状态前一个单元格中定义的变量、导入的库和计算得到的中间结果都会保留在内存中后续单元格可以直接复用这种有状态的计算模型非常适合探索性数据分析场景因为用户无需反复重新加载数据或重复前期计算步骤即可在任意位置修改参数并观察影响。在功能层面Jupyter Notebook 支持 Markdown 语法编写的说明性文本允许插入 LaTeX 数学公式以精准表达理论推导内嵌的 matplotlib 图表可以直接在文档中渲染也可以嵌入图片、音频和视频等多媒体元素。这种多模态信息的融合能力使其超越了单纯的代码编辑工具成为一种可执行的分析报告形式。研究者可以将问题背景、理论依据、数据处理代码、数值结果和可视化证据按逻辑顺序编排在同一份文档中形成完整的论证链条读者既可以通读全文理解推导思路也可以逐单元格运行代码以验证结果的正确性。在科学计算与机器学习的工程实践中Jupyter Notebook 承担着多重角色。它是快速原型开发的试验台允许研究者在单元格级别验证算法逻辑的正确性。它是实验过程的记录载体每一次运行结果和参数配置都留存在文档中保障了实验的可追溯性。它也是技术报告与教学讲义的发布媒介代码与解释交替编排的结构天然适合展示推理过程。正因如此Jupyter Notebook 已成为学术论文复现、数据科学竞赛、机器学习教学和高性能计算交互式监控等领域的标准工具。如想了解更多请阅读python数据分析神器Jupyter notebook快速入门【Jupyter Notebook安装】如果已经安装了anaconda distribution这个生态应该自带Jupyter Notebook。你可以在anaconda prompt中先检查conda是否能用再检查notebook是否能用具体操作流程如下①在anaconda prompt或者powershell中输入conda --versoin如果返回了conda的版本号则说明conda可用②在anaconda prompt或者powershell中输入Jupyter Notebook --version如果返回了Jupyter Notebook的版本号说明Nupyter Notebook能用③如果上述conda能用但Jupyter Notebook不能用的话可以在anaconda prompt或者powershell中输入conda install jupyter然后再测一遍Jupyter Notebook --version看看是否返回了jupyter的版本号。如果遇到其他问题或者需要重新安装Jupyter Notebook请参考下面的文章。手把手教你安装Jupyter Notebook(保姆级教程)【注意】Jupyter Notebook不依赖于本地虚拟环境所以不需要操作5.2节。5.6、IDEVisual Studio CodeVSCode集成了很多拓展所以也可以选择在VSCode中运行.ipynb文件。5.6.1、插件的安装从VSCode左侧导航栏中找到拓展图标搜素“Jupyter”并依次安装Jupyter、Jupyter Cell Tags、Jupyter Keymap、Jupyter Notebook Renderers、Jupyter Slide Show这几个插件。5.6.2、为Jupyter注册kernel【不注册会怎么样】Jupyter和conda是两套独立的系统他们互不相通。你在终端里激活 jupyter_309 我的虚拟环境名称环境然后跑 .py 文件这样没问题因为conda 知道怎么找到这个 python.exe但 VS Code 打开 .ipynb 文件时它问的不是 conda而是 Jupyter 的 kernel 列表jupyter kernelspec list如果 jupyter_309 我的虚拟环境名称不在这个列表里VS Code 的 kernel 选择器里就看不到它。【怎么注册】①首先激活项目用到的虚拟环境详见5.2节conda activate jupyter_309②输入如下代码python -m ipykernel install --user --name jupyter_309 --display-name Python 3.9 (jupyter_309)③等价效果它在 C:\Users\Admin\AppData\Roaming\jupyter\kernels\jupyter_309\ 下生成了一个 kernel.json内容是{ argv: [ E:/Python/anaconda3/envs/jupyter_309/python.exe, -m, ipykernel_launcher, -f, {connection_file} ], display_name: Python 3.9 (jupyter_309), language: python }VS Code 读到这个文件就知道有这么个 kernel 可以用并且知道去哪找它的 Python 解释器。就这么简单——本质就是写了个配置文件。5.6.3、为.ipynb文件选择内核点击VSCode右上角“选择内核”在跳出的选项栏中选择“Python环境…”。运行即可。5.7、仿真设计本仿真实验的核心目标是验证 KNNK 近邻算法在数字调制信号自动识别中的可行性与性能表现。待识别的调制方式共四种分别为 BPSK、QPSK、16QAM 和 64QAM涵盖了从低阶到高阶的典型数字调制类型。实验的输入数据来源于 MATLAB 端预先生成的高阶累积量特征数据集Python 端即 main.ipynb则负责完成分类器的训练、测试与结果可视化。在正式进行分类之前Cell-0 完成了基础准备工作一方面导入 numpy、scikit-learn、matplotlib 等必要的 Python 科学计算与可视化库另一方面定义了 file2matrix 函数用于解析以制表符分隔的 .dat 数据文件。该函数将每行数据的前 5 列提取为特征向量最后一列作为对应的调制类型标签标签值直接取调制阶数——2 表示 BPSK、4 表示 QPSK、16 表示 16QAM、64 表示 64QAM。这种以调制阶数作为标签的编码方式使得后续的预测输出天然具有可解释性。完成数据解析工具的构建后Cell-2 加载训练集 sample.dat 并创建 KNN 分类器。训练集共包含 40 个样本四种调制方式各占 10 条每条样本为 5 维高阶累积量特征向量。分类器采用 scikit-learn 封装的 KNeighborsClassifierK 值取 10距离度量为默认的欧氏距离投票策略为均匀权重的多数表决。模型在纯净的、无噪声污染的训练特征上完成拟合这意味着分类器的决策边界完全由理想信号的高阶统计特性决定。随后的三个 Cell 构成了实验的核心测试部分分别对 BPSK、QPSK 和 16QAM 三种调制方式进行独立的单向测试。所谓单向测试是指每个 Cell 中待测样本的真实标签只有一种调制方式分类器需要判断每个样本属于四类中的哪一类从而不仅能统计正确识别率还能观察错误分类的流向分布——例如 BPSK 样本在低信噪比下是被误判为 QPSK 更多还是被误判为 16QAM 更多。这种设计使得实验能够揭示不同调制方式之间的特征混淆边界。每个测试 Cell 均采用 SNR 扫描的实验范式遍历一系列离散信噪比值在每个 SNR 点加载对应的测试数据文件如 testBPSK-0.dat 表示 0 dB 下的 BPSK 测试集该文件包含 1000 个经 AWGN 信道污染的测试样本。程序逐样本调用 predict 方法进行分类并分别累计四类预测结果的计数。以 BPSK 测试为例预测为 2 计为正确识别预测为 4、16、64 则分别累计到 QPSK、16QAM、64QAM 的误判计数器中。最终用正确识别的样本数除以总测试样本数1000得到该 SNR 点的识别准确率。代码流程如下┌─────────────────────────────────────────────────────┐ │ Cell 1: 导入包 定义 file2matrix() │ 读取 .dat 文件 → 取前5列作特征, 最后一列作标签 └────────────────────┬────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────┐ │ Cell 3: 训练 KNN 分类器 │ sample.dat → KNeighborsClassifier(k10) → fit() │ │ 标签: 2BPSK 4QPSK 1616QAM 6464QAM └────────────────────┬────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────┐ │ Cell 5 / 7 / 9: 三类测试BPSK / QPSK / 16QAM │ │ for each SNR: │ 加载 test{调制}-{SNR}.dat │ for each 样本 → kNN_classifier.predict() │ 统计: 判对了几次误判成什么 │ accuracy 判对数 / 总样本数 │ │ 画图: SNR(x) vs Accuracy(y) 折线图 │ │ BPSK/QPSK: SNR -4 ~ 10 dB (步长2) │ 16QAM: SNR 0 ~ 40 dB (步长5) └─────────────────────────────────────────────────────┘值得注意的是不同调制方式采用了差异化的 SNR 测试范围。BPSK 和 QPSK 的 SNR 扫描区间为 -4 dB 至 10 dB步进 2 dB。这两种低阶调制方式由于星座点间距较大即便在负信噪比条件下仍保持一定的可识别性因此实验从负 SNR 开始评估其性能下限。而 16QAM 的扫描区间则设置为 0 dB 至 40 dB步进 5 dB。这是因为高阶 QAM 调制的星座点密集对噪声更为敏感在低 SNR 下几乎无法区分——将 SNR 测试范围放宽并向上扩展至 40 dB更能完整地刻画其从接近随机猜测到接近完全识别之间的过渡过程。实验结果的呈现方式为 SNR-Accuracy 曲线图。每张图统一采用 8×5 英寸画布、100 DPI 分辨率、虚线加圆形标记的绘图风格X 轴标注为 SNR (dB)Y 轴标注为 Test accuracyY 轴范围固定为 0 到 1并开启网格辅助读数。三种调制方式以不同颜色加以区分BPSK 使用皇家蓝royalblueQPSK 使用紫色#80008016QAM 使用森林绿#228B22。这种统一而区分的可视化策略便于横向比较不同调制方式在相同 SNR 条件下的识别性能差异。最后需要指出本仿真设计存在的若干局限。其一训练集规模较小每类仅 10 个样本共计 40 个训练实例模型泛化能力可能受到训练数据覆盖范围的制约。其二训练样本均为无噪声的理想信号特征而测试样本经过了不同程度的噪声污染这种训练集与测试集之间的分布差异可能导致模型在低 SNR 场景下性能退化。其三K 值固定为 10未经交叉验证进行超参数调优无法确定当前选择是否为最优。其四64QAM 调制虽然出现在训练集中但缺少对应的测试数据文件和测试 Cell使得完整四分类性能评估无法闭环。以上问题的存在也为后续的改进与扩展指明了方向。5.8、基于四阶累积量五个特征的仿真5.8.1、cell1导入包及数据部分import numpy as np #导入numpy用于科学计算如矩阵运算 from sklearn.neighbors import KNeighborsClassifier # 包装好的knn算法 from collections import defaultdict import collections import matplotlib.pyplot as plt def file2matrix(filename): fr open(filename) numberOfLines len(fr.readlines()) #get the number of lines in the file returnMat np.zeros((numberOfLines,5)) #prepare matrix to return the number of features classLabelVector [] #prepare labels return fr open(filename) index 0 for line in fr.readlines(): line line.strip() listFromLine line.split(\t) returnMat[index,:] listFromLine[0:5] #chose features classLabelVector.append(float(listFromLine[-1])) #classLabelVector.append(float(0)) index 1 return returnMat,classLabelVector5.8.2、cell2生成KNN分类器data_X,data_y file2matrix(data/sample.dat) data_y_name [BPSK,QPSK,16QAM,64QAM]#分类名称 X_train data_X #numpy ndarray格式 y_train data_y #numpy ndarray格式 kNN_classifier KNeighborsClassifier(n_neighbors10) # knn中k值 kNN_classifier.fit(X_train, y_train) # fit 拟合5.8.3、cell3BPSKModulationClassTest代码流程①将上一步生成好的待测试的BPSK信号导入②将生成的P1000路BPSK信号每一路都调用KNN算法识别并贴上标签③统计这P1000路BPSK的识别情况④正确率等于成功识别的数量/P。SNR [2*x for x in range(-2,6)] accuracy defaultdict(list) correctCount defaultdict(list) QPSKnumber defaultdict(list) QAM16number defaultdict(list) QAM64number defaultdict(list) for snr in SNR: testDataMat,testLabels file2matrix(data/testBPSK- str(snr) .dat) # load data setfrom file numTestVecs testDataMat.shape[0] correctCount[snr] 0.0 QPSKnumber[snr] 0.0 QAM16number[snr] 0.0 QAM64number[snr] 0.0 for i in range(numTestVecs): X_predict testDataMat[i, :].reshape(1, -1) y_predict kNN_classifier.predict(X_predict) if (y_predict 2): correctCount[snr] 1.0 if (y_predict 4): QPSKnumber[snr] 1.0 if (y_predict 16): QAM16number[snr] 1.0 if (y_predict 64): QAM64number[snr] 1.0 accuracy[snr] correctCount[snr] / (numTestVecs) print(the total correct rate on %d dB SNR is: % (snr), (accuracy[snr])) print(正确判断为BPSK: , correctCount[snr]) print(判断为QPSK: , QPSKnumber[snr]) print(判断为16QAM: , QAM16number[snr]) print(判断为64QAM: , QAM64number[snr]) accuracy collections.OrderedDict(sorted(accuracy.items())) # sort by ascending SNR values #画图 print (accuracy) plt.style.use(classic) plt.figure(figsize(8, 5), dpi100) x SNR y list(accuracy.values()) plt.plot(x, y, markero, linewidth2.0, linestyledashed, colorroyalblue) plt.axis([0, 10, 0, 1]) plt.xticks(np.arange(min(x), max(x)1, 2.0)) #横坐标范围及间隔 plt.yticks(np.arange(0, 1, 0.10)) ttl plt.title(SNR vs Accuracy - BPSK, fontsize16) ttl.set_weight(bold) plt.xlabel(SNR (dB), fontsize14) plt.ylabel(Test accuracy, fontsize14) plt.grid() plt.show()5.8.4、cell4QPSKModulationClassTestSNR [2*x for x in range(-2,6)] accuracy defaultdict(list) correctCount defaultdict(list) BPSKnumber defaultdict(list) QAM16number defaultdict(list) QAM64number defaultdict(list) for snr in SNR: testDataMat, testLabels file2matrix(data/testQPSK- str(snr) .dat) # load data setfrom file numTestVecs testDataMat.shape[0] correctCount[snr] 0.0 BPSKnumber[snr] 0.0 QAM16number[snr] 0.0 QAM64number[snr] 0.0 for i in range(numTestVecs): X_predict testDataMat[i, :].reshape(1, -1) y_predict kNN_classifier.predict(X_predict) if (y_predict 2): BPSKnumber[snr] 1.0 if (y_predict 4): correctCount[snr] 1.0 if (y_predict 16): QAM16number[snr] 1.0 if (y_predict 64): QAM64number[snr] 1.0 accuracy[snr] correctCount[snr] / (numTestVecs) print(the total correct rate on %d dB SNR is: % (snr), (accuracy[snr])) print(判断为BPSK:, BPSKnumber[snr]) print(正确判断为QPSK:, correctCount[snr]) print(判断为16QAM:, QAM16number[snr]) print(判断为64QAM:, QAM64number[snr]) accuracy collections.OrderedDict(sorted(accuracy.items())) # sort by ascending SNR values # 画图 print(accuracy) plt.style.use(classic) plt.figure(figsize(8, 5), dpi100) x SNR y list(accuracy.values()) plt.plot(x, y, markero, linewidth2.0, linestyledashed, color#800080) plt.axis([0, 10, 0, 1]) plt.xticks(np.arange(min(x), max(x) 1, 2.0)) plt.yticks(np.arange(0, 1, 0.10)) ttl plt.title(SNR vs Accuracy - QPSK, fontsize16) ttl.set_weight(bold) plt.xlabel(SNR (dB), fontsize14) plt.ylabel(Test accuracy, fontsize14) plt.grid() plt.show()5.8.5、cell516QAM ModulationClassTestSNR [5*x for x in range(0, 9)] accuracy defaultdict(list) correctCount defaultdict(list) BPSKnumber defaultdict(list) QPSKnumber defaultdict(list) QAM64number defaultdict(list) for snr in SNR: testDataMat, testLabels file2matrix(data/test16QAM- str(snr) .dat) # load data setfrom file numTestVecs testDataMat.shape[0] correctCount[snr] 0.0 BPSKnumber[snr] 0.0 QPSKnumber[snr] 0.0 QAM64number[snr] 0.0 for i in range(numTestVecs): X_predict testDataMat[i, :].reshape(1, -1) y_predict kNN_classifier.predict(X_predict) if (y_predict 2): BPSKnumber[snr] 1.0 if (y_predict 4): QPSKnumber[snr] 1.0 if (y_predict 16): correctCount[snr] 1.0 if (y_predict 64): QAM64number[snr] 1.0 accuracy[snr] correctCount[snr] / (numTestVecs) print(the total correct rate on %d dB SNR is: % (snr), (accuracy[snr])) print(判断为BPSK:, BPSKnumber[snr]) print(判断为QPSK:, QPSKnumber[snr]) print(正确判断为16QAM:, correctCount[snr]) print(判断为64QAM:, QAM64number[snr]) accuracy collections.OrderedDict(sorted(accuracy.items())) # sort by ascending SNR values # 画图 print(accuracy) plt.style.use(classic) plt.figure(figsize(8, 5), dpi100) x SNR y list(accuracy.values()) plt.plot(x, y, markero, linewidth2.0, linestyledashed, color#228B22) plt.axis([0, 10, 0, 1]) plt.xticks(np.arange(min(x), max(x) 1, 5.0)) plt.yticks(np.arange(0, 1, 0.10)) ttl plt.title(SNR vs Accuracy - 16QAM, fontsize16) ttl.set_weight(bold) plt.xlabel(SNR (dB), fontsize14) plt.ylabel(Test accuracy, fontsize14) plt.grid() plt.show()5.8.6、运行结果下面展示的是Pycharm Jetbrains运行效果。依次运行各个cell​​六、变参对比北邮 AI无线通信 | 基于KNN的调制模式识别4样本信号调制模式识别仿真设计的参数探究七、高阶累积量下的训练北邮 AI无线通信 | 基于KNN的调制模式识别4样本信号调制模式识别仿真设计的参数探究