Cidoyi commited on
Commit
49fcd22
·
verified ·
1 Parent(s): 3e5190e

Upload tabicl.ipynb

Browse files
Files changed (1) hide show
  1. tabicl.ipynb +680 -0
tabicl.ipynb ADDED
@@ -0,0 +1,680 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "metadata": {
7
+ "colab": {
8
+ "base_uri": "https://localhost:8080/"
9
+ },
10
+ "collapsed": true,
11
+ "id": "PmRSSg__E-qm",
12
+ "outputId": "2aecdb88-1734-46de-b579-9b169e5163b7"
13
+ },
14
+ "outputs": [
15
+ {
16
+ "output_type": "stream",
17
+ "name": "stdout",
18
+ "text": [
19
+ "\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/103.9 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m103.9/103.9 kB\u001b[0m \u001b[31m5.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
20
+ "\u001b[?25h Preparing metadata (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
21
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m160.4/160.4 kB\u001b[0m \u001b[31m7.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
22
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m95.8/95.8 kB\u001b[0m \u001b[31m10.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
23
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2.3/2.3 MB\u001b[0m \u001b[31m57.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
24
+ "\u001b[?25h Building wheel for liac-arff (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
25
+ "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m471.4/471.4 kB\u001b[0m \u001b[31m10.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
26
+ "\u001b[?25h"
27
+ ]
28
+ }
29
+ ],
30
+ "source": [
31
+ "!pip install -q tabicl\n",
32
+ "!pip install -q openml\n",
33
+ "!pip install -q kaggle\n",
34
+ "!pip install -q skrub -U"
35
+ ]
36
+ },
37
+ {
38
+ "cell_type": "code",
39
+ "execution_count": null,
40
+ "metadata": {
41
+ "colab": {
42
+ "base_uri": "https://localhost:8080/"
43
+ },
44
+ "id": "xTQPIegPezQC",
45
+ "outputId": "3fe90c6b-b82a-468a-a335-587286a93696"
46
+ },
47
+ "outputs": [
48
+ {
49
+ "output_type": "stream",
50
+ "name": "stdout",
51
+ "text": [
52
+ "Mounted at /content/MyDrive\n"
53
+ ]
54
+ }
55
+ ],
56
+ "source": [
57
+ "from google.colab import drive\n",
58
+ "drive.mount('/content/MyDrive')"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "source": [
64
+ "from typing import Optional\n",
65
+ "import os, json\n",
66
+ "import numpy as np\n",
67
+ "import pandas as pd\n",
68
+ "import torch\n",
69
+ "from skrub import TableVectorizer\n",
70
+ "from tabicl import TabICLClassifier\n",
71
+ "from sklearn.impute import SimpleImputer\n",
72
+ "from sklearn.pipeline import make_pipeline\n",
73
+ "from sklearn.preprocessing import OrdinalEncoder\n",
74
+ "from sklearn.metrics import accuracy_score, roc_auc_score"
75
+ ],
76
+ "metadata": {
77
+ "id": "_Ou6aK8ZkReU"
78
+ },
79
+ "execution_count": null,
80
+ "outputs": []
81
+ },
82
+ {
83
+ "cell_type": "markdown",
84
+ "source": [
85
+ "### Custom Softmax"
86
+ ],
87
+ "metadata": {
88
+ "id": "NoR1dLt_kcTM"
89
+ }
90
+ },
91
+ {
92
+ "cell_type": "code",
93
+ "source": [
94
+ "# raw_logits = None\n",
95
+ "# @staticmethod\n",
96
+ "# def hook_softmax(x, axis: int = -1, temperature: float = 0.9):\n",
97
+ "# \"\"\"Compute softmax values with temperature scaling using NumPy.\n",
98
+ "\n",
99
+ "# Parameters\n",
100
+ "# ----------\n",
101
+ "# x : ndarray\n",
102
+ "# Input array of logits.\n",
103
+ "\n",
104
+ "# axis : int, default=-1\n",
105
+ "# Axis along which to compute softmax.\n",
106
+ "\n",
107
+ "# temperature : float, default=0.9\n",
108
+ "# Temperature scaling parameter.\n",
109
+ "\n",
110
+ "# Returns\n",
111
+ "# -------\n",
112
+ "# ndarray\n",
113
+ "# Softmax probabilities along the specified axis, with the same shape as the input.\n",
114
+ "# \"\"\"\n",
115
+ "# global raw_logits\n",
116
+ "# raw_logits = np.copy(x) # save raw logits\n",
117
+ "# x = x / temperature\n",
118
+ "# # Subtract max for numerical stability\n",
119
+ "# x_max = np.max(x, axis=axis, keepdims=True)\n",
120
+ "# e_x = np.exp(x - x_max)\n",
121
+ "# # Compute softmax\n",
122
+ "# return e_x / np.sum(e_x, axis=axis, keepdims=True)\n",
123
+ "\n",
124
+ "# # Replace original softmax with hooked one\n",
125
+ "# TabICLClassifier.softmax = hook_softmax"
126
+ ],
127
+ "metadata": {
128
+ "id": "MnL-8godkV5G"
129
+ },
130
+ "execution_count": null,
131
+ "outputs": []
132
+ },
133
+ {
134
+ "cell_type": "markdown",
135
+ "source": [
136
+ "## Conformal Prediction"
137
+ ],
138
+ "metadata": {
139
+ "id": "wgxFkG3Fj9kD"
140
+ }
141
+ },
142
+ {
143
+ "cell_type": "code",
144
+ "source": [
145
+ "import numpy as np\n",
146
+ "from numpy._typing import NDArray\n",
147
+ "\n",
148
+ "def confidence_score(probs: NDArray):\n",
149
+ " return np.max(-probs, axis=1)\n",
150
+ "\n",
151
+ "def margin_score(probs: NDArray):\n",
152
+ " sorted_probs = np.sort(probs, axis=1)\n",
153
+ " return sorted_probs[:, -2] - sorted_probs[:, -1]\n",
154
+ "\n",
155
+ "def entropy_score(probs: NDArray, eps = 1e-9):\n",
156
+ " return -np.sum(probs * np.log(probs + eps), axis=1)\n",
157
+ "\n",
158
+ "def nnl_score(probs: NDArray, true_labels: NDArray, eps = 1e-9):\n",
159
+ " return -np.log(probs[np.arange(probs.shape[0]), true_labels] + eps)\n",
160
+ "\n",
161
+ "def ri_score(probs: NDArray, eps = 1e-9):\n",
162
+ " return -np.sum(np.log(probs + eps), axis=1)\n",
163
+ "\n",
164
+ "\n",
165
+ "def lac_conformal_score(probs: NDArray, true_labels: NDArray):\n",
166
+ " \"\"\"\n",
167
+ " Compute the LAC conformal score for a batch of softmax score vectors and true labels.\n",
168
+ "\n",
169
+ " Parameters:\n",
170
+ " - probs: 2D numpy array of shape (n_samples, num_classes), softmax probs for each sample\n",
171
+ " - true_labels: 1D numpy array of shape (n_samples,), true class labels for each sample\n",
172
+ "\n",
173
+ " Returns:\n",
174
+ " - conformal_scores: 1D numpy array of shape (n_samples,), LAC conformal probs for each sample\n",
175
+ " \"\"\"\n",
176
+ " conformal_scores = 1 - probs[np.arange(probs.shape[0]), true_labels]\n",
177
+ " return conformal_scores\n",
178
+ "\n",
179
+ "def aps_conformal_score(probs: NDArray, true_labels: NDArray):\n",
180
+ " \"\"\"\n",
181
+ " Compute the APS conformal score for a batch of softmax score vectors and true labels.\n",
182
+ "\n",
183
+ " Parameters:\n",
184
+ " - probs: 2D numpy array of shape (n_samples, num_classes), softmax probs for each sample\n",
185
+ " - true_labels: 1D numpy array of shape (n_samples,), true class labels for each sample\n",
186
+ "\n",
187
+ " Returns:\n",
188
+ " - conformal_scores: 1D numpy array of shape (n_samples,), APS conformal probs for each sample\n",
189
+ " \"\"\"\n",
190
+ " # Create a mask for each sample: probs >= true_score\n",
191
+ " true_scores = probs[np.arange(probs.shape[0]), true_labels]\n",
192
+ " mask = probs >= true_scores[:, np.newaxis]\n",
193
+ " # Sum along the class axis\n",
194
+ " conformal_scores = np.sum(probs * mask, axis=1)\n",
195
+ "\n",
196
+ " return conformal_scores\n",
197
+ "\n",
198
+ "def compute_quantile(probs: NDArray, calibration_labels, n: int, type = \"lac\", alpha = 0.1):\n",
199
+ " if type == \"lac\":\n",
200
+ " scores = lac_conformal_score(probs, calibration_labels)\n",
201
+ " elif type == \"aps\":\n",
202
+ " scores = aps_conformal_score(probs, calibration_labels)\n",
203
+ " else:\n",
204
+ " raise AttributeError(f\"type {type} is not supported. Use 'lac' or 'aps'\")\n",
205
+ "\n",
206
+ " q_level = np.ceil((n + 1) * (1 - alpha)) / n\n",
207
+ " return np.quantile(scores, q_level, method=\"higher\")\n",
208
+ "\n",
209
+ "def lac_prediction_set(calibration_probs: NDArray, probs: NDArray, calibration_labels: NDArray, alpha = 0.1):\n",
210
+ " n = calibration_labels.shape[0]\n",
211
+ " cal_scores = 1 - calibration_probs[np.arange(calibration_probs.shape[0]), calibration_labels]\n",
212
+ " # Get the score quantile\n",
213
+ "\n",
214
+ " q_level = np.ceil((n + 1) * (1 - alpha)) / n\n",
215
+ " qhat = np.quantile(cal_scores, q_level, method='higher')\n",
216
+ "\n",
217
+ " prediction_sets = probs >= (1 - qhat)\n",
218
+ " return prediction_sets\n",
219
+ "\n",
220
+ "def aps_prediction_set(calibration_probs: NDArray, probs: NDArray, calibration_labels: NDArray, alpha = 0.1):\n",
221
+ " # Get scores. calib_X.shape[0] == calib_Y.shape[0] == n\n",
222
+ " n = calibration_labels.shape[0]\n",
223
+ " cal_order = calibration_probs.argsort(1)[:,::-1]\n",
224
+ " # cal_sum = cal_probs[np.arange(n)[:, None], cal_pi].cumsum(axis=1)\n",
225
+ " cal_sum = np.take_along_axis(calibration_probs, cal_order, axis=1).cumsum(axis=1)\n",
226
+ " cal_scores = np.take_along_axis(cal_sum, cal_order.argsort(axis=1), axis=1)[range(n),calibration_labels]\n",
227
+ "\n",
228
+ " # Get the score quantile\n",
229
+ " q_level = np.ceil((n + 1) * (1 - alpha)) / n\n",
230
+ " qhat = np.quantile(cal_scores, q_level, method='higher')\n",
231
+ "\n",
232
+ " # Deploy (output=list of length n, each element is tensor of classes)\n",
233
+ " test_order = probs.argsort(1)[:,::-1]\n",
234
+ " test_sum = np.take_along_axis(probs,test_order,axis=1).cumsum(axis=1)\n",
235
+ " prediction_sets = np.take_along_axis(test_sum <= qhat, test_order.argsort(axis=1), axis=1)\n",
236
+ " return prediction_sets\n",
237
+ "\n",
238
+ "def raps_prediction_set(calibration_probs: NDArray, test_probs: NDArray, calibration_labels: NDArray, alpha = 0.1, lam_reg=0.01, k_reg = 5, disallow_zero_sets = False, rand = True):\n",
239
+ " probs = np.concatenate([calibration_probs, test_probs], axis=0)\n",
240
+ " k_reg = min(k_reg, probs.shape[1] - 1)\n",
241
+ " reg_vec = np.array(k_reg * [0,] + (probs.shape[1] - k_reg) * [lam_reg,])[None, :]\n",
242
+ "\n",
243
+ " n = calibration_labels.shape[0]\n",
244
+ " cal_order = calibration_probs.argsort(axis=1)[:,::-1]\n",
245
+ " cal_sort = np.take_along_axis(calibration_probs, cal_order, axis=1)\n",
246
+ " cal_sort_reg = cal_sort + reg_vec\n",
247
+ " cal_true_labels = np.where(cal_order == calibration_labels[:,None])[1]\n",
248
+ " cal_scores = cal_sort_reg.cumsum(axis=1)[np.arange(n), cal_true_labels] - np.random.rand(n) * cal_sort_reg[np.arange(n), cal_true_labels]\n",
249
+ "\n",
250
+ " # Get the score quantile\n",
251
+ " q_level = np.ceil((n + 1) * (1 - alpha)) / n\n",
252
+ " qhat = np.quantile(cal_scores, q_level, method='higher')\n",
253
+ "\n",
254
+ " n_test = test_probs.shape[0]\n",
255
+ " test_order = test_probs.argsort(1)[:,::-1]\n",
256
+ " test_sort = np.take_along_axis(test_probs, test_order, axis=1)\n",
257
+ " test_sort_reg = test_sort + reg_vec\n",
258
+ " test_srt_reg_cumsum = test_sort_reg.cumsum(axis=1)\n",
259
+ " indicators = (test_srt_reg_cumsum - np.random.rand(n_test, 1) * test_sort_reg) <= qhat if rand else test_srt_reg_cumsum - test_sort_reg <= qhat\n",
260
+ "\n",
261
+ " if disallow_zero_sets: indicators[:,0] = True\n",
262
+ " prediction_sets = np.take_along_axis(indicators, test_order.argsort(axis=1), axis=1)\n",
263
+ " return prediction_sets\n",
264
+ "\n",
265
+ "def accuracy(y_true, y_pred):\n",
266
+ " return np.mean(y_true == y_pred)\n",
267
+ "\n",
268
+ "def set_size(pred_set):\n",
269
+ " return np.mean([np.sum(ps) for ps in pred_set])\n",
270
+ "\n",
271
+ "def coverage_rate(y_true, pred_set):\n",
272
+ " return pred_set[np.arange(pred_set.shape[0]), y_true].mean()"
273
+ ],
274
+ "metadata": {
275
+ "id": "evNphyC0kAJx"
276
+ },
277
+ "execution_count": null,
278
+ "outputs": []
279
+ },
280
+ {
281
+ "cell_type": "markdown",
282
+ "metadata": {
283
+ "id": "C1VFdL01dffC"
284
+ },
285
+ "source": [
286
+ "## Eye Movement"
287
+ ]
288
+ },
289
+ {
290
+ "cell_type": "code",
291
+ "execution_count": null,
292
+ "metadata": {
293
+ "id": "gQYXkdVuFnNX"
294
+ },
295
+ "outputs": [],
296
+ "source": [
297
+ "import numpy as np\n",
298
+ "import torch\n",
299
+ "import openml\n",
300
+ "from tabicl import TabICLClassifier\n",
301
+ "from sklearn.model_selection import train_test_split\n",
302
+ "from sklearn.metrics import accuracy_score, roc_auc_score"
303
+ ]
304
+ },
305
+ {
306
+ "cell_type": "code",
307
+ "execution_count": null,
308
+ "metadata": {
309
+ "id": "F3ZdlqQUFzdV"
310
+ },
311
+ "outputs": [],
312
+ "source": [
313
+ "dataset = openml.datasets.get_dataset(1044) # or 31 or 40688\n",
314
+ "\n",
315
+ "X, y, _, _ = dataset.get_data(\n",
316
+ " dataset_format=\"dataframe\", target=dataset.default_target_attribute)\n",
317
+ "\n",
318
+ "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)"
319
+ ]
320
+ },
321
+ {
322
+ "cell_type": "code",
323
+ "execution_count": null,
324
+ "metadata": {
325
+ "colab": {
326
+ "base_uri": "https://localhost:8080/"
327
+ },
328
+ "id": "yM1CUt2-LahM",
329
+ "outputId": "c5502c00-9642-420e-d558-9e31fea40212"
330
+ },
331
+ "outputs": [
332
+ {
333
+ "name": "stdout",
334
+ "output_type": "stream",
335
+ "text": [
336
+ "Using device: cuda\n"
337
+ ]
338
+ }
339
+ ],
340
+ "source": [
341
+ "device = \"cuda\" if torch.cuda.is_available() else (\n",
342
+ " \"mps\" if getattr(torch.backends, \"mps\", None) and torch.backends.mps.is_available() else \"cpu\"\n",
343
+ ")\n",
344
+ "print(\"Using device:\", device)"
345
+ ]
346
+ },
347
+ {
348
+ "cell_type": "code",
349
+ "execution_count": null,
350
+ "metadata": {
351
+ "id": "gP-R0-oRFPg0"
352
+ },
353
+ "outputs": [],
354
+ "source": [
355
+ "clf = TabICLClassifier(device=device)\n",
356
+ "clf.fit(X_train, y_train) # this is cheap\n",
357
+ "proba = clf.predict_proba(X_test) # in-context learning happens here"
358
+ ]
359
+ },
360
+ {
361
+ "cell_type": "code",
362
+ "execution_count": null,
363
+ "metadata": {
364
+ "colab": {
365
+ "base_uri": "https://localhost:8080/"
366
+ },
367
+ "id": "m4fSOHNOLE3_",
368
+ "outputId": "8925965e-146b-4474-c87f-dcf19579b760"
369
+ },
370
+ "outputs": [
371
+ {
372
+ "name": "stdout",
373
+ "output_type": "stream",
374
+ "text": [
375
+ "ROC AUC: 0.8958693234799394\n",
376
+ "Accuracy: 0.7340036563071298\n"
377
+ ]
378
+ }
379
+ ],
380
+ "source": [
381
+ "print(\"ROC AUC:\", roc_auc_score(y_test.to_numpy(dtype=int), proba, multi_class='ovo'))\n",
382
+ "y = np.argmax(proba, axis=1)\n",
383
+ "y_pred = clf.y_encoder_.inverse_transform(y)\n",
384
+ "print(\"Accuracy:\", accuracy_score(y_test, y_pred))"
385
+ ]
386
+ },
387
+ {
388
+ "cell_type": "markdown",
389
+ "metadata": {
390
+ "id": "gfQvbD9BdqJC"
391
+ },
392
+ "source": [
393
+ "## Rain in Autralia"
394
+ ]
395
+ },
396
+ {
397
+ "cell_type": "code",
398
+ "execution_count": null,
399
+ "metadata": {
400
+ "colab": {
401
+ "base_uri": "https://localhost:8080/",
402
+ "height": 332
403
+ },
404
+ "id": "2us2QwSIdryV",
405
+ "outputId": "ebc49be5-9dbf-4c8b-ed92-ed16194d20e2"
406
+ },
407
+ "outputs": [
408
+ {
409
+ "name": "stdout",
410
+ "output_type": "stream",
411
+ "text": [
412
+ "Using device: cuda\n",
413
+ "C_train: (93094, 6) object\n",
414
+ "X_train: (93094, 18) object\n",
415
+ "X_test : (29092, 18) object\n",
416
+ "y_train: (93094,) int64\n",
417
+ "y_test: (29092,) int64\n",
418
+ "y_test unique: [0 1 2]\n"
419
+ ]
420
+ },
421
+ {
422
+ "ename": "AttributeError",
423
+ "evalue": "'numpy.ndarray' object has no attribute 'to_numpy'",
424
+ "output_type": "error",
425
+ "traceback": [
426
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
427
+ "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
428
+ "\u001b[0;32m/tmp/ipython-input-595776624.py\u001b[0m in \u001b[0;36m<cell line: 0>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 57\u001b[0m \u001b[0mproba\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpipe\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpredict_proba\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX_test\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# in-context learning happens here\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 58\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 59\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"ROC AUC:\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mroc_auc_score\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my_test\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mto_numpy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mint\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mproba\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmulti_class\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'ovo'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 60\u001b[0m \u001b[0my_pred\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mclf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpredict\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mX_test\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 61\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Accuracy:\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maccuracy_score\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0my_test\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_pred\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
429
+ "\u001b[0;31mAttributeError\u001b[0m: 'numpy.ndarray' object has no attribute 'to_numpy'"
430
+ ]
431
+ }
432
+ ],
433
+ "source": [
434
+ "from typing import Optional\n",
435
+ "import os, json\n",
436
+ "import numpy as np\n",
437
+ "import pandas as pd\n",
438
+ "import torch\n",
439
+ "from skrub import TableVectorizer\n",
440
+ "from tabicl import TabICLClassifier\n",
441
+ "from sklearn.impute import SimpleImputer\n",
442
+ "from sklearn.pipeline import make_pipeline\n",
443
+ "from sklearn.preprocessing import OrdinalEncoder\n",
444
+ "from sklearn.metrics import accuracy_score, roc_auc_score\n",
445
+ "\n",
446
+ "DATA_DIR = '/content/MyDrive/MyDrive/Datasets/Rain_in_Australia'\n",
447
+ "\n",
448
+ "device = \"cuda\" if torch.cuda.is_available() else (\n",
449
+ " \"mps\" if getattr(torch.backends, \"mps\", None) and torch.backends.mps.is_available() else \"cpu\"\n",
450
+ ")\n",
451
+ "print(\"Using device:\", device)\n",
452
+ "\n",
453
+ "def load(name) -> Optional[np.ndarray]:\n",
454
+ " p = os.path.join(DATA_DIR, name)\n",
455
+ " return np.load(p, allow_pickle=True) if os.path.exists(p) else None\n",
456
+ "\n",
457
+ "# ---- load arrays ----\n",
458
+ "C_train, N_train, y_train = load('C_train.npy'), load('N_train.npy'), load('y_train.npy')\n",
459
+ "C_val, N_val, y_val = load('C_val.npy'), load('N_val.npy'), load('y_val.npy')\n",
460
+ "C_test, N_test, y_test = load('C_test.npy'), load('N_test.npy'), load('y_test.npy')\n",
461
+ "\n",
462
+ "print(\"C_train:\", C_train.shape, C_train.dtype)\n",
463
+ "# ---- build X by concatenating [C | N] ----\n",
464
+ "def concat_features(C_part, N_part):\n",
465
+ " parts = [p for p in (C_part, N_part) if p is not None]\n",
466
+ " if not parts:\n",
467
+ " raise ValueError(\"No features found (need at least C_* or N_*).\")\n",
468
+ " return np.concatenate(parts, axis=1) if len(parts) > 1 else parts[0]\n",
469
+ "\n",
470
+ "X_train = concat_features(C_train, N_train)\n",
471
+ "X_val = concat_features(C_val, N_val) if (C_val is not None or N_val is not None) else None\n",
472
+ "X_test = concat_features(C_test, N_test)\n",
473
+ "\n",
474
+ "print(\"X_train:\", X_train.shape, X_train.dtype)\n",
475
+ "print(\"X_test :\", X_test.shape, X_test.dtype)\n",
476
+ "print(\"y_train:\", y_train.shape, y_train.dtype)\n",
477
+ "print(\"y_test:\", y_test.shape, y_test.dtype)\n",
478
+ "print(\"y_test unique:\", np.unique(y_test))\n",
479
+ "\n",
480
+ "X_train = pd.DataFrame(X_train)\n",
481
+ "X_test = pd.DataFrame(X_test)\n",
482
+ "\n",
483
+ "pipe = make_pipeline(\n",
484
+ " TableVectorizer(), # Automatically handles various data types\n",
485
+ " TabICLClassifier(device=device)\n",
486
+ ")\n",
487
+ "# pipe = TabICLClassifier(device=device)\n",
488
+ "\n",
489
+ "pipe.fit(X_train, y_train) # this is cheap\n",
490
+ "proba = pipe.predict_proba(X_test) # in-context learning happens here\n",
491
+ "print(\"ROC AUC:\", roc_auc_score(y_test, proba, multi_class='ovo'))\n",
492
+ "y_pred = pipe.predict(X_test)\n",
493
+ "print(\"Accuracy:\", accuracy_score(y_test, y_pred))"
494
+ ]
495
+ },
496
+ {
497
+ "cell_type": "code",
498
+ "execution_count": null,
499
+ "metadata": {
500
+ "colab": {
501
+ "base_uri": "https://localhost:8080/"
502
+ },
503
+ "id": "uWOT-zrmkUir",
504
+ "outputId": "d7efdba9-c5ce-4de8-8b51-ff2d404b1c13"
505
+ },
506
+ "outputs": [
507
+ {
508
+ "name": "stdout",
509
+ "output_type": "stream",
510
+ "text": [
511
+ "ROC AUC: 0.8840392885541616\n",
512
+ "Accuracy: 0.8509212154544205\n"
513
+ ]
514
+ }
515
+ ],
516
+ "source": [
517
+ "print(\"ROC AUC:\", roc_auc_score(y_test, proba, multi_class='ovo'))\n",
518
+ "y = np.argmax(proba, axis=1)\n",
519
+ "y_pred = pipe.y_encoder_.inverse_transform(y)\n",
520
+ "print(\"Accuracy:\", accuracy_score(y_test, y_pred))"
521
+ ]
522
+ },
523
+ {
524
+ "cell_type": "code",
525
+ "execution_count": null,
526
+ "metadata": {
527
+ "id": "yuukqVGooxwJ"
528
+ },
529
+ "outputs": [],
530
+ "source": [
531
+ "print(\"ROC AUC:\", roc_auc_score(y_test, proba, multi_class='ovr'))\n",
532
+ "y = np.argmax(proba, axis=1)\n",
533
+ "y_pred = pipe.y_encoder_.inverse_transform(y)\n",
534
+ "print(\"Accuracy:\", accuracy_score(y_test, y_pred))"
535
+ ]
536
+ },
537
+ {
538
+ "cell_type": "markdown",
539
+ "metadata": {
540
+ "id": "MupH1gZPiPph"
541
+ },
542
+ "source": [
543
+ "## Banknote auth"
544
+ ]
545
+ },
546
+ {
547
+ "cell_type": "code",
548
+ "execution_count": null,
549
+ "metadata": {
550
+ "colab": {
551
+ "base_uri": "https://localhost:8080/"
552
+ },
553
+ "id": "FZmc0osUiPXr",
554
+ "outputId": "ef61624e-08d6-4d6e-f8d7-829c25ef3a7b"
555
+ },
556
+ "outputs": [
557
+ {
558
+ "output_type": "stream",
559
+ "name": "stdout",
560
+ "text": [
561
+ "Using device: cuda\n",
562
+ "X_train: (877, 4) float64\n",
563
+ "X_test : (275, 4) float64\n",
564
+ "y_train: (877,) int64\n",
565
+ "y_test: (275,) int64\n",
566
+ "y_test unique: [0 1]\n"
567
+ ]
568
+ }
569
+ ],
570
+ "source": [
571
+ "DATA_DIR = '/content/MyDrive/MyDrive/Datasets/banknote_authentication'\n",
572
+ "\n",
573
+ "device = \"cuda\" if torch.cuda.is_available() else (\n",
574
+ " \"mps\" if getattr(torch.backends, \"mps\", None) and torch.backends.mps.is_available() else \"cpu\"\n",
575
+ ")\n",
576
+ "print(\"Using device:\", device)\n",
577
+ "\n",
578
+ "def load(name) -> Optional[np.ndarray]:\n",
579
+ " p = os.path.join(DATA_DIR, name)\n",
580
+ " return np.load(p, allow_pickle=True) if os.path.exists(p) else None\n",
581
+ "\n",
582
+ "# ---- load arrays ----\n",
583
+ "N_train, y_train = load('N_train.npy'), load('y_train.npy')\n",
584
+ "N_val, y_val = load('N_val.npy'), load('y_val.npy')\n",
585
+ "N_test, y_test = load('N_test.npy'), load('y_test.npy')\n",
586
+ "\n",
587
+ "X_train = N_train\n",
588
+ "X_val = N_val\n",
589
+ "X_test = N_test\n",
590
+ "\n",
591
+ "print(\"X_train:\", X_train.shape, X_train.dtype)\n",
592
+ "print(\"X_test :\", X_test.shape, X_test.dtype)\n",
593
+ "print(\"y_train:\", y_train.shape, y_train.dtype)\n",
594
+ "print(\"y_test:\", y_test.shape, y_test.dtype)\n",
595
+ "print(\"y_test unique:\", np.unique(y_test))\n",
596
+ "\n",
597
+ "X_train = pd.DataFrame(X_train)\n",
598
+ "X_test = pd.DataFrame(X_test)\n",
599
+ "\n",
600
+ "# pipe = make_pipeline(\n",
601
+ "# TableVectorizer(), # Automatically handles various data types\n",
602
+ "# TabICLClassifier(device=device)\n",
603
+ "# )\n",
604
+ "pipe = TabICLClassifier(device=device)\n",
605
+ "\n",
606
+ "pipe.fit(X_train, y_train) # this is cheap\n",
607
+ "cal_proba = pipe.predict_proba(X_val) # in-context learning happens here\n",
608
+ "proba = pipe.predict_proba(X_test) # in-context learning happens here"
609
+ ]
610
+ },
611
+ {
612
+ "cell_type": "code",
613
+ "source": [
614
+ "lac_pred_set = lac_prediction_set(cal_proba, proba, y_val)\n",
615
+ "aps_pred_set = aps_prediction_set(cal_proba, proba, y_val)\n",
616
+ "raps_pred_set = raps_prediction_set(cal_proba, proba, y_val)"
617
+ ],
618
+ "metadata": {
619
+ "id": "vvGP7d7xkpk7"
620
+ },
621
+ "execution_count": null,
622
+ "outputs": []
623
+ },
624
+ {
625
+ "cell_type": "code",
626
+ "source": [
627
+ "print(\"ROC AUC:\", roc_auc_score(y_test, proba[:,1]))\n",
628
+ "y = np.argmax(proba, axis=1)\n",
629
+ "y_pred = pipe.y_encoder_.inverse_transform(y)\n",
630
+ "print(\"Accuracy:\", accuracy_score(y_test, y_pred))\n",
631
+ "print(\"SS (LAC):\", set_size(lac_pred_set))\n",
632
+ "print(\"SS (APS):\", set_size(aps_pred_set))\n",
633
+ "print(\"SS (RAPS):\", set_size(raps_pred_set))\n",
634
+ "print(\"CR (LAC):\", coverage_rate(y_test, lac_pred_set))\n",
635
+ "print(\"CR (APS):\", coverage_rate(y_test, aps_pred_set))\n",
636
+ "print(\"CR (RAPS):\", coverage_rate(y_test, raps_pred_set))"
637
+ ],
638
+ "metadata": {
639
+ "colab": {
640
+ "base_uri": "https://localhost:8080/"
641
+ },
642
+ "id": "Sp87-tIbkheD",
643
+ "outputId": "ad366dee-6cbf-4c4c-89b7-7754d1c5ea59"
644
+ },
645
+ "execution_count": null,
646
+ "outputs": [
647
+ {
648
+ "output_type": "stream",
649
+ "name": "stdout",
650
+ "text": [
651
+ "ROC AUC: 0.5084913746919533\n",
652
+ "Accuracy: 0.5563636363636364\n",
653
+ "SS (LAC): 1.8254545454545454\n",
654
+ "SS (APS): 2.0\n",
655
+ "SS (RAPS): 1.8581818181818182\n",
656
+ "CR (LAC): 0.9236363636363636\n",
657
+ "CR (APS): 1.0\n",
658
+ "CR (RAPS): 0.9418181818181818\n"
659
+ ]
660
+ }
661
+ ]
662
+ }
663
+ ],
664
+ "metadata": {
665
+ "accelerator": "GPU",
666
+ "colab": {
667
+ "gpuType": "T4",
668
+ "provenance": []
669
+ },
670
+ "kernelspec": {
671
+ "display_name": "Python 3",
672
+ "name": "python3"
673
+ },
674
+ "language_info": {
675
+ "name": "python"
676
+ }
677
+ },
678
+ "nbformat": 4,
679
+ "nbformat_minor": 0
680
+ }