StabilityAnalyzer.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace TeamAAS_VP.Core
  7. {
  8. /// <summary>
  9. /// 稳定性分析器:提供一组统计方法用于评估一组数值数据的稳定性与过程能力。
  10. /// </summary>
  11. public class StabilityAnalyzer
  12. {
  13. /// <summary>
  14. /// 稳定性度量结果集
  15. /// </summary>
  16. public class StabilityMetrics
  17. {
  18. /// <summary>
  19. /// 样本平均值
  20. /// </summary>
  21. public double Mean { get; set; } // 平均值
  22. /// <summary>
  23. /// 样本标准差(使用 n-1 分母的样本标准差)
  24. /// </summary>
  25. public double StdDeviation { get; set; } // 标准差 (核心1)
  26. /// <summary>
  27. /// 3σ 区间的宽度(等于 6 * StdDeviation,表示 ±3σ 总宽)
  28. /// </summary>
  29. public double ThreeSigmaRange { get; set; } // 3σ范围 (核心2)
  30. /// <summary>
  31. /// 峰度(使用 Fisher 定义,正态分布为 0)
  32. /// </summary>
  33. public double Kurtosis { get; set; } // 峰度 (核心3)
  34. /// <summary>
  35. /// 过程能力指数 Cpk(若未提供规格限则为默认 0)
  36. /// </summary>
  37. public double Cpk { get; set; } // 过程能力指数 (核心4)
  38. /// <summary>
  39. /// 极差(最大值 - 最小值)
  40. /// </summary>
  41. public double Range { get; set; } // 极差
  42. /// <summary>
  43. /// 变异系数(标准差 / 平均值 * 100%)
  44. /// </summary>
  45. public double CV { get; set; } // 变异系数
  46. /// <summary>
  47. /// 95% 置信区间,返回 (Lower, Upper)
  48. /// </summary>
  49. public (double Lower, double Upper) Confidence95 { get; set; }
  50. }
  51. /// <summary>
  52. /// 对一组数值进行稳定性分析,返回各项统计度量。
  53. /// </summary>
  54. /// <param name="values">输入数据序列(至少 10 个点)</param>
  55. /// <param name="lowerSpec">下规格限(可选)</param>
  56. /// <param name="upperSpec">上规格限(可选)</param>
  57. /// <returns>StabilityMetrics 包含多项指标</returns>
  58. /// <exception cref="ArgumentException">当数据点少于 10 个时抛出</exception>
  59. public static StabilityMetrics AnalyzeStability(IEnumerable<double> values,
  60. double? lowerSpec = null,
  61. double? upperSpec = null)
  62. {
  63. // 将输入转换为数组以便重复使用并获取长度
  64. var data = values.ToArray();
  65. if (data.Length < 10) throw new ArgumentException("至少需要10个数据点");
  66. // 计算平均值与标准差(样本标准差)
  67. var mean = data.Average();
  68. var stdDev = CalculateStandardDeviation(data);
  69. // 构建指标对象并填充常规统计量
  70. var metrics = new StabilityMetrics
  71. {
  72. Mean = mean,
  73. StdDeviation = stdDev,
  74. // ThreeSigmaRange 表示 ±3σ 的总宽度(6σ)
  75. ThreeSigmaRange = CalculateKurtosis(data),//6 * stdDev,
  76. Kurtosis = CalculateKurtosis(data),
  77. Range = data.Max() - data.Min(),
  78. // 变异系数以百分比形式表示
  79. CV = (stdDev / mean) * 100,
  80. Confidence95 = Calculate95ConfidenceInterval(data)
  81. };
  82. // 如果提供了规格限,则计算并设置 Cpk(cp 也被计算但不保存)
  83. if (lowerSpec.HasValue && upperSpec.HasValue)
  84. {
  85. metrics.Cpk = CalculateProcessCapability(data,
  86. lowerSpec.Value, upperSpec.Value).cpk;
  87. }
  88. return metrics;
  89. }
  90. /// <summary>
  91. /// 根据标准差(StdDeviation)返回稳定性等级描述。
  92. /// 阈值为经验值,可根据业务需求调整。
  93. /// </summary>
  94. /// <param name="metrics">稳定性度量结果</param>
  95. /// <returns>稳定性等级字符串(中文 + 英文)</returns>
  96. public static string GetStabilityRating(StabilityMetrics metrics)
  97. {
  98. // 根据标准差的绝对值分级:阈值为示例值,应结合量纲与业务场景判断
  99. if (metrics.StdDeviation < 0.001)
  100. return "优秀 (Excellent)";
  101. else if (metrics.StdDeviation < 0.005)
  102. return "良好 (Good)";
  103. else if (metrics.StdDeviation < 0.01)
  104. return "合格 (Acceptable)";
  105. else
  106. return "不稳定 (Unstable)";
  107. }
  108. /// <summary>
  109. /// 根据 Cpk 值返回过程能力等级(常用阈值)
  110. /// </summary>
  111. /// <param name="cpk">Cpk 值</param>
  112. /// <returns>等级描述(中文)</returns>
  113. public static string GetCpkRating(double cpk)
  114. {
  115. if (cpk >= 1.67) return "卓越";
  116. if (cpk >= 1.33) return "良好";
  117. if (cpk >= 1.00) return "可接受";
  118. if (cpk >= 0.67) return "不足";
  119. return "严重不足";
  120. }
  121. /// <summary>
  122. /// 计算样本标准差(除以 n-1),适用于样本数据的离散程度估计。
  123. /// 公式:sqrt( Sum((x - mean)^2) / (n - 1) )
  124. /// </summary>
  125. /// <param name="values">输入数据序列</param>
  126. /// <returns>样本标准差</returns>
  127. public static double CalculateStandardDeviation(IEnumerable<double> values)
  128. {
  129. var vals = values.ToArray();
  130. var n = vals.Length;
  131. if (n < 2) return 0.0;
  132. var avg = vals.Average();
  133. var sumSq = vals.Sum(v => Math.Pow(v - avg, 2));
  134. // 使用样本标准差(除以 n-1)
  135. return Math.Sqrt(sumSq / (n - 1));
  136. }
  137. /// <summary>
  138. /// 计算极差(最大值 - 最小值)
  139. /// </summary>
  140. /// <param name="values">输入数据序列</param>
  141. /// <returns>极差</returns>
  142. public static double CalculateRange(IEnumerable<double> values)
  143. {
  144. var vals = values.ToArray();
  145. if (vals.Length == 0) return 0.0;
  146. return vals.Max() - vals.Min();
  147. }
  148. /// <summary>
  149. /// 计算变异系数(标准差 / 平均值 * 100%)
  150. /// </summary>
  151. /// <param name="values">输入数据序列</param>
  152. /// <returns>变异系数的百分比表示</returns>
  153. public static double CalculateCV(IEnumerable<double> values)
  154. {
  155. var vals = values.ToArray();
  156. var stdDev = CalculateStandardDeviation(vals);
  157. var mean = vals.Average();
  158. if (Math.Abs(mean) < double.Epsilon) return double.NaN; // 避免除以 0
  159. return (stdDev / mean) * 100; // 百分比
  160. }
  161. /// <summary>
  162. /// 计算与理论值的绝对偏差(常用于评估准确性)
  163. /// </summary>
  164. /// <param name="values">输入数据序列</param>
  165. /// <param name="theoreticalValue">理论或目标值</param>
  166. /// <returns>平均值与理论值的绝对差</returns>
  167. public static double CalculateAccuracy(IEnumerable<double> values, double theoreticalValue)
  168. {
  169. var mean = values.Average();
  170. return Math.Abs(mean - theoreticalValue);
  171. }
  172. /// <summary>
  173. /// 计算 95% 置信区间(基于正态近似,使用 z=1.96)
  174. /// 置信区间 = mean ± 1.96 * s / sqrt(n)
  175. /// </summary>
  176. /// <param name="values">输入数据序列</param>
  177. /// <returns>置信区间下限与上限</returns>
  178. public static (double lower, double upper) Calculate95ConfidenceInterval(IEnumerable<double> values)
  179. {
  180. var vals = values.ToArray();
  181. var n = vals.Length;
  182. if (n == 0) return (0, 0);
  183. var mean = vals.Average();
  184. var stdDev = CalculateStandardDeviation(vals);
  185. var margin = 1.96 * stdDev / Math.Sqrt(n); // 1.96 对应 95% 置信度(正态分布近似)
  186. return (mean - margin, mean + margin);
  187. }
  188. /// <summary>
  189. /// 便捷方法:返回样本标准差
  190. /// </summary>
  191. /// <param name="values">输入数据序列</param>
  192. /// <returns>样本标准差</returns>
  193. public static double GetStdDeviation(IEnumerable<double> values)
  194. {
  195. return CalculateStandardDeviation(values);
  196. }
  197. /// <summary>
  198. /// 返回平均值 ± 3σ 的上下限(约包含 99.73% 的正态分布数据)
  199. /// </summary>
  200. /// <param name="values">输入数据序列</param>
  201. /// <returns>(lower, upper)</returns>
  202. public static (double lower, double upper) Get3SigmaRange(IEnumerable<double> values)
  203. {
  204. var vals = values.ToArray();
  205. if (vals.Length == 0) return (0, 0);
  206. var mean = vals.Average();
  207. var stdDev = CalculateStandardDeviation(vals);
  208. return (mean - 3 * stdDev, mean + 3 * stdDev);
  209. }
  210. /// <summary>
  211. /// 计算峰度(Kurtosis),使用 Fisher 定义(返回值在正态分布时为 0)
  212. /// 公式(简化样本版本): (n * sum((x-mean)^4)) / (sum((x-mean)^2)^2) - 3
  213. /// </summary>
  214. /// <param name="values">输入数据序列</param>
  215. /// <returns>峰度值</returns>
  216. public static double CalculateKurtosis(IEnumerable<double> values)
  217. {
  218. var vals = values.ToArray();
  219. var n = vals.Length;
  220. if (n < 4) return 0.0; // 数据过少时峰度意义不大
  221. var mean = vals.Average();
  222. var sum4 = vals.Sum(v => Math.Pow(v - mean, 4));
  223. var sum2 = vals.Sum(v => Math.Pow(v - mean, 2));
  224. if (Math.Abs(sum2) < double.Epsilon) return 0.0;
  225. // Fisher 峰度(正态分布为 0)
  226. return (n * sum4) / Math.Pow(sum2, 2) - 3;
  227. }
  228. /// <summary>
  229. /// 计算过程能力指标 Cp 与 Cpk
  230. /// Cp = (USL - LSL) / (6 * sigma)
  231. /// Cpk = min( (USL - mean) / (3 * sigma), (mean - LSL) / (3 * sigma) )
  232. /// </summary>
  233. /// <param name="values">输入数据序列</param>
  234. /// <param name="lowerSpec">下规格限(LSL)</param>
  235. /// <param name="upperSpec">上规格限(USL)</param>
  236. /// <returns>(cp, cpk)</returns>
  237. public static (double cp, double cpk) CalculateProcessCapability(
  238. IEnumerable<double> values,
  239. double lowerSpec,
  240. double upperSpec)
  241. {
  242. var vals = values.ToArray();
  243. var stdDev = CalculateStandardDeviation(vals);
  244. var mean = vals.Average();
  245. if (stdDev <= 0) return (double.NaN, double.NaN); // 避免除以 0
  246. // Cp 反映公差带相对于总体变异的宽度
  247. var cp = (upperSpec - lowerSpec) / (6 * stdDev);
  248. // Cpk 考虑均值偏移,取靠近任一边的能力
  249. var cpu = (upperSpec - mean) / (3 * stdDev);
  250. var cpl = (mean - lowerSpec) / (3 * stdDev);
  251. var cpk = Math.Min(cpu, cpl);
  252. return (cp, cpk);
  253. }
  254. }
  255. }