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, NaN
la 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)
SaleID
es el ID de la transacción, regDate
y ya hemos construido creatDate
las 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_time
type
A continuación, verifiquemos qué columnas tienen valores faltantes y cuántas faltan:
print(data_all.isnull().sum()) #检查每一列有多少缺失值
Los resultados impresos son los siguientes:
Buenos chicos, de este resultado podemos ver que model
solo falta un valor en la columna, y hay muchos valores faltantes en estas columnas, , , , que son bodyType
decenas de miles .fuelType
gearbox
notRepairedDamage
price
used_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 bodyType
varios 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 bodyType
los 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()==True
La forma de escribir es seleccionar las filas que no están vacías, isnull()==True
es 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 True
suma .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 bodyType
el 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 bodyType
las 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 bodyType
características necesarias para la predicción.
De la misma manera, fuelType
el gearbox
preprocesamiento 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_time
el 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_time
realizan 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 sklearn
herramientas 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.XGBRegressor
se xgboost
importa 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 XGBRegressor
objeto 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?