2010-05-26 9 views
15

में कुशल एकाधिक रैखिक रिग्रेशन क्या किसी को सी # में एकाधिक रैखिक प्रतिगमन करने का एक प्रभावी तरीका पता है, जहां एक साथ समीकरणों की संख्या 1000 के (3 या 4 अलग-अलग इनपुट के साथ) हो सकती है।सी #/.NET

Matrix y = new Matrix(
    new double[,]{{745}, 
        {895}, 
        {442}, 
        {440}, 
        {1598}}); 

Matrix x = new Matrix(
    new double[,]{{1, 36, 66}, 
       {1, 37, 68}, 
       {1, 47, 64}, 
       {1, 32, 53}, 
       {1, 1, 101}}); 

Matrix b = (x.Transpose() * x).Inverse() * x.Transpose() * y; 

for (int i = 0; i < b.Rows; i++) 
{ 
    Trace.WriteLine("INFO: " + b[i, 0].ToDouble()); 
} 

हालांकि यह मैट्रिक्स उलट ऑपरेशन के कारण समीकरणों के 1000 के पैमाने पर करने के साथ-साथ बड़े पैमाने नहीं करता है: कई रेखीय प्रतीपगमन पर this article पढ़ने के बाद मैं एक मैट्रिक्स समीकरण के साथ लागू करने की कोशिश की। मैं आर भाषा को कॉल कर सकता हूं और इसका उपयोग कर सकता हूं, हालांकि मैं उम्मीद कर रहा था कि एक शुद्ध नेट समाधान होगा जो इन बड़े सेटों को स्केल करेगा।

कोई सुझाव?

संपादित करें # 1:

मैं कुछ समय के लिए आर का उपयोग कर बस गए। Statconn का उपयोग करके (डाउनलोड here) मैंने पाया है कि यह तेजी से & दोनों इस विधि का उपयोग करने के लिए अपेक्षाकृत आसान है। अर्थात। यहां एक छोटा कोड स्निपेट है, यह वास्तव में आर statconn पुस्तकालय का उपयोग करने के लिए बहुत अधिक कोड नहीं है (नोट: यह सभी कोड नहीं है!)।

_StatConn.EvaluateNoReturn(string.Format("output <- lm({0})", equation)); 
object intercept = _StatConn.Evaluate("coefficients(output)['(Intercept)']"); 
parameters[0] = (double)intercept; 
for (int i = 0; i < xColCount; i++) 
{ 
    object parameter = _StatConn.Evaluate(string.Format("coefficients(output)['x{0}']", i)); 
    parameters[i + 1] = (double)parameter; 
} 
+0

उपयोग शायद एक GPU पुस्तकालय? –

+0

क्या आप मैट्रिक्स ऑपरेशंस को तेज़ी से चलाने का मतलब रखते हैं? मुझे नहीं लगता कि यह सबसे अच्छा तरीका होगा, मुझे लगता है कि एक गैर-मैट्रिक्स शैली दृष्टिकोण (या कुछ जो उलटा से बचाता है) का उपयोग करना सबसे अच्छा तरीका होगा। – mike

+0

मुझे सफलता मिली है http://www.codeproject.com/KB/recipes/LinReg.aspx उपयोग करने के लिए बहुत आसान और खुला स्रोत! – BoroDrummer

उत्तर

3

रिकॉर्ड के लिए, मैं हाल ही में ALGLIB पुस्तकालय जो, ज्यादा प्रलेखन नहीं होने जबकि, linear regression जो बातें मैं के बाद था में से एक है के रूप में इस तरह के कुछ बहुत ही उपयोगी कार्य करता है पाया।

नमूना कोड (यह पुराना और असत्यापित है, मैं इसका उपयोग करने का एक मूल उदाहरण है)। मैं 3 प्रविष्टियों (3min/2min/1min कहा जाता है) और फिर परिष्करण मूल्य (अंतिम) के साथ समय श्रृंखला पर रैखिक प्रतिगमन का उपयोग कर रहा था।

public void Foo(List<Sample> samples) 
{ 
    int nAttributes = 3; // 3min, 2min, 1min 
    int nSamples = samples.Count; 
    double[,] tsData = new double[nSamples, nAttributes]; 
    double[] resultData = new double[nSamples]; 

    for (int i = 0; i < samples.Count; i++) 
    { 
    tsData[i, 0] = samples[i].Tminus1min; 
    tsData[i, 1] = samples[i].Tminus2min; 
    tsData[i, 2] = samples[i].Tminus3min; 

    resultData[i] = samples[i].Final; 
    } 

    double[] weights = null; 
    int fitResult = 0; 
    alglib.lsfit.lsfitreport rep = new alglib.lsfit.lsfitreport(); 
    alglib.lsfit.lsfitlinear(resultData, tsData, nSamples, nAttributes, ref fitResult, ref weights, rep); 

    Dictionary<string, double> labelsAndWeights = new Dictionary<string, double>(); 
    labelsAndWeights.Add("1min", weights[0]); 
    labelsAndWeights.Add("2min", weights[1]); 
    labelsAndWeights.Add("3min", weights[2]); 
} 
+0

अच्छा सुझाव। कोई कोड उदाहरण आप पोस्ट करने के इच्छुक होंगे? – Mario

+0

कुछ नमूना कोड के लिए संपादित देखें, मुझे उम्मीद है कि यह अभी भी काम करता है (आपको alglib के संदर्भ की आवश्यकता होगी) – mike

+0

अच्छा। आप इस नमूने में एक अज्ञात निरंतर चर कैसे शामिल करेंगे? – Oriental

1

Meta.Numerics का प्रयास करें:

Meta.Numerics .NET फ्रेमवर्क में उन्नत वैज्ञानिक गणना के लिए एक पुस्तकालय है। इसका उपयोग सी #, विजुअल बेसिक, एफ #, या किसी अन्य .NET प्रोग्रामिंग भाषा से किया जा सकता है। मेटा न्यूमेरिक्स लाइब्रेरी पूरी तरह से ऑब्जेक्ट उन्मुख है और कार्यान्वयन और निष्पादन की गति के लिए अनुकूलित है।

एक मैट्रिक्स भर दें, ColumnVector Constructor (IList<Double>) का एक उदाहरण देख। यह दोहरी [] और सूची सहित रीयल के कई आदेशित संग्रहों से ColumnVector का निर्माण कर सकता है।

+0

धन्यवाद, मैंने पहले उस पुस्तकालय को नहीं देखा था। अच्छा लग रहा है, लेकिन अभी भी matrices के साथ समीकरणों को हल करने के एक ही मुद्दे पीड़ित है। मुझे लगता है कि मुझे एक अलग दृष्टिकोण की जरूरत है। – mike

2

उलटा होने वाले मैट्रिक्स का आकार एक साथ समीकरणों (नमूने) की संख्या के साथ नहीं बढ़ता है। x.Transpose() * x एक वर्ग मैट्रिक्स है जहां आयाम स्वतंत्र चर की संख्या है।

+0

दिलचस्प बिंदु, मुझे आश्चर्य है कि मेरा प्रदर्शन इतना क्यों घटता है? मेरे सेट में मेरे पास लगभग 6000 नमूने थे। मुझे इसकी जांच करनी होगी। – mike

+0

मुझे लगता है कि आपका प्रदर्शन घटता है क्योंकि x.Transpose() * x को बड़ी मैट्रिक्स के साथ अधिक समय लगता है। मेरे पास कहीं लाइब्रेरी है जो लाखों डेटा पॉइंट्स के लिए काम करती है ... यदि आप रुचि रखते हैं तो मैं इसे खोदने की कोशिश करूंगा। मुझे बीस साल पहले इस समस्या का सामना करना पड़ा (हाँ मैं बूढ़ा हूं) और एक चतुर गणितीय समाधान मिला :-) –

+1

यदि आप बेहतर स्केलिंग चाहते हैं तो आपको ग्रेडियेंट वंश विधि का उपयोग करना चाहिए। –

1

मैं FinMath का उपयोग करने का सुझाव दे सकता हूं। यह बेहद अनुकूलित है। नेट संख्यात्मक गणना पुस्तकालय। यह जटिल गणना करने के लिए इंटेल मैथ कर्नेल लाइब्रेरी का उपयोग करता है जैसे रैखिक प्रतिगमन या मैट्रिक्स उलटा, लेकिन अधिकांश वर्गों में बहुत ही सरल पहुंचने योग्य इंटरफेस होते हैं। और निश्चित रूप से, यह डेटा के एक बड़े सेट के लिए स्केलेबल है। mrnye के उदाहरण हो इस तरह दिखेगा:

using FinMath.LeastSquares; 
using FinMath.LinearAlgebra; 

Vector y = new Vector(new double[]{745, 
    895, 
    442, 
    440, 
    1598}); 

Matrix X = new Matrix(new double[,]{ 
    {1, 36, 66}, 
    {1, 37, 68}, 
    {1, 47, 64}, 
    {1, 32, 53}, 
    {1, 1, 101}}); 

Vector b = OrdinaryLS.FitOLS(X, y); 

Console.WriteLine(b); 
0

मैं हाल ही में MathNet-Numerics में आए - जो MIT लाइसेंस के तहत उपलब्ध है।

यह आम (X.Transpose() * X).Inverse() * (X.Transpose() * y) प्रक्रिया के लिए तेज़ विकल्प प्रदान करने का दावा करता है।

यहां this article से कुछ अनुकूलन दिए गए हैं। सबसे पहले एक जा रहा है:

X.TransposeThisAndMultiply(X).Inverse() * X.TransposeThisAndMultiply(y) 

या, आप Cholesky decomposition इस्तेमाल कर सकते हैं: