Concursos CatBoost y ML

Análisis de datos y modelo base





Introducción

Este artículo se basa en datos de un concurso que Driven Data publicó para abordar los problemas de las fuentes de agua en Tanzania. 





La información para el concurso fue obtenida por el Ministerio de Recursos Hídricos de Tanzania utilizando una plataforma de código abierto llamada Taarifa. Tanzania es el país más grande de África Oriental con una población de alrededor de 60 millones. La mitad de la población no tiene acceso a agua potable y 2/3 de la población sufre de saneamiento deficiente. En los hogares pobres, las familias a menudo tienen que pasar horas a pie para obtener agua de las bombas de agua. 





Se están proporcionando miles de millones de dólares en ayuda exterior para abordar el problema del agua dulce en Tanzania. Sin embargo, el gobierno de Tanzania no ha podido resolver este problema hasta el día de hoy. Una parte importante de las bombas de agua están completamente averiadas o prácticamente no funcionan, y el resto requiere reparaciones importantes. El Ministerio de Recursos Hídricos de Tanzania estuvo de acuerdo con Taarifa y lanzaron un concurso con la esperanza de obtener sugerencias de la comunidad sobre cómo realizar sus tareas.





Datos

Hay muchas características (características) asociadas con las bombas de agua en los datos, hay información relacionada con las ubicaciones geográficas de los puntos con agua, las organizaciones que las construyeron y administran, así como algunos datos sobre las regiones, los territorios del gobierno local. También hay información sobre los tipos y la cantidad de pagos. 





Los puntos de suministro de agua se dividen en útiles , no funcionales y útiles, pero necesitan reparación . El objetivo del concurso es construir un modelo que prediga la funcionalidad de los puntos de suministro de agua.

Los datos contienen 59 400 filas y 40 columnas. La etiqueta de destino está contenida en un archivo separado.

La métrica utilizada para esta competencia es la tasa de clasificación , que calcula el porcentaje de filas donde la clase predicha coincide con la clase real en el conjunto de prueba. El valor máximo es 1 y el mínimo es 0. El objetivo es maximizar la tasa de clasificación .





Análisis de los datos

Descripciones de campos en la tabla de datos:





  • amount_tsh - altura estática total (cantidad de agua disponible para el punto de suministro de agua)





  • date_recorded — 





  • funder — 





  • gps_height — 





  • installer — 





  • longitude — GPS ()





  • latitude — GPS ()





  • wpt_name — ,





  • num_private — 





  • basin — 





  • subvillage — 





  • region — 





  • region_code —  ()





  • district_code — () 





  • lga — 





  • ward —





  • population — 





  • public_meeting — /





  • recorded_by —





  • scheme_management — 





  • scheme_name — 





  • permit — 





  • construction_year — 





  • extraction_type — 





  • extraction_type_group — 





  • extraction_type_class — 





  • management — 





  • management_group — 





  • payment — 





  • payment_type — 





  • water_quality — 





  • quality_group — 





  • quantity — 





  • quantity_group — 





  • source — 





  • source_type — 





  • source_class — 





  • waterpoint_type — 





  • waterpoint_type_group — 





    ,  —  :





    , . :





    • (under-sampling)





    • , (over-sampling)





    •  —  (SMOTE)





    • ,





    .





    , .





    .





    , scheme_name, , .





    / . permit, installer funder.





    .





    , . , (quantity_group).





    , , . . , . , , , .





    ? , quality_group.





    , , . .





    quality_group .





     —  (waterpoint_type_group).





    , other . ? , .





     —  , , , 80- . 





    . , . , 500 .





    Danida —  , , . RWSSP ( ), Dhv . , , , . , , , . , , .





    , , , . , .





     —  . .





    , . , .





     —  .





    , , , , - .





    0 . , amount_tsh (label = 0). amount_tsh. , 500 .





, .





  • installer , . . .





  • , 71 (0,95 ), «other».





  • funder.  — 98.





  • . . , . : scheme_management, quantity_group, water_quality, payment_type, extraction_type, waterpoint_type_group, region_code.





  • latitude longitude region_code.





  • subvillage scheme_name.





  • public_meeting permit .





  • subvillage, public_meeting, scheme_name, permit, , . , , .





  • scheme_management, quantity_group, water_quality, region_code, payment_type, extraction_type, waterpoint_type_group, date_recorded, recorded_by , , .





. , , CatBoost. .





, . .





def fit_model(train_pool, test_pool, **kwargs):
    model = CatBoostClassifier(
        max_ctr_complexity=5,
        task_type='CPU',
        iterations=10000,
        eval_metric='AUC',
        od_type='Iter',
        od_wait=500,
        **kwargs
    )return model.fit(
        train_pool,
        eval_set=test_pool,
        verbose=1000,
        plot=False,
        use_best_model=True)
      
      



AUC, , .





.  — 





def classification_rate(y, y_pred):
    return np.sum(y==y_pred)/len(y)
      
      



,  —  . OOF (Out-of-Fold). ; . , .





def get_oof(n_folds, x_train, y, x_test, cat_features, seeds):    ntrain = x_train.shape[0]
    ntest = x_test.shape[0]  
        
    oof_train = np.zeros((len(seeds), ntrain, 3))
    oof_test = np.zeros((ntest, 3))
    oof_test_skf = np.empty((len(seeds), n_folds, ntest, 3))    test_pool = Pool(data=x_test, cat_features=cat_features) 
    models = {}    for iseed, seed in enumerate(seeds):
        kf = StratifiedKFold(
            n_splits=n_folds,
            shuffle=True,
            random_state=seed)          
        for i, (train_index, test_index) in enumerate(kf.split(x_train, y)):
            print(f'\nSeed {seed}, Fold {i}')
            x_tr = x_train.iloc[train_index, :]
            y_tr = y[train_index]
            x_te = x_train.iloc[test_index, :]
            y_te = y[test_index]
            train_pool = Pool(data=x_tr, label=y_tr, cat_features=cat_features)
            valid_pool = Pool(data=x_te, label=y_te, cat_features=cat_features)model = fit_model(
                train_pool, valid_pool,
                loss_function='MultiClass',
                random_seed=seed
            )
            oof_train[iseed, test_index, :] = model.predict_proba(x_te)
            oof_test_skf[iseed, i, :, :] = model.predict_proba(x_test)
            models[(seed, i)] = modeloof_test[:, :] = oof_test_skf.mean(axis=1).mean(axis=0)
    oof_train = oof_train.mean(axis=0)
    return oof_train, oof_test, models
      
      



,  —  seeds.





Curva de aprendizaje de uno de los pliegues
 

, .





, ().





:





balanced accuracy: 0.6703822994494413
classification rate: 0.8198316498316498
      
      



.





, -5 0,005 , , .





,  —  . , , .





balanced accuracy: 0.6549535670689709
classification rate: 0.8108249158249158
      
      



.





:





  • ;





  • ;





  • CatBoost, ;





  • OOF-;





  • .





El enfoque correcto para preparar datos y elegir las herramientas adecuadas para crear un modelo puede dar excelentes resultados incluso sin la generación de funciones adicionales.





Como tarea para casa, sugiero agregar nuevas características, elegir los parámetros óptimos del modelo, usar otras bibliotecas para aumentar el gradiente y construir conjuntos a partir de los modelos resultantes.





El código del artículo se puede ver aquí .








All Articles