Análisis completo del código de predicción del precio de transacción de automóviles de segunda mano (3) Ingeniería de funciones y procesamiento de valores faltantes

El camino es largo y lejano, buscaré arriba y abajo.

Ideas de procesamiento de valor faltantes

Repasemos primero el contenido de la Sección 2. En la segunda sección, hablamos sobre la construcción de características: no solo analizamos la correlación entre características, eliminamos características inútiles, sino que también construimos algunas características nuevas. Por ejemplo used_time(duración de uso), brand_and_price_mean(marca y precio), etc.

Cuando construimos una nueva característica, usamos fillna()funciones para completar los valores faltantes en la nueva característica. Pero también debemos tener en cuenta que todavía faltan muchos valores en nuestras columnas de características originales, que deben procesarse. La idea aquí es:

(1) El número que falta es muy pequeño: reemplácelo directamente con la mediana o el promedio.
(2) La cantidad de valores faltantes es grande: utilice un modelo de aprendizaje automático para predecir los valores faltantes.

Además, con respecto a los valores faltantes, también debemos considerar las siguientes cuestiones:
(1) Es posible que falten valores en el conjunto de entrenamiento y en el conjunto de prueba, por lo que debemos completarlos.
(2) Necesitamos usar los valores existentes Valores para predecir valores faltantes. Después de todo, NaNla predicción no se puede utilizar NaN.

En este paso, primero eliminamos algunas columnas que no son relevantes para la predicción:

data_all=data_all.drop(['SaleID','regDate','creatDate','type'],axis=1)

SaleIDes el ID de la transacción, regDatey ya hemos construido creatDatelas nuevas características de y ; es la etiqueta que definimos al principio del código para distinguir el conjunto de entrenamiento del tren y el conjunto de prueba. Definitivamente es inútil para la predicción, así que elimine estos columnas primero.used_timetype

A continuación, verifiquemos qué columnas tienen valores faltantes y cuántas faltan:

print(data_all.isnull().sum())   #检查每一列有多少缺失值

Los resultados impresos son los siguientes:
Insertar descripción de la imagen aquí

Insertar descripción de la imagen aquí
Buenos chicos, de este resultado podemos ver que modelsolo falta un valor en la columna, y hay muchos valores faltantes en estas columnas, , , , que son bodyTypedecenas de miles .fuelTypegearboxnotRepairedDamagepriceused_time

Relleno de muy pocos valores faltantes.

Entonces, para la columna con la menor cantidad de valores faltantes model, la llenamos directamente con la mediana:

data_all['model']=data_all['model'].fillna(data_all['model'].median())

Para bodyTypevarios atributos con una cantidad particularmente grande de valores faltantes, necesitamos usar un modelo de aprendizaje automático para predecir y complementar los valores faltantes, lo que equivale a modelar cada columna que contiene valores faltantes por separado para predecir su ausencia, como construir un modelo de predicción bodyType. , modelo de predicción fuelType...

Gran cantidad de valores faltantes: completar con predicciones del modelo de aprendizaje automático

Primero, preprocesamos bodyTypelos datos necesarios para construir el modelo de predicción (conjunto de entrenamiento de entrenamiento y conjunto de prueba de prueba) y eliminamos columnas que contienen una gran cantidad de valores faltantes. Porque NaN no se puede usar para predecir NaN y NaN no se puede usar en el conjunto de entrenamiento para el entrenamiento. El código de preprocesamiento es el siguiente:

# 处理bodyType
X_bT=data_all.loc[(data_all['bodyType'].notnull()),:]   
#先找出所有bodyType行,按True和False(空和不空)分类
X_bT=X_bT.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)#XbT删去了空值较多的列
ybT_train=data_all.loc[data_all['bodyType'].notnull()==True,'bodyType']   #只选择bodyType不为空的列
XbT_test=data_all.loc[data_all['bodyType'].isnull()==True,:]
XbT_test=XbT_test.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)

En el código anterior:

notnull()==TrueLa forma de escribir es seleccionar las filas que no están vacías, isnull()==Truees seleccionar las filas que están vacías. La razón que mencionamos en la segunda sección es porque notnull()la función suma isnull()devuelve una matriz compuesta por Truesuma .False

X_bT: Es el conjunto de entrenamiento que utilizamos para entrenar el modelo de predicción bodyType. Es decir, utilice varias otras funciones sin valores perdidos para predecir bodyTypeel valor de la columna. Por lo tanto, eliminamos las características que contienen muchos valores faltantes y que también se necesitan con urgencia para predecir en la segunda línea de código.

ybT_train: ¡Por supuesto que es el valor objetivo que queremos predecir! Por supuesto, el valor predicho debe ser un número real y no NaN, por lo que aquí llamamos notnull()a la función para eliminar solo bodyTypelas filas que no contienen valores faltantes en la columna original.

XbT_test: Esto es fácil de entender, es el conjunto de pruebas que procesamos nosotros mismos. Aquí, todos los datos de las filas vacías en bodyType se colocan en XbT_test y drop()se eliminan varias otras columnas faltantes para predecir ['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'], dejando solo las bodyTypecaracterísticas necesarias para la predicción.

De la misma manera, fuelTypeel gearboxpreprocesamiento de datos de varias otras funciones como, etc., también se realiza exactamente de la misma manera. El código es el siguiente:

# 处理fuelType
X_fT=data_all.loc[(data_all['fuelType'].notnull()),:]
X_fT=X_fT.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)
yfT_train=data_all.loc[data_all['fuelType'].notnull()==True,'fuelType']
XfT_test=data_all.loc[data_all['fuelType'].isnull()==True,:]
XfT_test=XfT_test.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)

#处理gearbox
X_gb=data_all.loc[(data_all['gearbox'].notnull()),:]
X_gb=X_gb.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)
ygb_train=data_all.loc[data_all['gearbox'].notnull()==True,'gearbox']
Xgb_test=data_all.loc[data_all['gearbox'].isnull()==True,:]
Xgb_test=Xgb_test.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)

#处理notRepairedDamage
X_nRD=data_all.loc[(data_all['notRepairedDamage'].notnull()),:]
X_nRD=X_nRD.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)
ynRD_train=pd.DataFrame(data_all.loc[data_all['notRepairedDamage'].notnull()==True,'notRepairedDamage']).astype('float64')
XnRD_test=data_all.loc[data_all['notRepairedDamage'].isnull()==True,:]
XnRD_test=XnRD_test.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)

Curiosamente, used_timeel procesamiento de datos de las funciones de tiempo es ligeramente diferente de las funciones anteriores:

#处理used_time
scaler=preprocessing.StandardScaler()
uesed_time=scaler.fit(np.array(data_all['used_time']).reshape(-1, 1))
data_all['used_time']=scaler.fit_transform(np.array(data_all['used_time']).reshape(-1, 1),uesed_time)

X_ut=data_all.loc[(data_all['used_time'].notnull()),:]
X_ut=X_ut.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)
yut_train=data_all.loc[data_all['used_time'].notnull()==True,'used_time']
Xut_test=data_all.loc[data_all['used_time'].isnull()==True,:]
Xut_test=Xut_test.drop(['bodyType','fuelType','gearbox','notRepairedDamage','price','used_time'],axis=1)

En el código anterior, las primeras tres líneas simplemente used_timerealizan una operación de estandarización y normalización en estos datos de tipo de tiempo. para facilitar los cálculos posteriores.

Además, el código usa la función numpy.El reshape()primer parámetro de remodelación es -1, lo que significa que el número de filas es incierto (debido a que el número de columnas es fijo, la computadora misma calcula el número específico de filas). ), y el segundo parámetro es 1, lo que significa que la nueva matriz tiene solo una columna. Así que aquí vamos a convertir los datos de tiempo normalizados en una columna.

scaler.fit()y se utilizan aquí scaler.fit_transform(). Todas son sklearnherramientas estadísticas empaquetadas por la biblioteca. La explicación específica es la siguiente:

fit(): En pocas palabras, se trata de encontrar los atributos inherentes del conjunto de entrenamiento, como la media, la varianza, el valor máximo y el valor mínimo del conjunto de entrenamiento.

transform(): Según el ajuste, realice operaciones como estandarización, reducción de dimensionalidad y normalización (según la herramienta que se utilice, como PCA, StandardScaler, etc.).

fit_transform():fit_transform es una combinación de ajuste y transformación. Primero ajustará los datos para encontrar los indicadores generales de los datos, como la media, la varianza, los valores máximo y mínimo, etc., y luego transformará el conjunto de datos para lograr la estandarización y normalización. de los datos Operación unificada.

transform()La función de ambos fit_transform()es realizar algún procesamiento unificado de los datos (como estandarización ~N(0,1), escalar (mapear) los datos a un intervalo fijo, normalización, regularización, etc.).

Complete los valores faltantes con Xgboost

Después de procesar los datos, ahora, por supuesto, debemos comenzar a construir nuestro modelo de predicción de aprendizaje automático.
Primero definamos una función de predicción, que xgb.XGBRegressorse xgboostimporta de la biblioteca y, como sugiere el nombre, aplica el algoritmo xgb a problemas de regresión. Se puede usar directamente agregando parámetros, ¿no es muy conveniente?
El código de predicción específico es el siguiente:

def RFmodel(X_train,y_train,X_test):
    model_xgb= xgb.XGBRegressor(max_depth=4, colsample_btree=0.1, learning_rate=0.1, n_estimators=32, min_child_weight=2)#模型定义
    model_xgb.fit(X_train,y_train)#拟合
    y_pre=model_xgb.predict(X_test)#预测
    return y_pre

La primera línea de código de la función significa que se declara un XGBRegressorobjeto modelo . La segunda línea es ingresar los datos de entrenamiento que procesamos en el modelo para su ajuste.

De esta manera, el valor de retorno de la función y_pre es nuestro objetivo para completar los valores faltantes.

Predecir valores faltantes para cada característica

Después de definir nuestra función de predicción, podemos predecir los valores faltantes. Los datos ingresados ​​aquí son los datos que acabamos de procesar para cada función. Luego asigne el valor predicho a la posición del valor faltante original en la matriz para completar el suplemento de valores faltantes.

y_pred=RFmodel(X_bT,ybT_train,XbT_test)
data_all.loc[data_all['bodyType'].isnull(),'bodyType']=y_pred

y_pred0=RFmodel(X_fT,yfT_train,XfT_test)
data_all.loc[data_all['fuelType'].isnull(),'fuelType']=y_pred0

y_pred1=RFmodel(X_gb,ygb_train,Xgb_test)
data_all.loc[data_all['gearbox'].isnull(),'gearbox']=y_pred1

y_pred2=RFmodel(X_nRD,ynRD_train,XnRD_test)
data_all.loc[data_all['notRepairedDamage'].isnull(),'notRepairedDamage']=y_pred2

y_pred3=RFmodel(X_ut,yut_train,Xut_test)
data_all.loc[data_all['used_time'].isnull(),'used_time']=y_pred3

La parte de ingeniería de características termina aquí. Para la mayoría de nosotros, principiantes, la implementación del código en esta parte requiere un alto grado de dominio de bibliotecas como pandas y sklearn. Por lo tanto, a menudo hay un fragmento de código que lleva mucho tiempo comprender o no se puede entender. Comprenda los principios operativos detrás de la situación.

La excelente ingeniería de características tiene un muy buen efecto auxiliar en el rendimiento del modelo. Aunque el aprendizaje profundo actual presta más atención a la estructura del modelo, ¿quizás la optimización de la ingeniería de características también tenga un gran potencial en el aprendizaje profundo?

Supongo que te gusta

Origin blog.csdn.net/zoubaihan/article/details/115342851
Recomendado
Clasificación