非常感謝Tomas的幫助。
所以我在C#中實現了以下方法。
public static Tuple<double, double, double> performLinearRegression(Series<double, double> series)
{
REngine.SetEnvironmentVariables();
REngine engine = REngine.GetInstance();
engine.Initialize();
var x = engine.CreateNumericVector(series.Keys);
var y = engine.CreateNumericVector(series.Values);
engine.SetSymbol("x", x);
engine.SetSymbol("y", y);
var result = engine.Evaluate("lm(y~x)");
engine.SetSymbol("result", result);
var coefficients = result.AsList()["coefficients"].AsNumeric().ToList();
double r2 = engine.Evaluate("summary(result)").AsList()["r.squared"].AsNumeric().ToList()[0];
double intercept = coefficients[0];
double slope = coefficients[1];
return Tuple.Create(intercept, slope, r2);
}
其中我只引用RDotNet。
我也通過簡單地增加一個F#項目(FSharpInterop)我的C#解決方案實現的F#:
namespace FSharpInterop
open System
open RDotNet
open RProvider
open RProvider.graphics
open RProvider.stats
open System.Linq
module myRProvider =
let performLinearRegression X Y =
let dataset =
namedParams [
"Y", box Y;
"X", box X; ]
|> R.data_frame
let result = R.lm(formula = "Y~X", data = dataset)
let coefficients = result.AsList().["coefficients"].AsNumeric().ToList()
let r2=R.summary(result).AsList().["r.squared"].AsNumeric().ToList().[0]
let inter=coefficients.[0]
let slope=coefficients.[1]
(inter, slope, r2)
現在,在我的ConsoleApplication引用FSharpInterop,我可以做到以下幾點:
private static void Main(string[] args)
{
Series<double, double> series= //get a series
Tuple<double, double, double> deedleRes = myRProvider.performLinearRegression(series.Keys, series.Values);
Tuple<double, double, double> rDotNetRes=performLinearRegression(series);
}
我感覺它是「快速和骯髒」(特別是因爲我將結果格式化爲一個Tuple,而我猜想有更好的方法可以很容易地得到.Net類型的結果,這要歸功於Deedle),但至少它應該讓我去。
如果您有任何意見或建議,隨時讓我知道。
來源
2016-12-13 10:55:59
CDM