AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 133138
Accepted
kafe
kafe
Asked: 2016-03-24 04:36:26 +0800 CST2016-03-24 04:36:26 +0800 CST 2016-03-24 04:36:26 +0800 CST

Função de estimador Theil-Sen em T-SQL

  • 772

Alguém tem uma função de regressão Theil-Sen escrita em T-SQL?

Encontrei um escrito em Perl , mas não consigo recodificá-lo em SQL.

sql-server functions
  • 3 3 respostas
  • 293 Views

3 respostas

  • Voted
  1. Best Answer
    kafe
    2016-04-12T03:54:31+08:002016-04-12T03:54:31+08:00

    Eu estava mentindo quando disse que não consigo recodificá-lo em SQL. Eu era muito preguiçoso. Aqui está o código com um exemplo de uso.

    O código é baseado em uma biblioteca TheiSen perl, usando QuickMedian . Vamos definir um novo tipo de tabela para passar facilmente nossos dados para o procedimento.

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

    Observe a coluna ID, que é importante aqui, pois nossa solução usa a instrução CROSS APPLY para obter a interpretação correta do loop interno encontrado em TheilSen.pm.

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

    Também precisaremos de um novo tipo de dados para armazenar uma matriz de valores de tipo real.

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

    Aqui está a função f_QuickMedian , retornando mediana para determinado array. O crédito por este vai para Itzik Ben-Gan .

    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
    

    E o Estimador 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
    

    Exemplo:

    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
    

    Retorna:

    m = 52.7079
    c = -448.4853
    

    Apenas para comparação, a versão perl retorna os seguintes valores para o mesmo conjunto de dados:

    m = 52.7078651685394
    c = -448.484943820225
    

    Eu uso o estimador TheilSen para calcular a métrica DaysToFill para sistemas de arquivos. Apreciar!

    • 9
  2. Vérace
    2016-03-24T06:46:13+08:002016-03-24T06:46:13+08:00

    Verifiquei também T-SQL, Oracle e servidores em geral (muito complexos para serem escritos em SQL puro).

    No entanto, você pode estar interessado nisso (um pacote científico/estatístico para Python). O algoritmo é implementado lá também e em Python. Python é uma linguagem que os humanos têm pelo menos alguma chance de entender, ao contrário do Perl.

    Sua pergunta me intrigou e eu procurei. Existem bibliotecas C e C++ que contêm esse algoritmo - e também está disponível em alguns pacotes R. E a postagem de @srutzky também parece interessante.

    +1 para uma pergunta interessante BTW - e bem-vindo ao fórum :-)

    • 1
  3. Solomon Rutzky
    2016-03-24T08:10:14+08:002016-03-24T08:10:14+08:00

    Isso provavelmente seria uma boa opção para fazer algo no SQLCLR, semelhante à seguinte Pergunta/Resposta (também aqui no DBA.SE):

    Existe uma implementação do SQL Server do problema de substring comum mais longa?

    Quando tiver tempo mais tarde, verei como isso seria viável.

    • 1

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve