<jupyter_start><jupyter_text>ModellingThis notebook exists in script format as well, ``modelling/train_model.py``. This notebook is for illustration in an interactive way.  Loading DataProcessed Disruption Data: This is the disruption data joined with RSSI data to get location information.RSSI Combined data: This is the processed rssi data averaged over a day and Position of the train.<jupyter_code>disruption_df = pd.read_csv(
        DataProcessor.gen_proc_file_name("disruption.csv"),
        infer_datetime_format=True,
        parse_dates=True,
    )
    # ideally this should be from a database, as loading entirety of this data is super slow.
print("Following step takes a lot of time, around 30-35 min, go get a coffee!")
print("14 models into the future are trained")
print("Collecting RSSI historical Data")
rssi_comb_df = DataProcessor.combine_events(save=False)
print("Data collection Done!")<jupyter_output>Following step takes a lot of time, around 30-35 min, go get a coffee!
14 models into the future are trained
Collecting RSSI historical Data<jupyter_text>Data preperation for training and evaluationThe disruptions from disruption_df are used to look for the instances in rssi_comb where the information for signal values are observed `h` days in the past. These values are saved and used to train for the disruptions.(date, PositionNoLeap) -> DataGenerator -> historical values of signals  Data generation for trainingFor a position the signal values in neighbourhood of 20m are combined to remove effects of noise in the measurement. **Samples for disruption:**If the event happens `today` and we want to train a model that predicts disruption 7 days into future then we would train the model from a window of [`today`-7-h, `today`-7] with training label of `disruption`.**Normal samples:**Since we also need to train the model with normal behaviour of the signal, we also sample random windows from the data and label them as `NO disruption`.During training we sample equal proportion of disruptive and non disruptive samples. Feature EngineeringWe investigated the A2_rssi (averaged over a day and positional window = +- 20 m). Then we calculated mean and standard deviation of this value for the chosen historical window. The reason for this choice was on assumption that at a location the RSSI value follows a normal distrbution with a fixed mean and standard deviation.We calculated similar values for quality of signal 1 and signal 2 which are proportion of valid telegram received.We also used the position as one of the feature as well because each position can have a different characteristics.<jupyter_code>train_disruptions_df, test_disruptions_df = train_test_split(
        disruption_df, test_size=0.2
    )
features = ["A2_RSSI"]
train_disruptions_df, test_disruptions_df = train_test_split(
    disruption_df, test_size=0.2
)<jupyter_output><empty_output><jupyter_text>Model approachWe explored linear ridge classification for predicting disruption for its simplicity and GradientBoosting models for their fast inference and superior performance. In our experiments GradientBoosting performed better than a linear model.   The best feature with most predictive power was the mean and standard deviation of A2_RSSI , other feature did not improve the validation performance.  We train 7 models for predicting disruption into the future, one model for each day into the future starting from 2.<jupyter_code>models = []
scores = []
# in training script the future horizon is 1 to 13 days.
for d in range(3,4):
    train_data = DataGenerator(train_disruptions_df, rssi_comb_df, features)
    train_x, train_y = train_data.generate_samples(
        num_samples=300, prediction_days=d, history=20
    )
    test_data = DataGenerator(test_disruptions_df, rssi_comb_df, features)
    test_x, test_y = test_data.generate_samples(
        num_samples=50, prediction_days=d, history=20
    )
    model = lgb.LGBMClassifier()
    model.fit(X=train_x, y=train_y)
    print(
        f"Train accuracy score for {d} days into future  {model.score(train_x,train_y)}"
    )
    print(
        f"Test accuracy score for {d} days into future {model.score(test_x,test_y)}"
    )
    scores.append([model.score(test_x, test_y), model.score(train_x, train_y)])
    
    ## optionally one can save the model as here
#     model.booster_.save_model(
#         os.path.join(PATHS.data, "model", f"lgb_model_d{d}.txt")
#     )
    models.append(model)

print(scores)<jupyter_output>/home/aneesh/Documents/HackZurich2021/team_repo/HackZurich2021/data_processing/src/feature_extractor.py:14: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self.disruptions_df["Date"] = pd.to_datetime(disruptions_df["DateTime"]).dt.date
100%|██████████| 150/150 [01:07<00:00,  2.21it/s]
100%|██████████| 150/150 [00:59<00:00,  2.54it/s]
100%|██████████| 25/25 [00:10<00:00,  2.37it/s]
100%|██████████| 25/25 [00:10<00:00,  2.32it/s]
{'fraction_non_alphanumeric': 0.0808667053588702, 'fraction_numerical': 0.025149932288643838, 'mean_word_length': 4.855039637599094, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 13, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '138946', 'license': 'MIT', 'n_tokens_mistral': 1638, 'n_tokens_neox': 1492, 'n_words': 577, 'path': 'modelling/notebook/Modelling.ipynb', 'repo_name': 'BarrySunderland/HackZurich2021', 'size': '5169'}