Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

क्या SQL सर्वर में कोई रैखिक रिग्रेशन फ़ंक्शन है?

मेरी जानकारी के अनुसार, कोई नहीं है। हालाँकि, एक लिखना बहुत सीधा है। निम्नलिखित आपको y =अल्फा + बीटा * x + एप्सिलॉन के लिए निरंतर अल्फा और ढलान बीटा देता है:

-- test data (GroupIDs 1, 2 normal regressions, 3, 4 = no variance)
WITH some_table(GroupID, x, y) AS
(       SELECT 1,  1,  1    UNION SELECT 1,  2,  2    UNION SELECT 1,  3,  1.3  
  UNION SELECT 1,  4,  3.75 UNION SELECT 1,  5,  2.25 UNION SELECT 2, 95, 85    
  UNION SELECT 2, 85, 95    UNION SELECT 2, 80, 70    UNION SELECT 2, 70, 65    
  UNION SELECT 2, 60, 70    UNION SELECT 3,  1,  2    UNION SELECT 3,  1, 3
  UNION SELECT 4,  1,  2    UNION SELECT 4,  2,  2),
 -- linear regression query
/*WITH*/ mean_estimates AS
(   SELECT GroupID
          ,AVG(x * 1.)                                             AS xmean
          ,AVG(y * 1.)                                             AS ymean
    FROM some_table
    GROUP BY GroupID
),
stdev_estimates AS
(   SELECT pd.GroupID
          -- T-SQL STDEV() implementation is not numerically stable
          ,CASE      SUM(SQUARE(x - xmean)) WHEN 0 THEN 1 
           ELSE SQRT(SUM(SQUARE(x - xmean)) / (COUNT(*) - 1)) END AS xstdev
          ,     SQRT(SUM(SQUARE(y - ymean)) / (COUNT(*) - 1))     AS ystdev
    FROM some_table pd
    INNER JOIN mean_estimates  pm ON pm.GroupID = pd.GroupID
    GROUP BY pd.GroupID, pm.xmean, pm.ymean
),
standardized_data AS                   -- increases numerical stability
(   SELECT pd.GroupID
          ,(x - xmean) / xstdev                                    AS xstd
          ,CASE ystdev WHEN 0 THEN 0 ELSE (y - ymean) / ystdev END AS ystd
    FROM some_table pd
    INNER JOIN stdev_estimates ps ON ps.GroupID = pd.GroupID
    INNER JOIN mean_estimates  pm ON pm.GroupID = pd.GroupID
),
standardized_beta_estimates AS
(   SELECT GroupID
          ,CASE WHEN SUM(xstd * xstd) = 0 THEN 0
                ELSE SUM(xstd * ystd) / (COUNT(*) - 1) END         AS betastd
    FROM standardized_data pd
    GROUP BY GroupID
)
SELECT pb.GroupID
      ,ymean - xmean * betastd * ystdev / xstdev                   AS Alpha
      ,betastd * ystdev / xstdev                                   AS Beta
FROM standardized_beta_estimates pb
INNER JOIN stdev_estimates ps ON ps.GroupID = pb.GroupID
INNER JOIN mean_estimates  pm ON pm.GroupID = pb.GroupID

यहां GroupID यह दिखाने के लिए उपयोग किया जाता है कि आपकी स्रोत डेटा तालिका में किसी मान के आधार पर समूह कैसे बनाया जाए। यदि आप तालिका में सभी डेटा के आंकड़े चाहते हैं (विशिष्ट उप-समूह नहीं), तो आप इसे छोड़ सकते हैं और जुड़ सकते हैं। मैंने WITH . का उपयोग किया है स्पष्टता के लिए बयान। एक विकल्प के रूप में, आप इसके बजाय उप-प्रश्नों का उपयोग कर सकते हैं। कृपया अपनी तालिकाओं में उपयोग किए जाने वाले डेटा प्रकार की सटीकता के प्रति सावधान रहें क्योंकि यदि आपके डेटा के सापेक्ष सटीकता पर्याप्त नहीं है, तो संख्यात्मक स्थिरता जल्दी खराब हो सकती है।

संपादित करें: (टिप्पणियों में R2 जैसे अतिरिक्त आँकड़ों के लिए पीटर के प्रश्न के उत्तर में)

आप उसी तकनीक का उपयोग करके आसानी से अतिरिक्त आँकड़ों की गणना कर सकते हैं। यहाँ R2, सहसंबंध और नमूना सहप्रसरण वाला संस्करण दिया गया है:

-- test data (GroupIDs 1, 2 normal regressions, 3, 4 = no variance)
WITH some_table(GroupID, x, y) AS
(       SELECT 1,  1,  1    UNION SELECT 1,  2,  2    UNION SELECT 1,  3,  1.3  
  UNION SELECT 1,  4,  3.75 UNION SELECT 1,  5,  2.25 UNION SELECT 2, 95, 85    
  UNION SELECT 2, 85, 95    UNION SELECT 2, 80, 70    UNION SELECT 2, 70, 65    
  UNION SELECT 2, 60, 70    UNION SELECT 3,  1,  2    UNION SELECT 3,  1, 3
  UNION SELECT 4,  1,  2    UNION SELECT 4,  2,  2),
 -- linear regression query
/*WITH*/ mean_estimates AS
(   SELECT GroupID
          ,AVG(x * 1.)                                             AS xmean
          ,AVG(y * 1.)                                             AS ymean
    FROM some_table pd
    GROUP BY GroupID
),
stdev_estimates AS
(   SELECT pd.GroupID
          -- T-SQL STDEV() implementation is not numerically stable
          ,CASE      SUM(SQUARE(x - xmean)) WHEN 0 THEN 1 
           ELSE SQRT(SUM(SQUARE(x - xmean)) / (COUNT(*) - 1)) END AS xstdev
          ,     SQRT(SUM(SQUARE(y - ymean)) / (COUNT(*) - 1))     AS ystdev
    FROM some_table pd
    INNER JOIN mean_estimates  pm ON pm.GroupID = pd.GroupID
    GROUP BY pd.GroupID, pm.xmean, pm.ymean
),
standardized_data AS                   -- increases numerical stability
(   SELECT pd.GroupID
          ,(x - xmean) / xstdev                                    AS xstd
          ,CASE ystdev WHEN 0 THEN 0 ELSE (y - ymean) / ystdev END AS ystd
    FROM some_table pd
    INNER JOIN stdev_estimates ps ON ps.GroupID = pd.GroupID
    INNER JOIN mean_estimates  pm ON pm.GroupID = pd.GroupID
),
standardized_beta_estimates AS
(   SELECT GroupID
          ,CASE WHEN SUM(xstd * xstd) = 0 THEN 0
                ELSE SUM(xstd * ystd) / (COUNT(*) - 1) END         AS betastd
    FROM standardized_data
    GROUP BY GroupID
)
SELECT pb.GroupID
      ,ymean - xmean * betastd * ystdev / xstdev                   AS Alpha
      ,betastd * ystdev / xstdev                                   AS Beta
      ,CASE ystdev WHEN 0 THEN 1 ELSE betastd * betastd END        AS R2
      ,betastd                                                     AS Correl
      ,betastd * xstdev * ystdev                                   AS Covar
FROM standardized_beta_estimates pb
INNER JOIN stdev_estimates ps ON ps.GroupID = pb.GroupID
INNER JOIN mean_estimates  pm ON pm.GroupID = pb.GroupID

2 संपादित करें डेटा को मानकीकृत करके (केवल केंद्रित करने के बजाय) और STDEV . को प्रतिस्थापित करके संख्यात्मक स्थिरता में सुधार करता है क्योंकि संख्यात्मक स्थिरता समस्याएं . मेरे लिए, वर्तमान कार्यान्वयन स्थिरता और जटिलता के बीच सबसे अच्छा व्यापार-बंद प्रतीत होता है। मैं अपने मानक विचलन को संख्यात्मक रूप से स्थिर ऑनलाइन एल्गोरिदम के साथ बदलकर स्थिरता में सुधार कर सकता था, लेकिन यह कार्यान्वयन को काफी जटिल करेगा (और इसे धीमा कर देगा)। इसी तरह, कार्यान्वयन उदा। SUM . के लिए Kahan(-Babuška-Neumaier) मुआवज़ा और AVG ऐसा लगता है कि सीमित परीक्षणों में मामूली बेहतर प्रदर्शन करते हैं, लेकिन क्वेरी को और अधिक जटिल बनाते हैं। और जब तक मुझे नहीं पता कि टी-एसक्यूएल SUM को कैसे लागू करता है और AVG (उदाहरण के लिए यह पहले से ही जोड़ीदार योग का उपयोग कर रहा है), मैं गारंटी नहीं दे सकता कि ऐसे संशोधन हमेशा सटीकता में सुधार करते हैं।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर 2008 में हिब्रू मान सम्मिलित करना

  2. इंट से कास्ट/कन्वर्ट क्यों एक तारक देता है

  3. समूह का उपयोग करके तालिका से अंतिम रिकॉर्ड का चयन करें

  4. खाली स्ट्रिंग में डेटाटाइम प्रारूप में NULL मान बदलें

  5. एक टेबल में कितने क्लस्टर इंडेक्स हो सकते हैं?