Respuesta

35

Según mi leal saber y entender, no existe ninguno. Escribir uno es bastante sencillo, sin embargo. A continuación se le da la alfa y beta para pendiente constante y = alfa + beta * x + épsilon:

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

Aquí GroupID se utiliza para mostrar cómo agrupar por algún valor en la tabla de datos de origen. Si solo desea las estadísticas de todos los datos en la tabla (no los subgrupos específicos), puede soltarlos y unirlos. He utilizado la declaración WITH en aras de la claridad. Como alternativa, puede usar subconsultas en su lugar. Tenga en cuenta la precisión del tipo de datos utilizado en sus tablas, ya que la estabilidad numérica puede deteriorarse rápidamente si la precisión no es lo suficientemente alta en relación con sus datos.

EDIT: (en respuesta a la pregunta de Pedro para las estadísticas adicionales como R2 en los comentarios)

Se puede calcular fácilmente estadísticas adicionales utilizando la misma técnica. Aquí es una versión con R2, correlación y covarianza de muestra:

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

EDIT 2 mejora la estabilidad numérica mediante la estandarización de datos (en lugar de solamente el centrado) y mediante la sustitución de STDEV debido a numerical stability issues. Para mí, la implementación actual parece ser la mejor solución de compromiso entre la estabilidad y la complejidad. Podría mejorar la estabilidad reemplazando mi desviación estándar con un algoritmo en línea numéricamente estable, pero esto complicaría la implementación de manera sustancial (y la desaceleraría). De forma similar, las implementaciones que usan, p. Las compensaciones de Kahan (-Babuška-Neumaier) para SUM y AVG parecen funcionar modestamente mejor en pruebas limitadas, pero hacen que la consulta sea mucho más compleja. Y mientras no sepa cómo T-SQL implementa SUM y AVG (por ejemplo, puede que ya esté usando la suma de pares), no puedo garantizar que tales modificaciones siempre mejoren la precisión.

+0

Gracias! tuve que usar esto para resolver mi problema. El problema, en una perspectiva más amplia, era obtener una línea de tendencia en el informe SSRS (2005). Esta fue la única forma. – rao

+0

@pavanrao: de nada.Estimación agregada para la constante alfa de la consulta – stephan

+0

Me doy cuenta de que el hilo tiene 2 años, pero ¿es posible obtener el valor r-cuadrado con este método también? – Peter

12

Este es un método alternativo, basado en una blog post on Linear Regression in T-SQL, que utiliza las siguientes ecuaciones:

enter image description here

La sugerencia SQL en el blog utiliza cursores sin embargo. Aquí hay una versión prettified de un forum answer que utilicé:

table 
----- 
X (numeric) 
Y (numeric) 

/** 
* m = (nSxy - SxSy)/(nSxx - SxSx) 
* b = Ay - (Ax * m) 
* N.B. S = Sum, A = Mean 
*/ 
DECLARE @n INT 
SELECT @n = COUNT(*) FROM table 
SELECT (@n * SUM(X*Y) - SUM(X) * SUM(Y))/(@n * SUM(X*X) - SUM(X) * SUM(X)) AS M, 
     AVG(Y) - AVG(X) * 
     (@n * SUM(X*Y) - SUM(X) * SUM(Y))/(@n * SUM(X*X) - SUM(X) * SUM(X)) AS B 
FROM table 
+1

Esto demuestra que la respuesta con la segunda mayoría de votos es la mejor. – Chris

0

aquí es como una función que toma un tipo de tabla de tipo: mesa (Y flotador, doble X) que es llamada XYDoubleType y asume nuestra función lineal es de la forma Ax + B. vuelve a y B una columna de la tabla en caso de que desee tener en una unión o algo

CREATE FUNCTION FN_GetABForData(
@XYData as XYDoubleType READONLY 
) RETURNS @ABData TABLE(
      A FLOAT, 
      B FLOAT, 
      Rsquare FLOAT) 
AS 
BEGIN 
    DECLARE @sx FLOAT, @sy FLOAT 
    DECLARE @sxx FLOAT,@syy FLOAT, @sxy FLOAT,@sxsy FLOAT, @sxsx FLOAT, @sysy FLOAT 
    DECLARE @n FLOAT, @A FLOAT, @B FLOAT, @Rsq FLOAT 

    SELECT @sx =SUM(D.X) ,@sy =SUM(D.Y), @sxx=SUM(D.X*D.X),@syy=SUM(D.Y*D.Y), 
     @sxy =SUM(D.X*D.Y),@n =COUNT(*) 
    From @XYData D 
    SET @sxsx [email protected]*@sx 
    SET @sxsy [email protected]*@sy 
    SET @sysy = @sy*@sy 

    SET @A = (@n*@sxy [email protected])/(@n*@sxx [email protected]) 
    SET @B = @sy/@n - @A*@sx/@n 
    SET @Rsq = POWER((@n*@sxy [email protected]),2)/((@n*@[email protected])*(@n*@syy [email protected])) 

    INSERT INTO @ABData (A,B,Rsquare) VALUES(@A,@B,@Rsq) 

    RETURN 
END 
2

de hecho, he escrito una rutina de SQL utilizando Gram-Schmidt orthoganalization. Es, así como otras rutinas de aprendizaje automático y previsión, está disponible en sqldatamine.blogspot.com

Por sugerencia de Brad Larson, he agregado el código aquí en lugar de solo dirigir a los usuarios a mi blog. Esto produce los mismos resultados que la función de linest en Excel. Mi fuente principal es Elements of Statistical Learning (2008) de Hastie, Tibshirni y Friedman.

--Create a table of data 
create table #rawdata (id int,area float, rooms float, odd float, price float) 

insert into #rawdata select 1, 2201,3,1,400 
insert into #rawdata select 2, 1600,3,0,330 
insert into #rawdata select 3, 2400,3,1,369 
insert into #rawdata select 4, 1416,2,1,232 
insert into #rawdata select 5, 3000,4,0,540 

--Insert the data into x & y vectors 
select id xid, 0 xn,1 xv into #x from #rawdata 
union all 
select id, 1,rooms from #rawdata 
union all 
select id, 2,area from #rawdata 
union all 
select id, 3,odd from #rawdata 

select id yid, 0 yn, price yv into #y from #rawdata 

--create a residuals table and insert the intercept (1) 
create table #z (zid int, zn int, zv float) 
insert into #z select id , 0 zn,1 zv from #rawdata 

--create a table for the orthoganal (#c) & regression(#b) parameters 
create table #c(cxn int, czn int, cv float) 
create table #b(bn int, bv float) 


[email protected] is the number of independent variables including the intercept (@p = 0) 
declare @p int 
set @p = 1 


--Loop through each independent variable and estimate the orthagonal parameter (#c) 
-- then estimate the residuals and insert into the residuals table (#z) 
while @p <= (select max(xn) from #x) 
begin 
     insert into #c 
    select xn cxn, zn czn, sum(xv*zv)/sum(zv*zv) cv 
     from #x join #z on xid = zid where zn = @p-1 and xn>zn group by xn, zn 

    insert into #z 
    select zid, xn,xv- sum(cv*zv) 
     from #x join #z on xid = zid join #c on czn = zn and cxn = xn where xn = @p and zn<xn group by zid, xn,xv 

    set @p = @p +1 
end 

--Loop through each independent variable and estimate the regression parameter by regressing the orthoganal 
-- resiuduals on the dependent variable y 
while @p>=0 
begin 

    insert into #b 
    select zn, sum(yv*zv)/ sum(zv*zv) 
     from #z join 
      (select yid, yv-isnull(sum(bv*xv),0) yv from #x join #y on xid = yid left join #b on xn=bn group by yid, yv) y 
     on zid = yid where zn = @p group by zn 

    set @p = @p-1 
end 

--The regression parameters 
select * from #b 

--Actual vs. fit with error 
select yid, yv, fit, yv-fit err from #y join 
    (select xid, sum(xv*bv) fit from #x join #b on xn = bn group by xid) f 
    on yid = xid 

--R Squared 
select 1-sum(power(err,2))/sum(power(yv,2)) from 
(select yid, yv, fit, yv-fit err from #y join 
    (select xid, sum(xv*bv) fit from #x join #b on xn = bn group by xid) f 
    on yid = xid) d 
+0

En lugar de simplemente publicar un enlace a su blog (que podría desaparecer en algún momento en el futuro), ¿podría resumir la información relevante de su blog en su respuesta aquí? –

+0

Tengo un conjunto de datos y cuando uso su código, todo parece lo que esperaba, excepto R Squared. ¿Estás seguro de que el cálculo está bien en R2? Estoy comparando el resultado con la regresión de Excel y son diferentes. – sqluser

+0

¿También puede ampliar su solución para incluir valores de p para cada variable (X)? – sqluser

2

No hay funciones de regresión lineal en SQL Server. Pero para calcular una Regresión Lineal Simple (Y '= bX + A) entre pares de puntos de datos x, y - incluyendo el cálculo del Coeficiente de Correlación, Coeficiente de Determinación (R^2) y Estimación Estática del Error (Desviación Estándar), hacer lo siguiente:

Para una tabla regression_data con columnas numéricas x y y:

declare @total_points int 
declare @intercept DECIMAL(38, 10) 
declare @slope DECIMAL(38, 10) 
declare @r_squared DECIMAL(38, 10) 
declare @standard_estimate_error DECIMAL(38, 10) 
declare @correlation_coefficient DECIMAL(38, 10) 
declare @average_x DECIMAL(38, 10) 
declare @average_y DECIMAL(38, 10) 
declare @sumX DECIMAL(38, 10) 
declare @sumY DECIMAL(38, 10) 
declare @sumXX DECIMAL(38, 10) 
declare @sumYY DECIMAL(38, 10) 
declare @sumXY DECIMAL(38, 10) 
declare @Sxx DECIMAL(38, 10) 
declare @Syy DECIMAL(38, 10) 
declare @Sxy DECIMAL(38, 10) 

Select 
@total_points = count(*), 
@average_x = avg(x), 
@average_y = avg(y), 
@sumX = sum(x), 
@sumY = sum(y), 
@sumXX = sum(x*x), 
@sumYY = sum(y*y), 
@sumXY = sum(x*y) 
from regression_data 

set @Sxx = @sumXX - (@sumX * @sumX)/@total_points 
set @Syy = @sumYY - (@sumY * @sumY)/@total_points 
set @Sxy = @sumXY - (@sumX * @sumY)/@total_points 

set @correlation_coefficient = @Sxy/SQRT(@Sxx * @Syy) 
set @slope = (@total_points * @sumXY - @sumX * @sumY)/(@total_points * @sumXX - power(@sumX,2)) 
set @intercept = @average_y - (@total_points * @sumXY - @sumX * @sumY)/(@total_points * @sumXX - power(@sumX,2)) * @average_x 
set @r_squared = (@intercept * @sumY + @slope * @sumXY - power(@sumY,2)/@total_points)/(@sumYY - power(@sumY,2)/@total_points) 

-- calculate standard_estimate_error (standard deviation) 
Select 
@standard_estimate_error = sqrt(sum(power(y - (@slope * x + @intercept),2))/@total_points) 
From regression_data 
+0

¿Puede ampliar su solución para incluir el valor p también?Además, ¿cómo podemos hacer una regresión de línea múltiple en función de su respuesta? – sqluser

+0

@sqluser - El R-cuadrado es demasiado grande porque la suma total de cuadrados usa valores de Y sin procesar en lugar de desviaciones de la media. A continuación, yv debe reemplazarse por yv- @ meanY seleccionar 1-sum (power (err, 2))/sum (power (yv, 2)) desde – JRG

0

he traducido de la función de regresión lineal se utiliza en el pronóstico del funcion en Excel, y ha creado una función SQL que devuelve una, b, y el pronóstico. Puede ver la explicación teórica completa en la ayuda de Excel para la función de PRONÓSTICO. abetos de todo lo que necesita para crear la tabla de tipos de datos XYFloatType:

CREATE TYPE [dbo].[XYFloatType] 
AS TABLE(
[X] FLOAT, 
[Y] FLOAT) 

a continuación, escribir la función de seguimiento:

/* 
-- ============================================= 
-- Author:  Me  :) 
-- Create date: Today :) 
-- Description: (Copied Excel help): 
--Calculates, or predicts, a future value by using existing values. 
The predicted value is a y-value for a given x-value. 
The known values are existing x-values and y-values, and the new value is predicted by using linear regression. 
You can use this function to predict future sales, inventory requirements, or consumer trends. 
-- ============================================= 
*/ 

CREATE FUNCTION dbo.FN_GetLinearRegressionForcast 

(@PtXYData as XYFloatType READONLY ,@PnFuturePointint) 
RETURNS @ABDData TABLE(a FLOAT, b FLOAT, Forecast FLOAT) 
AS 

BEGIN 
    DECLARE @LnAvX Float 
      ,@LnAvY Float 
      ,@LnB Float 
      ,@LnA Float 
      ,@LnForeCast Float 
    Select @LnAvX = AVG([X]) 
      ,@LnAvY = AVG([Y]) 
    FROM @PtXYData; 
    SELECT @LnB = SUM (([X][email protected])*([Y][email protected]))/SUM (POWER([X][email protected],2)) 
    FROM @PtXYData; 
    SET @LnA = @LnAvY - @LnB * @LnAvX; 
    SET @LnForeCast = @LnA + @LnB * @PnFuturePoint; 
    INSERT INTO @ABDData ([A],[B],[Forecast]) VALUES (@LnA,@LnB,@LnForeCast) 
    RETURN 
END 

/* 
your tests: 

(I used the same values that are in the excel help) 
DECLARE @t XYFloatType 
INSERT @t VALUES(20,6),(28,7),(31,9),(38,15),(40,21)  -- x and y values 
SELECT *, A+B*30 [Prueba]FROM [email protected],30); 
*/ 
-1

espero que la siguiente respuesta ayuda a entender que algunas de las soluciones vienen de . Voy a ilustrarlo con un ejemplo simple, pero la generalización de muchas variables es teóricamente sencilla siempre que sepa cómo usar la notación de índice o las matrices. Para implementar la solución para algo más allá de 3 variables, Gram-Schmidt (ver la respuesta de Colin Campbell más arriba) u otro algoritmo de inversión de matriz.

Dado que todas las funciones que necesitamos son varianza, covarianza, promedio, suma, etc. son funciones de agregación en SQL, se puede implementar fácilmente la solución. Lo he hecho en HIVE para hacer la calibración lineal de las puntuaciones de un modelo logístico. Entre otras muchas ventajas, una es que puede funcionar completamente dentro de HIVE sin salir y regresar de algún lenguaje de scripting.

El modelo para sus datos (x_1, x_2, y), donde los puntos de datos son indexados por i, es

y (x_1, x_2) = m_1 * x_1 + m_2 * x_2 + c

El modelo parece "lineal", pero no es necesario, por ejemplo, x_2 puede ser cualquier función no lineal de x_1, siempre que no tenga parámetros libres, por ejemplo x_2 = Sinh (3 * (x_1)^2 + 42). Incluso si x_2 es ​​"solo" x_2 y el modelo es lineal, el problema de regresión no lo es. Solo cuando decida que el problema es encontrar los parámetros m_1, m_2, c de manera que minimicen el error L2, tendrá un problema de Regresión lineal.

El error de L2 es sum_i ((y [i] - f (x_1 [i], x_2 [i]))^2). Minimizando esto w.r.t. los 3 parámetros (establecer las derivadas parciales w.r.t. cada parámetro = 0) arrojan 3 ecuaciones lineales para 3 incógnitas. Estas ecuaciones son LINEALES en los parámetros (esto es lo que lo hace Regresión lineal) y se pueden resolver analíticamente. Hacer esto para un modelo simple (1 variable, modelo lineal, por lo tanto, dos parámetros) es sencillo e instructivo. La generalización de una norma métrica no euclidiana en el espacio del vector de error es sencilla, el caso especial diagonal equivale a usar "ponderaciones".

Volver a nuestro modelo con dos variables:

y = m_1 * x_1 + m_2 * x_2 + c

Tome el valor esperado =>

= m_1 * + m_2 * + c (0)

Ahora tome la covarianza wrt x_1 y x_2, y utilizar cov (x, x) = var (x):

cov (y, x_1) = m_1 * var (x_1) + m_2 * COVAR (x_2, x_1) (1)

cov (Y, x_2) = m_1 * COVAR (x_1, x_2) + m_2 * var (x_2) (2)

se trata de dos ecuaciones con dos incógnitas, que se pueden resolver mediante la inversión del 2X2 matriz.

en forma de matriz: ... que puede ser invertida para producir ... donde

det = var (x_1) * var (x_2) - COVAR (x_1, x_2)^2

(oh vomitar, ¿qué diablos son "puntos de reputación? Dame un poco si quieres ver las ecuaciones.)

en cualquier caso, ahora que tiene M1 y m2 en forma cerrada, se puede sol ve (0) para c.

Comprobé la solución analítica anterior a Solver de Excel para un cuadrático con ruido gaussiano y los errores residuales coinciden con 6 dígitos significativos.

Ponte en contacto conmigo si quieres hacer una Transformada de Fourier Discreta en SQL en unas 20 líneas.

0

Para agregar a la respuesta @ icc97, he incluido las versiones ponderadas para la pendiente y el intercepto. Si los valores son todos constantes, la pendiente será NULA (con la configuración apropiada SET ARITHABORT OFF; SET ANSI_WARNINGS OFF;) y deberá sustituirse por 0 mediante coalesce().

Aquí es una solución por escrito en SQL:

with d as (select segment,w,x,y from somedatasource) 
select segment, 

avg(y) - avg(x) * 
((count(*) * sum(x*y)) - (sum(x)*sum(y)))/ 
((count(*) * sum(x*x)) - (Sum(x)*Sum(x))) as intercept, 

((count(*) * sum(x*y)) - (sum(x)*sum(y)))/ 
((count(*) * sum(x*x)) - (sum(x)*sum(x))) AS slope, 

avg(y) - ((avg(x*y) - avg(x)*avg(y))/var_samp(X)) * avg(x) as interceptUnstable, 
(avg(x*y) - avg(x)*avg(y))/var_samp(X) as slopeUnstable, 
(Avg(x * y) - Avg(x) * Avg(y))/(stddev_pop(x) * stddev_pop(y)) as correlationUnstable, 

(sum(y*w)/sum(w)) - (sum(w*x)/sum(w)) * 
((sum(w)*sum(x*y*w)) - (sum(x*w)*sum(y*w)))/ 
    ((sum(w)*sum(x*x*w)) - (sum(x*w)*sum(x*w))) as wIntercept, 

((sum(w)*sum(x*y*w)) - (sum(x*w)*sum(y*w)))/ 
    ((sum(w)*sum(x*x*w)) - (sum(x*w)*sum(x*w))) as wSlope, 

(count(*) * sum(x * y) - sum(x) * sum(y))/(sqrt(count(*) * sum(x * x) - sum(x) * sum(x)) 
* sqrt(count(*) * sum(y * y) - sum(y) * sum(y))) as correlation, 

count(*) as n 

from d where x is not null and y is not null group by segment 

donde W es el peso. Lo comprobé dos veces contra R para confirmar los resultados. Puede ser necesario enviar los datos de algún origen de datos al punto flotante. Incluí las versiones inestables para advertirte contra eso. (Agradecimiento especial a Stephan en otra respuesta.)

Tenga en cuenta que la correlación es la correlación de los puntos de datos x e y no de la predicción.

Cuestiones relacionadas