IA - Laboratorio 1 (1).pdf

INTELIGENCIA ARTIFICIAL ! ! ! !! ! Laboratorio 1: Regresión Lineal Introducción En este ejercicio, se implementará un

Views 69 Downloads 0 File size 462KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

INTELIGENCIA ARTIFICIAL

! ! !

!! !

Laboratorio 1: Regresión Lineal Introducción En este ejercicio, se implementará un algorithm de regresión lineal y se verá como este trabaja con datos. Antes de empezar con este ejercicio de programación, se recomienda leer el material de la clase del tema asociado. Para empezar con el ejercicio, necesitará obtener el código de inicio y descomprimir su contenido a la carpeta en la que desea completar el ejercicio. Si se necesita, usar el comando cd en Octave para cambiar a ese directorio antes de empezar este ejercicio. También se puede encontrar instrucciones para instalar Octave en el documento adjunto “Instalación de Octave”

Archivos Incluidos en el ejercicio

!

! ! ! !! !!

ex1.m - Script de Octave que ayudará a avanzar con el ejercicio ex1 multi.m - Script de Octave para la parte última del ejercicio ex1data1.txt - Conjunto de datos para regresión lineal con una variable ex1data2.txt - Conjunto de datos para regresión lineal con múltiples variables [*] warmUpExercise.m - Ejemplo de una función simple en Octave [*] plotData.m - Función que muestra el conjunto de datos [*] computeCost.m - Función que calcula el costo de la regresión lineal [*] gradientDescent.m - Función que ejecuta el gradiente de descenso [†] computeCostMulti.m - Función de costo para variables múltiples [†] gradientDescentMulti.m - Gradiente de descenso para variables múltiples [†] featureNormalize.m - Función para normalizar las características [†] normalEqn.m - Función que calcula las ecuaciones normales

* indica los archivos que necesitan ser completados † Indica ejercicios adicionales

!1

!!

!

! !

A traves del ejercicio, se usarán los scripts ex1.m y ex1_multi.m. Estos scripts configuran el conjunto de datos para los problemas y realizan llamadas a las funciones que usted escribirá. No necesita modificar ninguno de los scripts. Solo se requiere que modifique funciones en otros archivos, siguiendo las instrucciones en esta asignación. Para este ejercicio de programación, solo se requiere que complete la primera parte del ejercicio para implementar regresión lineal con una variable. La segunda parte del ejercicio, la cual puede completar para obtener puntos adicionales, cubre regresión lineal con multiples variables.

Donde conseguir ayuda Los ejercicios en este curso usan Octave, un lenguaje de programación de alto nivel bien adaptado para cálculos numéricos. En la línea de comandos de Octave, al escribir help seguida por el nombre de una función muestra la documentación para una función incluida en el programa. Por ejemplo, help plot mostrará información de ayuda de como realizar un gráfico.

1. Función Simple de octave La primera parte de ex1.m brinda práctica con la sintaxis de Octave. En el archivo warmUpExercise.m, se encontrará el esquema de una función de Octave. Modificarla para que retorne una matriz identidad de 5 x 5 rellenando el siguiente código: A = eye(5);

Cuando termine, ejecutar ex1.m (asumiendo que esta en directorio correcto, escribir “ex1” en el prompt de Octave) y deberá ver una salida similar a lo siguiente: ans =

!

Diagonal Matrix   1 0 0 0 0

! ! ! ! !

0

0

0

0

1

0

0

0

0

1

0

0

0

0

1

0

0

0

0

1

1

!

Octave es una alternativa libre a MATLAB. Para los ejercicios de programación, es libre de usar ya sea Octave o MATLAB.

!2

! !!

!

Ahora ex1.m pausará hasta que se presione cualquier tecla, y luego ejecutará el código para la siguiente parte de la asignación. S i d e s e a d e t e n e r l a e j e c u c i ó n , p r e s i o n a r l a s t e c l a s ctrl-c lo cual detendrá la ejecución a la mitad.

1.1.

Enviando la Solución

Después de completar el ejercicio, este se debe de enviar a la dirección de correo electrónico [email protected] incluyendo la sección y el grupo en el asunto, por ejemplo si el Grupo 1 de la sección E va a enviar su trabajo, los integrantes del grupo deben escribir en el asunto: IA - Sección E - Grupo 1.

 

2. Regresión lineal con una variable En esta parte del ejercicio, se implementará regresión lineal con una variable para predecir las ganancias de un camión de comida. Suponga que usted es el CEO de una franquicia de restaurantes y está considerando diferentes ciudades para la apertura de un nuevo local. La cadena ya tiene camiones en varias ciudades y tiene datos de las ganancias y el número de habitantes para las ciudades. Te gustaría usar estos datos para ayudarte a seleccionar cual sería la siguiente ciudad a expandirte.

!

!

El archivo ex1data1.txt contiene el conjunto de datos para nuestro problema de regresión lineal. La primera columna es la población de una ciudad y la segunda columna son las ganancias del camión de comida en esa ciudad. Un valor de ganancia negativa indica pérdida. El script ex1.m ya ha sido configurado para que cargue estos datos por ti.

2.1.

Graficando los datos

Antes de iniciar cualquier tarea, es usualmente de ayuda el entender los datos visualizándolos. Para este conjunto de datos, se puede usar un gráfico de dispersión para visualizar los datos, dado que este tiene solo dos propiedades que graficar (ganancias y población). (Muchos de otros ejemplos que se encontrará en la vida real son multidimensionales y no pueden ser graficados en 2-d.) En ex1.m, el conjunto de datos es cargado del archivo a las variables X e y: data = load('ex1data1.txt'); X = data(:, 1); y = data(:, 2); m = length(y);

% read comma separated data % number of training examples

!3

!

Luego, el script llama a la función plotData para crear un gráfico de dispersión de los datos. Su trabajo es completar plotData.m para dibujar el gráfico; modificar el archivo y llenarlo con el siguiente código: plot(x, y, 'rx', 'MarkerSize', 10); ylabel('Profit in $10,000s'); xlabel('Population of City in 10,000s');

% Plot the data % Set the y−axis label % Set the x−axis label

!

!

Ahora, cuando se continua ejecutando ex1.m, nuestro resultado final debería parecerse a la figura 1, con las mismas “x" rojas de marcadores y etiquetas de ejes. Para aprender mas a cerca del comando plot, puede escribir help plot en el prompt de Octave o buscar en linea la documentación del comando. (Para cambiar los marcadores a "x" roja, se usó la opción “rx" junto con el comando plot, ejm., plot(..,[tus opciones acá],.., ‘rx’); )

2.2.

Pendiente de descenso

Ganancias en $ 10000

En esta parte, se encontrará los parámetros de regresión lineal θ para nuestro conjunto de datos usando la pendiente de descenso.

Población de la ciudad en 10000s

!!

Figure 1: Gráfico de dispersión de los datos de entrenamiento !4

2.2.1.

! ! ! !

! ! !

El objetivo de la regresión lineal es minimizar la función de costo


donde la hipótesis hθ (x) esta dada por el modelo lineal

T hθ (x) = θ x = θ0 + θ1x1 Recuerde que los parámetros de su modelo son los valores de θj. Estos son los valores que ajustará para minimizar la función de costo J (θ). Una forma de hacer esto es usando el algoritmo de pendiente de descenso “batch”. En la pendiente de descenso batch, cada iteración realiza una actualización each iteration performs the update

(simultáneamente actualiza θj para todos los j) Con cada paso de la pendiente de descenso, los parámetros θj se acercan más a los valores óptimos que alcanzarán el costo mas bajo de J (θ). Nota de implementación: Almacenamos cada ejemplo como una fila en la matriz X en Octave. Para tomar en consideración el termino de interceptación (θ0), adicionamos una primera columna adicional a X y fijamos todos los valores a uno. Esto nos permite tratar a θ0 como simplemente otra ‘característica’. 2.2.2.

! !

Ecuaciones de actualización

Implementación

En ex1.m, ya se ha fijado los datos para regresión lineal. En las siguientes lineas, se adiciona otra dimensión a nuestros datos para acomodar el término de interceptación θ0. También inicializamos los parámetros iniciales a 0 y la tasa de aprendizaje alpha a 0.01. X = [ones(m, 1), data(:,1)]; % Add a column of ones to x theta = zeros(2, 1); % initialize fitting parameters iterations = 1500; alpha = 0.01;

!5

! 2.2.3. Calculando el costo de J (θ)

!!

A medida que se ejecuta la pendiente de descenso para aprender a minimizar la función de costo J (θ), es de ayuda el monitorear la convergencia calculando el costo. En esta sección, se implementará una función para calcular J (θ) entonces se puede verificar la convergencia de la implementación de la pendiente de descenso. La siguiente tarea es completar el código en el archivo computeCost.m, el cual es la función que calcula J (θ). Al momento de hacerlo, recuerda que las variables X e y no son valores escalares, si no matrices cuyas filas representan los ejemplos del conjunto de entrenamiento. Una vez completada la función, el siguiente paso en ex1.m ejecutará computeCost una vez usando θ inicializada a ceros, y s e v e r á e l c o s t o impreso en la pantalla. Se debe esperar ver un costo de 32.07. 2.2.4.

Pendiente de descenso

Seguidamente, se implementará la pendiente de descenso en el archivo gradientDescent.m. La estructura de bucle ha sido escrita por ti, y solo se necesita proporcionar las actualizaciones a θ dentro de cada iteración. A medida que se va programando, asegurarse de entender que es lo que se está tratando de optimizar y que es lo que se está actualizando. Tener presente que el costo J (θ) es parametrizado por el vector θ, no X e y. Lo que significa que, minimizamos el valor de J (θ) cambiando los valores del vector θ, no cambiando X o y. Una buena manera de verificar que la pendiente de descenso esta funcionando correctamente es mirando al valor de J (θ) y verificando que este está decreciendo con cada paso. El código de inicio para gradientDescent.m llama a computeCost en cada iteración e imprime el costo. Asumiendo que se ha implementado la pendiente de descenso y computeCost correctamente, el valor de J (θ) nunca debe incrementarse, y deberá converger a un valor estable al final del algoritmo. Después de finalizar, ex1.m usará los parámetros finales para graficar el encaje lineal. El resultado debe verse algo como la figura 2: Los valores finales para θ también serán usados para hacer predicciones de las ganancias en áreas de 35,000 y 70,000 personas. Notar la forma en que las siguientes lineas en ex1.m usan la multiplicación de matrices, en lugar de sumas explícitas o hacer un bucle, para calcular las predicciones. Este es un ejemplo de vectorización de código en Octave.

!

!6

 

! ! !

predict1 = [1, 3.5] * theta; predict2 = [1, 7] * theta;

2.3 Depurando Aquí hay algunas cosas para tener en mente al momento de implementar la pendiente de descenso: Los indices de los arreglos en Octave inician en uno, no en cero. Si se está almacenando θ0 y θ1 en un vector llamado theta, los valores serán theta(1) y theta(2).



Si ve muchos errores al momento de la ejecución, inspeccionar la matriz de operación para asegurarse que se está sumando y multiplicando matrices de dimensiones compatibles. Imprimiendo las dimensiones de las variables con el comando size te ayudará a depurar.

Ganancias en $ 10000



Población de la ciudad en 10000s

Figure 2: Datos de entrenamiento con regresión lineal encajada

!! ❼

Por defecto, Octave interpreta los operadores matemáticos como si fueran operadores de matrices. Esto es una fuente común de errores de incompatibilidad por tamaño. Si no se quiere una multiplicación de matrices, se necesita agregar un “punto” para especificar esto a Octave. Por ejemplo ejemplo, A*B realiza la multiplicación de matrices, mientras !7

!

A.*B realiza una multiplicación elemento por elemento.

!!

2.4 Visualizando J (θ)

! !

! !!

Para entender la función de costo J (θ) mejor, se graficará ahora la función de costo sobre una cuadrícula de dos dimensiones con valores de θ0 y θ1. No se necesita codificar nada nuevo para esta parte, pero debe entender como el código que haz escrito esta creando estas imágenes. En el siguiente paso de ex1.m, hay código escrito para calcular J (θ) sobre la cuadrícula de valores usando la función computeCost que se escribió. % initialize J vals to a matrix of 0's J_ vals = zeros(length(theta0_ vals), length(theta1_ vals)); % Fill out J_ vals for i = 1:length(theta0_vals) for j = 1:length(theta1_vals) t = [theta0_ vals(i); theta1_ vals(j)]; J_ vals(i,j) = computeCost(x, y, t);
 end ! end

Después que estas lineas son ejecutadas, se tendrá un arreglo de 2-D de valores de J (θ). El script ex1.m usará luego estos valores para producir una superficie y un gráfico de nivel de J (θ) usando los comandos surf y contour. Los gráficos deben verse similares como la figura 3: !

!! !

(b)  Gráfico  de  nivel,  mostrando  el  mínimo

(a)  Superficie

Figura 3: Función de costo J (θ) !8

El propósito de este gráfico mostrar como varía J (θ) con los cambios en θ0 y θ1. La función de costo he cost function J (θ) tiene forma de tazón y tiene un mínimo global. (Esto es mas fácil de ver en la gráfica de nivel que en la superficie en 3D). Este mínimo es el punto óptimo para θ0 y θ1, y cada paso de la pendiente de descenso se acerca a este punto.


!9

!

!! !! !

!!

!

Ejercicio de créditos extra (opcional) Si haz completado de manera exitosa el material previo, ¡felicitaciones! Ahora entiendes regresión lineal y debes ser capaz de empezar a usar tu propio conjunto de datos. Para el resto de este ejercicio de programación, se ha incluido los siguientes ejercicios que darán créditos extra. Estos ejercicios te ayudarán a ganar un entendimiento mas profundo del material, y si eres capas de realizarlos, te alentamos a que los completes también.

3. Regresión lineal con múltiples variables En esta parte, se implementará regresión lineal con múltiples variables para predecir los precios de casas. Supongamos que está vendiendo casas y quiere saber cual será un buen precio de mercado. Una manera de hacer esto es primeramente recolectar información de casas recientemente vendidas y hacer un modelo de precios de casas. El archivo ex1data2.txt contiene un conjunto de entrenamiento del precio de casas en Portland, Oregon Estados Unidos. La primera columna es el tamaño de la casa (en pies cuadrados), la segunda columna es el número de habitaciones, y la tercera columna es el precio de la casa. El script ex1_multi.m ha sido escrito para ayudarte a través de este ejercicio.

3.1.

El script ex1_multi.m iniciará cargando y mostrando algunos valores de este grupo de datos. Mirando los valores, notar que el tamaño de las casas son aproximadamente 1000 veces el número de habitaciones. Cuando las características difieren por varios ordenes de magnitud, primero realizando el escalado de las características puede hacer que la pendiente de descenso converja de manera mas rápida. Tu tarea es completar el código en featureNormalize.m para ❼



!!

Normalización de características

Restar el valor promedio de cada característica del conjunto de datos. Después de restar el promedio, adicionalmente escalar (dividir) los valores de las características por su respectiva “desviación estándar.”
 !10

!! !

La desviación estándar es una manera de medir cuanta variación hay en el rango de valores de una característica particular (muchos de los puntos dato estarán entre ±2 de desviación estándar del promedio); esta es una alternativa a tomar el rango de valores (max-min). En Octave, se puede usar la función “std” para calcular la desviación estándar. P o r e j e m p l o , d e n t r o d e featureNormalize.m, la cantidad X(:,1) contiene todos los valores de x1 (tamaños de las casas) en el grupo de entrenamiento, entonces std(X(:, 1)) calcula la desviación estándar del tamaño de las casas. Al momento de llamar featureNormalize.m, la columna extra de 1’s correspondiente a x0 = 1 no ha sido incluido aún a X (ver ex1 multi.m para mayor detalle). Se hará lo mismo para todas las características y el código debe funcionar con conjuntos de datos de todos los tamaños (cualquier número de características /ejemplos). Notar que cada columna de la matriz X corresponde a una característica.

!

!

!! !!

Nota de implementation: Cuando se normaliza las características, es importante almacenar los valores usados para la normalización - el valor promedio y la desviación estándar usados para los cálculos. Después de aprender los parámetros del modelo, querremos predecir los precios de las casas que no hemos visto anteriormente. Dado un nuevo valor de x (area de la sala y el número de habitaciones), debemos primeramente normalizar x usando el promedio y la desviación estándar que hemos calculado previamente de nuestro conjunto de entrenamiento.

3.2.

Pendiente de descenso

Previamente, se implementó la pendiente de descenso en un problema de regresión de una variable. La única diferencia ahora es que hay una característica mas en la matriz X. La función hipótesis y la regla de actualización de la pendiente de descenso “batch” permanecen sin cambios. Debe completar el código en computeCostMulti.m y gradientDescentMulti.m para implementar la función de costo el gradiente de descenso para la regresión lineal con multiples variables. Si tu código en la parte previa (una variable) ya soporta variable múltiples, puedes usarla acá también. Asegurarse que el código soporte cualquier número de características y esta bien vectorizado. Puede usar ‘size(X, 2)’ para encontrar cuantas características están presentes en el conjunto de datos


!11

 

Nota de implementation: En el caso de múltiples variables, la función de costo también puede ser escrita en la siguiente forma vectorial:

donde

!! !

La versión vectorizada es eficiente cuando estas trabajando con herramientas de cálculo numérico como Octave. Se puede probar que ambas formas son equivalentes.

3.2.1 Ejercicio Opcional (no calificado): Seleccionando tasas de aprendizaje

!

En esta parte del ejercicio, se probará diferentes tasas de aprendizaje para el conjunto de datos y encontrar la tasa de aprendizaje que converge rápidamente. Puedes cambiar las tasas de aprendizaje modificando ex1_multi.m y cambiando la parte del código que establece la tasa de aprendizaje. La siguiente fase en ex1_multi.m llamará a la función gradientDescent.m y ejecutará la pendiente de descenso por aproximadamente 50 iteraciones en la tasa de aprendizaje elegida. La función debe también retornar la historia de valores J (θ) en un vector J. Después de la última iteración, el script ex1_multi.m grafica los valores de J versus el número de iteraciones. Si se escogió una tasa de aprendizaje dentro de un buen rango, el gráfico se verá similar a la Figura 4. Si el gráfico se ve muy diferente, especialmente si el valor de J (θ) aumenta o inclusive si explota, ajustar la tasa de aprendizaje e intentar nuevamente. Recomendamos probar valores de tasa de aprendizaje α en una escala larga, en pasos de multiplicación de aproximadamente 3 veces el valor previo (ejm., 0.3, 0.1, 0.03, 0.01 y así sucesivamente). También se debería ajustar el número de iteraciones que se están ejecutando si eso ayudaría a ver la curva de tendencia general.

!12

Costo  J  

! !  

Número  de  iteraciones

Figura 4: Convergencia de la pendiente de descenso con un valor apropiado de la tasa de aprendizaje Nota de implementation: Si la tasa de aprendizaje es muy grande, J (θ) puede diverger y “explotar”, resultando en valores que son muy elevados para el cálculo en computador. En esta situación, Octave tenderá a retornar NaNs. NaN significa “No es Número” y es comúnmente causado por operaciones no definidas que involucran −∞ y +∞. Consejo Octave: Para comparar como diferentes tasas de aprendizaje afectan la convergencia, es de mucha ayuda graficar J para varias tasas de aprendizaje en la misma figura. En Octave, esto puede hacerse realizando Pendiente de Descenso varias veces con el comando ‘hold on’ entre gráficos. Concretamente, si se ha probado tres valores diferentes de alpha (deberías probablemente probar mas valores que esto) y almacenar los costos en J1, J2 y J3, se puede usar los siguientes comandos para graficarlos en la misma figura: plot(1:50, J1(1:50), ‘b’); hold on; plot(1:50, J2(1:50), ‘r’); plot(1:50, J3(1:50), ‘k’); Los argumentos finales ‘b’, ‘r’, y ‘k’ especifican colores diferentes para las gráficas. !13

!

!!

Notar los cambios en las curvas de convergencia a medida que cambia la tasa de aprendizaje. Con una tasa de aprendizaje pequeña, encontrarás que la pendiente de descenso toma un tiempo bastante largo para converger al valor óptimo. Contrariamente, con un valor grande de tasa de aprendizaje, la pendiente de descenso puede no converger o por el contrario diverger. Usando la mejor tasa de aprendizaje que se encuentre, ejecutar el script ex1_multi.m para ejecutar la pendiente de descenso hasta que converja al encontrar los valores finales de θ. Siguiente, usar este valor de θ para predecir el precio de una cad de 1650 pies cuadrados y 3 dormitorios. Se usará el valor luego para verificar la implementación de la ecuación normal. No se olvide de normalizar sus características cuando se hacen esta predicción.

3.3

Ecuación normal

En la clase, aprendimos que la forma cerrada de solución para la regresión lineal es como sigue:

!

Usando esta fórmula no se requiere ningún escalamiento de características, y se obtendrá una solución exacta en un solo cálculo: no hay “bucle hasta que converja” como en la pendiente de descenso. Completar el código en normalEqn.m para usar la formula anterior y calcular θ. Recuerde que mientras no se necesite escalar las características, aún se necesita agregar una columna de 1’s a la matriz X para tener un término interceptor (θ0). E l c ó d i g o e n ex1.m agregará la columna de 1’s a X por ti. Ejercicio Opcional (no calificado): Ahora, una vez que haz encontrado θ usando este método, usarlo para hacer una predicción de precio para una casa de 1650 pies cuadrados con 3 habitaciones. Se debe encontrar que se obtiene la misma predicción de precio que el valor obtenido usando el modelo obtenido con la pendiente de descenso (en Sección 3.2.1).

!14

!! ! !

!

!

Envío y calificación Después de completar varias partes de la asignación, asegurarse de enviar por correo las soluciones. A continuación se muestra como serán calificados los ejercicios. Parte Ejercicio de calentamiento

Archivo enviado warmUpExercise.m

Puntos 2 puntos

Calcular el costo para una variable Pendiente de descenso para una variable

computeCost.m gradientDescent.m

8 puntos 10 puntos

Puntos Totales

20 puntos

Ejercicios de Creditos extra (opcional) Normalización de características Cálculo del costo para múltiples variables Pendiente de descenso para múltiples variables Ecuación  Normal

featureNormalize.m computeCostMulti.m

!

gradientDescentMulti.m normalEqn.m

!15

1 puntos 2 puntos

!

2 points 1 puntos