Sistema de regresión "Práctica ML": Predicción del precio medio de la vivienda

1. Análisis del proyecto

  • 目的: Utiliza datos del Censo de California para construir un modelo de precio de vivienda en California para predecir el precio medio de la vivienda en cualquier región en función de todos los demás indicadores;

Lista de verificación del proyecto de aprendizaje automático

  • Enmarque el problema y mire el conjunto;
  • recuperar datos;
  • estudiar datos para obtener información;
  • Prepare datos para alimentar patrones de datos subyacentes a algoritmos de aprendizaje automático;
  • Explore diferentes modelos y enumere los mejores;
  • Ajuste los modelos y combínelos en una buena solución;
  • solución de demostración;
  • iniciar, monitorear y mantener el sistema;

1. Cuestiones de encuadre

  • 业务目标: el resultado del modelo (predicción del precio medio de la vivienda en una región) se transmitirá a otro sistema de aprendizaje automático junto con otras señales; el sistema descendente se utilizará para decidir si vale la pena invertir en la región;

Por favor agregue una descripción de la imagen

  • 流水线, un componente de procesamiento de datos secuenciales, utilizado para la manipulación y transformación de datos en sistemas de aprendizaje automático;

Los componentes en la canalización suelen ser asincrónicos. Cada componente extrae una gran cantidad de datos, los procesa y luego transmite el resultado a otro almacén de datos, y luego el siguiente componente extrae la salida de datos anterior y proporciona su propia salida, a fin de Por analogía, los componentes son independientes entre sí, solo se conectan a través de almacenes de datos, y los componentes del sistema se mantienen simples y no interfieren entre sí;

Se debe implementar un monitoreo adecuado; de lo contrario, los componentes rotos no afectarán la disponibilidad de otros componentes, pero sin medidas correctivas durante mucho tiempo, se producirá una disminución en el rendimiento del sistema en general;

  • 现有解决方案: Estime manualmente el precio de la vivienda en el área por un equipo de expertos (primero continúe recopilando la información más reciente del área, calcule el precio medio de la vivienda, si no se puede calcular, use reglas complejas para estimar); el plan actual se puede usar para referencia;

  • 专家系统, el conocimiento es resumido por humanos y luego enseñado a la computadora; el proceso de implementación es costoso y los resultados del cálculo pueden no ser satisfactorios;

Esta es una 监督学习tarea típica (se han dado ejemplos de capacitación etiquetados), y también es una 多重回归tarea típica, 一元回归tarea (el sistema necesita predecir un valor a través de múltiples funciones); este es un 批量学习sistema (sin entrada continua de flujo de datos, y hay no es necesario realizar ajustes especiales para cambiar los datos, y la cantidad de datos no es muy grande);

2. Indicadores de desempeño

  • 均方根误差( RMSE), 欧几里得范数; se puede utilizar para reflejar cuánto error suele producir el sistema en la predicción;

RMSE ( X , h ) = 1 metro ∑ i = 1 metro ( h ( xi ) − yi ) 2 RMSE(X, h) = \sqrt{ \frac{1}{m} \sum_{i=1}^m (h(x^i) - y^i)^2 }RMSE ( X ,h )=metro1yo = 1m( h ( xyo )yyo )2

  • m, que indica el número de instancias en el conjunto de datos donde se mide RMSE (por ejemplo, evaluando RMSE en un conjunto de validación de 2000 regiones, luego m = 2000);
  • xix^iXi , un vector que representa todos los valores de las características (excluyendo las etiquetas) de la i-ésima instancia en el conjunto de datos;
  • yiy^iyi , que representa la etiqueta (valor de salida deseado de la instancia);

Por ejemplo, la primera área en el conjunto de datos está ubicada en -118.29° de longitud, 33.91° de latitud, 1416 residentes, ingreso medio $38372, valor medio de la casa $156400, luego

x 1 = ( − 118,29 33,91 1416 38372 ) x^1 = \begin{pmatrix} -118,29 \\ 33,91 \\ 1416 \\ 38372 \end{pmatrix}X1= 118,2933.91141638372

y 1 = 156400 y^1 = 156400 y1=156400

  • X, una matriz que contiene todos los valores propios (sin incluir las etiquetas) de todas las instancias en el conjunto de datos, donde cada fila representa una instancia y la fila i es igual a xix^iXmedios de i , es decir (xi) T (x^i)^T( Xyo )T ;

X = ( ( x 1 ) T ( x 2 ) T . . . ( x 1 999 ) T ( x 2 000 ) T ) = ( − 118,29 33,91 1416 38372 . . . . . . . . . . . . ) X = \begin{pmatrix} (x^1)^T \\ (x^2)^T \\ ... \\ (x^1999)^T \\ (x^2000)^T \end{pmatrix} = \begin{pmatrix} -118.29 & 33.91 & 1416 & 38372 \\ ... & ... & ... & ... \end{pmatrix}X= ( X1 )T( X2 )T...( X1 999)T( X2 000)T =(118,29...33.91...1416...38372...)

  • h, la función de predicción del sistema, también conocida como la hipótesis; cuando el sistema se ingresa con un vector de características de instancia xix^iXCuando i , generará un valor predichoy ^ i = h ( xi ) \hat{y}^i = h(x^i)y^i=h ( xi )(Si el sistema predice que el precio medio de la vivienda en la primera área es de $158 400, entoncesy ^ 1 = h ( x 1 ) \hat{y}^1 = h(x^1)y^1=h ( x1 )= 158400, su error de predicción esy ^ 1 − y 1 \hat{y}^1 - y^1y^1y1 = 2000);
  • RMSE(X, h), una función de costo medida sobre un conjunto de instancias utilizando la hipótesis h;

otras funciones

  • 平均绝对误差Mean Absolute ErrorMAE平均绝对偏差),曼哈顿范数

MAE ( X , h ) = 1 metro ∑ i = 1 metro ∣ h ( xi ) − yi ∣ MAE(X, h) = \frac{1}{m} \sum_{i=1}^m | h(x^i) - y^i |M A E ( X ,h )=metro1yo = 1mh ( xyo )yyo

Tanto RMSE como MAE son métodos para medir la distancia entre dos vectores (el vector de valor predicho y el vector de valor objetivo); cuanto mayor sea el índice de norma, más atención se presta a los valores grandes y se ignoran los valores pequeños ( RMSE es más sensible a valores atípicos que MAE, 离群值cuando RMSE funciona muy bien cuando la forma exponencial es rara);

2. Obtener datos

1. Prepara el espacio de trabajo

  • Crear un directorio de espacio de trabajo
export ML_HOME="$HOME/Documents/workspace/projects/aurelius/lmsl/studying/ml/handson-ml2/workspace"
mkdir -p $ML_HOME
  • Instale Python (los detalles de instalación se omiten aquí)

La versión de Python debe mantener una versión más nueva de python3, y la versión de pip debe mantenerse actualizada;

# 查看 pip 版本号
python3 -m pip --version

# 升级 pip 至最新版
python3 -m pip install --user -U pip
  • Crear un entorno de Python dedicado
cd $ML_HOME
# 创建一个名为 `.venv` 的专属 Python 环境
python3 -m venv .venv

# 进入专属 Python 环境
source .venv/bin/activate     # on Linux or macOS
# $ .\.venv\Scripts\activate  # on Windows

# 退出专属 Python 环境
deactivate
  • Instalar módulos dependientes

    • peticiones
    • Jupyter
    • NumPy
    • pandas
    • matplotlib
    • ScikitAprender
# 通过 pip 按照依赖模块
pip install requests jupyter matplotlib numpy pandas scipy scikit-learn

# 将专属环境注册到 Jupyter 并给它一个名字
python -m ipykernel install --user --name=ml-venv
# 若安装缓慢,可切换 pip 清华镜像源
cd ~/.pip
vi pip.conf
# 在 ~/.pip/pip.conf 加入如下配置
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple

[install]
trusted-host=pypi.tuna.tsinghua.edu.cn
  • Habilitar cuaderno Jupyter
jupyter notebook

Habilitar Jupyter Notebook abrirá un servicio web localmente y accederá al servicio a través de http://localhost:8888;

Se recomienda usar directamente el complemento Jupter de VS Code para usar Jupyter Notebook, sin tener que iniciar el servicio Jupyter a través del comando jupyter notebook (el método de uso específico puede explorarlo usted mismo);

2. Descargar datos

Los datos de este proyecto son un paquete comprimido en formato csv, se puede descargar a través de un navegador y descomprimir mediante el comando tar, pero se recomienda crear una función de Python para el procesamiento general;

import tarfile
import requests

def fetch_data(url, path, tgz):
    if not os.path.isdir(path):
        os.makedirs(path)

    tgz_path = os.path.join(path, tgz)
    with open(tgz_path, 'wb') as w:
        w.write(requests.get(url).content)

    housing_tgz = tarfile.open(tgz_path)
    housing_tgz.extractall(path=path)
    housing_tgz.close()
  • Descargue y presione los datos en la ruta del espacio de trabajo
import os

DOWNLOAD_ROOT = "https://raw.githubusercontent.com/ageron/handson-ml2/master/"
HOUSING_PATH = os.path.join("workspace", "datasets", "housing")
HOUSING_URL = DOWNLOAD_ROOT + "datasets/housing/housing.tgz"
HOUSING_TGZ = "housing.tgz"

fetch_data(HOUSING_URL, HOUSING_PATH, HOUSING_TGZ)
  • Cargar y ver datos usando pandas
import pandas as pd

def load_data(path, csv):
    csv_path = os.path.join(path, csv)
    return pd.read_csv(csv_path)

housing = load_data(HOUSING_PATH, 'housing.csv')

3. Ver datos

Ver las primeras 5 filas del conjunto de datos

housing.head()

Por favor agregue una descripción de la imagen

  • 实例属性
    • longitud: longitud
    • latitud: latitud
    • housing_median_age: edad media de la vivienda
    • total_rooms: número total de habitaciones
    • total_bedrooms: número total de dormitorios
    • población: población
    • hogares: familia (número de hogares)
    • ingreso_medio: ingreso medio
    • median_house_value: precio medio de la vivienda
    • ocean_proximity: la distancia del océano

Ver una breve descripción del conjunto de datos

housing info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20640 entries, 0 to 20639
Data columns (total 10 columns):
 #   Column              Non-Null Count  Dtype
---  ------              --------------  -----
 0   longitude           20640 non-null  float64
 1   latitude            20640 non-null  float64
 2   housing_median_age  20640 non-null  float64
 3   total_rooms         20640 non-null  float64
 4   total_bedrooms      20433 non-null  float64
 5   population          20640 non-null  float64
 6   households          20640 non-null  float64
 7   median_income       20640 non-null  float64
 8   median_house_value  20640 non-null  float64
 9   ocean_proximity     20640 non-null  object
dtypes: float64(9), object(1)
memory usage: 1.6+ MB
  • 数据集摘要: Contiene 20640 instancias, total_bedroomssolo 20433 valores no nulos; ocean_proximityes tipo de objeto, y todos los demás atributos son 数值类型;

Ver propiedades de clasificación de campos

housing['ocean_proximity'].value_counts()

<1H OCEAN     9136
INLAND        6551
NEAR OCEAN    2658
NEAR BAY      2290
ISLAND           5
Name: ocean_proximity, dtype: int64

ocean_proximityHay cinco tipos de valores, distribuidos como salida arriba;

Ver un resumen de las propiedades numéricas

housing.describe()

Por favor agregue una descripción de la imagen

  • std, desviación estándar (utilizada para medir el grado de dispersión de los valores);
  • 25%// 50%, 75%el percentil, que indica que un porcentaje dado de observaciones en el grupo de observación está por debajo de este valor;
  • count, el número total de filas y los valores nulos se ignorarán, como el recuento de total_bedrooms es 20433;

trazar un histograma para cada atributo

# 指定 Matplotlib 使用哪个后端,在 VS Code 中则无需指定
# %matplotlib inline   # only in a Jupyter notebook,令 Matplotlib 使用 Jupyter 的后端,图形在 Notebook 上显示;
import matplotlib.pyplot as plt

# hist() 依赖于 matplotlib
housing.hist(bins=50, figsize=(20,15))
plt.show()

Por favor agregue una descripción de la imagen

  • median_income, el ingreso medio obviamente no se mide en dólares estadounidenses (sino en diez mil dólares estadounidenses), sino que se ha reducido en una determinada proporción (límite superior 15, límite inferior 0,5) y otros valores de atributos también se han escalado para variar grados;
  • housing_median_agey median_house_valuetambién limitados, y median_house_valuecomo atributos de destino de predicción, se requiere atención especial;
    • Recopilar valores de etiquetas para áreas donde se han limitado los valores de etiquetas;
    • Eliminar regiones donde el valor de la etiqueta exceda el límite superior;
  • Los histogramas en su mayoría muestran colas pesadas (efecto de cola larga), lo que puede dificultar que algunos algoritmos de aprendizaje automático detecten patrones, y se necesitan algunos métodos de transformación para convertir estas propiedades en una distribución más en forma de campana;

4. Crear un conjunto de prueba

  • 数据窥探偏误( data snooping bias), si explora los datos del conjunto de prueba con anticipación, puede caer en un patrón de datos de prueba aparentemente interesante y luego elegir un modelo especial de aprendizaje automático; luego, cuando use el conjunto de prueba para evaluar el error de generalización, el resultado será demasiado optimista, y el rendimiento del sistema no será el esperado cuando se ponga oficialmente en producción;

Seleccione aleatoriamente algunas instancias (generalmente 20%, se puede reducir cuando el conjunto de datos es grande) y déjelas a un lado;

import numpy as np

def split_train_test(data, test_ratio):
    shuffled_indices = np.random.permutation(len(data))
    test_set_size = int(len(data) * test_ratio)
    test_indices = shuffled_indices[:test_set_size]
    train_indices = shuffled_indices[test_set_size:]
    return data.iloc[train_indices], data.iloc[test_indices]

train_set, test_set = split_train_test(housing, 0.2)
print(len(train_set), len(test_set))
# 16512 4128

Las ejecuciones repetidas de un conjunto de prueba dividido de este tipo darán resultados diferentes, lo que hará que el algoritmo de aprendizaje vea el conjunto de datos completo, lo que debe evitarse al crear el conjunto de prueba;

Puede hacer que el conjunto de prueba indexado sea siempre el mismo al volcar el conjunto de prueba o arreglar la semilla del generador de números aleatorios (por ejemplo, usando np.random.seed(42));

De esta manera, el conjunto de prueba fijo no puede dividir el conjunto de datos actualizado. Una mejor manera es usar un algoritmo fijo (algoritmo hash) y usar el identificador único (como el valor hash) de cada instancia como entrada para decidir si ingresar el equipo de prueba;

from zlib import crc32

# 是否进入测试集的固定算法
def test_set_check(identifier, test_ratio):
    return crc32(np.int64(identifier)) & 0xffffffff < test_ratio * 2**32

def split_train_test_by_id(data, test_ratio, id_column):
    ids = data[id_column]
    in_test_set = ids.apply(lambda id_: test_set_check(id_, test_ratio))
    return data.loc[~in_test_set], data.loc[in_test_set]
  • Ingrese el índice como identificador único
housing_with_id = housing.reset_index()   # adds an `index` column
train_set, test_set = split_train_test_by_id(housing_with_id, 0.2, "index")

Es necesario asegurarse de que los nuevos datos solo se agreguen al final del conjunto de datos y que no se eliminen filas;

  • Introduzca la latitud y la longitud como identificador único
housing_with_id["id"] = housing["longitude"] * 1000 + housing["latitude"]
train_set, test_set = split_train_test_by_id(housing_with_id, 0.2, "id")

usarScikit-Learn

  • tren_prueba_dividir()
from sklearn.model_selection import train_test_split
train_set, test_set = train_test_split(housing, test_size=0.2, random_state=42)

random_state se puede usar para configurar el generador de números aleatorios, y también puede enviar múltiples conjuntos de datos con el mismo número de filas a la vez, para dividirlos con el mismo índice;

  • 随机抽样, adecuado para conjuntos de datos que son lo suficientemente grandes (en comparación con el número de atributos), de lo contrario, es fácil causar obvio 抽样偏差;

  • 分层抽样, divida el conjunto de datos en varios subconjuntos (capas) según los atributos y luego extraiga la misma proporción de instancias de cada subconjunto y combínelos en un conjunto de prueba;

Preservar la distribución original de atributos importantes en el conjunto de prueba

Predecir el precio medio de la vivienda y el ingreso medio son atributos importantes, y el conjunto de prueba debe poder representar varios tipos de ingresos en todo el conjunto de datos;

# 将收入按 0 ~ 1.5 ~ 3 ~ 4.5 ~ 6 ~ 无穷大,分为 5 个子集(层);
housing["income_cat"] = pd.cut(housing["median_income"],
                               bins=[0., 1.5, 3.0, 4.5, 6., np.inf],
                               labels=[1, 2, 3, 4, 5])

housing["income_cat"].hist()

Por favor agregue una descripción de la imagen

StratifiedShuffleSplitMuestreo estratificado por ingreso vía Scikin-Learn ;

from sklearn.model_selection import StratifiedShuffleSplit
split = StratifiedShuffleSplit(n_splits=1, test_size=0.2, random_state=42)
for train_index, test_index in split.split(housing, housing["income_cat"]):
    strat_train_set = housing.loc[train_index]
    strat_test_set = housing.loc[test_index]

# 验证分层的实例占比
strat_test_set["income_cat"].value_counts() / len(strat_test_set)

3    0.350533
2    0.318798
4    0.176357
5    0.114341
1    0.039971
Name: income_cat, dtype: float64

Conjunto completo de datos, conjunto de prueba de muestreo estratificado, conjunto de prueba de muestreo aleatorio distribución de proporción de atributos de ingresos;

def income_cat_proportions(data):
    return data["income_cat"].value_counts() / len(data)

train_set, test_set = train_test_split(housing, test_size=0.2, random_state=42)

compare_props = pd.DataFrame({
    
    
    "Overall": income_cat_proportions(housing),
    "Stratified": income_cat_proportions(strat_test_set),
    "Random": income_cat_proportions(test_set),
}).sort_index()
compare_props["Rand. %error"] = 100 * compare_props["Random"] / compare_props["Overall"] - 100
compare_props["Strat. %error"] = 100 * compare_props["Stratified"] / compare_props["Overall"] - 100

compare_props

Por favor agregue una descripción de la imagen

eliminar el atributo income_cat;

for set_ in (strat_train_set, strat_test_set):
    set_.drop("income_cat", axis=1, inplace=True)

3. Exploración de datos

Cree una copia del conjunto de entrenamiento para que los intentos posteriores no dañen el conjunto de entrenamiento;

housing = strat_train_set.copy()

1. Visualización de geolocalización

Trazar la distribución de latitud y longitud por densidad de datos

housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.1)

Por favor agregue una descripción de la imagen

Las áreas de alta densidad se pueden distinguir claramente de la figura;

Distribución de latitud y longitud por densidad de población y precio medio de la vivienda

housing.plot(kind="scatter", x="longitude", y="latitude", alpha=0.4,
    s=housing["population"]/100, label="population", figsize=(10,7),
    c="median_house_value", cmap=plt.get_cmap("jet"), colorbar=True,
)
plt.legend()

Por favor agregue una descripción de la imagen

La población está representada por el radio del círculo (opción s), el precio medio de la vivienda está representado por la presentación (opción c), donde la gama de colores (opción cmap) se toma de la tabla de colores predefinida jet;

Se puede confirmar a partir de la figura que los precios de la vivienda están estrechamente relacionados con la ubicación geográfica y la densidad de población;

2. Busca correlaciones

Use corr() para calcular el coeficiente de correlación estandarizado (Pearson) entre cada par de atributos

corr_matrix = housing.corr()
corr_matrix["median_house_value"].sort_values(ascending=False)

median_house_value    1.000000
median_income         0.687151
total_rooms           0.135140
housing_median_age    0.114146
households            0.064590
total_bedrooms        0.047781
population           -0.026882
longitude            -0.047466
latitude             -0.142673
Name: median_house_value, dtype: float64
  • 相关系数, correlación lineal, que va de -1 a 1; cuanto más cerca de 1, más correlación positiva; cuanto más cerca de -1, más correlación negativa; 0 significa que no hay correlación lineal entre los dos;

Trazado de correlaciones usando pandas' scatter_matrix()

from pandas.plotting import scatter_matrix

attributes = ["median_house_value", "median_income", "total_rooms", "housing_median_age"]
scatter_matrix(housing[attributes], figsize=(12, 8))

Por favor agregue una descripción de la imagen

La diagonal principal muestra el histograma de cada atributo, las demás posiciones muestran la correlación entre atributos;

  • Mire el atributo con el mejor potencial para predecir el precio medio de la vivienda: ingreso medio (el atributo más relevante);
housing.plot(kind="scatter", x="median_income", y="median_house_value", alpha=0.1)

Por favor agregue una descripción de la imagen

Se puede confirmar a partir de la figura que la correlación entre los dos es fuerte, y hay líneas horizontales claras en 50 W, 35 W y 45 W. Esto puede deberse a precios máximos objetivamente existentes. Para evitar que el algoritmo de aprendizaje aprenda estos datos extraños, puede intentar eliminar esta área;

3. Propiedades compuestas

Del análisis de correlación de atributos anterior, podemos encontrar que algunos 异常数据(como las líneas horizontales) deben limpiarse por adelantado, y algunas 重尾distribuciones deben convertirse (como los cálculos 对数), etc.; y tratar de combinar atributos puede permitirnos descubrir nuevos atributos de alta correlación;

  • Intente combinar atributos y observe la correlación con el atributo de destino
housing["rooms_per_household"] = housing["total_rooms"]/housing["households"]
housing["bedrooms_per_room"] = housing["total_bedrooms"]/housing["total_rooms"]
housing["population_per_household"]=housing["population"]/housing["households"]

corr_matrix = housing.corr()
corr_matrix["median_house_value"].sort_values(ascending=False)

median_house_value          1.000000
median_income               0.687151
rooms_per_household         0.146255
total_rooms                 0.135140
housing_median_age          0.114146
households                  0.064590
total_bedrooms              0.047781
population_per_household   -0.021991
population                 -0.026882
longitude                  -0.047466
latitude                   -0.142673
bedrooms_per_room          -0.259952
Name: median_house_value, dtype: float64

El nuevo atributo dormitorios_por_habitación tiene una correlación significativamente mayor con la mediana del número de habitaciones que los atributos originales (total_dormitorios, total_habitaciones);

4. Preparación de datos

Innove una nueva copia del conjunto de entrenamiento, separando su período de predicción de las etiquetas;

housing = strat_train_set.drop("median_house_value", axis=1)
housing_labels = strat_train_set["median_house_value"].copy()

drop no afectará a strat_train_set, solo creará una nueva copia de los datos;

1. Limpieza de datos

Resuelve el problema de faltar algunos valores de total_bedrooms

  • dropna(), abandonar estas áreas de valor perdido;
  • drop(), desechando toda la propiedad;
  • fillna(), para establecer valores faltantes en algún valor (0, media, mediana, etc.);
housing.dropna(subset=["total_bedrooms"])    # option 1
housing.drop("total_bedrooms", axis=1)       # option 2
median = housing["total_bedrooms"].median()  # option 3
housing["total_bedrooms"].fillna(median, inplace=True)

Manejo de valores faltantes con SimpleImputer de Scikit-Learn

from sklearn.impute import SimpleImputer
# 创建中位数填充处理器
imputer = SimpleImputer(strategy="median")
# 因为中位数值只能计算数值属性,这里需要移除 ocean_proximity 属性
housing_num = housing.drop("ocean_proximity", axis=1)
# 使用 fit() 将 imputer 实例适配到训练数据(计算每个属性的中位数值,并存储在 statistics_)
imputer.fit(housing_num)
# 查看中位数值
imputer.statistics_
# 比较中位数值是否计算正确
housing_num.median().values

# 使用 transform() 将中位数值替换到缺失值
X = imputer.transform(housing_num)

# 重新将 numpy 数组加载到 pandas 的 DataFrame
housing_tr = pd.DataFrame(X, columns=housing_num.columns, index=housing_num.index)

2. Diseño de Scikit-Learn

  • 一致性, el diseño de la API de Scikit-Learn sigue 一致性los principios y todos los objetos comparten una interfaz simple y consistente;

estimador

Algunos parámetros se estiman de acuerdo con el conjunto de datos (como la mediana estimada por el imputador), y la estimación se realiza mediante el método fit(). Solo se requiere un conjunto de datos como parámetro (o un par de parámetros, uno como un entrenador y otro como conjunto de etiquetas), los otros parámetros que guían el proceso de estimación son 超参数(como la estrategia de la estrategia = 'median'), y el hiperparámetro debe ser una variable de instancia;

convertidor

La fuente de estimación (como un imputer) que puede transformar el conjunto de datos también se denomina convertidor. El método transform() realiza la transformación junto con el conjunto de datos que se transformará como un parámetro, y el resultado devuelto es el conjunto de datos transformado; el proceso de transformación generalmente depende de parámetros aprendidos (por ejemplo, imputer.statistics);

El método fit_transform() es equivalente a ejecutar fit() antes de ejecutar transform() y, a veces, puede contener algunas optimizaciones, que se ejecutarán más rápido;

vaticinador

Un estimador que puede hacer predicciones basadas en un conjunto de datos determinado, también conocido como predictor (como un modelo de regresión lineal), predice un conjunto de datos de una nueva instancia mediante el método predict() y devuelve un conjunto de datos que contiene la predicción correspondiente resultados;

El método score() se puede utilizar para medir la calidad de las predicciones (y las etiquetas correspondientes en los algoritmos de aprendizaje supervisado) para un conjunto de pruebas determinado;

  • 检查

Se puede acceder directamente a todos los estimadores 超参数a través de variables de instancia pública (como imputer.strategy), se puede acceder directamente
a todos los estimadores 学习参数a través de variables públicas con un sufijo de subrayado (como imputer.statistics_);

  • 防止类扩散

Los conjuntos de datos se representan como matrices NumPy o matrices dispersas SciPy, no como tipos personalizados;
los hiperparámetros son simplemente cadenas o valores de Python;

  • 构成

Los bloques de construcción se reutilizan tanto como sea posible (cualquier secuencia de convertidores se puede agregar con un predictor al final para construir un estimador de Pipeline);

  • 合理的默认值

Scikit-Learn proporciona valores predeterminados sensibles para la mayoría de los parámetros para construir rápidamente un sistema de trabajo básico;

3. Texto de procesamiento, atributos de clasificación

Ver las primeras 10 líneas de propiedades de texto

housing_cat = housing[["ocean_proximity"]]
housing_cat.head(10)

	ocean_proximity
12655	INLAND
15502	NEAR OCEAN
2908	INLAND
14053	NEAR OCEAN
20496	<1H OCEAN
1481	NEAR BAY
18125	<1H OCEAN
5830	<1H OCEAN
17989	<1H OCEAN
4861	<1H OCEAN

ocean_proximity no es un texto arbitrario, sino un valor de enumeración, es decir, un atributo de clasificación;

Convierta atributos de texto en atributos numéricos usando OrdinalEncoder de Scikit-Learn

from sklearn.preprocessing import OrdinalEncoder

ordinal_encoder = OrdinalEncoder()
housing_cat_encoded = ordinal_encoder.fit_transform(housing_cat)

housing_cat_encoded[:10]

array([[1.],
       [4.],
       [1.],
       [4.],
       [0.],
       [3.],
       [0.],
       [0.],
       [0.],
       [0.]])

ver lista de categorías

ordinal_encoder.categories_

[array(['<1H OCEAN', 'INLAND', 'ISLAND', 'NEAR BAY', 'NEAR OCEAN'],
       dtype=object)]
  • 独热编码, cree un atributo binario para cada valor de atributo del atributo de categoría (1 significa caliente, 0 significa frío), para evitar tratar erróneamente los atributos con valores más cercanos como más cercanos después de convertir los atributos de texto en atributos de valor;

Convierta atributos de texto en vectores one-hot utilizando el codificador OneHotEncoder de Scikin-Learn

from sklearn.preprocessing import OneHotEncoder

cat_encoder = OneHotEncoder()
housing_cat_1hot = cat_encoder.fit_transform(housing_cat)
housing_cat_1hot
# 输出一个 SciPy 稀疏矩阵;
<16512x5 sparse matrix of type '<class 'numpy.float64'>'
	with 16512 stored elements in Compressed Sparse Row format>
  • 稀疏矩阵, que solo almacena la posición de elementos distintos de cero, todavía se puede usar como una matriz bidimensional normal;

Ver representación de matriz 2D de matriz dispersa

housing_cat_1hot.toarray()

array([[0., 1., 0., 0., 0.],
       [0., 0., 0., 0., 1.],
       [0., 1., 0., 0., 0.],
       ...,
       [1., 0., 0., 0., 0.],
       [1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.]])

Ver la lista de categorías de codificadores

cat_encoder.categories_

[array(['<1H OCEAN', 'INLAND', 'ISLAND', 'NEAR BAY', 'NEAR OCEAN'],
       dtype=object)]

Si hay muchas categorías de valor de atributo de atributos de categoría, la codificación one-hot generará una gran cantidad de características de entrada, lo que puede ralentizar el entrenamiento y reducir el rendimiento. En este momento, puede ser necesario utilizar características digitales relacionadas en lugar de entradas de categoría. (como usar la distancia del océano en lugar de ocean_proximity, o reemplazar cada categoría con un vector de baja dimensión que se pueda aprender);

4. Convertidor personalizado

Los convertidores personalizados de Scikit-Learn se pueden usar para implementar algunas operaciones de limpieza o combinar atributos específicos, etc., que se pueden conectar a la perfección con las funciones propias de Scikit-Learn;

Scikit-Learn se basa en la compilación tipo pato, no en la herencia, siempre que la clase creada contenga fit() (return self), transform(), fit_transform();

  • TransformerMixin, implementa automáticamente el método fit_transform();
  • BaseEstimator, obtenga los métodos get_params() y set_params() para ajustar automáticamente los hiperparámetros;

Implementación de un convertidor para propiedades compuestas a través de un convertidor personalizado

from sklearn.base import BaseEstimator, TransformerMixin

rooms_ix, bedrooms_ix, population_ix, households_ix = 3, 4, 5, 6

class CombinedAttributesAdder(BaseEstimator, TransformerMixin):
    def __init__(self, add_bedrooms_per_room = True): # no *args or **kargs
        self.add_bedrooms_per_room = add_bedrooms_per_room

    def fit(self, X, y=None):
        return self  # nothing else to do

    def transform(self, X):
        rooms_per_household = X[:, rooms_ix] / X[:, households_ix]
        population_per_household = X[:, population_ix] / X[:, households_ix]
        if self.add_bedrooms_per_room:
            bedrooms_per_room = X[:, bedrooms_ix] / X[:, rooms_ix]
            return np.c_[X, rooms_per_household, population_per_household,
                        bedrooms_per_room]
        else:
            return np.c_[X, rooms_per_household, population_per_household]

attr_adder = CombinedAttributesAdder(add_bedrooms_per_room=False)
housing_extra_attribs = attr_adder.transform(housing.values)

El hiperparámetro add_bedrooms_per_room se puede usar para controlar si se agrega el atributo dormitorios_por_habitación, y esta implementación puede proporcionar más combinaciones;

5. Escalado de funciones

La transformación más importante que debe aplicarse a los datos es el escalado de características;

Dos formas comunes de escalar todos los atributos por igual son 最小-最大缩放y 标准化;

  • 最小-最大缩放, 归一法, para escalar el valor de modo que su rango esté 0 ~ 1entre (restar todos los valores del valor mínimo y dividir por la diferencia entre los valores máximo y mínimo); el transformador MinMaxScaler de Scikit-Learn se puede implementar fácilmente y su hiperparámetro feature_range puede ajustar su rango;

  • 标准化, reste la media de todos los valores (la media de los valores estandarizados siempre es 0) y divida por la varianza (la distribución del resultado tiene varianza unitaria); la estandarización no vincula los valores a un rango específico , y se ve menos afectado por valores atípicos; el transformador StandardScaler de Scikit-Learn permite la estandarización;

6. Línea de montaje

  • 流水线, Pipeline, realizar múltiples conversiones de datos en ciertos pasos, y Pipeline de Scikit-Learn proporciona dicho soporte de conversión;
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler

num_pipeline = Pipeline([
        ('imputer', SimpleImputer(strategy="median")),
        ('attribs_adder', CombinedAttributesAdder()),
        ('std_scaler', StandardScaler()),
    ])

housing_num_tr = num_pipeline.fit_transform(housing_num)

El Pipeline constructor es una secuencia definida por una serie de pares de nombres y estimadores, salvo que el último es un estimador, los anteriores deben ser transformadores (implementando el método fit_transform());

Cuando se llama al método fit() de la canalización, se llama secuencialmente al método fit_transform() del convertidor, y la salida del convertidor anterior se pasa como parámetro al siguiente convertidor hasta que se pasa al estimador final y se ejecuta. método del último estimador;

Use el transformador ColumnTransformer de Scikit-Learn para procesar todas las columnas

from sklearn.compose import ColumnTransformer
num_attribs = list(housing_num)
cat_attribs = ["ocean_proximity"]

full_pipeline = ColumnTransformer([
        ("num", num_pipeline, num_attribs),
        ("cat", OneHotEncoder(), cat_attribs),
    ])
housing_prepared = full_pipeline.fit_transform(housing)

ColumnTransformer puede aplicar transformaciones en columnas específicas del conjunto de datos al pasar una lista de nombres de columna y fusionar la salida a lo largo del segundo eje (los transformadores deben devolver la misma cantidad de filas);

La matriz dispersa se fusiona con la matriz densa, y ColumnTransformer estimará la densidad de la matriz final (la proporción distinta de cero de la celda) y devolverá una matriz dispersa si la densidad es inferior a un umbral determinado (sparse_threshold por defecto es 0.3);

5. Seleccionar y entrenar el modelo

1. Entrenamiento y evaluación del conjunto de entrenamiento

Entrenar un modelo de regresión lineal

from sklearn.linear_model import LinearRegression

lin_reg = LinearRegression()
lin_reg.fit(housing_prepared, housing_labels)

Probar predicciones usando instancias del conjunto de entrenamiento

some_data = housing.iloc[:5]
some_labels = housing_labels.iloc[:5]
some_data_prepared = full_pipeline.transform(some_data)
print("Predictions:", lin_reg.predict(some_data_prepared))
print("Labels:", list(some_labels))

Predictions: [ 86208. 304704. 153536. 185728. 244416.]
Labels: [72100.0, 279600.0, 82700.0, 112500.0, 238300.0]

Medición del RMSE del modelo de regresión en el conjunto de entrenamiento

Utilice mean_squared_error() de Scikit-Learn para medir el error cuadrático medio de la raíz;

from sklearn.metrics import mean_squared_error
housing_predictions = lin_reg.predict(housing_prepared)
lin_mse = mean_squared_error(housing_labels, housing_predictions)
lin_rmse = np.sqrt(lin_mse)
print(lin_rmse)

68633.40810776998

Muestra que el error de predicción alcanza los $ 68 628, y la totalidad de los valores medios de vivienda solo se distribuye entre $ 120 000 y $ 26 500. Un error tan grande muestra que este es un esquema en el que el modelo no se ajusta a los datos de entrenamiento;

En este momento, los métodos de optimización que podemos probar son: elegir un modelo más potente, proporcionar mejores funciones para el entrenamiento de algoritmos y reducir las restricciones en el modelo;

Entrenar un árbol de decisión usando DecisionTreeRegressor

Encuentre relaciones no lineales complejas en los datos;

from sklearn.tree import DecisionTreeRegressor
tree_reg = DecisionTreeRegressor()
tree_reg.fit(housing_prepared, housing_labels)

Medición del RMSE del modelo de regresión en el conjunto de entrenamiento

housing_predictions = tree_reg.predict(housing_prepared)
tree_mse = mean_squared_error(housing_labels, housing_predictions)
tree_rmse = np.sqrt(tree_mse)
print(tree_rmse)

0.0

Un error de 0 significa que el modelo es absolutamente perfecto (lo cual es imposible) o se sobreajusta severamente a los datos;

2. Validación cruzada

Evaluación de modelos de árboles de decisión mediante validación cruzada;

Validación cruzada de K-fold usando cross_val_score de Scikit-Learn

from sklearn.model_selection import cross_val_score

scores = cross_val_score(tree_reg, housing_prepared, housing_labels, scoring="neg_mean_squared_error", cv=10)
tree_rmse_scores = np.sqrt(-scores)

Las puntuaciones son el número negativo de MSE (que representa la función de utilidad, cuanto más grande, mejor), np.sqrt(-scores)simplemente calcule RMSE;

def display_scores(scores):
    print("Scores:", scores)
    print("Mean:", scores.mean())
    print("Standard deviation:", scores.std())

display_scores(tree_rmse_scores)

Scores: [73444.02930862 69237.91537492 67003.65412022 71810.57760783
 70631.08058123 77465.52053272 70962.67507776 73613.93631416
 68442.91744801 72364.26672416]
Mean: 71497.65730896383
Standard deviation: 2835.532019536459

La puntuación RMSE promedio del árbol de decisión en el conjunto de validación es 71497 (conjunto de entrenamiento: 0) y la fluctuación (precisión) es 2835;

Validación cruzada para modelos de regresión lineal

lin_scores = cross_val_score(lin_reg, housing_prepared, housing_labels,
                             scoring="neg_mean_squared_error", cv=10)
lin_rmse_scores = np.sqrt(-lin_scores)
display_scores(lin_rmse_scores)

Scores: [71800.38078269 64114.99166359 67844.95431254 68635.19072082
 66801.98038821 72531.04505346 73992.85834976 68824.54092094
 66474.60750419 70143.79750458]
Mean: 69116.4347200802
Standard deviation: 2880.6588594759014

La puntuación media de RMSE del modelo de regresión lineal en el conjunto de validación es 69116 (conjunto de entrenamiento: 68633) y la fluctuación (precisión) es 2880;

La puntuación RMSE del árbol de decisión es más alta que la del modelo de regresión lineal, lo que muestra que se está sobreajustando gravemente;

Entrenar bosques aleatorios con RandomForestRegressor

  • 随机森林: al entrenar muchos árboles de decisión en un subconjunto aleatorio de características y luego promediar sus predicciones, la construcción de un modelo sobre la base de múltiples modelos se denomina aprendizaje conjunto;
from sklearn.ensemble import RandomForestRegressor

forest_reg = RandomForestRegressor()
forest_reg.fit(housing_prepared, housing_labels)
housing_predictions = forest_reg.predict(housing_prepared)
forest_mse = mean_squared_error(housing_labels, housing_predictions)
forest_rmse = np.sqrt(forest_mse)
print(forest_rmse)

forest_scores = cross_val_score(forest_reg, housing_prepared, housing_labels,
                scoring="neg_mean_squared_error", cv=10)
forest_rmse_scores = np.sqrt(-forest_scores)
display_scores(forest_rmse_scores)

18580.285001969234
Scores: [51420.10657898 48950.26905778 46724.70163181 52032.16751813
 47382.48485738 51644.10218989 52532.85241798 50040.96772226
 48869.83863791 53727.35461654]
Mean: 50332.484522865096
Standard deviation: 2191.1726721020977

El puntaje RMSE del conjunto de entrenamiento es 18580, el puntaje del conjunto de validación es 50332 y la fluctuación (precisión) es 2191. Aunque el rendimiento es mucho mejor que los dos modelos anteriores, el puntaje del conjunto de entrenamiento es mucho más bajo que el conjunto de validación. lo que demuestra que todavía se está sobreajustando;

Antes de la simplificación del modelo y las restricciones del modelo, puede probar más algoritmos de aprendizaje automático (como máquinas de vectores de soporte con diferentes kernels, modelos de redes neuronales, etc.), primero evalúe algunos modelos efectivos y no pierda demasiado tiempo ajustando hiperparámetros;

guardar modelo

import joblib

joblib.dump(forest_reg, "./workspace/models/forest_reg.pkl")
# and later, reload model...
forest_reg_loaded = joblib.load("./workspace/models/forest_reg.pkl")

6. Afinando el modelo

Una vez que tenga varios modelos candidatos válidos, puede ajustarlos;

1. Búsqueda de cuadrícula

  • 网格搜索, se puedeScikit-Learn utilizar para evaluar todas las combinaciones posibles de hiperparámetros configurando los hiperparámetros del experimento y los valores que deben probarse, para obtener la mejor combinación;GridSearchCV交叉验证
from sklearn.model_selection import GridSearchCV

param_grid = [
    {
    
    'n_estimators': [3, 10, 30], 'max_features': [2, 4, 6, 8]},
    {
    
    'bootstrap': [False], 'n_estimators': [3, 10], 'max_features': [2, 3, 4]},
    ]
forest_reg = RandomForestRegressor()
grid_search = GridSearchCV(forest_reg, param_grid, cv=5,
                            scoring='neg_mean_squared_error',
                            return_train_score=True)
grid_search.fit(housing_prepared, housing_labels)
  • parram_grid, la configuración de la cuadrícula de hiperparámetros;
    • n_estimators, max_features, nombre del hiperparámetro, 3 * 4 = 12tipos ;
    • bootstrap, n_estimators, max_features, nombre del hiperparámetro, 1 * 2 * 3 = 6tipos ;
  • cv, las 18 combinaciones anteriores de hiperparámetros se entrenaron 5 veces (validación cruzada de 5 veces);
  • refit, =True (predeterminado) permite que GridSearchCV encuentre el mejor estimador a través de la validación cruzada y luego vuelva a entrenar el modelo en todo el conjunto de entrenamiento (más datos pueden mejorar el rendimiento del modelo);

Ver resultados de búsqueda de cuadrícula

grid_search.best_params_

{
    
    'max_features': 6, 'n_estimators': 30}

obtener el mejor estimador

grid_search.best_estimator_

Puntaje de evaluación del estimador

cvres = grid_search.cv_results_
for mean_score, params in zip(cvres["mean_test_score"], cvres["params"]):
    print(np.sqrt(-mean_score), params)

63475.5397459137 {
    
    'max_features': 2, 'n_estimators': 3}
55754.473565553184 {
    
    'max_features': 2, 'n_estimators': 10}
52830.64714547093 {
    
    'max_features': 2, 'n_estimators': 30}
60296.33920014068 {
    
    'max_features': 4, 'n_estimators': 3}
52504.03498357088 {
    
    'max_features': 4, 'n_estimators': 10}
50328.7606181505 {
    
    'max_features': 4, 'n_estimators': 30}
59328.255990059035 {
    
    'max_features': 6, 'n_estimators': 3}
51909.34406264884 {
    
    'max_features': 6, 'n_estimators': 10}
49802.234477838996 {
    
    'max_features': 6, 'n_estimators': 30}
58997.87515871176 {
    
    'max_features': 8, 'n_estimators': 3}
52036.752607340735 {
    
    'max_features': 8, 'n_estimators': 10}
50321.971231209965 {
    
    'max_features': 8, 'n_estimators': 30}
62389.547952235145 {
    
    'bootstrap': False, 'max_features': 2, 'n_estimators': 3}
53800.36505088281 {
    
    'bootstrap': False, 'max_features': 2, 'n_estimators': 10}
59953.45347364427 {
    
    'bootstrap': False, 'max_features': 3, 'n_estimators': 3}
52115.46931655621 {
    
    'bootstrap': False, 'max_features': 3, 'n_estimators': 10}
59061.9294179386 {
    
    'bootstrap': False, 'max_features': 4, 'n_estimators': 3}
52197.755732390906 {
    
    'bootstrap': False, 'max_features': 4, 'n_estimators': 10}

La puntuación RMSE del mejor estimador (max_features: 6, n_estimators: 30) es 49802, que es ligeramente mejor que los hiperparámetros predeterminados de 50332, y el modelo está optimizado;

La búsqueda en cuadrícula se puede realizar a través de hiperparámetros definidos durante la fase de preparación de datos (para controlar el manejo de valores atípicos, características faltantes, selección de características, etc.) para explorar automáticamente la mejor solución a un problema;

2. Búsqueda aleatoria

  • 随机搜素, esScikit-Learn más o menos lo mismo que , pero solo se elige un valor aleatorio para cada hiperparámetro en cada iteración, y luego se evalúa un cierto número de combinaciones aleatorias; RandomizedSearchCVGridSearchCV
    • Las búsquedas aleatorias se pueden realizar repetidamente para explorar diferentes hiperparámetros cada vez; a diferencia de la búsqueda en cuadrícula, el rango de búsqueda de cada hiperparámetro debe ser fijo;
    • Puede controlar mejor el presupuesto de cálculo asignado a la búsqueda de hiperparámetros a través de la configuración del número de iteración simple;

Evaluar regresores de máquinas de vectores de soporte mediante RandomizedSearchCV

from sklearn.svm import SVR
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import expon, reciprocal

# see https://docs.scipy.org/doc/scipy/reference/stats.html
# for `expon()` and `reciprocal()` documentation and more probability distribution functions.

# Note: gamma is ignored when kernel is "linear"
param_distribs = {
    
    
        'kernel': ['linear', 'rbf'],
        'C': reciprocal(20, 200000),
        'gamma': expon(scale=1.0),
    }

svm_reg = SVR()
rnd_search = RandomizedSearchCV(svm_reg, param_distributions=param_distribs,
                                n_iter=50, cv=5, scoring='neg_mean_squared_error',
                                verbose=2, random_state=42)
rnd_search.fit(housing_prepared, housing_labels)

Fitting 5 folds for each of 50 candidates, totalling 250 fits
[CV] END C=629.782329591372, gamma=3.010121430917521, kernel=linear; total time=   3.3s
[CV] END C=629.782329591372, gamma=3.010121430917521, kernel=linear; total time=   3.3s
[CV] END C=629.782329591372, gamma=3.010121430917521, kernel=linear; total time=   3.2s
[CV] END C=629.782329591372, gamma=3.010121430917521, kernel=linear; total time=   3.2s
[CV] END C=629.782329591372, gamma=3.010121430917521, kernel=linear; total time=   3.2s
...

negative_mse = rnd_search.best_score_
rmse = np.sqrt(-negative_mse)
print(rmse)

54767.960710084146

print(rnd_search.best_params_)

{
    
    'C': 157055.10989448498, 'gamma': 0.26497040005002437, 'kernel': 'rbf'}

Se buscó aleatoriamente un conjunto de hiperparámetros óptimos del regresor de la máquina de vectores de soporte y la puntuación final de RMSE fue 54767;

3. Métodos de integración

  • 集成方法, la combinación de los modelos de mejor rendimiento generalmente funciona mejor que un solo modelo (como bosques aleatorios para árboles de decisión), especialmente cuando un solo modelo producirá diferentes tipos de errores;

4. Error de modelo

Ver el nivel de importancia relativa de cada atributo

feature_importances = grid_search.best_estimator_.feature_importances_
print(feature_importances)

array([8.30181927e-02, 7.09849240e-02, 4.24425223e-02, 1.76691115e-02,
       1.61540923e-02, 1.71789859e-02, 1.59395934e-02, 3.39837758e-01,
       6.50843504e-02, 1.04717194e-01, 6.48945156e-02, 1.47186585e-02,
       1.38881431e-01, 6.76526692e-05, 3.02499407e-03, 5.38602332e-03])

extra_attribs = ["rooms_per_hhold", "pop_per_hhold", "bedrooms_per_room"]
cat_encoder = full_pipeline.named_transformers_["cat"]
cat_one_hot_attribs = list(cat_encoder.categories_[0])
attributes = num_attribs + extra_attribs + cat_one_hot_attribs
sorted(zip(feature_importances, attributes), reverse=True)

[(0.3398377582278221, 'median_income'),
 (0.13888143088401578, 'INLAND'),
 (0.10471719429817675, 'pop_per_hhold'),
 (0.0830181926813895, 'longitude'),
 (0.07098492396156919, 'latitude'),
 (0.06508435039879204, 'rooms_per_hhold'),
 (0.06489451561779028, 'bedrooms_per_room'),
 (0.042442522257867, 'housing_median_age'),
 (0.017669111520336293, 'total_rooms'),
 (0.017178985883288055, 'population'),
 (0.016154092256827887, 'total_bedrooms'),
 (0.015939593408818325, 'households'),
 (0.0147186585483286, '<1H OCEAN'),
 (0.005386023320075893, 'NEAR OCEAN'),
 (0.0030249940656810405, 'NEAR BAY'),
 (6.765266922142473e-05, 'ISLAND')]

Puede intentar eliminar algunas funciones menos útiles (en este caso, solo una ocean_proximity es útil, otras se pueden eliminar);

También puede optimizar el modelo agregando características adicionales, eliminando características no informativas y eliminando valores atípicos;

5. Evaluar el sistema en el equipo de prueba

Evaluar el modelo final en el conjunto de prueba

final_model = grid_search.best_estimator_
X_test = strat_test_set.drop("median_house_value", axis=1)
y_test = strat_test_set["median_house_value"].copy()
X_test_prepared = full_pipeline.transform(X_test)
final_predictions = final_model.predict(X_test_prepared)
final_mse = mean_squared_error(y_test, final_predictions)
final_rmse = np.sqrt(final_mse)
print(final_rmse)

47785.02562107877

Calcule los intervalos de confianza del 95% para el error de generalización usando scipy.stats.t.interval()

from scipy import stats

confidence = 0.95
squared_errors = (final_predictions - y_test) ** 2
np.sqrt(stats.t.interval(confidence, len(squared_errors) - 1,
                         loc=squared_errors.mean(),
                         scale=stats.sem(squared_errors)))

array([45805.04012754, 49686.17157851])

Los resultados de la evaluación del conjunto de prueba serán ligeramente peores que el rendimiento del uso anterior de validación cruzada. En este momento, no continúe ajustando los hiperparámetros para intentar que los resultados del conjunto de prueba se vean mejor, ya que estas mejoras no tiene efecto sobre el efecto de generalización sobre el nuevo conjunto de datos es inútil;

El rendimiento final del sistema puede no ser mejor que el del sistema experto (por ejemplo, una caída de alrededor del 20%), pero esto no es necesariamente inútil. Este sistema de aprendizaje automático puede proporcionar información útil y liberar la tarea del sistema experto hasta cierto punto;

Las fortalezas y debilidades del modelo se pueden evaluar con un conjunto de prueba específico (por ejemplo, áreas del interior, áreas cercanas al océano);

7. Despliegue, monitoreo y mantenimiento del sistema

1. Despliegue

Exponer servicios a través de REST API

Por favor agregue una descripción de la imagen

  • Serialice y guarde el modelo de Scikit-Learn entrenado a través de joblib, que incluye una canalización completa de preprocesamiento y predicción;
  • Cargue este modelo a través del servicio web en el entorno de producción y abra la interfaz para llamar a la función de predicción del modelo;
  • Puede interactuar con él a través de una aplicación web frente al servicio modelo, proporcionar nueva entrada de datos y predecir el procesamiento de resultados, y abrir los resultados a usuarios de escritorio y móviles;

Implementar a través de Google Cloud AI Platform

  • Cargue el modelo serializado por joblib en Google CloudStorage (GCS);
  • Crea una nueva versión del modelo en Google Cloud AI Platform y el modelo apunta al archivo del modelo en GCS;
  • Google Cloud AI Platform proporcionará directamente un servicio web simple (similar al servicio modelo anterior);

2. Monitoreo del sistema

  • 监控目标

    • Escriba un código de monitoreo para verificar regularmente el rendimiento en tiempo real del sistema y active una alarma cuando el rendimiento del sistema se degrade;
  • 监控方向

    • Los componentes dañados en la infraestructura pueden degradar el rendimiento del motor;
    • Ligeras caídas en el rendimiento pueden pasar desapercibidas durante largos períodos de tiempo;
    • El mundo exterior está cambiando, y es posible que el modelo que se puede entrenar ya no se adapte a los nuevos datos de entrada después de un período de tiempo;
  • 评估方式

    • Los indicadores de rendimiento del modelo se pueden inferir del downstream (como el peso del sistema de recomendación, el número de pedidos generados por recomendación y no recomendación, que refleja el rendimiento del sistema de recomendación);
    • Deje que el análisis humano intervenga en la evaluación del rendimiento del sistema (como la introducción de expertos, no expertos y trabajadores en plataformas de crowdsourcing para marcar datos, y el código de verificación de Google tiene la función de marcar datos de entrenamiento);
    • La calidad de los datos de entrada del modelo de monitoreo (como comparar el valor promedio y la desviación estándar de los datos de entrada con el conjunto de entrenamiento, o la aparición de nuevas categorías de características de clasificación, etc.), puede detectar la causa del rendimiento del sistema degradación por adelantado;

3. Mantenimiento del sistema

La mejor práctica para el mantenimiento del sistema es automatizar todo el proceso;

Qué hacer para el mantenimiento del sistema

  • Recopile regularmente nuevos datos y etiquételos (manualmente si es necesario);
  • Escriba un script para entrenar el modelo regularmente y ajuste automáticamente los hiperparámetros (deje que el script se ejecute regularmente según la demanda);
  • Escriba un script para evaluar el modelo nuevo y el modelo anterior en el conjunto de prueba actualizado, compare el rendimiento de los dos para decidir si reemplazarlo en el entorno de producción;
  • Conservar todas las versiones del modelo para una reversión rápida; conservar cada versión del conjunto de datos para revertir (cuando se destruye el nuevo conjunto de datos, como al agregar valores atípicos) y otras evaluaciones del modelo;

El aprendizaje automático implica una gran cantidad de trabajo de infraestructura. Es normal que el primer proyecto de aprendizaje automático dedique mucha energía y tiempo a construir e implementar estos componentes. Una vez que se completen estos procesos, será fácil lanzar e iterar servicios modelo en el materia futura;

Se recomienda que los lectores elijan un buen objetivo de un sitio web de competencia como Kaggle y luego ejecuten todo el proceso;

8. Fuentes de datos disponibles


PD: Bienvenidos amigos de todos los ámbitos de la vida 阅读, ¡ 评论gracias 点赞amigos 关注!收藏


Referencias:

  • [1] "Aprendizaje automático"
  • [2] "Aprendizaje automático en la práctica"

Supongo que te gusta

Origin blog.csdn.net/ChaoMing_H/article/details/129413048
Recomendado
Clasificación