C#中多元多项式回归需求:拟合三维向量至三次多项式
C#实现三元三次多项式回归获取系数
多元多项式回归可以通过特征转换转化为多元线性回归来实现——把三次多项式的所有展开项作为新的特征变量,就能用Math.NET等库支持的多元线性回归求解系数。针对RGB三维向量的三次多项式,展开后共有20项(对应l0到l19),具体项包括:常数项、一次项(R/G/B)、二次项(R²/RG/RB/G²/GB/B²)、三次项(R³/R²G/R²B/RG²/RGB/RB²/G³/G²B/GB²/B³)。
实现步骤与代码示例
以下是基于Math.NET Numerics的具体实现:
using MathNet.Numerics.LinearAlgebra; using MathNet.Numerics.Statistics; public class CubicPolynomialFitter { // 将RGB样本转换为三元三次多项式的特征向量 private static Vector<double> CreateFeatureVector(double r, double g, double b) { return Vector<double>.Build.DenseOfArray(new[] { 1.0, // l0: 常数项 r, // l1: R一次项 g, // l2: G一次项 b, // l3: B一次项 r*r, // l4: R二次项 r*g, // l5: RG交叉项 r*b, // l6: RB交叉项 g*g, // l7: G二次项 g*b, // l8: GB交叉项 b*b, // l9: B二次项 r*r*r, // l10: R三次项 r*r*g, // l11: R²G交叉项 r*r*b, // l12: R²B交叉项 r*g*g, // l13: RG²交叉项 r*g*b, // l14: RGB交叉项 r*b*b, // l15: RB²交叉项 g*g*g, // l16: G三次项 g*g*b, // l17: G²B交叉项 g*b*b, // l18: GB²交叉项 b*b*b // l19: B三次项 }); } // 拟合三元三次多项式,返回系数l0到l19 public static Vector<double> Fit(double[][] rgbSamples, double[] targetValues) { int sampleCount = rgbSamples.Length; int featureCount = 20; // 构造特征矩阵X:每行对应一个样本的特征向量 Matrix<double> featureMatrix = Matrix<double>.Build.Dense(sampleCount, featureCount); for (int i = 0; i < sampleCount; i++) { double[] rgb = rgbSamples[i]; featureMatrix.SetRow(i, CreateFeatureVector(rgb[0], rgb[1], rgb[2])); } // 构造目标值向量 Vector<double> targetVector = Vector<double>.Build.Dense(targetValues); // 使用QR分解求解多元线性回归(数值稳定性优于正规方程) var regressionResult = MultipleRegression.QR(featureMatrix, targetVector); return regressionResult.Coefficients; } }
关键说明
- 特征转换逻辑:
CreateFeatureVector方法严格按照三元三次多项式的所有项生成特征,确保每个项对应唯一的系数位置(l0到l19)。 - 回归求解选择:使用
MultipleRegression.QR而非NormalEquations,避免样本量较大或特征数值差异大时的数值稳定性问题。 - 数据预处理:建议将RGB值归一化到0-1区间,减少因数值范围差异导致的拟合偏差。
使用示例
// 示例RGB样本(假设有3个样本) double[][] rgbData = new double[][] { new double[] { 0.2, 0.4, 0.6 }, new double[] { 0.3, 0.5, 0.7 }, new double[] { 0.1, 0.8, 0.9 } }; // 对应目标值(根据实际场景替换) double[] targets = new double[] { 0.15, 0.25, 0.30 }; // 拟合并获取系数 Vector<double> coefficients = CubicPolynomialFitter.Fit(rgbData, targets); // 输出l0到l19 for (int i = 0; i < coefficients.Count; i++) { Console.WriteLine($"l{i}: {coefficients[i]:F6}"); }
内容的提问来源于stack exchange,提问作者Lucas Pevidor
相关产品推荐
相关产品推荐

