2016-12-11 37 views
0

線性迴歸我建立了一個deedle系列類型:一個C#解決方案中C# - 在deedle系列

Series<DateTime, double> 

。我試圖執行使用R函數「LM」(仍然在該溶液中)的線性迴歸(其語法LM(Y〜X,數據),其中Y是響應和x的預測值)

public static void performLinearRegression(Series<DateTime, double> series) 
{ 
} 

如果有人能夠幫助我做到這一點,我將不勝感激 - 如果可能的話!我想我必須使用RProvider.RInterop.callFunc,但我沒有設法這樣做。

非常感謝。

回答

1

R提供程序頁面上有一個F#示例,顯示how to call the lm function,但這是使用R類型的提供程序,可惜不受C#支持。從C#調用R時,您可能不會從引用R提供程序中獲益太多,因此您需要使用R.NET直接重寫樣本。

沒有說明如何調用How to Use lm function in r.net?lm這將數據保存到磁盤上,但你真的只需要創建一個數據幀(如F#的樣品一樣),該函數可以訪問一個例子 - 和創建數據幀是涵蓋在Creating a Data.Frame using R.NET。所以,我認爲如果你把這兩者結合在一起,你應該可以做到這一點 - 在這裏,Deedle可悲的幫助不了你,因爲好的R型提供者支持它只有F#。

0

非常感謝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),但至少它應該讓我去。

如果您有任何意見或建議,隨時讓我知道。