Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Có bất kỳ chức năng hồi quy tuyến tính nào trong SQL Server không?

Theo hiểu biết tốt nhất của tôi, không có. Viết một cái là khá đơn giản, mặc dù. Phần sau cung cấp cho bạn hệ số alpha và beta độ dốc không đổi cho y =Alpha + Beta * x + epsilon:

-- 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

Đây GroupID được sử dụng để hiển thị cách nhóm theo một số giá trị trong bảng dữ liệu nguồn của bạn. Nếu bạn chỉ muốn thống kê trên tất cả dữ liệu trong bảng (không phải các nhóm con cụ thể), bạn có thể loại bỏ nó và các kết hợp. Tôi đã sử dụng WITH tuyên bố vì lợi ích của sự rõ ràng. Thay vào đó, bạn có thể sử dụng các truy vấn phụ. Hãy lưu ý đến độ chính xác của loại dữ liệu được sử dụng trong các bảng của bạn vì độ ổn định số có thể giảm đi nhanh chóng nếu độ chính xác không đủ cao so với dữ liệu của bạn.

CHỈNH SỬA: (trả lời câu hỏi của Peter để biết thêm số liệu thống kê như R2 trong phần nhận xét)

Bạn có thể dễ dàng tính toán các số liệu thống kê bổ sung bằng cách sử dụng cùng một kỹ thuật. Đây là phiên bản có R2, tương quan và hiệp phương sai mẫu:

-- 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

CHỈNH SỬA 2 cải thiện độ ổn định số bằng cách chuẩn hóa dữ liệu (thay vì chỉ căn giữa) và bằng cách thay thế STDEV vấn đề ổn định số . Đối với tôi, việc triển khai hiện tại dường như là sự cân bằng tốt nhất giữa tính ổn định và sự phức tạp. Tôi có thể cải thiện độ ổn định bằng cách thay thế độ lệch chuẩn của mình bằng một thuật toán trực tuyến ổn định về số, nhưng điều này sẽ làm phức tạp đáng kể việc triển khai (và làm chậm nó). Tương tự, các triển khai bằng cách sử dụng ví dụ:Kahan (-Babuška-Neumaier) đền bù cho SUMAVG dường như hoạt động tốt hơn một cách khiêm tốn trong các thử nghiệm hạn chế, nhưng làm cho truy vấn phức tạp hơn nhiều. Và miễn là tôi không biết cách T-SQL triển khai SUMAVG (ví dụ:nó có thể đã sử dụng tính toán tổng hợp theo cặp), tôi không thể đảm bảo rằng những sửa đổi đó luôn cải thiện độ chính xác.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách bắt đầu với SQL Server trên Azure

  2. Thống kê đối tượng cơ sở dữ liệu SQL Server

  3. Những tài nguyên nào tồn tại để điều chỉnh hiệu suất Cơ sở dữ liệu?

  4. Làm cách nào để thêm giờ vào ngày hiện tại trong SQL Server?

  5. Khắc phục sự cố trong Sql Server 2008