टी-एसक्यूएल में इल-सेन अनुमानक फ़ंक्शन


जवाबों:


9

मेरे कहने पर मैं झूठ बोल रहा था, मैं इसे एसक्यूएल में नहीं पा रहा हूं। मैं अभी बहुत आलसी था। यहां एक कोड है जिसमें उपयोग का उदाहरण है।

कोड QuickMedian का उपयोग करते हुए TheiSen पर्ल लाइब्रेरी पर आधारित है । आइए एक नया टेबल प्रकार परिभाषित करें जो हमारे डेटा को प्रक्रिया में आसानी से पास कर सके।

CREATE TYPE dbo.TheilSenInputDataTableType AS TABLE 
(
    ID INT IDENTITY(1,1),
    x REAL, 
    y REAL
)

कृपया ID कॉलम पर ध्यान दें, जो यहाँ महत्वपूर्ण है क्योंकि हमारा समाधान TheilSen.pm में पाए गए इनर लूप की सही व्याख्या प्राप्त करने के लिए CROSS APPLY स्टेटमेंट का उपयोग करता है।

my ($x1,$x2,$y1,$y2);
foreach my $i(0 .. $n-2){
    $y1 = $y->[$i];
    $x1 = $x->[$i];
    foreach my $j($i+1 .. $n-1){
        $y2 = $y->[$j];
        $x2 = $x->[$j];

हमें वास्तविक प्रकार मानों की एक सरणी को संग्रहीत करने के लिए एक नए डेटा प्रकार की भी आवश्यकता होगी।

CREATE TYPE [dbo].[RealArray] AS TABLE(
    [val] [real] NULL
)

यहाँ f_QuickMedian फंक्शन दिया गया है, दिए गए एरे के लिए माडियन लौट रहा है। इसका श्रेय इत्ज़िक बेन-गण को जाता है ।

CREATE FUNCTION [dbo].[f_QuickMedian](@RealArray RealArray READONLY)
RETURNS REAL
AS
BEGIN
    DECLARE @Median REAL;
    DECLARE @QMedian REAL;

    SELECT @Median = AVG(1.0 * val)
    FROM
    (
        SELECT o.val, rn = ROW_NUMBER() OVER (ORDER BY o.val), c.c
        FROM @RealArray AS o
        CROSS JOIN (SELECT c = COUNT(*) FROM @RealArray) AS c
    ) AS x
    WHERE rn IN ((c + 1)/2, (c + 2)/2);

    SELECT TOP 1 @QMedian = val FROM @RealArray
    ORDER BY ABS(val - @Median) ASC, val DESC

    RETURN @QMedian
END

और p_TheilSen अनुमानक:

CREATE PROCEDURE [dbo].[p_TheilSen](
      @TheilSenInput TheilSenInputDataTableType READONLY
    , @m Real OUTPUT
    , @c Real OUTPUT
)
AS
BEGIN
    DECLARE 
        @m_arr RealArray
      , @c_arr RealArray;       

    INSERT INTO @m_arr
        SELECT m
        FROM 
        (
            SELECT  
                t1.x as x1
                , t1.y as y1
                , t2o.x as x2
                , t2o.y as y2
                , t2o.y-t1.y as [y2 - y1]
                , t2o.x-t1.x as [x2 - x1]
                , CASE WHEN (t2o.x <> t1.x) THEN  CAST((t2o.y-t1.y) AS Real)/(t2o.x-t1.x) ELSE NULL END AS [($y2-$y1)/($x2-$x1)]
                , CASE WHEN t1.y = t2o.y THEN 0
                  ELSE
                    CASE WHEN t1.x = t2o.x THEN NULL
                        ELSE 
                        -- push @M, ($y2-$y1)/($x2-$x1);
                        CAST((t2o.y-t1.y) AS Real)/(t2o.x-t1.x)
                    END
                  END as m
            FROM @TheilSenInput t1
            CROSS APPLY
                    (
                    SELECT  t2.x, t2.y
                    FROM    @TheilSenInput t2
                    WHERE   t2.ID > t1.ID
                     ) t2o
        ) t
        WHERE m IS NOT NULL 

    SELECT @m = dbo.f_QuickMedian(@m_arr)

    INSERT INTO @c_arr
        SELECT y - (@m * x)
            FROM @TheilSenInput

    SELECT @c = dbo.f_QuickMedian(@c_arr)

END

उदाहरण:

DECLARE 
      @in TheilSenInputDataTableType
    , @m Real
    , @c Real

INSERT INTO @in(x,y) VALUES (10.79,118.99)
INSERT INTO @in(x,y) VALUES (10.8,120.76)
INSERT INTO @in(x,y) VALUES (10.86,122.71)
INSERT INTO @in(x,y) VALUES (10.93,125.48)
INSERT INTO @in(x,y) VALUES (10.99,127.31)
INSERT INTO @in(x,y) VALUES (10.96,130.06)
INSERT INTO @in(x,y) VALUES (10.98,132.41)
INSERT INTO @in(x,y) VALUES (11.03,135.89)
INSERT INTO @in(x,y) VALUES (11.08,139.02)
INSERT INTO @in(x,y) VALUES (11.1,140.25)
INSERT INTO @in(x,y) VALUES (11.19,145.61)
INSERT INTO @in(x,y) VALUES (11.25,153.45)
INSERT INTO @in(x,y) VALUES (11.4,158.03)
INSERT INTO @in(x,y) VALUES (11.61,162.72)
INSERT INTO @in(x,y) VALUES (11.69,167.67)
INSERT INTO @in(x,y) VALUES (11.91,172.86)
INSERT INTO @in(x,y) VALUES (12.07,177.52)
INSERT INTO @in(x,y) VALUES (12.32,182.09)


EXEC p_TheilSen @in, @m = @m OUTPUT, @c = @c OUTPUT

SELECT @m
SELECT @c

यह दिखाता है:

m = 52.7079
c = -448.4853

केवल एक तुलना के लिए, पर्ल संस्करण समान डेटा सेट के लिए निम्न मान देता है:

m = 52.7078651685394
c = -448.484943820225

मैं फ़ाइल सिस्टम के लिए DaysToFill मीट्रिक की गणना करने के लिए TheilSen अनुमानक का उपयोग करता हूं। का आनंद लें!


1

SQLCLR में कुछ करने के लिए यह सबसे अच्छी संभावना होगी, निम्न प्रश्न / उत्तर के समान (DBA पर यहां भी।):

वहाँ एक SQL सर्वर कार्यान्वयन के सबसे लंबे समय तक आम समस्या है?

जब मेरे पास बाद में समय होगा, तो मैं देखूंगा कि यह कितना संभव होगा।


1

मैंने सामान्य रूप से टी-एसक्यूएल, ओरेकल और सर्वर के लिए भी जाँच की (शुद्ध एसक्यूएल में लिखे जाने के लिए बहुत जटिल)।

हालांकि, अगर आप में रुचि हो सकती है इस (पायथन के लिए एक वैज्ञानिक / सांख्यिकीय पैकेज)। एल्गोरिथ्म को वहां और पायथन में भी लागू किया गया है। पायथन एक ऐसी भाषा है, जिसमें मनुष्यों को कम से कम पर्ल के विपरीत समझने का मौका मिलता है।

आपके प्रश्न ने मुझे और मुझे चारों ओर से घेर लिया। C और C ++ लाइब्रेरीज़ हैं, जिनमें यह एल्गोरिथम है - और यह कुछ आर पैकेजों में भी उपलब्ध है। और @srutzky की पोस्ट भी दिलचस्प लग रही है।

एक दिलचस्प प्रश्न के लिए +1 BTW - और मंच पर आपका स्वागत है :-)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.