using MathNet.Numerics.LinearAlgebra;
|
using MathNet.Numerics.LinearAlgebra.Double;
|
|
namespace IStation.Test
|
{
|
|
public class NonlinearRegressionHelper
|
{
|
//static void Main(string[] args)
|
//{
|
// // 示例数据:Flow1 和 Pressure1
|
// double[] flow1 = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };
|
// double[] pressure1 = { 2.1, 4.5, 6.8, 9.2, 11.5, 13.8, 16.1, 18.4, 20.7, 23.0 };
|
|
// // 多项式回归的阶数(例如,二次多项式)
|
// int degree = 2;
|
|
// // 拟合多项式回归模型
|
// double[] coefficients = FitPolynomial(flow1, pressure1, degree);
|
|
// // 输出回归系数
|
// Console.WriteLine("多项式回归系数:");
|
// for (int i = 0; i <= degree; i++)
|
// {
|
// Console.WriteLine($"系数 {i}: {coefficients[i]}");
|
// }
|
|
// // 使用模型进行预测
|
// double xNew = 11.0;
|
// double yPredicted = PredictPolynomial(xNew, coefficients);
|
// Console.WriteLine($"\n当 Flow1 = {xNew} 时,预测的 Pressure1 = {yPredicted}");
|
|
// // 计算 R² 和 MSE
|
// double rSquared = CalculateRSquared(flow1, pressure1, coefficients);
|
// double mse = CalculateMSE(flow1, pressure1, coefficients);
|
// Console.WriteLine($"\nR² = {rSquared}");
|
// Console.WriteLine($"MSE = {mse}");
|
//}
|
|
public static void Test(DataCellViewModel xCell, DataCellViewModel yCell)
|
{
|
var x = xCell.ValueList.ToArray();
|
var y = yCell.ValueList.ToArray();
|
|
// 多项式回归的阶数(例如,二次多项式)
|
int degree = 4;
|
|
// 拟合多项式回归模型
|
double[] coefficients = FitPolynomial(x, y, degree);
|
|
// 输出回归系数
|
Console.WriteLine("多项式回归系数:");
|
for (int i = 0; i <= degree; i++)
|
{
|
Console.WriteLine($"系数 {i}: {coefficients[i]}");
|
}
|
|
// 使用模型进行预测
|
double xNew = x.Average();
|
double yPredicted = PredictPolynomial(xNew, coefficients);
|
Console.WriteLine($"\n当 {xCell.Name} = {xNew} 时,预测的 {yCell.Name} = {yPredicted}");
|
|
// 计算 R² 和 MSE
|
double rSquared = CalculateRSquared(x, y, coefficients);
|
double mse = CalculateMSE(x, y, coefficients);
|
Console.WriteLine($"\nR² = {rSquared}");
|
Console.WriteLine($"MSE = {mse}");
|
|
Console.WriteLine();
|
Console.WriteLine();
|
|
}
|
|
// 多项式回归拟合
|
public static double[] FitPolynomial(double[] x, double[] y, int degree)
|
{
|
// 构建设计矩阵
|
Matrix<double> X = DenseMatrix.OfArray(new double[x.Length, degree + 1]);
|
for (int i = 0; i < x.Length; i++)
|
{
|
for (int j = 0; j <= degree; j++)
|
{
|
X[i, j] = Math.Pow(x[i], j);
|
}
|
}
|
|
// 构建目标向量
|
Vector<double> Y = DenseVector.OfArray(y);
|
|
// 使用最小二乘法求解
|
var qr = X.QR();
|
Vector<double> coefficients = qr.Solve(Y);
|
|
return coefficients.ToArray();
|
}
|
|
// 使用多项式模型进行预测
|
public static double PredictPolynomial(double x, double[] coefficients)
|
{
|
double prediction = 0.0;
|
for (int i = 0; i < coefficients.Length; i++)
|
{
|
prediction += coefficients[i] * Math.Pow(x, i);
|
}
|
return prediction;
|
}
|
|
// 计算 R²(决定系数)
|
public static double CalculateRSquared(double[] x, double[] y, double[] coefficients)
|
{
|
double yMean = 0.0;
|
double ssTotal = 0.0;
|
double ssResidual = 0.0;
|
|
for (int i = 0; i < y.Length; i++)
|
{
|
yMean += y[i];
|
}
|
yMean /= y.Length;
|
|
for (int i = 0; i < y.Length; i++)
|
{
|
double yPredicted = PredictPolynomial(x[i], coefficients);
|
ssTotal += Math.Pow(y[i] - yMean, 2);
|
ssResidual += Math.Pow(y[i] - yPredicted, 2);
|
}
|
|
return 1.0 - (ssResidual / ssTotal);
|
}
|
|
// 计算 MSE(均方误差)
|
public static double CalculateMSE(double[] x, double[] y, double[] coefficients)
|
{
|
double mse = 0.0;
|
for (int i = 0; i < y.Length; i++)
|
{
|
double yPredicted = PredictPolynomial(x[i], coefficients);
|
mse += Math.Pow(y[i] - yPredicted, 2);
|
}
|
return mse / y.Length;
|
}
|
|
|
//static void Main(string[] args)
|
//{
|
// // 示例数据:Flow 和 Pressure
|
// double[] flow = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0 };
|
// double[] pressure = { 2.1, 4.5, 6.8, 9.2, 11.5, 13.8, 16.1, 18.4, 20.7, 23.0 };
|
|
// // 指数回归
|
// double[] exponentialCoefficients = FitExponentialRegression(flow, pressure);
|
// Console.WriteLine("指数回归系数:");
|
// Console.WriteLine($"a = {Math.Exp(exponentialCoefficients[0])}");
|
// Console.WriteLine($"b = {exponentialCoefficients[1]}");
|
|
// double flowNew = 11.0;
|
// double pressurePredictedExponential = PredictExponential(flowNew, exponentialCoefficients);
|
// Console.WriteLine($"\n当 Flow = {flowNew} 时,指数回归预测的 Pressure = {pressurePredictedExponential}");
|
|
// // 对数回归
|
// double[] logarithmicCoefficients = FitLogarithmicRegression(flow, pressure);
|
// Console.WriteLine("\n对数回归系数:");
|
// Console.WriteLine($"a = {logarithmicCoefficients[0]}");
|
// Console.WriteLine($"b = {logarithmicCoefficients[1]}");
|
|
// double pressurePredictedLogarithmic = PredictLogarithmic(flowNew, logarithmicCoefficients);
|
// Console.WriteLine($"\n当 Flow = {flowNew} 时,对数回归预测的 Pressure = {pressurePredictedLogarithmic}");
|
|
// // 模型评估
|
// double rSquaredExponential = CalculateRSquaredExponential(flow, pressure, exponentialCoefficients);
|
// double mseExponential = CalculateMSEExponential(flow, pressure, exponentialCoefficients);
|
// Console.WriteLine($"\n指数回归模型评估:");
|
// Console.WriteLine($"R² = {rSquaredExponential}");
|
// Console.WriteLine($"MSE = {mseExponential}");
|
|
// double rSquaredLogarithmic = CalculateRSquaredLogarithmic(flow, pressure, logarithmicCoefficients);
|
// double mseLogarithmic = CalculateMSELogarithmic(flow, pressure, logarithmicCoefficients);
|
// Console.WriteLine($"\n对数回归模型评估:");
|
// Console.WriteLine($"R² = {rSquaredLogarithmic}");
|
// Console.WriteLine($"MSE = {mseLogarithmic}");
|
//}
|
|
//public static void Test(DataCellViewModel xCell, DataCellViewModel yCell)
|
//{
|
// // 示例数据:Flow 和 Pressure
|
// double[] x = xCell.ValueList.ToArray();
|
// double[] y = yCell.ValueList.ToArray();
|
|
// // 指数回归
|
// double[] exponentialCoefficients = FitExponentialRegression(x, y);
|
// Console.WriteLine("指数回归系数:");
|
// Console.WriteLine($"a = {Math.Exp(exponentialCoefficients[0])}");
|
// Console.WriteLine($"b = {exponentialCoefficients[1]}");
|
|
// double flowNew = x.Average();
|
// double pressurePredictedExponential = PredictExponential(flowNew, exponentialCoefficients);
|
// Console.WriteLine($"\n当 {xCell.Name} = {flowNew} 时,指数回归预测的 {yCell.Name} = {pressurePredictedExponential}");
|
|
// // 对数回归
|
// double[] logarithmicCoefficients = FitLogarithmicRegression(x, y);
|
// Console.WriteLine("\n对数回归系数:");
|
// Console.WriteLine($"a = {logarithmicCoefficients[0]}");
|
// Console.WriteLine($"b = {logarithmicCoefficients[1]}");
|
|
// double pressurePredictedLogarithmic = PredictLogarithmic(flowNew, logarithmicCoefficients);
|
// Console.WriteLine($"\n当 {xCell.Name} = {flowNew} 时,对数回归预测的 {yCell.Name} = {pressurePredictedLogarithmic}");
|
|
// // 模型评估
|
// double rSquaredExponential = CalculateRSquaredExponential(x, y, exponentialCoefficients);
|
// double mseExponential = CalculateMSEExponential(x, y, exponentialCoefficients);
|
// Console.WriteLine($"\n指数回归模型评估:");
|
// Console.WriteLine($"R² = {rSquaredExponential}");
|
// Console.WriteLine($"MSE = {mseExponential}");
|
|
// double rSquaredLogarithmic = CalculateRSquaredLogarithmic(x, y, logarithmicCoefficients);
|
// double mseLogarithmic = CalculateMSELogarithmic(x, y, logarithmicCoefficients);
|
// Console.WriteLine($"\n对数回归模型评估:");
|
// Console.WriteLine($"R² = {rSquaredLogarithmic}");
|
// Console.WriteLine($"MSE = {mseLogarithmic}");
|
//}
|
|
|
|
// 指数回归拟合
|
public static double[] FitExponentialRegression(double[] x, double[] y)
|
{
|
// 将 y 转换为自然对数
|
double[] logY = new double[y.Length];
|
for (int i = 0; i < y.Length; i++)
|
{
|
logY[i] = Math.Log(y[i]);
|
}
|
|
// 构建设计矩阵
|
Matrix<double> X = DenseMatrix.OfArray(new double[x.Length, 2]);
|
for (int i = 0; i < x.Length; i++)
|
{
|
X[i, 0] = 1.0; // 常数项
|
X[i, 1] = x[i];
|
}
|
|
// 构建目标向量
|
Vector<double> Y = DenseVector.OfArray(logY);
|
|
// 使用最小二乘法求解
|
var qr = X.QR();
|
Vector<double> coefficients = qr.Solve(Y);
|
|
return coefficients.ToArray();
|
}
|
|
// 指数回归预测
|
public static double PredictExponential(double x, double[] coefficients)
|
{
|
double a = Math.Exp(coefficients[0]);
|
double b = coefficients[1];
|
return a * Math.Exp(b * x);
|
}
|
|
// 对数回归拟合
|
public static double[] FitLogarithmicRegression(double[] x, double[] y)
|
{
|
// 将 x 转换为自然对数
|
double[] logX = new double[x.Length];
|
for (int i = 0; i < x.Length; i++)
|
{
|
logX[i] = Math.Log(x[i]);
|
}
|
|
// 构建设计矩阵
|
Matrix<double> X = DenseMatrix.OfArray(new double[x.Length, 2]);
|
for (int i = 0; i < x.Length; i++)
|
{
|
X[i, 0] = 1.0; // 常数项
|
X[i, 1] = logX[i];
|
}
|
|
// 构建目标向量
|
Vector<double> Y = DenseVector.OfArray(y);
|
|
// 使用最小二乘法求解
|
var qr = X.QR();
|
Vector<double> coefficients = qr.Solve(Y);
|
|
return coefficients.ToArray();
|
}
|
|
// 对数回归预测
|
public static double PredictLogarithmic(double x, double[] coefficients)
|
{
|
double a = coefficients[0];
|
double b = coefficients[1];
|
return a + b * Math.Log(x);
|
}
|
|
// 计算指数回归的 R²
|
public static double CalculateRSquaredExponential(double[] x, double[] y, double[] coefficients)
|
{
|
double yMean = 0.0;
|
double ssTotal = 0.0;
|
double ssResidual = 0.0;
|
|
for (int i = 0; i < y.Length; i++)
|
{
|
yMean += y[i];
|
}
|
yMean /= y.Length;
|
|
for (int i = 0; i < y.Length; i++)
|
{
|
double yPredicted = PredictExponential(x[i], coefficients);
|
ssTotal += Math.Pow(y[i] - yMean, 2);
|
ssResidual += Math.Pow(y[i] - yPredicted, 2);
|
}
|
|
return 1.0 - (ssResidual / ssTotal);
|
}
|
|
// 计算指数回归的 MSE
|
public static double CalculateMSEExponential(double[] x, double[] y, double[] coefficients)
|
{
|
double mse = 0.0;
|
for (int i = 0; i < y.Length; i++)
|
{
|
double yPredicted = PredictExponential(x[i], coefficients);
|
mse += Math.Pow(y[i] - yPredicted, 2);
|
}
|
return mse / y.Length;
|
}
|
|
// 计算对数回归的 R²
|
public static double CalculateRSquaredLogarithmic(double[] x, double[] y, double[] coefficients)
|
{
|
double yMean = 0.0;
|
double ssTotal = 0.0;
|
double ssResidual = 0.0;
|
|
for (int i = 0; i < y.Length; i++)
|
{
|
yMean += y[i];
|
}
|
yMean /= y.Length;
|
|
for (int i = 0; i < y.Length; i++)
|
{
|
double yPredicted = PredictLogarithmic(x[i], coefficients);
|
ssTotal += Math.Pow(y[i] - yMean, 2);
|
ssResidual += Math.Pow(y[i] - yPredicted, 2);
|
}
|
|
return 1.0 - (ssResidual / ssTotal);
|
}
|
|
// 计算对数回归的 MSE
|
public static double CalculateMSELogarithmic(double[] x, double[] y, double[] coefficients)
|
{
|
double mse = 0.0;
|
for (int i = 0; i < y.Length; i++)
|
{
|
double yPredicted = PredictLogarithmic(x[i], coefficients);
|
mse += Math.Pow(y[i] - yPredicted, 2);
|
}
|
return mse / y.Length;
|
}
|
}
|
|
|
}
|