Ejercicio 1: Regresión Lineal
introducir
En este ejercicio, implementará la regresión lineal y verá cómo funciona en sus datos.
Antes de comenzar el ejercicio, debe descargar los siguientes archivos para la carga de datos :
- ex1data1.txt - Conjunto de datos de regresión lineal univariada
- ex1data2.txt - Conjunto de datos de regresión lineal multivariable
A lo largo del ejercicio, están involucradas las siguientes asignaciones obligatorias y asignaciones*
opcionales marcadas :
- Implementar una función de ejemplo simple ---------- (5 puntos)
- Realice la función de visualización del conjunto de datos ------- (5 puntos)
- Función para calcular el costo de la regresión lineal ----- (40 puntos)
- La función funcional de correr descenso en pendiente ----- (50 puntos)
- Estandarización de datos*
- Implementación de la función de descenso de gradiente para regresión lineal multivariante*
La tarea requerida es implementar la regresión lineal univariada; la tarea opcional es implementar la regresión lineal multivariada.
1 Implementar una función de ejemplo simple
En esta parte del ejercicio, implementará el código para devolver una 5*5
matriz diagonal de . La salida es la misma que:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
1.1 Enviar una solución
Realice la implementación anterior en el siguiente cuadro de código Después de completar algunos ejercicios, si obtiene el mismo resultado que el anterior, es un aprobado.
###在这里填入代码###
import numpy as np
print(np.eye(5))
[[1. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0.]
[0. 0. 0. 1. 0.]
[0. 0. 0. 0. 1.]]
2 Regresión lineal univariada
En esta parte del ejercicio, se implementará y utilizará la regresión lineal univariada para predecir la ganancia de un camión de comida.
Suponga que usted es el jefe de un restaurante y está considerando abrir nuevas ubicaciones en diferentes ciudades. La cadena ya tiene camiones de comida en diferentes ciudades, y obtienes datos de población y ganancias para cada ciudad.
Ahora necesita usar estos datos para ayudarlo a elegir la próxima ciudad para expandirse.
El archivo ex1data1.txt
contiene el conjunto de datos para el problema de regresión lineal. La primera columna de datos corresponde a la población de la ciudad, y la segunda columna de datos corresponde a la ganancia de los food trucks en esa ciudad. Una ganancia negativa indica una pérdida.
2.1 Trazado de datos
Suele ser útil visualizar los datos antes de pasar a los ejercicios. Para este conjunto de datos, se puede usar un diagrama de dispersión para la visualización, ya que solo tiene dos atributos (población, ganancias).
# 引入所需要的库文件
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
%matplotlib inline
# 数据存储路径
path = '/home/jovyan/work/ex1data1.txt'
# 读入相应的数据文件
data = pd.read_csv(path, header=None,names=['Population','Profit'])
#查看数据的前五条
data.head(5)
Población | Ganancia | |
---|---|---|
0 | 6.1101 | 17.5920 |
1 | 5.5277 | 9.1302 |
2 | 8.5186 | 13.6620 |
3 | 7.0032 | 11.8540 |
4 | 5.8598 | 6.8233 |
A continuación, se necesita el código para la visualización de datos, y la imagen dibujada por esta parte de los datos debe ser la misma que la siguiente.
Puntos principales:
- Realice la visualización de diagramas de dispersión
- Los datos se distribuyen como puntos rojos.
- SD nombre de coordenadas horizontales y verticales
###在这里填入代码###
data.plot(kind='scatter', x='Population',y='Profit',c='red',figsize=(12,8))
plt.show()
2.2 Descenso de gradiente
En esta sección, se usará el descenso de gradiente para seleccionar los parámetros de regresión lineal θ apropiados para ajustarse a un conjunto de datos dado.
2.2.1 Actualizar fórmula
El propósito de la regresión lineal es minimizar una función de costo:
Establecer h θ ( X ) h_{\theta}(X)hi( X ) viene dado por el siguiente modelo lineal:
Para repasar, los parámetros del modelo son θ j \theta_jijvalores de , estos serán ajustados para minimizar el costo J ( θ ) J(\theta)J ( θ )。
Uno de estos métodos es usar el algoritmo de descenso de gradiente por lotes. En el descenso de gradiente por lotes, la actualización se realiza en cada iteración. A medida que se calcula cada paso del descenso de gradiente, el parámetro θ j \ theta_jijCada vez más cerca de hacer el costo J ( θ ) J(\theta)J ( θ ) alcanza el valor óptimo más bajo.
(Actualice simultáneamente todos los θ j \theta_jij)
2.2.2 Implementación
En la parte anterior del ejercicio, cargamos los datos requeridos en variables data
y nombramos sus columnas por separado.
A continuación, agregamos una dimensión a los datos para ajustar el término de intersección θ 0 \theta_0i0. Y establezca el valor del parámetro inicial en 0, la tasa de aprendizaje α \ alphaα se establece en 0,01.
#在列索引为0处添加数据列,该列值均为1
data.insert(0, 'Ones', 1)
#获取数据列数
cols = data.shape[1]
#对变量X和y进行初始化,并将其数据类型转换为矩阵
X = data.iloc[:,0:cols-1]
y = data.iloc[:,cols-1:cols]
X = np.matrix(X.values)
y = np.matrix(y.values)
#学习率、迭代次数的初始化
alpha = 0.01
iterations = 1500
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-10-ba7d5fe01814> in <module>
1 #在列索引为0处添加数据列,该列值均为1
----> 2 data.insert(0, 'Ones', 1)
3
4 #获取数据列数
5 cols = data.shape[1]
/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py in insert(self, loc, column, value, allow_duplicates)
3220 value = self._sanitize_column(column, value, broadcast=False)
3221 self._data.insert(loc, column, value,
-> 3222 allow_duplicates=allow_duplicates)
3223
3224 def assign(self, **kwargs):
/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py in insert(self, loc, item, value, allow_duplicates)
4336 if not allow_duplicates and item in self.items:
4337 # Should this be a different kind of error??
-> 4338 raise ValueError('cannot insert {}, already exists'.format(item))
4339
4340 if not isinstance(loc, int):
ValueError: cannot insert Ones, already exists
2.2.3 Costo de cálculo J(θ)
Al realizar un descenso de gradiente para minimizar la función de costo J ( θ ) J(\theta)Cuando J ( θ ) , es útil monitorear el estado de convergencia calculando el costo.
En esta parte de la tarea del ejercicio, debe implementar un costo computacional J ( θ ) J(\theta)Función de J ( θ )computeCost
para verificar la convergencia de la implementación de descenso de gradiente.
donde X
y y
no son valores escalares sino matrices cuyas filas representan ejemplos en el conjunto de entrenamiento.
Importante:
Después de completar la función, establezca θ \thetaEl valor de θ se inicializa a 0 y se calcula el costo, y se imprime el valor de costo obtenido.
Si el resultado es 32.07, el cálculo pasa.
###在这里填入代码###
# 代价函数
def computeCost(X,y,w):
inner = np.power(((X * w) - y),2)
return np.sum(inner) / (2 * len(X))
theta = np.matrix(np.zeros((2,1)))
computeCost(X,y,theta)
32.072733877455676
2.2.4 Descenso de gradiente
A continuación, implementaremos el descenso de gradiente, el código dado ha implementado la estructura de bucle, solo necesita proporcionar θ \theta en cada iteraciónactualización de θ .
Al implementar el código, asegúrese de comprender qué se está optimizando y qué se está actualizando.
Recuerda, el costo J ( θ ) J(\theta)J ( θ ) es un parámetro-ser vectorθ \thetaθ termina en lugar deXXX和 y y y . Es decir, haremosJ ( θ ) J(\theta)El valor de J ( θ ) se minimiza cambiando el vectorθ \thetavalor de θ , en lugar de cambiarXXX或 y y y。
Una buena manera de verificar que el descenso de gradiente está funcionando es observar J ( θ ) J(\theta)J ( θ ) y compruebe si el valor disminuye con cada paso. En cada iteración, el código llamacomputeCost
a la función e imprime el costo. Suponiendo que implemente el descenso de gradiente, calcule el costo correctamente,J ( θ ) J(\theta)El valor de J ( θ ) nunca debe aumentar y debe converger a un valor estable al final del algoritmo.
Puntos principales:
Después de implementar el descenso de gradiente, los valores finales de los parámetros deben usarse para visualizar los resultados de ajuste de la regresión lineal, y los resultados del dibujo deben ser similares a los que se muestran en la figura a continuación.
###在这里填入代码###
def gradientDescent(X, y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape))
parameters = int(theta.ravel().shape[1])
cost = np.zeros(iters)
for i in range(iters):
error = (X * theta) - y
for j in range(parameters):
term = np.multiply(error, X[:,j])
temp[j,0] = theta[j,0] - ((alpha / len(X)) * np.sum(term))
theta = temp
cost[i] = computeCost(X, y, theta)
return theta, cost
# 开始训练,最终输出训练完成的模型参数
t_final, cost_final = gradientDescent(X, y, theta, alpha, iterations)
# 计算最终的参数所得到的成本值
computeCost(X, y, t_final)
4.483388256587726
###在这里填入代码###
#对拟合曲线进行绘制
x = np.linspace(data.Population.min(), data.Population.max(), 100)
f = t_final[0,0] + (t_final[1,0] * x)
fig, ax = plt.subplots(figsize=(9,6))
ax.plot(x, f, 'b', label='Prediction')
ax.scatter(data.Population, data.Profit, c='red',label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
Text(0.5, 1.0, 'Predicted Profit vs. Population Size')
2.3 Visualizando la función de costo
Para comprender mejor el cálculo iterativo de la función de costo, se registra y grafica el valor del costo calculado en cada paso.
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iterations), cost, 'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
Text(0.5, 1.0, 'Error vs. Training Epoch')
ejercicio opcional
3 Regresión lineal multivariante
En esta parte, se utilizarán múltiples variables para implementar la regresión lineal para predecir los precios de la vivienda. Supongamos que actualmente está vendiendo una casa y quiere saber cuál es un buen precio de mercado.
Un enfoque consiste en recopilar primero información sobre viviendas vendidas recientemente y, en segundo lugar, modelar los precios de las viviendas.
El archivo ex1data2.txt
contiene precios de casas e información relacionada para Portland, Oregón. 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.
3.1 Estandarización de funciones
El siguiente código cargará ex1data2.txt
y mostrará este conjunto de datos desde un archivo.
Mirando los datos, se puede ver que el tamaño de la casa es aproximadamente 1000 veces el número de habitaciones. Cuando la diferencia entre diferentes autovalores es de varios órdenes de magnitud, escalar las características puede hacer que el descenso del gradiente converja más rápido .
path = '/home/jovyan/work/ex1data2.txt'
data2 = pd.read_csv(path, header=None, names=['Size', 'Bedrooms', 'Price'])
data2.head()
Tamaño | Dormitorios | Precio | |
---|---|---|---|
0 | 2104 | 3 | 399900 |
1 | 1600 | 3 | 329900 |
2 | 2400 | 3 | 369000 |
3 | 1416 | 2 | 232000 |
4 | 3000 | 4 | 539900 |
En esta parte del ejercicio, su tarea es escribir el código y estandarizar los datos en el conjunto de datos .
Puntos principales :
- Reste la media de cada característica del conjunto de datos.
- Después de restar la media, divida los nuevos valores propios por sus respectivas "desviaciones estándar"
La desviación estándar es una medida de cuánto varía el rango de valores para una característica particular (la mayoría de los puntos de datos estarán dentro de dos desviaciones estándar de la media); esta es una alternativa al rango de valores.
Al normalizar características, debe almacenar los valores utilizados para la normalización: media y desviación estándar. Después de aprender los parámetros del modelo, a menudo es necesario predecir el precio de las casas nuevas. Dado un nuevo xx en este puntoLos valores de x (tamaño de la casa y número de dormitorios) primero deben normalizarse a los nuevos datos utilizando la media y la desviación estándar calculadas previamente a partir del conjunto de entrenamiento.
###在这里填入代码###
data2 = (data2 - data2.mean()) / data2.std()
data2.head()
Tamaño | Dormitorios | Precio | |
---|---|---|---|
0 | 0.130010 | -0.223675 | 0.475747 |
1 | -0.504190 | -0.223675 | -0.084074 |
2 | 0.502476 | -0.223675 | 0.228626 |
3 | -0.735723 | -1.537767 | -0.867025 |
4 | 1.257476 | 1.090417 | 1.595389 |
3.2 Descenso de gradiente
En el ejercicio anterior, implementamos el problema del descenso de gradiente usando una regresión lineal univariada. En esta parte del enlace, la única diferencia es que en este punto nuestros datos se convierten en la matriz XXX. _
Suponiendo que la función y la regla de actualización del descenso del gradiente por lotes permanezcan constantes, su tarea es codificar la función de costo y el descenso del gradiente para la regresión lineal multivariante .
Puntos principales :
- Asegúrese de que su código pueda admitir datos de cualquier tamaño y que los datos estén vectorizados.
- Después de que el código implemente la función de costo y el descenso de gradiente, el valor de costo final debe ser de aproximadamente 0,13.
- Siga los requisitos del ejercicio de regresión lineal univariante para dibujar la curva de cambio del costo.
###在这里填入代码###
data2.insert(0, 'Ones', 1)
cols = data2.shape[1]
X2 = data2.iloc[:,0:cols-1]
y2 = data2.iloc[:,cols-1:cols]
X2 = np.matrix(X2.values)
y2 = np.matrix(y2.values)
theta = np.matrix(np.array([0,0,0]))
w2_final, cost2_final = gradientDescent(X2, y2, theta.T, alpha, iterations)
print('The weight vector:\n',w2_final)
computeCost(X2, y2, w2_final)
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iterations), cost2_final, 'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Iterations')
The weight vector:
[[-1.00309831e-16]
[ 8.84042349e-01]
[-5.24551809e-02]]
Text(0.5, 1.0, 'Error vs. Iterations')