"Si un trabajador quiere hacer bien su trabajo, primero debe afilar sus herramientas." - Confucio, "Las Analectas de Confucio. Lu Linggong"
Página delantera > Programación > Aprendizaje automático para ingenieros de software

Aprendizaje automático para ingenieros de software

Publicado el 2024-08-07
Navegar:756

Machine Learning for Software Engineers

¡Avísame si esto te parece valioso y continuaré!

Capítulo 1 - El modelo lineal

Uno de los conceptos más simples pero poderosos es el modelo lineal.

En ML, uno de nuestros objetivos principales es hacer predicciones basadas en datos. El modelo lineal es como el "Hola mundo" del aprendizaje automático: es sencillo pero constituye la base para comprender modelos más complejos.

Construyamos un modelo para predecir los precios de las viviendas. En este ejemplo, el resultado es el "precio de la vivienda" esperado, y sus entradas serán cosas como "sqft", "num_bedrooms", etc...

def prediction(sqft, num_bedrooms, num_baths):
    weight_1, weight_2, weight_3 = .0, .0, .0  
    home_price = weight_1*sqft, weight_2*num_bedrooms, weight_3*num_baths
    return home_price

Notarás un "peso" para cada entrada. Estos pesos son los que crean la magia detrás de la predicción. Este ejemplo es aburrido ya que siempre generará cero ya que los pesos son cero.

Entonces, descubramos cómo podemos encontrar estos pesos.

Encontrar los pesos

El proceso para encontrar los pesos se llama "entrenar" el modelo.

  • Primero, necesitamos un conjunto de datos de viviendas con características (entradas) y precios (salidas) conocidos. Por ejemplo:
data = [
    {"sqft": 1000, "bedrooms": 2, "baths": 1, "price": 200000},
    {"sqft": 1500, "bedrooms": 3, "baths": 2, "price": 300000},
    # ... more data points ...
]
  • Antes de crear una forma de actualizar nuestras ponderaciones, necesitamos saber qué tan equivocadas están nuestras predicciones. Podemos calcular la diferencia entre nuestra predicción y el valor real.
home_price = prediction(1000, 2, 1) # our weights are currently zero, so this is zero
actual_value = 200000

error = home_price - actual_value # 0 - 200000 we are way off. 
# let's square this value so we aren't dealing with negatives
error = home_price**2

Ahora que tenemos una manera de saber qué tan equivocados (error) estamos para un punto de datos, podemos calcular el error promedio en todos los puntos de datos. Esto se conoce comúnmente como error cuadrático medio.

  • Finalmente, actualice los pesos de una manera que reduzca el error cuadrático medio.

Por supuesto, podríamos elegir números aleatorios y seguir guardando el mejor valor a medida que avanzamos, pero eso es ineficiente. Entonces, exploremos un método diferente: el descenso de gradiente.

Descenso de gradiente

El descenso de gradiente es un algoritmo de optimización que se utiliza para encontrar los mejores pesos para nuestro modelo.

El gradiente es un vector que nos dice cómo cambia el error a medida que hacemos pequeños cambios en cada peso.

Intuición de la barra lateral
Imagínese que se encuentra en un paisaje montañoso y su objetivo es alcanzar el punto más bajo (el error mínimo). La pendiente es como una brújula que siempre señala el ascenso más empinado. Al ir en contra de la dirección del gradiente, estamos dando pasos hacia el punto más bajo.

Así es como funciona:

  1. Comience con pesos aleatorios (o ceros).
  2. Calcule el error para los pesos actuales.
  3. Calcule el gradiente (pendiente) del error para cada peso.
  4. Actualiza los pesos moviendo un pequeño paso en la dirección que reduce el error.
  5. Repita los pasos 2 a 4 hasta que el error deje de disminuir significativamente.

¿Cómo calculamos el gradiente para cada error?

Una forma de calcular el gradiente es hacer pequeños cambios en el peso, ver cómo eso afectó nuestro error y ver hacia dónde debemos movernos a partir de ahí.

def calculate_gradient(weight, data, feature_index, step_size=1e-5):
    original_error = calculate_mean_squared_error(weight, data)

    # Slightly increase the weight
    weight[feature_index]  = step_size
    new_error = calculate_mean_squared_error(weight, data)

    # Calculate the slope
    gradient = (new_error - original_error) / step_size

    # Reset the weight
    weight[feature_index] -= step_size

    return gradient

Desglose paso a paso

  • Parámetros de entrada:

    • peso: el conjunto actual de pesos para nuestro modelo.
    • data: Nuestro conjunto de datos sobre características y precios de casas.
    • feature_index: el peso para el que estamos calculando el gradiente (0 para pies cuadrados, 1 para dormitorios, 2 para baños).
    • step_size: un valor pequeño que usamos para cambiar ligeramente el peso (el valor predeterminado es 1e-5 o 0,00001).
  • Calcular error original:

   original_error = calculate_mean_squared_error(weight, data)

Primero calculamos el error cuadrático medio con nuestras ponderaciones actuales. Esto nos da nuestro punto de partida.

  • Aumentar ligeramente el peso:
   weight[feature_index]  = step_size

Aumentamos el peso en una pequeña cantidad (step_size). Esto nos permite ver cómo un pequeño cambio en el peso afecta nuestro error.

  • Calcular nuevo error:
   new_error = calculate_mean_squared_error(weight, data)

Calculamos nuevamente el error cuadrático medio con el peso ligeramente aumentado.

  • Calcular la pendiente (gradiente):
   gradient = (new_error - original_error) / step_size

Este es el paso clave. Nos preguntamos: "¿Cuánto cambió el error cuando aumentamos ligeramente el peso?"

  • Si new_error > original_error, el gradiente es positivo, lo que significa que aumentar este peso aumenta el error.
  • Si new_error
  • La magnitud nos dice qué tan sensible es el error a los cambios en este peso.

    • Restablecer el peso:
   weight[feature_index] -= step_size

Volvimos a colocar el peso en su valor original ya que estábamos probando qué pasaría si lo cambiáramos.

  • Devolver el degradado:
   return gradient

Devolvemos el gradiente calculado para este peso.

Esto se llama "cálculo de gradiente numérico" o "método de diferencias finitas". Estamos aproximando el gradiente en lugar de calcularlo analíticamente.

Actualicemos los pesos.

Ahora que tenemos nuestros gradientes, podemos empujar nuestros pesos en la dirección opuesta al gradiente restando el gradiente.

weights[i] -= gradients[i]

Si nuestro gradiente es demasiado grande, fácilmente podríamos sobrepasar nuestro mínimo actualizando demasiado nuestro peso. Para solucionar este problema, podemos multiplicar el gradiente por un número pequeño:

learning_rate = 0.00001
weights[i] -= learning_rate*gradients[i]

Y así es como lo hacemos para todos los pesos:

def gradient_descent(data, learning_rate=0.00001, num_iterations=1000):
    weights = [0, 0, 0]  # Start with zero weights

    for _ in range(num_iterations):
        gradients = [
            calculate_gradient(weights, data, 0), # sqft
            calculate_gradient(weights, data, 1), # bedrooms
            calculate_gradient(weights, data, 2)  # bathrooms
        ]

        # Update each weight
        for i in range(3):
            weights[i] -= learning_rate * gradients[i]

        if _ % 100 == 0:
            error = calculate_mean_squared_error(weights, data)
            print(f"Iteration {_}, Error: {error}, Weights: {weights}")

    return weights

¡Por fin tenemos nuestras pesas!

Interpretando el modelo

Una vez que tengamos nuestros pesos entrenados, podemos usarlos para interpretar nuestro modelo:

  • El peso de 'sqft' representa el aumento de precio por pie cuadrado.
  • El peso de 'dormitorios' representa el aumento de precio por dormitorio adicional.
  • El peso de 'baños' representa el incremento de precio por baño adicional.

Por ejemplo, si nuestros pesos entrenados son [100, 10000, 15000], significa:

  • Cada pie cuadrado agrega $100 al precio de la vivienda.
  • Cada habitación agrega $10,000 al precio de la vivienda.
  • Cada baño agrega $15,000 al precio de la vivienda.

Los modelos lineales, a pesar de su simplicidad, son herramientas poderosas en el aprendizaje automático. Proporcionan una base para comprender algoritmos más complejos y ofrecen información interpretable sobre problemas del mundo real.

Declaración de liberación Este artículo se reproduce en: https://dev.to/akdevelop/machine-learning-for-software-engineers-2hid?1 Si hay alguna infracción, comuníquese con [email protected] para eliminarla.
Último tutorial Más>

Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.

Copyright© 2022 湘ICP备2022001581号-3