简介面向需要快速上手云模型实现的 MATLAB 用户这份代码包提供可直接调用的正向云发生器与云变换相关函数适合从事不确定性建模、权重计算与模糊综合评价的研究生、教师及工程技术人员用于课程实验、论文复现与算法原型验证。压缩包共 2 个文件均为 .m 源码文件体积约 1KB轻量简洁便于阅读整体逻辑并嵌入现有 MATLAB 工程无需额外依赖即可运行。已有 1581 人学习下载说明其在教学与科研场景中具有一定参考价值。使用者可从中获得云模型数字特征到云滴生成的完整实现思路理解期望、熵、超熵等参数对云图形态的影响并在此基础上调整参数或改写函数完成权重确定、评价指标隶属度计算等任务代码结构短小也便于逐步调试与二次开发适合作为云模型入门与项目应用的起点。1. 三个数字特征顶替一张专家打分表MATLAB 云模型代码能用在哪去年帮某实验室复核一套边坡稳定性评价六份专家打分表收回来判断矩阵的一致性比率怎么调都压不到 0.1 以下。后来换个思路把「很重要 / 比较重要 / 一般」这类语言值直接映射成一组 (Ex, En, He)正向云发生器撒云滴、逆向云把六位专家的意见聚成一朵云权重就带上了可解释的离散范围不用再跟一致性比率较劲。这套 MATLAB 云模型代码做的正是这件事正向云、逆向云、云模型赋权、云模型综合评价、云图绘制全部函数级封装改数据就能跑。适合手里已有指标体系、需要把定性判断量化成权重和等级的人只想画一张云图交作业也能用但那样用不出这套代码的价值。2. 正向云与逆向云Ex、En、He 的生成与反推云模型把「模糊」和「随机」揉进一组参数期望 Ex 是概念的集中位置熵 En 是概念能覆盖的跨度超熵 He 是这朵云本身的厚度也就是「跨度本身有多不确定」。三个数一给一朵云就定了反过来给一堆云滴也能把三个数估回来。正向和逆向这两个发生器是所有上层应用的地基代码包里的其他函数都在调它们。2.1 正向云发生器两步正态采样正向云的采样逻辑是「先把熵随机化再以随机的熵为尺度撒点」。第一步以 En 为期望、He 为标准差生成一个临时熵 En_i第二步以 Ex 为期望、|En_i| 为标准差生成云滴 x确定度 y 由高斯型隶属函数算出。这个两步结构是云模型区别于普通模糊隶属函数的关键也是云滴图呈现「中间密、边缘散、腰身有厚度」的原因。function [x, y] forwardCloud(Ex, En, He, n) % forwardCloud 正向云发生器 % Ex 期望 En 熵 He 超熵 n 云滴数量 % x 云滴坐标 (n×1) y 确定度 (n×1) if nargin 4, n 2000; end % 默认 2000 滴够画图也够估隶属度 if He 0, error(超熵 He 必须非负); end Eni En He .* randn(n,1); % 第一步对熵做一次正态扰动 x Ex abs(Eni) .* randn(n,1); % 第二步以随机熵为尺度撒云滴 y exp(-(x-Ex).^2 ./ (2*Eni.^2)); % 高斯型确定度值域 (0,1] end代码里没用normrnd而是用randn手工换算成均值 标准差 × randn这样不依赖统计工具箱装个基础 MATLAB 就能跑。abs(Eni)那一层绝对值不能省He 一大Eni会采到负值不取绝对值会得到一个反向的云滴分布。n的取值分场景画图 10003000 滴足够要拿云滴频率估计某个区间的确定度建议 5000 滴往上否则同一份参数跑两次的均值能差出 3% 以上。He 的经验取值是 En 的 1/10 到 1/3。取到 1/10云看起来很「薄」像一个熨平的模糊隶属函数取到 1/3腰身明显散开适合表达专家意见分歧大的概念。He 再往上加云滴会散成一片确定度接近 0此时云已经不再表达任何概念属于典型的参数翻车。2.2 逆向云发生器只给云滴也能反推特征实际工程里更常见的是反向需求手上只有一组专家打分或者一组实测数据想知道它对应哪朵云。逆向云发生器有无确定度和带确定度两套算法代码包里实现的是无需确定度的一阶矩法因为它只要求你有云滴坐标 x不要求你事先知道每个点的隶属度——而后者在实测数据里根本拿不到。function [Ex, En, He] backwardCloud(x) % backwardCloud 逆向云发生器一阶矩法无需确定度输入 x x(:); n numel(x); if n 5 error(云滴少于 5 个数字特征不可信); end Ex mean(x); % 期望样本一阶矩 En sqrt(pi/2) * mean(abs(x - Ex)); % 熵一阶绝对中心矩换算 S2 var(x); % 样本方差 He sqrt(max(S2 - En^2, 0)); % 超熵方差扣掉熵的贡献 if S2 En^2 warning(样本方差小于 En^2He 被截断为 0建议增加样本量或改用带确定度算法); end end三个公式各有来路sqrt(pi/2)这个系数来自正态分布的一阶绝对中心矩与标准差的关系不是随手拍的。He那一行最容易出问题理论上S2 En^2 He^2一旦样本量小、数据又集中S2可能小于En^2开根号就是虚数MATLAB 会直接给你NaN或者复数。代码里用max(..., 0)兜住同时抛警告让你知道这朵云的超熵不可信而不是悄悄给你一个 0。注意逆向云的输入必须是同一朵云的云滴。把不同指标、不同专家的数据混在一起做逆向得到的 Ex 没有物理意义En 会被组间差异撑得很大看起来「很分散」实际是把两朵云硬拼成了一朵。2.3 云图与确定度的读法云图是这个方法最直观的输出也是一个容易被误读的图。横轴是云滴的取值纵轴是确定度同一个 x 位置上可能出现好几个 y——这正是云模型和普通隶属函数的区别隶属度本身是随机的所以你看到的不是一个函数曲线而是一团有厚度的点云。function cloudPlot(Ex, En, He, n, col) % cloudPlot 绘制单朵云 if nargin 4, n 2000; end if nargin 5, col [0.20 0.40 0.80]; end Eni En He .* randn(n,1); x Ex abs(Eni) .* randn(n,1); y exp(-(x-Ex).^2 ./ (2*Eni.^2)); scatter(x, y, 6, col, filled, MarkerFaceAlpha, 0.35); xlabel(指标值 x); ylabel(确定度 \mu); grid on; box on; end读图时看三件事云滴最密的位置是不是落在你预期的 Ex 附近横向铺开的宽度是不是和 En 匹配大约 3 倍 En 能覆盖绝大部分点纵向的「雾感」是不是和 He 匹配。如果画出来发现左右严重不对称、或者中心明显偏离 Ex先检查是不是把两组数据混在一起喂进去了其次检查 En 是不是被设成了负数——负的 En 在第一步abs之后会变成正的云滴照样能出来但整个语义已经错了这种错误最难查。3. 云模型赋权把专家语言值折算成归一化权重权重才是这套代码被搜到的主因。传统 AHP 让专家填 19 判断矩阵一致性检验是道硬门槛DELPHI 让专家反复打分轮次多了人会烦。云模型赋权换个做法专家只需要给每个指标一个语言等级等级到云参数有固定的映射表多专家的意见用逆向云聚合成一朵权重云期望当权重、超熵当可信度。整个过程不需要一致性检验但要接受一个事实——权重不再是点值而是一个带离散范围的分布。3.1 评语云标定语言值到参数的映射表标定是整套流程里唯一需要人工拍板的地方拍完之后就不能再动。常见做法是把指标的重要性分成 5 级Ex 在 01 上均匀铺开En 取相邻 Ex 间距的 1/3 到 1/2He 取 En 的 0.1 倍左右。间距太密相邻等级云会重叠到无法区分间距太疏会留下大片「无云区」实测值掉进去算出来的确定度全是 0。等级语言值ExEnHe覆盖区间约1很不重要0.100.040.0040.00 ~ 0.222不太重要0.300.040.0040.18 ~ 0.423一般0.500.050.0050.35 ~ 0.654比较重要0.700.040.0040.58 ~ 0.825很重要0.900.040.0040.78 ~ 1.00表里的 En 取了 0.040.05相邻 Ex 间距是 0.2比值落在 1/4 到 1/5 之间云与云之间有轻微交叠但中心可分辨。He 压到 En 的十分之一是因为评语云表达的是「标准」标准本身不该有太大不确定性如果你希望专家在语义上更宽松可以把 He 提到 0.015 左右代价是等级边界变糊综合评价时容易出现两个等级确定度咬得很紧的情况。3.2 专家打分矩阵的逆向聚合专家打分表整理成一个指标数 × 专家数的矩阵元素是 15 的等级分每一行就是一朵「专家意见云」的云滴。逐行做逆向云得到每个指标的 (Ex, En, He)再用 Ex 归一化得到权重。function [W, C] cloudWeight(score) % cloudWeight 云模型赋权 % score 指标×专家 的等级打分矩阵元素取值 1~5 % W 归一化权重 (p×1) % C 各指标的权重云参数 (p×3)每行 [Ex En He] [nIdx, nExp] size(score); C zeros(nIdx, 3); for i 1:nIdx x score(i,:); Ex mean(x); En sqrt(pi/2) * mean(abs(x - Ex)); S2 var(x); He sqrt(max(S2 - En^2, 0)); C(i,:) [Ex, En, He]; end W C(:,1) / sum(C(:,1)); % 用期望归一化得到点值权重 end这段代码看起来简单真正决定结果的是score矩阵怎么组织。常见错误是把专家按列、指标按行搞反了跑出来权重个数等于专家人数还以为是算法出了问题。另一个隐性问题是打分尺度如果一部分专家用 15、另一部分用 19逆向出来的 En 会虚高因为量纲不同带来的差异被当成了意见分歧。发问卷之前把尺度统一能省掉后面一大堆解释工作。W之所以用 Ex 归一化而不用 Ex 加权 En是因为 En 在权重语义里表示「这个指标的重要性有多模糊」而不是「这个指标有多重要」。把 En 掺进权重会让模糊性大的指标权重被抬高逻辑上是反的。En 和 He 的正确用法是下游的可信度过滤也就是下一节。3.3 分歧度折扣He 大的指标怎么处理六个专家里五个打「比较重要」、一个打「很不重要」Ex 会落在 3.7 附近看起来挺高但 He 会明显变大。这种指标直接按期望给权重等于把一条分歧极大的意见当成了共识。我一般会做一次折扣分歧越大权重按平方衰减同时留一个 0.2 的保底避免某个指标被彻底清零。function W discountWeight(C, W0, beta) % discountWeight 按超熵对权重做折扣 % C 权重云参数 (p×3)每行 [Ex En He] % W0 期望归一化后的权重 (p×1) % beta 折扣强度0 不折扣1 折扣最狠 He C(:,3); hmax max(He); if hmax 0 W W0; return; end k 1 - beta * (He / hmax).^2; % 分歧越大折扣越狠 k max(k, 0.2); % 保底系数防止权重归零 W W0 .* k; W W / sum(W); % 折扣后重新归一化 endbeta取 0.5 是我常用的默认值能压住明显分歧又不至于把排序打乱太多。取 1 的时候He 最大的那个指标会被压到原权重的 20%适合专家意见质量参差、需要强筛选的场景取 0 就退化成纯期望赋权。折扣之后一定要重新归一化W0 .* k的和不再是 1忘了这一步后面的综合评价会整体偏低。提示折扣系数会改变指标排序交付前把折扣前后的权重表并排打出来看一眼。如果某个指标因为折扣从第 2 位掉到第 6 位先回头看看那位打极端分的专家是不是理解错了指标定义而不是直接接受算法结果。3.4 与熵权法组合给主观云找一个客观锚点纯主观赋权的通病是「专家说什么就是什么」评审场合经常被追问依据。稳妥的做法是留一份客观权重做对照用组合权重交付。云模型权重负责体现领域判断熵权法负责体现数据本身的离散程度两者线性加权。function W comboWeight(Wc, X, alpha) % comboWeight 云模型权重与熵权法组合 % Wc 云模型主观权重 (p×1) % X 原始指标矩阵 (n样本 × p指标)需先做同向化 % alpha 主观权重占比常取 0.5~0.7 [n, p] size(X); Xm (X - min(X)) ./ (max(X) - min(X) eps); % 极差归一化到 [0,1] P Xm ./ sum(Xm, 1); P(P 0) 1e-12; % 防止 log(0) e -sum(P .* log(P), 1) / log(n); % 各指标信息熵 d 1 - e; % 差异系数 We d / sum(d); % 熵权 W alpha * Wc(:) (1 - alpha) * We(:); W W / sum(W); endalpha取 0.6 比较常见主观占大头但客观有话语权。X进函数之前必须先做同向化成本型指标要翻转过否则熵权会奖励那些「数值越大越差」的指标方向完全反了。另外样本量 n 小于 10 的时候熵权很不稳log(n)太小一点点数据波动就能让权重跳变这种场景干脆把alpha提到 0.8 以上让客观权重只起微调作用。4. 云模型综合评价从权重矩阵推到等级落点权重有了下一步是把实测值送进等级云算出每个指标对每个等级的确定度加权合成之后定级。这一段的代码量不大坑主要集中在「确定度怎么算」和「定级用什么规则」两个地方前者关系到数值是否稳定后者关系到结论是否可信。4.1 等级云与单指标确定度矩阵给定指标实测值 x 和某个等级云 (Ex, En, He)确定度不能直接代高斯公式因为 En 本身是随机的。常见做法是对 En 做 m 次抽样每次算一个确定度最后取平均这相当于用蒙特卡洛方法估计「这朵云对 x 的平均确定度」。function [B, S, MU] cloudEval(W, x, C, levelScore, m) % cloudEval 云模型综合评价 % W 指标权重 (p×1)已归一化 % x 各指标无量纲化实测值 (p×1)落在 [0,1] % C 等级云参数 (K×3)每行 [Ex En He] % levelScore 各等级对应分值 (K×1)如 [1 2 3 4 5] % m 每个指标-等级组合的抽样次数 p numel(W); K size(C,1); MU zeros(p, K); for i 1:p for k 1:K Ex C(k,1); En C(k,2); He C(k,3); Eni En He .* randn(m,1); % 对熵抽样 Eni max(abs(Eni), 1e-6); % 防除零 MU(i,k) mean(exp(-(x(i)-Ex).^2 ./ (2*Eni.^2))); end end B (W * MU); % 综合确定度 (K×1) S sum(B .* levelScore) / sum(B); % 加权平均等级分 endMU是 p 行 K 列的确定度矩阵每行是一个指标对 K 个等级的确定度分布。m取 10003000 就够稳定再往上收益很小因为误差量级是 1/sqrt(m)从 1000 加到 4000 只能把波动压掉一半。1e-6那个下限是给 He 接近 0 的等级云留的后路否则Eni抽到 0 会除出Inf。4.2 加权合成、最大隶属度与综合得分B算出来之后有两条定级路线选哪条取决于你的分布形状。最大隶属度原则简单直接取B最大的那个等级适合B有明显尖峰的情况综合得分S用等级分值加权平均适合B比较平缓、两三个等级咬得很紧的情况能避免「0.31 对 0.29 就定成高一级」这种脆断。[~, lv] max(B); % 最大隶属度定级 fprintf(最大隶属度等级 %d\n, lv); fprintf(综合得分 %.3f\n, S); % 得分法可与等级阈值对照我一般两个都算交付时以综合得分为主、最大隶属度为辅并在报告里注明「两种规则结论一致」或「存在跨级需复核边界指标」。评审最怕的就是只报一个数被问到为什么不是另一级时答不上来。如果B出现两个几乎相等的峰值说明指标体系里有两类指标在往不同方向拉这时候该做的是检查指标相关性而不是换个定级规则把结果凑过去。4.3 指标无量纲化与区间型指标处理云模型的等级云默认铺在 01 上实测值必须先压到这个区间。效益型指标直接极差归一化成本型指标翻转适度型指标越接近某个值越好要单独处理不能简单套极差。function Xn normalizeIdx(X, type) % normalizeIdx 指标无量纲化 % X 原始指标矩阵 (n×p) % type 1×p 元胞元素为 benefit / cost [n, p] size(X); Xn zeros(n, p); for j 1:p lo min(X(:,j)); hi max(X(:,j)); if strcmpi(type{j}, benefit) Xn(:,j) (X(:,j) - lo) / (hi - lo eps); else Xn(:,j) (hi - X(:,j)) / (hi - lo eps); end end endeps是为了防止某个指标所有样本取值相同导致除零这种指标本身也没有区分度归一化后全是 0权重再高也不影响结果属于正常现象。真正要小心的是极值单个离群点会把hi拉得很远其余样本全挤在 0 附近等级云的区分能力直接失效。样本量小于 30 的时候我一般改用 5% 和 95% 分位数代替 min/max牺牲一点极值信息换取整体的分辨率。4.4 一个完整的最小可运行脚本把前面几个函数串起来三指标、六专家、五等级的完整流程不到 20 行。这个脚本可以直接当模板改改数据、改等级云参数就能套到自己的指标体系上。%% 最小可运行示例3 指标 / 6 专家 / 5 级评语 rng(42); % 固定随机种子保证可复现 score [4 5 4 4 5 4; % 指标 1 的六位专家打分 3 4 3 4 3 3; % 指标 2 5 4 5 5 4 5]; % 指标 3 [W0, C] cloudWeight(score); % 逆向云聚合 期望归一化 W discountWeight(C, W0, 0.5); % 按分歧度折扣 x [0.85; 0.62; 0.90]; % 三个指标的无量纲化实测值 Cstd [0.10 0.040 0.004; % 5 个等级云 0.30 0.040 0.004; 0.50 0.050 0.005; 0.70 0.040 0.004; 0.90 0.040 0.004]; levelScore (1:5); [B, S] cloudEval(W, x, Cstd, levelScore, 2000); fprintf(权重: %.3f %.3f %.3f\n, W); fprintf(综合确定度: ); fprintf(%.3f , B); fprintf(\n); fprintf(综合得分 %.3f\n, S);跑之前确认两件事x的元素个数必须和W一致否则W * MU直接报维度错Cstd的行顺序要和levelScore一一对应等级分值反着写不会报错但结论会整体翻转。rng(42)这行别删云模型带随机抽样不固定种子的话同一份数据跑两次可能给出不同等级交付场合很难解释。5. 排查清单云模型代码最容易翻车的五个地方这套代码我在不同项目里反复用过出问题的位置高度集中。下面五条按出现频率排序每条都按「看到什么现象、为什么会这样、怎么改」来写照着对一遍能省掉大半天。5.1 云滴图散成一片确定度全贴着 0现象是cloudPlot画出来的点云横向铺得极宽纵轴几乎全在 0.1 以下看不出任何「云」的形状。原因基本是 He 设得太大Eni抽样时频繁出现远大于 En 的值云滴被甩到离 Ex 很远的位置确定度自然衰减到接近 0。另一个可能是 En 本身被设成了量纲外的数值比如指标归一化在 01En 却填了 10。解决方式是把 He 压回 En 的 1/10 到 1/3先跑forwardCloud(Ex, En, En/10, 2000)看基准形状再逐步加到合适值。每次只改一个参数改完立刻画图别一次调三个参数然后对着一团糊判断是谁的问题。5.2 逆向云算出 He 为 0 或者 NaN现象是cloudWeight返回的C(:,3)全是 0或者直接是NaN。根源是样本方差S2小于En^2开根号被截断。这在小样本、专家意见高度一致的情况下特别常见——六个人全打 4 分S2 0En也为 0He理论上是 0代码返回 0 是正确行为不是 bug。真正要处理的是「专家意见略有差异但S2仍小于En^2」的情况这通常意味着样本量太小一阶矩估计不稳。解决办法是把专家数加到 8 人以上或者改用带确定度的逆向云算法需要每个云滴附带一个确定度工程上不好拿。如果实在加不了人就在报告里注明「He 不可估计权重仅按期望解释」别硬编一个数值出来。5.3 权重全部趋同指标之间拉不开差距现象是归一化后每个指标的权重都在 0.3 附近三指标场景排序没有意义。原因有两层一是评语云的 Ex 间距太小专家打 3 分和打 4 分映射到的云中心只差 0.05逆向出来的期望自然接近二是专家打分本身趋中大家都填 3 和 4不敢打极端分。第一层靠改标定表解决把 Ex 拉回到 0.10.9 均匀分布间距 0.2 起步。第二层靠问卷设计解决把语言值写得更具体比如「一般」改成「有无皆可不影响结论」逼专家在语义上做区分。标定表改完之后原来的打分要重新映射不能拿旧分数直接套新云。5.4 综合评价出现跨级跳变两次运行结论不同现象是同一份数据跑两次一次定 3 级、一次定 4 级。原因是没有固定随机种子cloudEval里对 En 的抽样每次都不同当B的两个峰值差距小于抽样误差时max就会在两级之间摇摆。这不是算法不稳是蒙特卡洛估计的固有波动。解决方式很直接在主脚本开头加rng(42)全流程共用一套随机流。同时把m从 1000 提到 3000 以上降低单次估计的方差。如果固定种子后仍然跨级说明B本身就在两级之间这时候该改用综合得分S定级或者检查是不是有指标的实测值正好落在两朵等级云的交叠区。5.5 循环版正向云在大样本下慢到不可用现象是n设到 10 万做收敛性测试时forwardCloud跑了几十秒还没出来。原因是代码里虽然已经向量化但如果下游自己写了个for循环逐滴调用每次调用都重新分配内存开销全花在函数调用上。处理办法是把云滴生成和逐点计算拆开一次性生成全部Eni和x再向量化算y不要在外层套循环。真需要不同参数的多次采样用arrayfun或者把参数堆成矩阵一次算完。MATLAB 里凡是能写成矩阵运算的就别写循环这一条在云滴数量上万之后差距非常明显。6. 进阶验证云滴数、超熵与权重排序的交叉校验代码能跑通只是及格线交付前还得回答两个追问结果稳不稳依据在哪。我的习惯是做三组校验每组都能量化写在报告附录里比空口解释有用得多。第一组是云滴数收敛性。固定 (Ex, En, He)把 n 从 500 扫到 20000看某个固定区间的确定度估计值怎么收敛。正常情况下前 2000 滴波动明显5000 滴之后基本压到 1% 以内。如果 20000 滴还在跳说明 He 太大、分布太散得回头调参数而不是继续加样本。rng(7); Ex 0.5; En 0.05; He 0.01; ns [500 1000 2000 5000 10000 20000]; for k 1:numel(ns) [~, y] forwardCloud(Ex, En, He, ns(k)); fprintf(n%6d 平均确定度%.4f\n, ns(k), mean(y)); end第二组是超熵敏感性。把 He 从 En/20 扫到 En/2观察综合评价的等级落点是否变化。如果 He 翻五倍结论就翻转说明这套指标体系对模糊性太敏感权重和等级云的标定都需要重新论证如果 He 在合理区间内结论稳定那就可以放心地说「结果对参数不敏感」。He / En0.050.100.200.330.50综合得分3.823.793.713.583.36定级44443这张表是典型形态He 在 0.1 到 0.33 之间结论不动到 0.5 才掉级。交付时把这个区间标出来等于告诉评审「结论在合理参数范围内是稳的」。第三组是和熵权法的排序一致性。用 Spearman 相关系数比较云模型权重和熵权的排序系数在 0.6 以上说明主客观判断大体一致可以放心组合低于 0.4 就要在报告里专门解释分歧来源往往是某个指标的数据分布和领域认知严重背离。rho corr(W_cloud, W_entropy, Type, Spearman); fprintf(主客观权重排序一致性 rho %.3f\n, rho);corr的Type,Spearman参数在较老的版本里可能不支持那就先转秩再算 Pearson效果一样。这一步我吃过亏有次云模型权重和熵权排序几乎相反当时偷懒没查直接按 0.6 的组合系数交付后来被问出某个成本型指标忘了翻转熵权方向整个是反的。从那以后我每次做完赋权都强制把两列权重并排打出来跑一遍排序一致性再往下走。希望帮到你。本文还有配套的精品资源点击获取