atodorov284 commited on
Commit
88b8e22
·
1 Parent(s): 153c799

Add extra scripts. Format code. \n Add .vs to .gitignore

Browse files
.gitignore CHANGED
@@ -1,3 +1,7 @@
 
 
 
 
1
  # Mac OS-specific storage files
2
  .DS_Store
3
 
 
1
+ #
2
+ .vs
3
+ .vscode
4
+
5
  # Mac OS-specific storage files
6
  .DS_Store
7
 
configs/hyperparameter_search_spaces.yaml CHANGED
@@ -1,5 +1,5 @@
1
  decision_tree:
2
- max_depth: [2, 100]
3
  min_samples_split: [2, 20]
4
  min_samples_leaf: [25, 35]
5
  max_leaf_nodes: [20, 60]
 
1
  decision_tree:
2
+ max_depth: [2, 150]
3
  min_samples_split: [2, 20]
4
  min_samples_leaf: [25, 35]
5
  max_leaf_nodes: [20, 60]
extra_scripts/feature_importance.tex ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ \documentclass[border=0.2cm]{standalone}
2
+ \usepackage{pgfplots}
3
+ \pgfplotsset{compat=1.18}
4
+
5
+ % Define custom colors
6
+ \definecolor{customcolor1}{RGB}{58, 164, 250} % Blue for bars
7
+
8
+ \begin{document}
9
+
10
+ \begin{tikzpicture}
11
+
12
+ \begin{axis}[
13
+ xbar, % Horizontal bars
14
+ bar width=9pt, % Narrower bars
15
+ xmin=0,
16
+ xmax=6,
17
+ title={Feature Importance for Predictor Variables},
18
+ xlabel={Mean Absolute SHAP},
19
+ ytick={0,1,...,33},
20
+ yticklabels={
21
+ Temperature (lag=1), O$_3$ (lag=1), PM$_{2.5}$ (lag=1), Humidity (lag=1), Solar Radiation (lag=1), O$_3$ (lag=3), Solar Radiation (lag=2), Solar Radiation (lag=3), NO$_2$ (lag=1), O$_3$ (lag=2),
22
+ Wind Direction (lag=1), Visibility (lag=1), PM$_{10}$ (lag=1), Visibility (lag=3), Precipitation (lag=1), Precipitation (lag=3), Precipitation (lag=2), Temperature (lag=2), NO$_2$ (lag=3), Humidity (lag=3),
23
+ Wind Speed (lag=2), Wind Speed (lag=3), PM$_{2.5}$ (lag=3), Temperature (lag=3), Wind Speed (lag=1), PM$_{2.5}$ (lag=2), Humidity (lag=2), PM$_{10}$ (lag=2), NO$_2$ (lag=2), Visibility (lag=2),
24
+ Wind Direction (lag=3), Wind Direction (lag=2), PM$_{10}$ (lag=3)
25
+ },
26
+ xtick={0,1,2,3,4,5,6}, % Set x ticks
27
+ enlarge y limits=0.05, % Increase space between bars
28
+ y dir=reverse, % Reverse y-direction so labels appear in correct order
29
+ width=16cm,
30
+ height=18cm, % Adjust height for more spacing
31
+ ytick distance=1, % Increase vertical spacing between rows
32
+ ]
33
+
34
+ % Plot the importance values
35
+ \addplot[fill=cyan] coordinates {
36
+ (5.766941,0) (5.63263,1) (3.5815392,2) (3.475367,3) (3.456865,4)
37
+ (2.3959482,5) (1.8265718,6) (1.6795981,7) (1.5732919,8) (1.464834,9)
38
+ (1.2373743,10) (0.8109572,11) (0.60146403,12) (0.5048162,13) (0.49500573,14)
39
+ (0.44572872,15) (0.41351405,16) (0.4023266,17) (0.38021353,18) (0.3769183,19)
40
+ (0.3461746,20) (0.3079201,21) (0.285651,22) (0.28092846,23) (0.23774858,24)
41
+ (0.20836349,25) (0.1959943,26) (0.18470103,27) (0.1738453,28) (0.16350256,29)
42
+ (0.14222378,30) (0.14136884,31) (0.09763571,32)
43
+ };
44
+
45
+ \end{axis}
46
+
47
+ \end{tikzpicture}
48
+
49
+ \end{document}
extra_scripts/shap_values.py CHANGED
@@ -5,57 +5,52 @@ import pandas as pd
5
  import shap
6
  import matplotlib.pyplot as plt
7
  import numpy as np
8
-
9
  if __name__ == "__main__":
10
-
11
  x_test = pd.read_csv("data/processed/x_test.csv", index_col=0)
12
  y_test = pd.read_csv("data/processed/y_test.csv", index_col=0)
13
 
14
  predictor = PredictorModels()
15
-
16
  xgb_model = predictor._xgboost
17
  explainer = shap.TreeExplainer(xgb_model)
18
  shap_values = explainer.shap_values(x_test)
19
-
20
 
21
  # Sum over the output dimension (axis=2) to get overall feature importance
22
  shap_values_sum = shap_values.sum(axis=2)
23
 
24
-
25
  # Compute the mean absolute SHAP values for each feature
26
- shap_importance = pd.DataFrame({
27
- 'feature': x_test.columns,
28
- 'importance': np.abs(shap_values_sum).mean(axis=0)
29
- }).sort_values(by='importance', ascending=False)
30
-
31
- # shap_importance.to_csv("shap_importance.csv", index=False)
32
 
 
33
 
34
  # PLOTTING
35
  plt.figure(figsize=(10, 6))
36
- bars = plt.barh(shap_importance['feature'], shap_importance['importance'], color='skyblue')
 
 
37
 
38
  # Add text labels to the bars
39
  for bar in bars:
40
  plt.text(
41
- bar.get_width(),
42
  bar.get_y() + bar.get_height() / 2,
43
- f'{bar.get_width():.4f}',
44
- va='center'
45
  )
46
 
47
  plt.xlabel("Mean |SHAP value| (Feature Importance)")
48
  plt.ylabel("Feature")
49
  plt.title("Overall Feature Importance based on SHAP values")
50
  plt.gca().invert_yaxis()
51
-
52
  # Save the bar plot to shap_data folder in the data folder
53
  # plt.savefig("shap_data/shap_feature_importance.png", format='png', dpi=300, bbox_inches='tight')
54
 
55
-
56
-
57
  # OTHER PLOTS
58
- '''output_features = ['NO2 - Day 1', 'O3 - Day 1', 'NO2 - Day 2', 'O3 - Day 2', 'NO2 - Day 3', 'O3 - Day 3']
59
 
60
  shap_values = explainer.shap_values(x_test)
61
  n_outputs = shap_values.shape[2]
@@ -72,4 +67,4 @@ if __name__ == "__main__":
72
  plt.savefig(f"shap_summary_plot_{output_features[i].replace(' ', '_').replace('-', '')}.png", format='png', dpi=300, bbox_inches='tight')
73
 
74
  plt.close()
75
- '''
 
5
  import shap
6
  import matplotlib.pyplot as plt
7
  import numpy as np
8
+
9
  if __name__ == "__main__":
 
10
  x_test = pd.read_csv("data/processed/x_test.csv", index_col=0)
11
  y_test = pd.read_csv("data/processed/y_test.csv", index_col=0)
12
 
13
  predictor = PredictorModels()
14
+
15
  xgb_model = predictor._xgboost
16
  explainer = shap.TreeExplainer(xgb_model)
17
  shap_values = explainer.shap_values(x_test)
 
18
 
19
  # Sum over the output dimension (axis=2) to get overall feature importance
20
  shap_values_sum = shap_values.sum(axis=2)
21
 
 
22
  # Compute the mean absolute SHAP values for each feature
23
+ shap_importance = pd.DataFrame(
24
+ {"feature": x_test.columns, "importance": np.abs(shap_values_sum).mean(axis=0)}
25
+ ).sort_values(by="importance", ascending=False)
 
 
 
26
 
27
+ # shap_importance.to_csv("shap_importance.csv", index=False)
28
 
29
  # PLOTTING
30
  plt.figure(figsize=(10, 6))
31
+ bars = plt.barh(
32
+ shap_importance["feature"], shap_importance["importance"], color="skyblue"
33
+ )
34
 
35
  # Add text labels to the bars
36
  for bar in bars:
37
  plt.text(
38
+ bar.get_width(),
39
  bar.get_y() + bar.get_height() / 2,
40
+ f"{bar.get_width():.4f}",
41
+ va="center",
42
  )
43
 
44
  plt.xlabel("Mean |SHAP value| (Feature Importance)")
45
  plt.ylabel("Feature")
46
  plt.title("Overall Feature Importance based on SHAP values")
47
  plt.gca().invert_yaxis()
48
+
49
  # Save the bar plot to shap_data folder in the data folder
50
  # plt.savefig("shap_data/shap_feature_importance.png", format='png', dpi=300, bbox_inches='tight')
51
 
 
 
52
  # OTHER PLOTS
53
+ """output_features = ['NO2 - Day 1', 'O3 - Day 1', 'NO2 - Day 2', 'O3 - Day 2', 'NO2 - Day 3', 'O3 - Day 3']
54
 
55
  shap_values = explainer.shap_values(x_test)
56
  n_outputs = shap_values.shape[2]
 
67
  plt.savefig(f"shap_summary_plot_{output_features[i].replace(' ', '_').replace('-', '')}.png", format='png', dpi=300, bbox_inches='tight')
68
 
69
  plt.close()
70
+ """
extra_scripts/timeseries.tex ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ \documentclass[border=0.2cm]{standalone}
2
+ \usepackage{pgfplots}
3
+ \pgfplotsset{compat=1.18}
4
+
5
+ % Define custom colors
6
+ \definecolor{testcolor}{RGB}{250, 164, 58} % Orange for test
7
+
8
+ \begin{document}
9
+
10
+ \begin{tikzpicture}
11
+
12
+ \begin{axis}[
13
+ xbar stacked, % Stacked bar style
14
+ bar width=12pt,
15
+ xmin=0,
16
+ xmax=2500,
17
+ xlabel={Sample index},
18
+ ytick={0,1,2,3,4},
19
+ title={5-fold Cross-Validation Timeseries Split},
20
+ yticklabels={Split 1, Split 2, Split 3, Split 4, Split 5},
21
+ xtick={0,500,1000,1500,2000,2500}, % Set x ticks at intervals of 500
22
+ enlarge y limits={abs=0.75},
23
+ legend style={at={(0.975,0.25)}, anchor=east, legend columns=1}, % Move legend to the right
24
+ legend cell align={left},
25
+ reverse legend, % Match the order of entries in the legend
26
+ width=14cm,
27
+ height=8cm,
28
+ ]
29
+
30
+ % Orange bars (Train)
31
+ \addplot[fill=cyan] coordinates {(412,0) (820,1) (1228,2) (1636,3) (2044,4)};
32
+
33
+ % Blue bars (Test)
34
+ \addplot[fill=testcolor] coordinates {(408,0) (408,1) (408,2) (408,3) (408,4)};
35
+
36
+ \legend{Training, Validation}
37
+
38
+ \end{axis}
39
+
40
+ \end{tikzpicture}
41
+
42
+ \end{document}
extra_scripts/training_eval.tex ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ \documentclass[border=0.2cm]{standalone}
2
+
3
+ % Bar chart drawing library
4
+ \usepackage{pgfplots}
5
+ \pgfplotsset{compat=1.18}
6
+
7
+ % Define custom colors
8
+ \definecolor{testcolor}{RGB}{250, 164, 58} % Orange for test
9
+
10
+ \begin{document}
11
+
12
+ % RMSE Graph
13
+ \begin{tikzpicture}
14
+ \begin{axis} [
15
+ xbar = .05cm,
16
+ bar width = 12pt, % Keep the original bar width
17
+ xmin = 0,
18
+ xmax = 35,
19
+ at={(0cm,0)},
20
+ enlarge y limits = {abs = .8},
21
+ enlarge x limits = {value = .25, upper},
22
+ title={Mean Squared Error Statistics},
23
+ ytick={0,1,2},
24
+ yticklabels={Decision Tree, Random Forest, XGBoost},
25
+ xlabel={Mean Squared Error (MSE)},
26
+ xmajorgrids, % Add gridlines on x-axis
27
+ grid style={dashed, gray!30},
28
+ legend style={at={(1.05,0.5)},
29
+ anchor=west, legend columns=1}, % Adjusted for single line
30
+ legend cell align={left},
31
+ ]
32
+
33
+ % Train MSE values (colored in cyan)
34
+ \addplot[fill=cyan] coordinates {(35.32,0) (28.60,1) (21.78,2)};
35
+
36
+ % Test MSE values (colored in orange)
37
+ \addplot[fill=testcolor] coordinates {(36.69,0) (31.74,1) (28.70,2)};
38
+
39
+ \addlegendentry{Train} % Single legend entry for Train
40
+ \addlegendentry{Test} % Single legend entry for Test
41
+
42
+ % Add annotations for MSE (Train)
43
+ \node at (axis cs:35.32,0) [yshift=-0.25cm, xshift=0.5cm] {35.32};
44
+ \node at (axis cs:28.60,1) [yshift=-0.25cm, xshift=0.5cm] {28.60};
45
+ \node at (axis cs:21.78,2) [yshift=-0.25cm, xshift=0.5cm] {21.78};
46
+
47
+ % Add annotations for MSE (Test)
48
+ \node at (axis cs:36.69,0) [yshift=0.25cm, xshift=0.5cm] {36.69};
49
+ \node at (axis cs:31.74,1) [yshift=0.25cm, xshift=0.5cm] {31.74};
50
+ \node at (axis cs:28.70,2) [yshift=0.25cm, xshift=0.5cm] {28.70};
51
+
52
+
53
+ \end{axis}
54
+
55
+ \begin{axis} [
56
+ xbar = .05cm,
57
+ bar width = 12pt, % Keep the original bar width
58
+ xmin = 0,
59
+ xmax = 6,
60
+ at={(9cm,0)},
61
+ title={Root Mean Squared Error Statistics},
62
+ enlarge y limits = {abs = .8},
63
+ enlarge x limits = {value = .25, upper},
64
+ yticklabels=\empty,
65
+ xlabel={Root Mean Squared Error (RMSE)},
66
+ xmajorgrids, % Add gridlines on x-axis
67
+ grid style={dashed, gray!30},
68
+ legend style={at={(1.05,0.5)},
69
+ anchor=west, legend columns=1}, % Adjusted for single line
70
+ legend cell align={left},
71
+ ]
72
+
73
+ % Train RMSE values (colored in light blue)
74
+ \addplot[fill=cyan] coordinates {(5.66,0) (5.11,1) (4.40,2)}; % Decision Tree, Random Forest, XGBoost
75
+
76
+ % Test RMSE values (colored in orange)
77
+ \addplot[fill=testcolor] coordinates {(5.76,0) (5.36,1) (5.04,2)}; % Decision Tree, Random Forest, XGBoost
78
+
79
+ % Add annotations for RMSE (Train)
80
+ \node at (axis cs:5.66,0) [yshift=-0.25cm, xshift=0.5cm] {5.66};
81
+ \node at (axis cs:5.31,1) [yshift=-0.25cm, xshift=0.5cm] {5.11};
82
+ \node at (axis cs:5.04,2) [yshift=-0.25cm, xshift=0.5cm] {4.40};
83
+
84
+ % Add annotations for RMSE (Test)
85
+ \node at (axis cs:5.66,0) [yshift=0.25cm, xshift=0.5cm] {5.76};
86
+ \node at (axis cs:5.31,1) [yshift=0.25cm, xshift=0.5cm] {5.36};
87
+ \node at (axis cs:5.04,2) [yshift=0.25cm, xshift=0.5cm] {5.04};
88
+
89
+ \end{axis}
90
+
91
+ \end{tikzpicture}
92
+
93
+ \end{document}
notebooks/n3_model_selection_training.ipynb CHANGED
@@ -151,7 +151,7 @@
151
  },
152
  {
153
  "cell_type": "code",
154
- "execution_count": 11,
155
  "metadata": {},
156
  "outputs": [],
157
  "source": [
@@ -292,9 +292,31 @@
292
  },
293
  {
294
  "cell_type": "code",
295
- "execution_count": 2,
296
  "metadata": {},
297
- "outputs": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  "source": [
299
  "import numpy as np\n",
300
  "import matplotlib.pyplot as plt\n",
@@ -317,6 +339,8 @@
317
  " # Train set (blue)\n",
318
  " ax.scatter(train_index, [n_splits - i - 0.5] * len(train_index), c=[cmap_data(0.8)] * len(train_index), marker='_', lw=10, label='Training set' if i == 0 else \"\")\n",
319
  " # Test set (red)\n",
 
 
320
  " ax.scatter(test_index, [n_splits - i - 0.5] * len(test_index), c=[cmap_data(0.1)] * len(test_index), marker='_', lw=10, label='Testing set' if i == 0 else \"\")\n",
321
  "\n",
322
  " y_ticks = np.arange(n_splits) + 0.5\n",
@@ -339,6 +363,23 @@
339
  "plot_cv_indices(cv, X, n_splits)\n"
340
  ]
341
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
  {
343
  "cell_type": "code",
344
  "execution_count": 3,
 
151
  },
152
  {
153
  "cell_type": "code",
154
+ "execution_count": 1,
155
  "metadata": {},
156
  "outputs": [],
157
  "source": [
 
292
  },
293
  {
294
  "cell_type": "code",
295
+ "execution_count": 4,
296
  "metadata": {},
297
+ "outputs": [
298
+ {
299
+ "name": "stdout",
300
+ "output_type": "stream",
301
+ "text": [
302
+ "412\n",
303
+ "820\n",
304
+ "1228\n",
305
+ "1636\n",
306
+ "2044\n"
307
+ ]
308
+ },
309
+ {
310
+ "data": {
311
+ "image/png": "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+cnDw0N33nmn1q1bZ9NvSEiIzdVWi8WiBQsWqE+fPnJ3d1f9+vX16aefWreb81NiYqJ8fHz01VdfqXHjxvLw8FB0dLRNqL906ZKefvpp+fj46I477tDzzz+voUOHqnfv3lc9399++009e/aUr6+vqlatqqZNm+qLL76wbt+1a5e6d+8uDw8P+fn56bHHHrPOJR82bJi+/vprvf7667JYLLJYLDp8+PCNf/Ovw64h+dSpUxo7dqyCgoLk4uIif39/RUVFadOmTTfcp/nPBZcHuThSUlLUpk0bubi4qF69ekpMTLzhOgAAAErDCy+8oJkzZ2rPnj1q0aKFcnJydP/99ys5OVnbt29XdHS0evbsqSNHjlyzn/j4ePXv3187d+7U/fffr8GDB+vMmTNXbZ+bm6tXXnlFS5Ys0caNG3XkyBFNmjTJun3WrFlKSkrSwoULtWnTJmVnZ2v16tXXrGHcuHHKy8vTxo0b9dNPP2nWrFnWq+WZmZm655571Lp1a23dulVffvmlTpw4of79+0uSXn/9dYWHh2vUqFFKT09Xenq6AgMDi/ldLDm7Trfo27ev8vPztWjRIoWFhenEiRNKTk5WRkbGDfd5o38uOHTokHr06KExY8YoKSlJycnJGjlypAICAhQVFXXD9QAAANyMl156SZGRkdblatWqqWXLltbl6dOna9WqVfr00081fvz4q/YzbNgwDRo0SJL08ssv64033tD333+v6OjoIttfvHhR77zzjurWrStJGj9+vF566SXr9nnz5ikmJkZ9+vSRJM2fP9/mqnBRjhw5or59+6p58+aSpLCwMOu2+fPnq3Xr1nr55Zet6z744AMFBgbql19+UYMGDeTs7Cx3d/dymRpityvJmZmZSk1N1axZs9S1a1cFBwerffv2iomJ0YMPPmhtZ7FY9Pbbb6t79+5yc3NTWFiYVq5cedV+//zngpSUFA0fPlxZWVnWy/JXm/z+zjvvKDQ0VK+++qoaN26s8ePH6+GHH9acOXNK+9QBAACKrV27djbLOTk5mjRpkho3biwfHx95eHhoz549172S3KJFC+vXVatWlZeXl06ePHnV9u7u7taALEkBAQHW9llZWTpx4oTat29v3e7g4KC2bdtes4ann35af/vb39SxY0fFxcVp586d1m07duzQhg0b5OHhYf00atRIknTw4MFr9lsW7BaS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IfL19dXTTz+tgoIC634hISGaPn26Bg0apKpVq6p27dp68803r1nz0aNH1b9/f/n4+KhatWrq1auXDh8+fNX25ukWl2v96quv1LhxY3l4eCg6Olrp6enWfQoKCvTcc8/Jx8dHd9xxh6ZMmSLDMGz6LSws1IwZMxQaGio3Nze1bNlSK1eulCQZhqFu3bopKirKut+ZM2dUp04dvfjii9ceFAC4DkIyAJQxDw8PeXh4aPXq1crLy7tquypVquiNN97Q7t27tWjRIq1fv15TpkyxaZObm6s33nhDy5cv15dffqmUlBT16dNHX3zxhb744gstWbJE7777rjVIXjZ79my1bNlS27dv1wsvvKBnnnlGa9euLbKOixcvKioqSp6enkpNTdWmTZusITc/P7/Y552bm6tXXnlFS5Ys0caNG3XkyBFNmjTJuv3VV19VYmKiPvjgA33zzTc6c+aMVq1aZdPHjBkztHjxYr3zzjvavXu3nn32WT366KP6+uuvZbFYtGjRIv3www964403JEljxoxR7dq1CckAbp4BAChzK1euNHx9fQ1XV1cjIiLCiImJMXbs2HHNfVasWGHccccd1uWFCxcakowDBw5Y140ePdpwd3c3zp07Z10XFRVljB492rocHBxsREdH2/Q9YMAAo3v37tZlScaqVasMwzCMJUuWGA0bNjQKCwut2/Py8gw3Nzfjq6++KrLWDRs2GJKMs2fPXrXWN9980/Dz87MuBwQEGAkJCdblixcvGnXq1DF69eplGIZhXLhwwXB3dze+/fZbm2M9/vjjxqBBg6zLH330keHq6mq88MILRtWqVY1ffvmlyBoBoCS4kgwA5aBv3746duyYPv30U0VHRyslJUVt2rRRYmKitc26det07733qnbt2vL09NRjjz2mjIwM5ebmWtu4u7urbt261mU/Pz+FhITIw8PDZt3Jkydtjh8eHn7F8p49e4qsdceOHTpw4IA8PT2tV8GrVaumCxcu6ODBg8U+Z3OtAQEB1rqysrKUnp6uDh06WLc7OjqqXbt21uUDBw4oNzdXkZGR1jo8PDy0ePFimzr69eunPn36aObMmXrllVdUv379YtcIAFfDjXsAUE5cXV0VGRmpyMhIxcbGauTIkYqLi9OwYcN0+PBhPfDAAxo7dqz+/ve/q1q1avrmm2/0+OOPKz8/X+7u7pIkJycnmz4tFkuR6woLC2+4zpycHLVt21ZJSUlXbKtRo0ax+ymqLsM05/h6dUjS559/rtq1a9tsc3FxsX6dm5urbdu2ycHBQfv37y92/wBwLYRkALCTJk2aWJ9NvG3bNhUWFurVV19VlSp//JHvo48+KrVjbdmy5Yrlxo0bF9m2TZs2+vDDD1WzZk15eXmVWg1/5u3trYCAAH333Xfq0qWLJOnSpUvatm2b2rRpI+mP74+Li4uOHDmiu+6666p9TZw4UVWqVNGaNWt0//33q0ePHrrnnnvKpG4Atw9CMgCUsYyMDPXr108jRoxQixYt5Onpqa1btyohIUG9evWSJNWrV08XL17UvHnz1LNnT23atEnvvPNOqdWwadMmJSQkqHfv3lq7dq1WrFihzz//vMi2gwcP1uzZs9WrVy+99NJLqlOnjn777Td9/PHHmjJliurUqVMqNT3zzDOaOXOm6tevr0aNGum1116zeRmJp6enJk2apGeffVaFhYXq1KmTsrKytGnTJnl5eWno0KH6/PPP9cEHH2jz5s1q06aNJk+erKFDh2rnzp3y9fUtlToB3J6YkwwAZczDw0MdOnTQnDlz1KVLFzVr1kyxsbEaNWqU5s+fL0lq2bKlXnvtNc2aNUvNmjVTUlKSZsyYUWo1TJw4UVu3blXr1q31t7/9Ta+99pqioqKKbOvu7q6NGzcqKChIDz30kBo3bqzHH39cFy5cKNUryxMnTtRjjz2moUOHKjw8XJ6enurTp49Nm+nTpys2NlYzZsxQ48aNFR0drc8//1yhoaE6deqUHn/8cU2bNs169Tk+Pl5+fn4aM2ZMqdUJ4PZkMUoyQQwAcMsJCQnRhAkTNGHCBHuXAgC3DK4kAwAAACaEZAAAAMCE6RYAAACACVeSAQAAABNCMgAAAGBCSAYAAABMCMkAAACACSEZAAAAMCEkAwAAACaEZAAAAMCEkAwAAACY/H8xpKNoFW9jrwAAAABJRU5ErkJggg==",
312
+ "text/plain": [
313
+ "<Figure size 800x600 with 1 Axes>"
314
+ ]
315
+ },
316
+ "metadata": {},
317
+ "output_type": "display_data"
318
+ }
319
+ ],
320
  "source": [
321
  "import numpy as np\n",
322
  "import matplotlib.pyplot as plt\n",
 
339
  " # Train set (blue)\n",
340
  " ax.scatter(train_index, [n_splits - i - 0.5] * len(train_index), c=[cmap_data(0.8)] * len(train_index), marker='_', lw=10, label='Training set' if i == 0 else \"\")\n",
341
  " # Test set (red)\n",
342
+ " print(len(train_index))\n",
343
+ " print(len(test_index))\n",
344
  " ax.scatter(test_index, [n_splits - i - 0.5] * len(test_index), c=[cmap_data(0.1)] * len(test_index), marker='_', lw=10, label='Testing set' if i == 0 else \"\")\n",
345
  "\n",
346
  " y_ticks = np.arange(n_splits) + 0.5\n",
 
363
  "plot_cv_indices(cv, X, n_splits)\n"
364
  ]
365
  },
366
+ {
367
+ "cell_type": "code",
368
+ "execution_count": 3,
369
+ "metadata": {},
370
+ "outputs": [
371
+ {
372
+ "name": "stdout",
373
+ "output_type": "stream",
374
+ "text": [
375
+ "(2452, 33)\n"
376
+ ]
377
+ }
378
+ ],
379
+ "source": [
380
+ "print(x_train.shape)"
381
+ ]
382
+ },
383
  {
384
  "cell_type": "code",
385
  "execution_count": 3,