C# .Net 最小二乘法 线性回归 linear regression

源码

public static SlopeInfo LinearRegression(float[] xVals, float[] yVals)
{
	return LinearRegression(xVals, yVals, 0, yVals.Length);
}

public static SlopeInfo LinearRegression(float[] xVals, float[] yVals,
								   int inclusiveStart, int exclusiveEnd)
{
	Debug.Assert(xVals.Length == yVals.Length);
	float sumOfX = 0;
	float sumOfY = 0;
	float sumOfXSq = 0;
	float sumOfYSq = 0;
	float ssX = 0;
	float ssY = 0;
	float sumCodeviates = 0;
	float sCo = 0;
	float count = exclusiveEnd - inclusiveStart;

	for (int ctr = inclusiveStart; ctr < exclusiveEnd; ctr++)
	{
		float x = xVals[ctr];
		float y = yVals[ctr];
		sumCodeviates += x * y;
		sumOfX += x;
		sumOfY += y;
		sumOfXSq += x * x;
		sumOfYSq += y * y;
	}
	ssX = sumOfXSq - ((sumOfX * sumOfX) / count);
	ssY = sumOfYSq - ((sumOfY * sumOfY) / count);
	float RNumerator = (count * sumCodeviates) - (sumOfX * sumOfY);
	float RDenom = (count * sumOfXSq - (sumOfX * sumOfX))
	 * (count * sumOfYSq - (sumOfY * sumOfY));
	sCo = sumCodeviates - ((sumOfX * sumOfY) / count);

	var meanX = sumOfX / count;
	var meanY = sumOfY / count;
	var dblR = RNumerator / (float)Math.Sqrt(RDenom);

	var rsquared = dblR * dblR;
	var yintercept = meanY - ((sCo / ssX) * meanX);
	var slope = sCo / ssX;
	return new SlopeInfo() { Intercept = yintercept, MeanSqureError = rsquared, Slope = slope };
}

public struct SlopeInfo
{
	/// <summary>
	/// 斜率
	/// </summary>
	public float Slope { get; set; }

	/// <summary>
	/// 截距
	/// </summary>
	public float Intercept { get; set; }

	/// <summary>
	/// 均方差
	/// </summary>
	public float MeanSqureError { get; set; }

	public override string ToString()
	{
		return $"Slope {Slope:f2} Intercept {Intercept:f2} MeanSqureError:{MeanSqureError}";
	}
}

示例

引用 包 XPlot.Plotly 一个C#的画图库

    var y = new float[] { 0.5f, 2.5f, 3.1f, 4.9f, 4.3f, 6, 7, 8, 9.5f, 9.5f };
	var x = Enumerable.Range(1, y.Length).Select(x => (float)x).ToArray();
	var info = LinearRegression(x, y);

	info.Dump();

    //跟据公式 y= ax+b 算出我们要的点
	var lines = x.Select(x => x * info.Slope + info.Intercept).ToArray();
	var scatter = new XPlot.Plotly.Scatter()
	{
		y = y,
		x = x
	};

	var scatter3 = new XPlot.Plotly.Scatter()
	{
		y = lines,
		x = x
	};
	var chart = Chart.Plot(new[] { scatter, scatter3 }, new Layout.Layout()
	{
	});

	chart.Show();

看到的是下面的效果。

趋势永存:打败市场的动量策略 里面就是用这个来计算动量的。

最近更新的
...