{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":90765,"databundleVersionId":10583383,"sourceType":"competition"}],"dockerImageVersionId":31012,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.base import BaseEstimator, TransformerMixin, ClassifierMixin\nfrom sklearn.pipeline import Pipeline\nfrom sklearn.preprocessing import MinMaxScaler\nfrom sklearn.model_selection import KFold\nimport lightgbm as lgb\nfrom sklearn.metrics import precision_score, recall_score, f1_score\nfrom sklearn.ensemble import VotingRegressor\nfrom sklearnex import patch_sklearn\nfrom joblib import Parallel, delayed\nimport os, warnings, tqdm\n\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\npd.set_option('display.max_rows', 500)\npd.set_option('display.max_columns', 500)\npd.set_option('display.width', 1000)\nwarnings.filterwarnings('ignore')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:39:47.828639Z","iopub.execute_input":"2025-05-09T17:39:47.828970Z","iopub.status.idle":"2025-05-09T17:39:57.864466Z","shell.execute_reply.started":"2025-05-09T17:39:47.828945Z","shell.execute_reply":"2025-05-09T17:39:57.863418Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/directional-forecasting-cryptocurrencies/train.csv')\ntest = pd.read_csv('/kaggle/input/directional-forecasting-cryptocurrencies/test.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:39:57.866168Z","iopub.execute_input":"2025-05-09T17:39:57.866814Z","iopub.status.idle":"2025-05-09T17:40:05.920297Z","shell.execute_reply.started":"2025-05-09T17:39:57.866785Z","shell.execute_reply":"2025-05-09T17:40:05.918911Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Data Profile","metadata":{}},{"cell_type":"code","source":"train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:05.921477Z","iopub.execute_input":"2025-05-09T17:40:05.922213Z","iopub.status.idle":"2025-05-09T17:40:05.958949Z","shell.execute_reply.started":"2025-05-09T17:40:05.922179Z","shell.execute_reply":"2025-05-09T17:40:05.958006Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Check for mission values","metadata":{}},{"cell_type":"code","source":"train.isna().any()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:05.961069Z","iopub.execute_input":"2025-05-09T17:40:05.961355Z","iopub.status.idle":"2025-05-09T17:40:06.042363Z","shell.execute_reply.started":"2025-05-09T17:40:05.961333Z","shell.execute_reply":"2025-05-09T17:40:06.027165Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test.isna().any()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:06.043544Z","iopub.execute_input":"2025-05-09T17:40:06.044285Z","iopub.status.idle":"2025-05-09T17:40:06.076128Z","shell.execute_reply.started":"2025-05-09T17:40:06.044238Z","shell.execute_reply":"2025-05-09T17:40:06.074822Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.nunique()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:06.077320Z","iopub.execute_input":"2025-05-09T17:40:06.077989Z","iopub.status.idle":"2025-05-09T17:40:07.997913Z","shell.execute_reply.started":"2025-05-09T17:40:06.077865Z","shell.execute_reply":"2025-05-09T17:40:07.996694Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Target distribution","metadata":{}},{"cell_type":"code","source":"train['target'].value_counts().plot(kind='bar')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:07.999042Z","iopub.execute_input":"2025-05-09T17:40:07.999327Z","iopub.status.idle":"2025-05-09T17:40:08.385252Z","shell.execute_reply.started":"2025-05-09T17:40:07.999305Z","shell.execute_reply":"2025-05-09T17:40:08.383991Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Data correlation","metadata":{}},{"cell_type":"code","source":"def plot_correlation(df, cols): #Plot feature correlation\n    fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(12, 8))\n    sns.heatmap(df[cols].corr(), vmin=0, vmax=1, annot=True, cmap='PiYG', ax=ax)\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:08.386216Z","iopub.execute_input":"2025-05-09T17:40:08.386572Z","iopub.status.idle":"2025-05-09T17:40:08.397815Z","shell.execute_reply.started":"2025-05-09T17:40:08.386536Z","shell.execute_reply":"2025-05-09T17:40:08.396127Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_correlation(train, cols=['open', 'high', 'low', 'close', 'volume', 'quote_asset_volume', 'number_of_trades', 'taker_buy_base_volume', \n                              'taker_buy_quote_volume', 'target'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:08.399890Z","iopub.execute_input":"2025-05-09T17:40:08.400284Z","iopub.status.idle":"2025-05-09T17:40:09.781780Z","shell.execute_reply.started":"2025-05-09T17:40:08.400258Z","shell.execute_reply":"2025-05-09T17:40:09.780595Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"From the heatmap we can notice that there is a perfect correlation between open, high, low, close features and also there exists strong correlations between some other features like taker_buy_quote_volume and quote_asset_volume etc.","metadata":{}},{"cell_type":"markdown","source":"## Data distribution","metadata":{}},{"cell_type":"code","source":"def plot_distribution(df, columns):\n    ncols = 4\n    nrows = int(np.ceil(len(columns) / ncols))\n    fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=(14 * ncols, 12 * nrows))\n\n    for ax, col in zip(axes.flat ,columns):\n        ax.hist(df[col], bins=20, label=col)\n        ax.set_title(f\"{col} data distribution\", fontweight='bold', fontsize=34)\n        ax.legend(loc='best', fontsize=12)\n        ax.tick_params(axis='both', which='major', labelsize=34)\n\n    for j in range(len(columns), len(axes.flat)):\n        fig.delaxes(axes.flat[j])\n\n    plt.tight_layout(pad=3.0)\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:09.784723Z","iopub.execute_input":"2025-05-09T17:40:09.785038Z","iopub.status.idle":"2025-05-09T17:40:09.792833Z","shell.execute_reply.started":"2025-05-09T17:40:09.785015Z","shell.execute_reply":"2025-05-09T17:40:09.791682Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_distribution(train, columns=['open', 'high', 'low', 'close', 'volume','quote_asset_volume', \n                                  'number_of_trades','taker_buy_base_volume','taker_buy_quote_volume'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:09.793867Z","iopub.execute_input":"2025-05-09T17:40:09.794290Z","iopub.status.idle":"2025-05-09T17:40:13.562886Z","shell.execute_reply.started":"2025-05-09T17:40:09.794255Z","shell.execute_reply":"2025-05-09T17:40:13.561809Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"Enough of exploratory analysis, let's build our solution. First we build the data pipeline which carries out all the preprocessing and feature transformation steps","metadata":{}},{"cell_type":"code","source":"def split_data(df):\n    train_size = int(len(df) * 0.75)\n    test_size = int(len(df) * 0.2)\n    return df[:train_size], df[train_size:train_size+test_size], df[train_size+test_size:]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:13.564183Z","iopub.execute_input":"2025-05-09T17:40:13.565343Z","iopub.status.idle":"2025-05-09T17:40:13.572524Z","shell.execute_reply.started":"2025-05-09T17:40:13.565125Z","shell.execute_reply":"2025-05-09T17:40:13.571156Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Data Pipeline","metadata":{}},{"cell_type":"markdown","source":"---\n\n### Sliding Window Feature Engineering Pipeline\n\nThe cell below defines a custom transformation pipeline to engineer temporal and rolling window features from the time series data, preparing them as inputs for machine learning models.\n\n#### `TemporalFeatures` Transformer\n\nThe `TemporalFeatures` class extracts time-based features from a timestamped dataset. Specifically:\n\n* It converts UNIX timestamps into human-readable datetime format.\n* It derives two temporal features: the hour and the minute of each timestamp.\n* It calculates the **1-hour price change** (`1_hour_change`) as the difference between the current close price and the open price from 30 minutes earlier.\n* It computes **volatility** (`volatility_change`) as the difference between the maximum high and the current low within a 30-minute rolling window.\n\n#### `RollingHistory` Transformer\n\nThe `RollingHistory` class implements a sliding window mechanism to convert sequences of historical values into fixed-length vectors:\n\n* It takes a user-defined `window` size and list of feature columns (`cols`) to operate on.\n* It uses NumPy's `sliding_window_view` to efficiently construct overlapping sub-sequences (flattened as feature vectors).\n* If `target=True`, it aligns each input window with the corresponding target value at the end of the window.\n* If a test set is provided, it is transformed using the same temporal logic and concatenated with the training set before applying the sliding window transformation.\n\n___","metadata":{}},{"cell_type":"code","source":"class TemporalFeatures(BaseEstimator, TransformerMixin):\n    def __init__(self):\n        pass\n\n    def get_temporal_(self, df):\n        df = df.copy()\n        df['date_time'] = pd.to_datetime(df['timestamp'], unit='s')\n        df = df.set_index('date_time').sort_index(ascending=True)\n        df['hour'] = df.index.hour\n        df['min'] = df.index.minute\n        df['1_hour_change'] = df['close'] - df['open'].shift(freq='30min')\n        df['volatility_change'] = df['high'].rolling('30min', min_periods=30).max() - df['low']\n        return df.dropna()\n        \n    def fit(self, X, y=None):\n        return self\n\n    def transform(self, X):\n        return self.get_temporal_(X)\n\nclass RollingHistory(BaseEstimator, TransformerMixin):\n    def __init__(self, window, cols, test=None):\n        self.cols = cols\n        self.window = window\n        self.test = test\n\n    def rolling_window_(self, data, window, cols, target=True):\n        df = data[cols].values \n        size = df.shape[0] - window + 1\n        emb = df.shape[1]\n        \n        if size <= 0:\n            return np.empty((0, len(cols) * window))\n    \n        inputs = np.lib.stride_tricks.sliding_window_view(df, \n                                                          (window, emb), \n                                                          axis=(0, 1)).reshape(size, window * emb)\n        if target:\n            targets = data['target'].values[window-1:]\n            return inputs, targets\n            \n        return inputs\n    \n    \n    def fit(self, X, y=None):\n        if self.test is not None and not self.test.empty:\n            self.test = TemporalFeatures().fit_transform(self.test)\n        return self\n        \n    def transform(self, X):\n        X_sorted = X.sort_values(by='date_time')  # Sort once globally\n        if self.test is not None:\n            df = pd.concat([X_sorted, self.test], axis=0, join='inner', ignore_index=False)\n            windowed_data = self.rolling_window_(df, self.window, self.cols, target=False)\n            return windowed_data\n            \n        windowed_data, targets = self.rolling_window_(X_sorted, self.window, self.cols, target=True)\n        return windowed_data, targets","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:13.573922Z","iopub.execute_input":"2025-05-09T17:40:13.574391Z","iopub.status.idle":"2025-05-09T17:40:13.601796Z","shell.execute_reply.started":"2025-05-09T17:40:13.574364Z","shell.execute_reply":"2025-05-09T17:40:13.600571Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def make_data_pipeline(columns, window, test=None): #Construct Pipeline\n    pipe =  Pipeline([\n        ('temporal_inputs', TemporalFeatures()),\n        ('sliding_window', RollingHistory(window=window, cols=columns, test=test))\n    ])\n    return pipe","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:13.603116Z","iopub.execute_input":"2025-05-09T17:40:13.603411Z","iopub.status.idle":"2025-05-09T17:40:13.646528Z","shell.execute_reply.started":"2025-05-09T17:40:13.603386Z","shell.execute_reply":"2025-05-09T17:40:13.645290Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Test Pipeline","metadata":{}},{"cell_type":"code","source":"cols = ['open', 'close', 'volume', 'number_of_trades', 'hour', 'min', '1_hour_change', 'volatility_change']\ndata_pipeline = make_data_pipeline(columns=cols, window=5)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:13.648036Z","iopub.execute_input":"2025-05-09T17:40:13.648351Z","iopub.status.idle":"2025-05-09T17:40:13.677044Z","shell.execute_reply.started":"2025-05-09T17:40:13.648328Z","shell.execute_reply":"2025-05-09T17:40:13.676062Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"windowed_data, targets = data_pipeline.fit_transform(train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:13.677953Z","iopub.execute_input":"2025-05-09T17:40:13.678253Z","iopub.status.idle":"2025-05-09T17:40:16.045437Z","shell.execute_reply.started":"2025-05-09T17:40:13.678230Z","shell.execute_reply":"2025-05-09T17:40:16.044495Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Training Pipeline","metadata":{}},{"cell_type":"code","source":"def make_lgb(params): # Construct pipeline\n    pipe = Pipeline([\n        ('scaler', MinMaxScaler(feature_range=(0, 10))),\n        ('model', lgb.LGBMClassifier(**params))\n    ])\n    \n    return pipe","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:16.047151Z","iopub.execute_input":"2025-05-09T17:40:16.047712Z","iopub.status.idle":"2025-05-09T17:40:16.052844Z","shell.execute_reply.started":"2025-05-09T17:40:16.047676Z","shell.execute_reply":"2025-05-09T17:40:16.051669Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"---\n\n### Model Evaluation Function\n\nThe `evaluate_model` function performs cross-validation to assess the performance of the model on time-series data that has been transformed using a sliding window approach. Here's a breakdown of what it does:\n\n1. **Data Preparation**:\n\n   * A data pipeline is created using the specified feature `columns` and `window` size, transforming the raw time-series data into overlapping windowed samples.\n   * The resulting features and labels are concatenated and split into `train_data` and `test_data` using a split_data function.\n\n2. **Cross-Validation Setup**:\n\n   * A K-Fold cross-validation strategy is initialized with parameters such as `n_splits`, `shuffle`, and `random_state`.\n\n3. **Training and Evaluation Loop**:\n\n   * For each fold, the model is trained on a subset of `train_data`.\n   * The model's predictions are evaluated on the fold’s validation set (`X_test`, `y_test`) and also on the separate `test_data`.\n   * The F1 score is computed for both sets and stored for averaging.\n\n4. **Performance Summary**:\n\n   * After all folds are processed, the average F1 scores for the cross-validation and test sets are computed and printed.\n   * The function also prints the number of input features (i.e., the shape of each windowed input).\n\n5. **Output**:\n\n   * Returns two lists: `cv_scores` (F1 scores from each fold) and `test_scores` (F1 scores on the test set for each fold).\n\n---","metadata":{}},{"cell_type":"code","source":"def evaluate_model(train, params, window, cols, n_splits=5, shuffle=True, random_state=11):\n    kfold = KFold(n_splits=n_splits, shuffle=shuffle, random_state=random_state)\n    data_pipeline = make_data_pipeline(columns=cols, window=window)\n    windowed_data, targets = data_pipeline.fit_transform(train)\n    train_data, test_data, _ =  split_data(np.hstack((windowed_data, targets.reshape(-1,1))))\n\n    cv_scores = []\n    test_scores = []\n    for train_index, test_index in tqdm.tqdm(kfold.split(train_data), desc=\"Evaluation model....\"):\n        X_train, X_test, y_train, y_test = train_data[train_index, :-1], train_data[test_index, :-1], train_data[train_index, -1], train_data[test_index, -1]\n        model = make_lgb(params)\n        model.fit(X_train, y_train)\n        \n        preds = model.predict(X_test)\n        test_preds = model.predict(test_data[:, :-1])\n        cv_scores.append(f1_score(y_test, preds))\n        test_scores.append(f1_score(test_data[:, -1], test_preds))\n\n    avg_cv_score = np.mean(cv_scores)\n    avg_test_score = np.mean(test_scores)\n    input_shape = windowed_data.shape[-1]\n    print(f\"(Features: {cols}, Window: {window}) - Validation Score: {avg_test_score:.4f} - CV Score: {avg_cv_score:.4f}\\nInput Shape: {input_shape}\")\n\n    return cv_scores, test_scores","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T17:40:16.053963Z","iopub.execute_input":"2025-05-09T17:40:16.054367Z","iopub.status.idle":"2025-05-09T17:40:16.077083Z","shell.execute_reply.started":"2025-05-09T17:40:16.054336Z","shell.execute_reply":"2025-05-09T17:40:16.075821Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"params = {\"boosting_type\": 'gbdt',\"num_leaves\": 77, \"max_depth\": 7, \"colsample_bytree\": 0.45, \"learning_rate\": 0.45,\n          'min_child_samples': 20,'min_split_gain': 0.45, \"n_estimators\": 200,\"verbose\": -1, \"objective\": \"binary\",\n          'random_state':11}\ncols = ['1_hour_change','volatility_change', 'low', 'close', 'volume', 'quote_asset_volume', 'number_of_trades', \n        'taker_buy_base_volume', 'taker_buy_quote_volume', 'hour', 'min'] #volatility_change\n\ncv_scores, test_scores = evaluate_model(train, params=params, window=18, cols=cols, n_splits=5, shuffle=True, random_state=11)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T18:29:21.443502Z","iopub.execute_input":"2025-05-09T18:29:21.443893Z","iopub.status.idle":"2025-05-09T18:36:15.877184Z","shell.execute_reply.started":"2025-05-09T18:29:21.443869Z","shell.execute_reply":"2025-05-09T18:36:15.875828Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"(Features: ['volatility_change', '1_hour_change', 'low', 'close', 'volume', 'quote_asset_volume', 'number_of_trades', 'taker_buy_base_volume', 'taker_buy_quote_volume', 'hour', 'min'], Window: 18) - Validation Score: 0.4944 - CV Score: 0.4372\nInput Shape: 198","metadata":{}},{"cell_type":"code","source":"def get_temporal_(df):\n    df = df.copy()\n    df['date_time'] = pd.to_datetime(df['timestamp'], unit='s')\n    df = df.set_index('date_time').sort_index(ascending=True)\n    df['hour'] = df.index.hour\n    df['min'] = df.index.minute\n    df['1_hour_change'] = df['close'] - df['open'].shift(freq='30min')\n    df['volatility_change'] = df['high'].rolling('30min', min_periods=30).max() - df['low']\n    return df.dropna()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T20:06:19.690265Z","iopub.execute_input":"2025-05-09T20:06:19.690620Z","iopub.status.idle":"2025-05-09T20:06:19.696584Z","shell.execute_reply.started":"2025-05-09T20:06:19.690576Z","shell.execute_reply":"2025-05-09T20:06:19.695778Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"updated_data = get_temporal_(train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T20:06:20.021167Z","iopub.execute_input":"2025-05-09T20:06:20.021454Z","iopub.status.idle":"2025-05-09T20:06:21.252756Z","shell.execute_reply.started":"2025-05-09T20:06:20.021433Z","shell.execute_reply":"2025-05-09T20:06:21.251887Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_distribution(updated_data, columns=['open', 'high', 'low', 'close', 'volume', 'quote_asset_volume', 'number_of_trades', \n                                         'taker_buy_base_volume', 'taker_buy_quote_volume', 'volatility_change', '1_hour_change'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T20:06:21.254348Z","iopub.execute_input":"2025-05-09T20:06:21.254703Z","iopub.status.idle":"2025-05-09T20:06:25.594940Z","shell.execute_reply.started":"2025-05-09T20:06:21.254672Z","shell.execute_reply":"2025-05-09T20:06:25.593842Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_correlation(updated_data, cols=['open', 'high', 'low', 'close', 'volume', 'quote_asset_volume', 'number_of_trades', \n                                     'taker_buy_base_volume', 'taker_buy_quote_volume', 'hour', 'min', 'volatility_change', \n                                     '1_hour_change','target'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T11:37:32.714393Z","iopub.execute_input":"2025-05-09T11:37:32.714677Z","iopub.status.idle":"2025-05-09T11:37:34.725042Z","shell.execute_reply.started":"2025-05-09T11:37:32.714650Z","shell.execute_reply":"2025-05-09T11:37:34.724230Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def generate_predictions(train, test, params, window, cols, n_splits=5, shuffle=True, random_state=11):\n    kfold = KFold(n_splits=n_splits, shuffle=shuffle, random_state=random_state)\n    train_pipeline = make_data_pipeline(columns=cols, window=window)\n    test_pipeline = make_data_pipeline(columns=cols, window=window, test=test)\n    windowed_data, targets = train_pipeline.fit_transform(train)\n    test_data = test_pipeline.fit_transform(train)[-len(test):]\n    assert len(test) == len(test_data)\n    \n    all_predictions = []\n    for train_index, _ in tqdm.tqdm(kfold.split(windowed_data), desc=\"generating predictions....\"):\n        X_train, y_train = windowed_data[train_index], targets[train_index]\n        model = make_lgb(params)\n        model.fit(X_train, y_train)\n        \n        preds = model.predict(test_data)\n        all_predictions.append(preds)\n    all_predictions = np.array(all_predictions)\n    \n    return (np.mean(all_predictions, axis=0) > 0.5).astype(int)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T19:18:54.503974Z","iopub.execute_input":"2025-05-09T19:18:54.505070Z","iopub.status.idle":"2025-05-09T19:18:54.530323Z","shell.execute_reply.started":"2025-05-09T19:18:54.505023Z","shell.execute_reply":"2025-05-09T19:18:54.528259Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"params = {\"boosting_type\": 'gbdt',\"num_leaves\": 77, \"max_depth\": 7, \"colsample_bytree\": 0.45, \"learning_rate\": 0.45,\n          'min_child_samples': 20,'min_split_gain': 0.45, \"n_estimators\": 200,\"verbose\": -1, \"objective\": \"binary\",\n          'random_state':11}\ncols = ['1_hour_change','volatility_change', 'low', 'close', 'volume', 'quote_asset_volume', 'number_of_trades', \n        'taker_buy_base_volume', 'taker_buy_quote_volume', 'hour', 'min'] #volatility_change\n\npredictions = generate_predictions(train=train, test=test, params=params, window=18, cols=cols, n_splits=5, shuffle=True, random_state=11)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T19:18:58.111365Z","iopub.execute_input":"2025-05-09T19:18:58.112565Z","iopub.status.idle":"2025-05-09T19:28:14.828938Z","shell.execute_reply.started":"2025-05-09T19:18:58.112527Z","shell.execute_reply":"2025-05-09T19:28:14.827549Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame(predictions, columns=['target']).reset_index(names='row_id')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T19:55:22.722158Z","iopub.execute_input":"2025-05-09T19:55:22.722462Z","iopub.status.idle":"2025-05-09T19:55:22.730962Z","shell.execute_reply.started":"2025-05-09T19:55:22.722440Z","shell.execute_reply":"2025-05-09T19:55:22.730176Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-05-09T20:32:21.552371Z","iopub.execute_input":"2025-05-09T20:32:21.552757Z","iopub.status.idle":"2025-05-09T20:32:22.268491Z","shell.execute_reply.started":"2025-05-09T20:32:21.552730Z","shell.execute_reply":"2025-05-09T20:32:22.267653Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}