Menu Close

Regresión lineal

Dadas dos listas de valores

   xs = [x(1), x(2), ..., x(n)]
   ys = [y(1), y(2), ..., y(n)]

la ecuación de la recta de regresión de ys sobre xs es y = a+bx, donde

   b = (nΣx(i)y(i) - Σx(i)Σy(i)) / (nΣx(i)² - (Σx(i))²)
   a = (Σy(i) - bΣx(i)) / n

Definir la función

   regresionLineal :: [Double] -> [Double] -> (Double,Double)

tal que (regresionLineal xs ys) es el par (a,b) de los coeficientes de la recta de regresión de ys sobre xs. Por ejemplo, para los valores

   ejX, ejY :: [Double]
   ejX = [5,  7, 10, 12, 16, 20, 23, 27, 19, 14]
   ejY = [9, 11, 15, 16, 20, 24, 27, 29, 22, 20]

se tiene

   λ> regresionLineal ejX ejY
   (5.195045748716805,0.9218924347243919)

Para comprobar la definición, se importa la librería Graphics.Gnuplot.Simple y se define el procedimiento

   grafica :: [Double] -> [Double] -> IO ()
   grafica xs ys = 
       plotPathsStyle 
         [YRange (0,10+mY)] 
         [(defaultStyle {plotType = Points,
                         lineSpec = CustomStyle [LineTitle "Datos",
                                                 PointType 2,
                                                 PointSize 2.5]},
                        zip xs ys),
          (defaultStyle {plotType = Lines,
                         lineSpec = CustomStyle [LineTitle "Ajuste",
                                                 LineWidth 2]},
                        [(x,a+b*x) | x <- [0..mX]])]
       where (a,b) = regresionLineal xs ys                      
             mX    = maximum xs
             mY    = maximum ys

tal que (grafica xs ys) pinta los puntos correspondientes a las listas de valores xs e ys y su recta de regresión. Por ejemplo, con (grafica ejX ejY) se obtiene el siguiente dibujo
Regresion_lineal

Soluciones

import Data.List (genericLength)
import Graphics.Gnuplot.Simple
 
ejX, ejY :: [Double]
ejX = [5,  7, 10, 12, 16, 20, 23, 27, 19, 14]
ejY = [9, 11, 15, 16, 20, 24, 27, 29, 22, 20]
 
regresionLineal :: [Double] -> [Double] -> (Double,Double)
regresionLineal xs ys = (a,b)
    where n     = genericLength xs
          sumX  = sum xs
          sumY  = sum ys
          sumX2 = sum (zipWith (*) xs xs)
          sumY2 = sum (zipWith (*) ys ys)
          sumXY = sum (zipWith (*) xs ys)
          b     = (n*sumXY - sumX*sumY) / (n*sumX2 - sumX^2)
          a     = (sumY - b*sumX) / n
 
grafica :: [Double] -> [Double] -> IO ()
grafica xs ys = 
    plotPathsStyle 
      [YRange (0,10+mY)] 
      [(defaultStyle {plotType = Points,
                      lineSpec = CustomStyle [LineTitle "Datos",
                                              PointType 2,
                                              PointSize 2.5]},
                     zip xs ys),
       (defaultStyle {plotType = Lines,
                      lineSpec = CustomStyle [LineTitle "Ajuste",
                                              LineWidth 2]},
                     [(x,a+b*x) | x <- [0..mX]])]
    where (a,b) = regresionLineal xs ys                      
          mX    = maximum xs
          mY    = maximum ys
Medio

6 soluciones de “Regresión lineal

  1. enrnarbej
    regresionLineal :: [Double] -> [Double] -> (Double,Double)
    regresionLineal xs ys = (a,b)
      where
        sxy = (sum . zipWith (*) xs) ys
        sx  = sum xs
        sx2 = (sum . zipWith (*) xs) xs
        sy  = sum ys
        n   = genericLength xs
        b   = (n * sxy - sx * sy) / (n * sx2 - sx^2)
        a   = (sy - b * sx) / n
  2. albcercid
    regresionLineal :: [Double] -> [Double] -> (Double,Double)
    regresionLineal xs ys = ((d-b*c)/n,b)
      where n = genericLength xs
            d = sum ys
            c = sum xs
            b = (n*sum (zipWith (*) xs ys) - d*c)/(n*q - c^2)
            q = sum (map (^2) xs)
  3. Juanjo Ortega (juaorture)
    import Data.List
     
    regresionLineal :: [Double] -> [Double] -> (Double,Double)
    regresionLineal xs ys = (a , b)
      where n  = genericLength xs
            x  = sum xs
            y  = sum ys
            x2 = sum $ map (^2) xs
            xy = sum $ zipWith (*) xs ys
            b  = (n*xy - x*y) / (n*x2 - x^2)
            a  =  (y - b*x) / n
  4. Alejandro

    Usando la librería EasyPlot para las gráficas.

    import Graphics.EasyPlot
    import Data.List (genericLength)
     
    ejX, ejY :: [Double]
    ejX = [5,  7, 10, 12, 16, 20, 23, 27, 19, 14]
    ejY = [9, 11, 15, 16, 20, 24, 27, 29, 22, 20]
     
    regresionLineal :: [Double] -> [Double] -> (Double,Double)
    regresionLineal xs ys = (a,b)
        where n     = genericLength xs
              sumX  = sum xs
              sumY  = sum ys
              sumX2 = sum (zipWith (*) xs xs)
              sumY2 = sum (zipWith (*) ys ys)
              sumXY = sum (zipWith (*) xs ys)
              b     = (n*sumXY - sumX*sumY) / (n*sumX2 - sumX^2)
              a     = (sumY - b*sumX) / n
     
    grafica :: [Double] -> [Double] -> IO Bool
    grafica xs ys = 
        plot X11
             [Data2D     [Title "Datos", Color Red]   []          (zip xs ys),
              Function2D [Title "Ajuste", Color Blue] [Range 0 m] (x -> a+b*x) ]
        where (a,b) = regresionLineal xs ys                      
              m     = 10 + maximum xs
  5. monlagare
    regresionLineal :: [Double] -> [Double] -> (Double,Double)
    regresionLineal xs ys = (a,b)
      where b = covarianza xs ys / varianza xs
            a = media ys - b * media xs
     
    media :: [Double] -> Double
    media xs = sum xs / genericLength xs
     
    varianza :: [Double] -> Double
    varianza xs = media ys - media xs ^ 2
      where ys = map (^2) xs 
     
    covarianza :: [Double] -> [Double] -> Double
    covarianza xs ys = media zs - media xs * media ys
      where zs = zipWith (*) xs ys
  6. Alejandro

    Usando la librería Statistics.LinearRegression

    import Statistics.LinearRegression
    import qualified Data.Vector as V
     
    regresionLineal :: [Double] -> [Double] -> (Double,Double)
    regresionLineal xs ys =
      linearRegression (V.fromList xs) (V.fromList ys)

Escribe tu solución

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.