Aún no tienes acceso a esta clase

Crea una cuenta y continúa viendo este curso

Función de coste: calcula qué tan erradas son tus predicciones

13/30
Recursos

Aportes 39

Preguntas 4

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

Me tome el tiempo para hacer el ejercicio en Python et voilà aquí esta el resultado

import numpy as np
import matplotlib.pyplot as plt

a = np.array([0, 100])
b = np.array([20, 150])
c = np.array([30, 200])
d = np.array([40, 180])
e = np.array([50, 250])
g = np.array([60, 230])
xy = a[0]*a[1] + b[0]*b[1] + c[0]*c[1] + d[0]*d[1] + e[0]*e[1] + g[0]*g[1] #Aqui aplico las ecuaciones clasicas para calcular la regresion lineal
sumx = a[0] + b[0] + c[0] + d[0] + e[0] + g[0]
sumy = a[1] + b[1] + c[1] + d[1] + e[1] + g[1]
sumx2 = a[0]**2 + b[0]**2 + c[0]**2 + d[0]**2 + e[0]**2 + g[0]**2
n = 6
A1 = (n*xy - sumx*sumy) / (n*sumx2 - sumx**2)
A0 = sumy/n - (A1*sumx/n)

def f(x):
  return A0 + A1*x;
N=1000
x = np.linspace(0,(60), num=N)

y = f(x)
print("y =",A0,"+",A1,"x")
ECM = ((f(0)-a[1]) + (f(20)-b[1]) + (f(30)-c[1]) + (f(40)-d[1]) + (f(50)-e[1]) +(f(60)-g[1]))**2/n # Aqui aplico la formula del error cuadratico medio que nos explica Enrique donde y gorrito viene dada por la funcion f(x) evaluada en cada uno de los puntos x del conjunto de datos que nos dio Enrique
                                                                                                  
                                                                                                  
print("El erro cuadratico medio, ECM = ", ECM)

fig, ax = plt.subplots()
ax.plot(x,y,label='y = 106.43 + 2.36 X')
ax.scatter(a[0], a[1], c='red')
ax.scatter(b[0], b[1], c='red')
ax.scatter(c[0], c[1], c='red')
ax.scatter(d[0], d[1], c='red')
ax.scatter(e[0], e[1], c='red')
ax.scatter(g[0], g[1], c='red')
ax.set_xlabel('Gasto en publicidad')
ax.set_ylabel('Ventas')
ax.legend()
ax.grid()

Para sacar la ecucacion de regresión lineal use la formula clásica:


Y la Ecuación del error cuadrático medio la saque de lo que nos explico Enrique

Pd: Estoy seguro de que el código se puede optimizar mucho mas pero estoy nuevo en esto y lo hice como pude 😉

Hola, solo una observación sobre la ecuación del ECM. El propósito de indicar el subíndice i en los limites de la sumatoria, es expresar la idea de sumar componentes indexadas. Esto se puede automatizar, por ejemplo, en un ciclo for de la siguiente manera (en Python, desde luego):

def Mean_squared_error (y_hat, y) : #los argumentos son listas
    n = len(y_hat) #Se supone que la longitud de los argumentos es la misma.
    sigma = 0
    for i in range(n):	#Aqui esta la magia de la sumatoria.
        sigma += ( y_hat[i] - y[i] )**2
    
    return (1/n)*sigma

Dicho lo anterior, es importante mantener el rigor del lenguaje matemático e indicar los subindices cada vez que se hace uso de expresiones como las sumatorias. La ecuación del ECM con sus subindices quedaría de la siguinete manera:

Moraleja: El diablo está en los detalles.

Les comparto mi solucion en GoogleColaboratory 🤠

FUNCIÓN DE COSTE --> ES EL ERROR CUADRÁTICO MEDIO --> E.C.M.
El Error cuadrático medio es un nombre muy complejo y rimbombante para algo más sencillo que es hallar la media de todos los errores, pero ponemos los errores al cuadrado (supongo que para exagerarlos más).
E.C.M. --> Errores al cuadrado dividido entre número de errores.
Denominamos errores a la diferencia entre la predicción y la realidad. (O entre la gráfica y su simplificación a una linea).

Esto si lo he visto en otros cursos, pero aquí se te entiende mucho mejor! Que buen curso, me está aclarando varios conceptos.

📝 Al principio no había entendido la “1/n” que multiplicaba la sumatoria, pero ya lo vi y se los comparto.

Si compras 5 cosas con diferentes precios, para sacar el promedio tienes que sumar todos los precios y dividirlos entre 5. Esa misma división es la que estamos haciendo 🧮 (promedio).

De ahí sale ese 1/n * Σ…

🤯🤯🤯🤯🤯

For the record:
Tratamos de encontrar una linea recta que pase por todos nuetros puntos o que esté lo más cerca a todos los puntos, es decir, minimizar el error al estimar los puntos. Esto con el fin de poder hacer predicciones de puntos que no están en nuestros valores. La regresión Lineal resuelve el problema de optimización min (y_mean-yi)^2

Cuando el error es muy chico, el cuadrado se hace más pequeño…” Pero ¿Cuán chico debe ser el error para que esto suceda? 👀
.
Concretamente, los números < 1 son los que una vez elevados al cuadrado el resultado será menor. Por lo tanto:
.

cuando error < 1, error^2 < error
y cuando error > 1, error^2 > error.
.
¿Y cuando error = 1? El resultado se mantiene igual (“no castigo, no premio”) 😁

Recuerde que la suma de los errores elevados al cuadrado es igual a cero, por ese motivo necesitamos la varianza para luego obtener la desviacion estandar el cual es una medida de dispersion.

aca comparto mi solucion :

y el resultado de las predicciones

La forma más facil:

import numpy as np
import matplotlib.pyplot as plt 
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
X = np.array((0,20,30,40,50,60)).reshape(-1,1)
y= np.array((100,150,200,180,250,230))
regresion_lineal = LinearRegression()
regresion_lineal.fit(X,y)
y_pred = regresion_lineal.predict(X)
mean_squared_error(y, y_pred)

Se prefiere elevar al cuadrado la diferencia entre el valor predicho y el valor real con el fin de hacer más relevantes las grandes diferencias. Head exploding

En la práctica dejar el error al cuadrado es demasiado castigo para nuestro modelo. Para contrarrestar esto se usa el RMSE (Root Mean Squared Error) que es solo realizar la raíz cuadrada de nuestro resultado final para no castigarlo demasiado y agrandar el error original sin ninguna razón práctica.

Fuente

Hola les dejo mi codigo en colab graficando con seaborn y calculando el MSE con sklearn.

Comparto el código, el gráfico resultante en google colaboratory

import pandas as np
import numpy as np
import matplotlib.pyplot as plt

lista_ventas=[0, 100],[20,150],[30,200],[40,180],[50,250],[60,230]
matriz_lista_ventas = np.array(lista_ventas)
# tabla
matriz_lista_ventas

dim_x = matriz_lista_ventas[:,0] # representa a los datos de gastos o en el plano los valores del dominio
dim_y = matriz_lista_ventas[:,1] # representa a los datos de ingresos o en el plano los valores del rango

def suma_productos(dom, co_dom):   # suma de los productos entre los valores del dominio y del rango
  return np.sum(dom * co_dom)

sum_producto = suma_productos(dim_x, dim_y)

def suma_arreglo(arr):  # suma de los miembros de un arreglo
  return np.sum(arr)

sum_cod = suma_arreglo(dim_y) # suma de miembros del rango
sum_dom = suma_arreglo(dim_x) # suma de miembros del dominio
suma_cuadrado_dom = suma_arreglo(dim_x**2) # suma de miembros del dominio al cuadrado

def calculo_de_pendiente(arr, sum_productos,sum_dom, sum_codom, sum_dom_cuadratico): # función del calculo de la pendiente
  n = len(arr) # número de valores dentro de la matriz a calcular
  return (((n * sum_productos)-(sum_dom * sum_codom))/((n * sum_dom_cuadratico) - (sum_dom**2)))

m = calculo_de_pendiente(dim_x, sum_producto, sum_dom, sum_cod, suma_cuadrado_dom) # pendiente calculada

def calculo_intersesccion(arr, pendiente, sum_dom, sum_rango): # calculo de la intersección
  n = len(arr) # número de valores dentro de la matriz a calcular
  return (sum_rango - (pendiente * sum_dom))/n

b = calculo_intersesccion(dim_x, m, sum_dom, sum_cod) # interseccion calculada

def valor_prediccion(pendiente, interseccion,valor_dom): # función para calcular el valor predictivo en el rango
  return interseccion + (pendiente * valor_dom)

def valor_ECM(arr_dom, arr_codom, pendiente, interseccion): # función para calcular el valor del error cuadrático medio
  n = len(arr_dom)
  sum_ecm = 0
  for i in range(n):
    sum_ecm = sum_ecm + ((valor_prediccion(pendiente, interseccion, arr_dom[i])-arr_codom[i])**2)
  return sum_ecm / n

ECM = valor_ECM(dim_x, dim_y, m, b) # calculo del valor del error cuadrático medio
print(ECM)

fig, ax = plt.subplots()
ax.scatter(dim_x,dim_y)
ax.plot([0,60],[max(dim_x),max(dim_y)], color='red')
ax.set_xlabel('Gasto en publicidad')
ax.set_ylabel('Ventas')
ax.legend()
ax.grid()

https://colab.research.google.com/drive/14OCrCW8DPw6qGsbeRdNZaZPYb_b9YvA-?usp=sharing

Para quien le interese, es una función lineal del tipo
**y = mx + b **

Esta sería la función de la línea que trata de unir todos los puntos. Esta sería la mejor función que se adapta a nuestros datos.
y_estimada = (2.3571428571428577)x + (106.4285714285714)

Después de esto podríamos usar nuestro para estimar las ventas después de x gasto de publicidad y tener una idea de cuanto podría ser las ventas.

Hola desarrollé el ejercicio en python

import numpy as np
import matplotlib.pyplot as plt
from tabulate import tabulate #importo esto para poder generar y trabajar ocn la tabla

#Estos son los datos de la tabla
x=[0,20,30,40,50,60]
y=[100,150,200,180,250, 230]

line=[]
def lr(j):
    return 100+2.6*j
res=100 
j= np.linspace(0,60,res)
plt.scatter(x,y, label="Datos,y")
plt.plot(j,lr(j),'m',label="Aproximación, $\hat{y}$")#estimación
plt.grid()
plt.xlabel('Gastos en publicidad')
plt.ylabel('Ventas')
plt.xlim(-1,65) #indico limites en x
plt.ylim(bottom=75) #indico el límite únicamente para la parte de abajo de l eje y.
plt.legend()#coloca la leyenda de mis gráficas

datos = {'Gastos en publicidad': x,'Ventas': y}#Esto me ayuda a generar la tabla
print(tabulate(datos,headers=["Gastos en publicidad", "Ventas"],tablefmt='pretty'))#Esto imprime la tabla, con headers indico los encabezados y con tablefmt, indico el formato de la tabla

Para practicar:

y = [100,150,200,180,250,230]
x = [0,20,30,40,50,60]

xSuma = sum(x)
ySuma = sum(y)

n = len(x)
xy = [x[i]*y[i] for i in range(n)]
xsquare = [i**2 for i in x]

xySuma = sum(xy)
xsquareSuma = sum(xsquare)

m = ((n*xySuma)-(xSuma*ySuma))/((n*xsquareSuma)-((xSuma)**2))
b = (ySuma-(m*xSuma))/n
print(f'y1 = {m}x + {b}')

y1 = [m*i + b for i in x] #Predicciones

C = [((y1[i] - y[i])**2)/n for i in range(n)]
ECM = sum(C)
print(f'El error cuadratico medio es de {ECM}')

fig, ax = plt.subplots()
ax.scatter(x,y, c='r')
ax.set_xlabel('Gasto en publicidad')
ax.set_ylabel('Ventas')
ax.plot(x,y1)
ax.grid()

Excelente iniciativa @Daniel Perez ayudas a complementear la idea sobre la necesidad primera de realizar la regresion lineal, para asi poder evaluar punto a punto los calculos del error, y claro, sumarlos posteriormente!

Aquí mi intento de regresión

import numpy as np
import matplotlib.pyplot as plt

def parameters(x,y,n):
  sum_x = x.sum()
  sum_y = y.sum()
  sum_x2 = (x**2).sum()
  sum_xy = (x*y).sum()

  a = (n*sum_xy - sum_x*sum_y)/(n*sum_x2 - sum_x**2)
  b = (sum_x2*sum_y - sum_x*sum_xy)/(n*sum_x2 - sum_x**2)

  return (a,b)

def regression(a,b,x):
  return a*x + b

def ECM(y, y_hat, n):
  error = ((y_hat - y)**2).sum()
  return error/n

datos = np.array([[0,100],[20,150],[30,200],[40,180],[50,250],[60,230]])

n = len(datos)
x = datos[:,0]
y = datos[:,1]

(a,b) = parameters(x, y, n)
y_hat = regression(a, b, x)
error = ECM(y, y_hat, n)

print(f"Pendiente = {a}, Ordenada origen {b}")
print(f"Error cuadratico medio = {error}")

fig, ax = plt.subplots()
ax.scatter(x,y, color = 'r')
ax.plot(x,y_hat, color = 'k')
plt.grid()

Acá esta como lo hice…

```python
import numpy as np
import matplotlib.pyplot as plt
import random

def f(x,m,b):
  return m*x1 + b

m = 1
b = 1
res = 10

x1 = np.linspace(0,10, num = res)
#print(x1)
y1 = f(x1,m,b)

#Aca se generan aleatoriamente las coordenadas de la nube de puntos
cordList = []

for i in range(0,10):
  x2 = x1[i]
  y2 = random.randint(0,10)
  cord = (x2,y2)
  cordList.append(cord)

fig, ax = plt.subplots()

ax.plot(x1,y1)

ax.grid()

ax.axhline(y=0, color = 'r')
ax.axvline(x=0, color = 'r')

#Acá se imprime la nube de puntos
#print(y1)
errors = []
errorsSum = 0;
for i in range(len(cordList)):
  #print(f'Esta es la coordenada {i}:{cordList[i]}')
  plt.plot(cordList[i][0],cordList[i][1],marker="o", color="red")
  print(f'Esta es la cordenada y2 {i}: {cordList[i][1]} y y1 es: {y1[i]}')
  error = (y1[i]-cordList[i][1])**2
  errors.append(error)
#print(errors)
for i in range(len(errors)):
  errorsSum += errors[i]
  

#print(errorsSum)
ECM = errorsSum/len(errors)
print(f'El error cuadratico medio es {round(ECM,2)}')

Excelente clase, muchas gracias por explica a detalle los conceptos !

import numpy as np
import matplotlib.pyplot as plt


#Defino la variable dependiente e independiente:
x = np.array([0,20,30,40,50,60])
y = np.array([100,150,200,180,250,230])

#Función para obtener los parametros de la funcion:
# Nota: observa lo facil que es hacer operaciones con arrays de numpy!
def parameters(x,y):
  sumxy = (x*y).sum()
  sumx = x.sum()
  sumy = y.sum()
  sumx2 = (x**2).sum()
  n= len(x)
  m = (n*sumxy -sumx*sumy)/(n*sumx2-sumx**2)
  b = sumy/n - (m*sumx/n)
  return np.array([b,m]) 

#Funcion de regresion:
def lineal_regression(x,array):
  return array[0] + array[1]*x

#Funcion Error cuadratico medio:
def meanSquareError(Ypredict,y):
  EMC = 1/len(y)*((Ypredict - y).sum())**2
  return EMC


bYm = parameters(x,y)

Ypredict = lineal_regression(x,bYm)

error = meanSquareError(Ypredict,y)

print(f'function: Y = {bYm[1]}x + {bYm[0]}')
print(f'Mean Square Error (EMC) = {error}')
fig, ax = plt.subplots(1,1,figsize=(8,6),dpi=80)
ax.scatter(x,y, color = 'red',label='valores reales')
ax.plot(x,Ypredict,color= 'blue', label='Predicción')
ax.set_xlabel('Gasto en publicidad')
ax.set_ylabel('Ventas')
ax.legend()
ax.grid()

function: Y = 2.357142857142857x + 106.42857142857143
Mean Square Error (EMC) = 8.414516322357458e-28

Podemos obtener la linea de regresion al utilizar el metodo de minimos cuadrados (el cual se optiene a partir de la optimizacion de la funcion de coste ECM):

import pandas as pd
import matplotlib.pyplot as plt
def estimate_b0_b1(df):
    x_mean , y_mean = df['x'].mean(), df['y'].mean()
    df['x-mx']= df['x'] - x_mean
    df['y-my']= df['y'] - y_mean
    df['xy'] = df['x-mx']*df['y-my']
    df['xx'] = df['x']*df['x-mx']

    b_1 = df['xy'].sum()/df['xx'].sum()
    b_0 = y_mean - b_1*x_mean

    return (b_0,b_1)
def plot_regression(x,y,b):
    plt.scatter(x,y,color='b',marker='o',s=30)
    y_pred = b[0]+b[1]*x

    plt.plot(x,y_pred,color='k')

    plt.xlabel('x-Independiente')
    plt.ylabel('y-Dependiente')

    plt.show()
data = { 'x': [0,20,30,40,50,60], 'y':[100,150,200,180,250,230]}
df = pd.DataFrame(data)
b = estimate_b0_b1(df)

print(f'El valor b es {b[0]} y m es {b[1]}')

plot_regression(df['x'],df['y'],b)

bienvenida, bienvenida, bienvenida, cientificA, ya me tienen cansado de tanto sexismo

Para los que quieran copiar la “y” con "gorrito"
ŷ Ŷ

excelente explicación
# Función ejemplo
def regresion_ejemplo():
    x = range(0,20,1)
    y = random.randint(5, 15, size = 20)
    return x, y

# Función de coste en código
def funcion_coste(x, y):
    y_mean = np.mean(y)
    sum_y2 = np.sum((y_mean-y)**2)
    ecm = sum_y2 / np.size(y)
    print(f'ECM = {ecm}')
    return ecm

Resultado:

Función de coste o la regresión lineal simple.

Más o menos sería así:

import numpy as np
import matplotlib.pyplot as plt

x = np.array([0,20,30,40,50,60])
y = np.array([100,150,200,180,250,230])

coeff = np.polyfit(x,y,1)
print(coeff)

m = coeff[0]
b = coeff[1]
est_y = (m * x) + b


plt.plot(x, est_y)
plt.scatter(x,y)
plt.show()

Elevar el error al cuadrado en lugar de extraer el valor absoluto puede verse como una forma de castigo 👊 por haber producido un error.

Del curso anterior de Datacademy, reutilicé el algoritmo de regresion y le hice unos pequeños cambios para obtener el ECM.

import numpy as np
import matplotlib.pyplot as plt

def estimatedB0B1(x, y):
    n = np.size(x)
    # Obtenemos los promedios de x e y
    m_x, m_y = np.mean(x), np.mean(y)

    # Sumatoria de xy y sumatoria de xx
    sumXY = np.sum((x-m_x)*(y-m_y))
    sumXX = np.sum((x-m_x)**2)

    # Coeficientes de regresión
    b1 = sumXY/sumXX

    b0 = m_y - b1 * m_x

    return b0,b1


def f(x, b):
    return b[0] + b[1]*x
  

def plotReg(x, y, b):
    plt.scatter(x, y, color = "g", marker = "o", s=30)

    yPredictions = f(x, b)
    plt.plot(x, yPredictions, color = "b")

    #etiquetado
    plt.xlabel("x - Independiente")
    plt.ylabel("y - Dependiente")

    plt.show()


def main():
    x = np.array([0,20,30,40,50,60])
    y = np.array([100,150,200,180,250,230])

    b = estimatedB0B1(x, y)

    ECM = 0
    yHat = f(x, b)
    for n in range(np.size(y)):
        ECM = ECM + (y[n]-yHat[n])**2
        print(y[n])
        print(yHat[n])
    ECM = ECM/(np.size(y))

    print("Los valores de b0 = {}, b1 = {}".format(b[0],b[1]))
    print("El ECM es: ", str(ECM))

    plotReg(x, y, b)



if __name__ == "__main__":
    main()

En el colegio le llamábamos Varianza.

Error cuadrático medio

Comparto mi implementación 💜

import matplotlib.pyplot as plt
import numpy as np
import math

# Vamos a hacer la línea recta que corresponderá a y_hat
# Ya que ahí efectuamos la evaluación del erro predicho
def calc_m_b(data):
    # obtenemos n
    n = len(data)
    # obtenemos la suma de xy
    # Y sum x y sum y
    sum_xy = 0
    sum_x = 0
    sum_y = 0
    sum_x2 = 0
    for i in data:
        sum_xy += (i[0] * i[1])
        sum_x  += (i[0])
        sum_y  += (i[1])
        sum_x2 += (i[0])**2
    # Calculamos la pendiente
    m = (n * sum_xy - (sum_x * sum_y)) / ( (n * sum_x2) - (sum_x)**2 )
    # Ahora calculemos  b
    b = (sum_y - (m * sum_x) ) / (n)
    #Devolvemos valores
    return m,b
    
    
def y_hat_line(x,m,b):   
    return x*m + b

def ecm(data,m,b):
    n= len(data)
    y_hat = []
    add = 0
    for i in data:
        y_hat.append(y_hat_line(i[0],m,b) )
    #print(f'y_hat values:{y_hat}\n')
    
    for i in range(n):
        add += (( y_hat[i]) - (data[i][1]))**2
        print(f'Predicción {i+1}: {y_hat[i]}')
        print(f'Dato real {i+1}: {data[i][1]}')
    return (1/n)*add
    
def graph(x,data,line):
    #Creamos el cuadrito
    fig, ax = plt.subplots()
    ax.grid()
    plt.title('Función de coste')
    plt.xlabel("Gasto en publicidad")
    plt.ylabel("Ventas")
    ax.plot(x,line)
    for i in data:
        plt.plot(i[0], i[1], 'o')
    plt.legend(['Regresión lineal'])
    
def main():
    # Datos
    res = 10000
    x = np.linspace(0.0, 70.0, num=res)
    data = [[0,100],[20,150],[30,200],[40,180],[50,250],[60,230]]
    m,b = calc_m_b(data)
    print(f'\nPendiente: {m}')
    print(f'Intersección: {b}')
    print(f'-------------------------------------')
    line = y_hat_line(x,m,b)
    ECM = ecm(data,m,b)
    graph(x,data, line)
    print(f'-------------------------------------')
    print(f'Error Cuadrático Medio: {ECM}\n')
    
    
if __name__ == '__main__':
    main()

¡Mil gracias Enrique!
Ya había visto este tema antes, pero nunca lo había visto tan bien explicado.
Poder ver el paso a paso de cómo y por qué se construye la función permite entender todo y el propósito de la misma, mucho mejor.

El error cuadrático medio ECM: saca el promedio de los errores en las predicciones!

Creo que sería útil para la comprobación de resultados que se dijeran las respuestas a este ejercicio al final o mínimo en algún recurso adicional. Se explica cómo calcular las cosas, pero veo que hay respuestas bastante dispares en los comentarios. Sólo por aportar mi humilde opinión.