VovanMC / raifhack_2021_solution

Публичное решение хакатона Raifhack2021

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Решение хакатона Raifhack 2021

Публичное решение хакатона Raifhack2021 от команды Magic City

Скоры:

LB_score: 1.4289593437149333 (25.09.21 21:10:38)

CV_scores:

  1. NN: 1.4365
  2. LGB: 1.6616
  3. XGB: 1.492
  4. Weighted: 1.282784

Краткое описание решения:

  1. Считывание данных
  2. Хот энкодинг категориальных фичей
  3. Применение квантильного преобразования для численных фичей
  4. Применение минмакс преобразования для численных фичей
  5. Обучение моделей: NN, LGB, XGB
  6. Поиск оптимальных весов для модлелей

Метрика

Для LightGBM и XGBoost была использована функция потерь = метрика задачи. Для NN такая метрика не очень хорошо подходит ввиду нулевой производной в некоторых точках графика. Поэтому была реализована собственная функция потерь (очень похожая на метрику задачи) для NN:

def tf_custom_loss(y_true, y_pred):     
    threshold = 0.6     
    error = tf.abs(y_true - y_pred) / y_true
    is_small_error = error <= threshold     
    small_error_loss = tf.square(error / 0.15 - 1)    
    big_error_loss = 9.0 * tf.ones_like(small_error_loss) + tf.abs(error)    
    return tf.where(is_small_error, small_error_loss, big_error_loss)

Loss pic

Структура NN

Model: "model"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
model_realty_input (InputLayer) [(None, 1)]          0                                            
__________________________________________________________________________________________________
model_region_input (InputLayer) [(None, 1)]          0                                            
__________________________________________________________________________________________________
model_city_input (InputLayer)   [(None, 1)]          0                                            
__________________________________________________________________________________________________
embedding (Embedding)           (None, 1, 4)         12          model_realty_input[0][0]         
__________________________________________________________________________________________________
embedding_1 (Embedding)         (None, 1, 32)        1568        model_region_input[0][0]         
__________________________________________________________________________________________________
embedding_2 (Embedding)         (None, 1, 32)        7616        model_city_input[0][0]           
__________________________________________________________________________________________________
model_features_input (InputLaye [(None, 67)]         0                                            
__________________________________________________________________________________________________
flatten (Flatten)               (None, 4)            0           embedding[0][0]                  
__________________________________________________________________________________________________
flatten_1 (Flatten)             (None, 32)           0           embedding_1[0][0]                
__________________________________________________________________________________________________
flatten_2 (Flatten)             (None, 32)           0           embedding_2[0][0]                
__________________________________________________________________________________________________
flatten_3 (Flatten)             (None, 67)           0           model_features_input[0][0]       
__________________________________________________________________________________________________
concatenate (Concatenate)       (None, 135)          0           flatten[0][0]                    
                                                                 flatten_1[0][0]                  
                                                                 flatten_2[0][0]                  
                                                                 flatten_3[0][0]                  
__________________________________________________________________________________________________
dense (Dense)                   (None, 128)          17408       concatenate[0][0]                
__________________________________________________________________________________________________
dense_1 (Dense)                 (None, 64)           8256        dense[0][0]                      
__________________________________________________________________________________________________
dense_2 (Dense)                 (None, 32)           2080        dense_1[0][0]                    
__________________________________________________________________________________________________
model_output (Dense)            (None, 1)            33          dense_2[0][0]                    
==================================================================================================
Total params: 36,973
Trainable params: 36,973
Non-trainable params: 0

Loss pic

Запуск train_predict.py

  1. Установить опцию обучения для NN на GPU.
IS_GPU
  1. Убедиться, что в папке с ноутбуком есть файлы: train.csv, test.csv и test_submission.csv
  2. Вызвать код командой:
python3 train_predict.py

Запуск notebook

Для запуска ноутбука нужно убедиться:

  1. Что в папке с ноутбуком есть файлы: train.csv, test.csv и test_submission.csv
  2. В случае обучения нейронной сети на CPU установить
IS_GPU = False
  1. По необходимости удалить вторую ячейку кода:
IS_GPU = True
IS_COLAB = True
if IS_COLAB:
  from google.colab import drive
  drive.mount('/content/drive')
  
  cur_path = "/content/drive/MyDrive/ML/RAIFDS/train.csv"
  !cp $cur_path .
  cur_path = "/content/drive/MyDrive/ML/RAIFDS/test.csv"
  !cp $cur_path .
  cur_path = "/content/drive/MyDrive/ML/RAIFDS/test_submission.csv"
  !cp $cur_path .

Кросс-валидация

В решении использовалась стандартное разбиение данных на 5 фолдов в случайном порядке. Далее перекретное out-of-fold обучение и предикт.

Идеи по улучшению

  1. Перебор гиппер параметров - параметры вообще не перебирались, скорее всего это может неплохо улучшить предсказания.
  2. С целью улучшения скора можно сдвинуть предсказания, так как у нас несимметричный штраф за отрицательную ошибку и положетльную, что неверно для нейронной сети (она обучалась на симметричной функции потерь ошибки).
  3. Попробовать использовать данные из объявлений, там находится большой кладезь информации, которую к сожалению практически не получилось использовать. Были подходы по извлечению статистик и обучению на данных из объявлений, но к сожалению, к текущему моменту улучшить скор не удалось.
  4. Усложнение структуры сети. Можно попробовать очень многое от банального накидывания слоев/изменения функций активации до решения задачи в контексте временной серии.
  5. Попробовать другую кросс-валидацию, ведь в текущей есть лик данных из будущего.

About

Публичное решение хакатона Raifhack2021


Languages

Language:Jupyter Notebook 88.9%Language:Python 11.1%