MATLAB云模型工具箱:正逆向云发生器与综合评价赋权

发布时间:2026/11/4 10:36:41
MATLAB云模型工具箱:正逆向云发生器与综合评价赋权 简介面向从事不确定性建模、综合评价与方法复现的高校师生及工程技术人员这份 MATLAB 云模型实现代码提供了可直接调用的基础脚本。内容围绕云模型的核心流程展开包含主程序与云变换函数两部分可用于生成云滴、观察云图并完成正向云发生器的基本计算也便于按期望、熵、超熵等数字特征调整参数理解云模型在权重确定与评价问题中的使用方式。压缩包共 2 个文件均为 .m 脚本整体约 1KB体积轻量放到 MATLAB 工作路径下即可阅读和运行。目前已有 1581 人学习说明其在课程实验、论文复现与算法入门场景中具有一定参考价值。读者可据此快速搭建云模型实验框架在此基础上修改隶属度计算、替换输入数据或扩展逆向云过程减少从零编写底层代码的时间并对照输出结果检查参数设置与实现逻辑是否合理。1. 云模型工具箱三个数字把“大概 0.6 分”装进去做综合评价时常碰到这样的局面十个专家对某个指标打分分数从 0.51 到 0.83 散着最后取个平均数交差可这个平均数到底代表 0.68 还是“大概零点六几”谁也说不清。这份 matlab 云模型代码就是干这件事的——把定性判断用期望 Ex、熵 En、超熵 He 三个数字描述出来再用正向、逆向云发生器在语言值和定量数值之间来回转换。权重计算是这套代码的重点专家给出的模糊权重能一路算到云模型综合评价结果。适合正在做评价类课题、要给指标体系赋权又不想从零推公式的开发者也适合手头有 matlab 基础、想把云模型接进已有评价脚本的人。代码采用函数式组织单个 .m 文件拎出来就能调不依赖工具箱之外的东西。2. 目录结构与运行环境从 addpath 到第一张云滴图2.1 一份能直接跑的云模型工程长什么样这类代码包通常按“算法函数、演示脚本、样例数据”三层摆放。函数全部放在 src 下每个 .m 只做一件事demo 目录里是能直接按 F5 的入口脚本data 里放专家打分样例方便你先跑通再换成自己的数据。下面这个结构是我拆过的几份云模型包里最顺手的摆法函数名和文件名对齐找起来不用翻 README。cloud-model/ ├── src/ │ ├── forwardCloud.m % 正向云发生器 │ ├── backwardCloud.m % 逆向云发生器 │ ├── cloudAdd.m % 云模型加法 │ ├── cloudMul.m % 云模型乘法 │ ├── cloudSimilarity.m % 两朵云的相似度 │ ├── cloudScale.m % 评价等级标准云 │ ├── cloudWeight.m % 专家打分转权重云 │ └── cloudEvaluate.m % 综合评价合成 ├── demo/ │ ├── demo_cloud.m % 正逆向发生器演示 │ ├── demo_weight.m % 权重计算演示 │ └── demo_evaluate.m % 综合评价演示 ├── data/ │ └── expert_score.mat % 专家打分样例 └── README.md表格里再对一遍每个文件的职责免得你拿到包之后不知道先看哪个文件输入输出什么时候用forwardCloud.mEx、En、He、NN 个云滴画云图、做仿真backwardCloud.m云滴样本向量Ex、En、He从专家打分反推云参数cloudWeight.mm×n 专家打分矩阵n×3 权重云指标赋权cloudEvaluate.m权重云、评价云1×3 综合云综合评价cloudSimilarity.m两朵云0~1 相似度等级判定2.2 运行环境和启动方式MATLAB R2016b 以上就能跑核心函数只用到mean、var、randn、exp这些基础函数。唯一需要留意的是normrnd它在 Statistics and Machine Learning Toolbox 里没装这个工具箱的机器会直接报Undefined function normrnd。替代写法很简单normrnd(mu, sigma)等价于mu sigma .* randn(...)后面第 5 章会专门讲这个替换。启动脚本一般长这样先加路径再调函数% demo_cloud.m addpath(genpath(fullfile(pwd, src))); % 把 src 及子目录加入搜索路径 Ex 0.6; En 0.10; He 0.02; N 3000; [x, y] forwardCloud(Ex, En, He, N); % 生成 3000 个云滴 figure; scatter(x, y, 4, filled); grid on; xlabel(指标取值); ylabel(隶属度); title(sprintf(Ex%.2f, En%.2f, He%.2f, Ex, En, He));addpath(genpath(...))这行的作用是递归添加src 下如果还有 util 子目录也能一并找到。参数上N取 3000 到 5000 比较合适低于 1000 画出来的云会稀稀拉拉看不出“中间厚、两边薄”的形态He一般取En的 0.1 到 0.3 倍太大云会糊成一团太小又退化成一条正态曲线。2.3 数据结构约定云参数和云滴怎么传整个包最容易被新手搞混的地方是参数顺序。统一约定成云参数用 1×3 行向量[Ex, En, He]云滴用 N×2 矩阵[x, y]多朵云拼成 M×3 矩阵一行一朵云。这个约定定死了后面所有函数都按这个来就不会出现把 En 当 He 传进去的低级错误。% 单个云一行三个数 cloud [0.60, 0.10, 0.02]; % 三个指标的权重云三行每行 [Ex, En, He] W [0.30, 0.05, 0.01; 0.25, 0.04, 0.01; 0.45, 0.06, 0.02]; % 云滴N×2第一列是横坐标第二列是隶属度 drops forwardCloud(cloud(1), cloud(2), cloud(3), 2000); size(drops) % 2000×2我一般会在cloudEvaluate.m开头加两行断言检查size(W, 2) 3和size(W, 1) size(Rmat, 1)一旦维度对不上立刻报错比跑到一半出现维度不匹配要省时间。2.4 三种典型调用姿势拿到包之后不用全看按你要做的事挑入口就行。只想看云长什么样直接跑demo_cloud.m手头有一批专家打分想算权重改data/expert_score.mat然后跑demo_weight.m要做完整评价跑demo_evaluate.m它会依次调cloudScale、cloudWeight、cloudEvaluate、cloudSimilarity把从打分到等级的链路走一遍。三个 demo 的输出分别是云滴散点图、权重云柱状图和等级相似度条形图跑完对着图看比看数字直观。3. 正逆向云发生器拆解Ex、En、He 如何互相还原3.1 正向云发生器三个参数生成 N 个云滴正向云发生器是整个包的基础输入三个数字输出一堆带隶属度的散点。核心就三步先以 En 为期望、He 为标准差抽一个随机熵再以 Ex 为期望、这个随机熵为标准差抽云滴横坐标最后套隶属度公式算纵坐标。代码不长但每一行都有讲究。function [x, y] forwardCloud(Ex, En, He, N) % forwardCloud 正向云发生器 % 输入Ex 期望En 熵He 超熵N 云滴数量 % 输出x 云滴横坐标N×1y 隶属度N×1 if nargin 4, N 3000; end % 不传 N 就默认 3000 x zeros(N, 1); y zeros(N, 1); for i 1:N En_i normrnd(En, He); % 第一步随机熵 En_i abs(En_i); % 取绝对值防止负标准差 x(i) normrnd(Ex, En_i); % 第二步云滴横坐标 y(i) exp(-(x(i) - Ex)^2 / (2 * En_i^2)); % 第三步隶属度 end end逐行看En_i normrnd(En, He)这一步让每次循环的“云宽”都不一样这正是云模型区别于普通正态分布的地方——普通正态的标准差是固定的云模型的熵本身是个随机变量。abs(En_i)这行不能省normrnd抽出来的值有概率为负负标准差传进下一次normrnd会直接报错。第三步的隶属度公式是标准正态型En_i越小曲线越尖云滴越集中。参数的影响可以直接从图上读Ex决定云的中心位置改它云整体平移En决定云的横向跨度改大云变宽、变矮He决定云的“厚度”He越大En_i的波动越大散点越分散看起来像雾化。我一般先用En0.1, He0.02这组默认值起手看图形形态再调。一个常见误区是直接把normrnd(Ex, En)写进循环跳过随机熵那一步。那样画出来的只是一条正态分布曲线He完全没参与云模型的“不确定性中的不确定性”就丢了后面的逆向还原也对不上。3.2 逆向云发生器从一堆散点倒推三个参数逆向云发生器干的是反事手上有一批云滴实际场景里就是专家打分要估出 Ex、En、He。常用的无确定度算法基于一阶绝对矩和方差分解公式不复杂但有个边界情况必须处理。function [Ex, En, He] backwardCloud(x) % backwardCloud 逆向云发生器无需确定度输入 % 输入x 云滴样本向量 % 输出Ex 期望En 熵He 超熵 x x(:); % 强制列向量防止行向量传进来 Ex mean(x); % 期望用样本均值 En sqrt(pi/2) * mean(abs(x - Ex)); % 熵用一阶绝对矩估计 He sqrt(max(var(x) - En^2, 0)); % 超熵由方差分解得到 endEn那行的sqrt(pi/2)来自正态分布绝对偏差的期望换算不是随手写的系数。He那行是方差分解样本方差约等于En^2 He^2减掉En^2再开方就是He。max(..., 0)这层保护很关键样本量小或者数据特别集中时var(x)可能小于En^2不减到 0 会开出虚数后面全崩。参数说明上Ex对样本均值最敏感样本偏移会直接反映En反映样本的离散程度但它是用绝对偏差估的比标准差更抗极端值He反映“离散程度的离散程度”样本里如果混进了两个不同来源的打分He会明显偏大。实际用的时候专家人数少于 5 个He的估计就很不稳这时候我一般直接把He固定成0.1*En别让它自己算。3.3 云相似度两朵云到底有多像综合评价最后要判等级判等级就要比较“综合云”和“标准等级云”有多像。严格做法是算云滴分布的相似度工程上常用隶属度曲线重叠面积来近似够用且快。function sim cloudSimilarity(c1, c2, n) % cloudSimilarity 两朵云的相似度0~1越大越像 % c1、c2 为 1×3 的 [Ex, En, He]n 为采样点数 if nargin 3, n 2000; end lo min(c1(1) - 4*c1(2), c2(1) - 4*c2(2)); % 取两条曲线公共横轴范围 hi max(c1(1) 4*c1(2), c2(1) 4*c2(2)); xg linspace(lo, hi, n); y1 exp(-(xg - c1(1)).^2 ./ (2*c1(2)^2)); % 用 En 当确定标准差近似 y2 exp(-(xg - c2(1)).^2 ./ (2*c2(2)^2)); sim trapz(xg, min(y1, y2)) / trapz(xg, max(y1, y2)); endlo和hi取的是两朵云各自 ±4 倍熵的范围覆盖 99% 以上的概率质量不会截断曲线。min和max逐点比较后做数值积分比值就是重叠度。这里有个近似真正算相似度应该对云滴做二维核密度但那样每次比较都要生成几千个点评价矩阵一大就慢得没法看。用En当确定标准差近似误差在He较小时可以忽略如果两朵云的He差异特别大相似度会偏乐观这点第 5 章会展开。3.4 云模型加法与乘法合成评价结果的两个零件综合评价要把“权重云 × 评价云”再求和云模型的加法和乘法有固定近似公式直接封装成两个短函数主流程里读起来清爽。function c cloudAdd(c1, c2) % 云模型加法期望相加熵与超熵平方和开方 c [c1(1) c2(1), ... sqrt(c1(2)^2 c2(2)^2), ... sqrt(c1(3)^2 c2(3)^2)]; end function c cloudMul(c1, c2) % 云模型乘法线性近似公式 c [c1(1) * c2(1), ... sqrt((c1(1)*c2(2))^2 (c2(1)*c1(2))^2), ... sqrt((c1(1)*c2(3))^2 (c2(1)*c1(3))^2)]; end加法的逻辑很直观两个不确定量相加期望直接加方差相加再开方。乘法稍微绕一点En那项是sqrt((Ex1*En2)^2 (Ex2*En1)^2)本质上是乘积的相对误差传播He同理。这套公式是云模型在参数较小情况下的线性近似Ex在 0 到 1 之间时误差很小如果指标取值范围跑到几百上千得先把数据归一化到 [0,1] 再用否则En会被放大得离谱。4. 云模型赋权与综合评价专家打分怎么一路算到等级4.1 专家打分转云模型权重权重计算的入口是一张 m×n 矩阵m 个专家、n 个指标每格是一个分数。常见做法是逐列做逆向云发生器把同一指标下多个专家的分歧聚成云再用期望占比归一化。function W cloudWeight(score) % cloudWeight 专家打分矩阵转云模型权重 % 输入score m×nm 个专家、n 个指标 % 输出W n×3每行是一个指标的权重云 [Ex, En, He] [m, n] size(score); W zeros(n, 3); for j 1:n W(j, :) backwardCloud(score(:, j)); % 每个指标聚成一朵云 end s sum(abs(W(:, 1))); % 用期望绝对值之和做归一化 W W / s; % 三个参数同比例缩放 end这里最容易翻车的是归一化那一步。只把Ex除以总和、En和He原样保留会导致权重云的期望加起来是 1但熵和超熵还是原始量纲后面做乘法合成时不确定性被放大。W W / s让整行同比例缩放云的形状不变期望和归一这是我认为更稳的写法。abs是为了防止专家打分里有负数导致归一化系数为 0。如果分数不是直接打的而是“很重要、重要、一般、不重要”这种语言等级那要先过一遍等级到云的映射再进cloudWeight。映射表可以手工定也可以用 4.2 节的黄金分割生成。4.2 评价等级标准云黄金分割法生成五级标度做综合评价前得先有“标尺”。常用五级优、良、中、差、很差对应期望 1.0、0.691、0.5、0.309、0.0这个 0.309 就是黄金分割数 0.618 的一半保证相邻等级在隶属度上平滑过渡。function C cloudScale(nLevel) % cloudScale 黄金分割法生成评价等级标准云默认五级 % 输出nLevel×3从高等级到低等级排列 if nargin 1, nLevel 5; end if nLevel 5 Ex [1.0, 0.691, 0.5, 0.309, 0.0]; else Ex linspace(1, 0, nLevel); end En zeros(nLevel, 1); for k 1:nLevel if k 1 En(k) (Ex(1) - Ex(2)) / 3; % 边界用内侧间隔 elseif k nLevel En(k) (Ex(end-1) - Ex(end)) / 3; else En(k) (Ex(k-1) - Ex(k1)) / 6; % 中间用两侧间隔的 1/6 end end He 0.1 * En; % 超熵取熵的十分之一 C [Ex, En, He]; endEn的取值直接决定等级之间的重叠程度取大了相邻等级云会糊在一起相似度排序分不开取小了云与云之间出现空档综合云落在空档里就判不出等级。用两侧间隔的 1/6 是个经验值正好让相邻云在 3 倍熵处轻微交叠。He 0.1*En也是经验比例想要云图更“雾”一点可以调到 0.2但别超过 0.3。4.3 综合评价合成权重云乘评价云再求和有了权重云和每个指标的评价云合成就是把cloudMul和cloudAdd串起来。评价云可以来自专家对该指标的直接打分逆向云也可以来自等级映射正向云两种都行接口统一成 n×3 矩阵。function R cloudEvaluate(W, Rmat) % cloudEvaluate 云模型综合评价 % 输入W n×3 权重云Rmat n×3 各指标评价云 % 输出R 1×3 综合云 assert(size(W, 2) 3 size(Rmat, 2) 3, 云参数必须是 n×3); assert(size(W, 1) size(Rmat, 1), 权重与评价的指标数不一致); R [0, 0, 0]; for j 1:size(W, 1) R cloudAdd(R, cloudMul(W(j, :), Rmat(j, :))); end end两个assert是我后来加的。之前有一次改了指标数忘了同步改评价矩阵cloudMul里两个长度不一样的向量做运算MATLAB 不报错而是自动广播结果算出来一个看着正常但完全错位的综合云查了半天才发现。合成完得到一朵综合云再拿它和cloudScale生成的五级标准云逐个比相似度取最大值对应的等级C cloudScale(); % 五级标准云 sim zeros(size(C, 1), 1); for k 1:size(C, 1) sim(k) cloudSimilarity(R, C(k, :)); end [bestSim, idx] max(sim); fprintf(综合云 Ex%.3f, En%.3f, He%.3f\n, R(1), R(2), R(3)); fprintf(判定等级第 %d 级相似度 %.3f\n, idx, bestSim);R(1)是综合评价的期望值可以直接当综合得分报出去R(2)越大说明专家意见越分散可以在报告里加一句“结果不确定性较高”。这套输出比单一平均数信息量大审稿人问“你怎么处理专家分歧”时En和He就是答案。4.4 结果可视化与等级对比数字看完还得看图。综合云和五级标准云叠在一张图上能直观看出综合云落在哪两级之间、重叠度如何。figure; hold on; colors lines(size(C, 1)); for k 1:size(C, 1) [xd, yd] forwardCloud(C(k,1), C(k,2), C(k,3), 1500); scatter(xd, yd, 3, colors(k,:), filled, MarkerFaceAlpha, 0.3); end [xr, yr] forwardCloud(R(1), R(2), R(3), 2000); scatter(xr, yr, 6, k, filled, MarkerFaceAlpha, 0.5); legend([string(1:size(C,1)), 综合云]); xlabel(评价值); ylabel(隶属度);MarkerFaceAlpha调透明度是关键不调的话点全叠在一起成实心块看不出云的形态。标准云用彩色、综合云用黑色加粗一眼能分清。5. 常见问题排查云滴散乱、参数越界和相似度失真5.1 现象云滴散成满天星看不出中间厚两边薄原因基本是En设太大或者He没设。En决定云的横向宽度取值超过0.3时横轴跨度拉到 ±1.2散点铺满整个画布He为 0 时每次抽的En_i都一样云退化成一条标准正态曲线但如果你同时把En设得很大看起来就是一片均匀的雾。解决先按指标取值范围定En。指标归一化到 [0,1] 时En取0.05到0.15之间比较合适He取0.1*En到0.2*En。画图时把N提到 3000 以上散点密度够了云的形态才出得来。5.2 现象逆向云发生器报错或者He算出来是NaN原因有两类。一是样本量太小三五个专家打分做逆向云var(x)很不稳定可能小于En^2开方开出虚数MATLAB 返回复数后续normrnd就崩。二是输入向量里混进了NaNmean和var一路传染最后整个结果都是NaN。解决He那行加max(..., 0)保护是第一步样本少于 8 个时干脆不用逆向云估He直接固定He 0.1*En。输入前加一行x x(~isnan(x))过滤缺失值比事后查错省事。至于样本量做权重计算时专家人数最好不少于 5 个低于这个数He基本没有统计意义。5.3 现象权重归一化后综合云期望正确但相似度排序乱原因是只归一化了ExEn和He还是原始量纲。综合评价做乘法时cloudMul的En项是sqrt((Ex1*En2)^2 (Ex2*En1)^2)如果权重云的En没跟着缩小这一项会偏大综合云的熵被抬高和标准云比相似度时宽云对谁都像排序就失真。解决用W W / sum(abs(W(:,1)))整行缩放三个参数同比例变。改完之后拿同一个案例对比一下归一化前后的综合云参数Ex应该基本不变En和He明显下降这才对。5.4 现象Undefined function normrnd原因很直接机器上没装 Statistics and Machine Learning Toolbox。学校机房或者精简安装的 MATLAB 经常缺这个工具箱代码一跑就停。解决全局把normrnd(mu, sigma)换成mu sigma .* randn(size(mu))。注意randn的维度参数标量时直接randn向量时要传size。替换后结果分布完全等价只是少了工具箱的参数检查。5.5 现象两个明显不同的指标相似度都在 0.8 以上这是cloudSimilarity用确定En近似带来的副作用。当两朵云的En差异很大时比如一朵En0.05、另一朵En0.3用各自的En画隶属度曲线再取重叠宽的那朵会覆盖窄的那朵大部分面积相似度虚高。解决等级判定场景下标准云的En都是同一套黄金分割值这个问题影响不大如果要做云与云之间的精细聚类把cloudSimilarity换成基于云滴二维核密度的方法或者至少把两朵云的He也纳入比较相似度公式改成sim simOverlap * exp(-abs(c1(3)-c2(3))/max(c1(3),c2(3)))对超熵差异做一个惩罚。6. 二次开发向量化改造与参数回收验证原包的forwardCloud是for循环N取 5000 时还行做蒙特卡洛或者批量评价时一秒钟调几百次就成瓶颈。改法很简单把循环拆成向量运算function [x, y] forwardCloudVec(Ex, En, He, N) % 向量化版正向云发生器比 for 循环快 5~10 倍 if nargin 4, N 3000; end En_i abs(En He .* randn(N, 1)); % 一次性抽 N 个随机熵 x Ex En_i .* randn(N, 1); % 一次性抽 N 个横坐标 y exp(-(x - Ex).^2 ./ (2 * En_i.^2)); % 向量化算隶属度 endrandn(N,1)一次生成整列.*和./逐元素运算逻辑和循环版一一对应。注意En_i的abs不能省randn抽出来的负值照样会让normrnd等价式产生非法标准差。换成向量化之后N10000的耗时从 0.08 秒降到 0.01 秒左右批量评价时体感明显。第二个改造点是把函数式改成classdef把云参数封进对象方法链式调用。这个看个人习惯函数式的好处是单个文件能直接拷进别的项目面向对象的好处是参数校验可以写在构造函数里不会出现传错顺序的问题。改造完必须验证参数能不能“回收”。方法是给定一组已知的Ex/En/He生成 5000 个云滴再跑逆向云发生器看估出来的三个数和原值差多少。我一般跑 20 次取平均误差Ex的相对误差应该在 1% 以内En在 5% 以内He在 15% 以内算正常He的误差天生就大因为它依赖四阶量样本量不够时波动明显。指标设定值回收均值相对误差Ex0.6000.5990.17%En0.1000.0973.0%He0.0200.02315%这套回收验证我每次改完发生器都会跑一遍有一次偷懒没跑把En的系数从sqrt(pi/2)误改成pi/2云图看着没差别但权重算出来整体偏大三成直到答辩前一周才发现。从那以后我每次动核心函数都强制走一遍“生成—回收—比误差”的流程图省事的结果往往是返工。希望这套拆解能帮到你先把 demo 跑通再换成自己的专家打分数据云模型这条路就算走顺了。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询