{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","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":"nvidiaTeslaT4","dataSources":[{"sourceId":87323,"databundleVersionId":9934427,"sourceType":"competition"}],"dockerImageVersionId":31041,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install autogluon","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:41:37.763092Z","iopub.execute_input":"2025-06-07T06:41:37.763431Z","iopub.status.idle":"2025-06-07T06:41:43.715868Z","shell.execute_reply.started":"2025-06-07T06:41:37.763409Z","shell.execute_reply":"2025-06-07T06:41:43.714925Z"},"_kg_hide-input":true,"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"---\n## Setup","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport autogluon.multimodal as agmm\nfrom PIL import Image, ImageStat\nimport cv2","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:41:43.717581Z","iopub.execute_input":"2025-06-07T06:41:43.717820Z","iopub.status.idle":"2025-06-07T06:41:43.722404Z","shell.execute_reply.started":"2025-06-07T06:41:43.717798Z","shell.execute_reply":"2025-06-07T06:41:43.721609Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train = pd.read_csv('/kaggle/input/cidaut-ai-fake-scene-classification-2024/train.csv')\ntest = pd.read_csv('/kaggle/input/cidaut-ai-fake-scene-classification-2024/sample_submission.csv')\nsub = pd.read_csv('/kaggle/input/cidaut-ai-fake-scene-classification-2024/sample_submission.csv')\n\ntrain_path = '/kaggle/input/cidaut-ai-fake-scene-classification-2024/Train/'\ntest_path = '/kaggle/input/cidaut-ai-fake-scene-classification-2024/Test/'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:41:43.723055Z","iopub.execute_input":"2025-06-07T06:41:43.723309Z","iopub.status.idle":"2025-06-07T06:41:43.745838Z","shell.execute_reply.started":"2025-06-07T06:41:43.723293Z","shell.execute_reply":"2025-06-07T06:41:43.745207Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# label binary encoding\ncls_to_idx = {'editada': 0, 'real': 1}\n\ntrain['label'] = [cls_to_idx[x] for x in train['label'].values]\n\ntrain['label'].head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:41:43.746503Z","iopub.execute_input":"2025-06-07T06:41:43.746677Z","iopub.status.idle":"2025-06-07T06:41:43.754023Z","shell.execute_reply.started":"2025-06-07T06:41:43.746664Z","shell.execute_reply":"2025-06-07T06:41:43.753277Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"---\n## Preprocessing","metadata":{}},{"cell_type":"code","source":"train['image'] = train_path + train['image']\ntest['image'] = test_path + test['image']\n\ntrain['image'].iloc[0], test['image'].iloc[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:41:43.755828Z","iopub.execute_input":"2025-06-07T06:41:43.756375Z","iopub.status.idle":"2025-06-07T06:41:43.769086Z","shell.execute_reply.started":"2025-06-07T06:41:43.756359Z","shell.execute_reply":"2025-06-07T06:41:43.768354Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nfrom PIL import Image, ImageStat\nimport cv2\nfrom scipy.stats import entropy as sk_entropy\n\n# --- Feature Functions ---\n\ndef brightness(im_file):\n    im = Image.open(im_file).convert('L')\n    stat = ImageStat.Stat(im)\n    return stat.mean[0]\n\ndef blur(im_file):\n    img = cv2.imread(im_file, cv2.IMREAD_GRAYSCALE)\n    if img is None:\n        return np.nan\n    return cv2.Laplacian(img, cv2.CV_64F).var()\n\ndef contrast(im_file):\n    im = Image.open(im_file).convert('L')\n    stat = ImageStat.Stat(im)\n    return stat.stddev[0]\n\ndef sharpness(im_file):\n    img = cv2.imread(im_file, cv2.IMREAD_GRAYSCALE)\n    if img is None:\n        return np.nan\n    return cv2.Laplacian(img, cv2.CV_64F).var()\n\ndef image_entropy(im_file):\n    img = cv2.imread(im_file, cv2.IMREAD_GRAYSCALE)\n    if img is None:\n        return np.nan\n    hist = cv2.calcHist([img], [0], None, [256], [0,256]).ravel()\n    hist = hist / hist.sum()\n    return sk_entropy(hist + 1e-10)\n\ndef colorfulness(im_file):\n    img = cv2.imread(im_file)\n    if img is None:\n        return np.nan\n    (B, G, R) = cv2.split(img.astype(\"float\"))\n    rg = np.abs(R - G)\n    yb = np.abs(0.5 * (R + G) - B)\n    std_root = np.sqrt(np.std(rg)**2 + np.std(yb)**2)\n    mean_root = np.sqrt(np.mean(rg)**2 + np.mean(yb)**2)\n    return std_root + 0.3 * mean_root\n\ndef saturation(im_file):\n    img = cv2.imread(im_file)\n    if img is None:\n        return np.nan\n    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)\n    return hsv[..., 1].mean()\n\n# --- General Feature Extraction Helper ---\n\ndef get_all_features(df, feature_fn):\n    features = []\n    for path in df['image'].values:\n        features.append(feature_fn(path))\n    return features\n\n# --- Apply All Features to Train/Test ---\n\nfeature_functions = {\n    'brightness': brightness,\n    'blur': blur,\n    'contrast': contrast,\n    'sharpness': sharpness,\n    'entropy': image_entropy,\n    'colorfulness': colorfulness,\n    'saturation': saturation\n}\n\nfor name, func in feature_functions.items():\n    train[name] = get_all_features(train, func)\n    test[name] = get_all_features(test, func)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:41:43.769962Z","iopub.execute_input":"2025-06-07T06:41:43.770481Z","iopub.status.idle":"2025-06-07T06:42:48.855695Z","shell.execute_reply.started":"2025-06-07T06:41:43.770464Z","shell.execute_reply":"2025-06-07T06:42:48.855093Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"---\n## EDA","metadata":{}},{"cell_type":"code","source":"train_1 = train[train['label']==1]\ntrain_0 = train[train['label']==0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:42:48.856485Z","iopub.execute_input":"2025-06-07T06:42:48.856699Z","iopub.status.idle":"2025-06-07T06:42:48.862979Z","shell.execute_reply.started":"2025-06-07T06:42:48.856684Z","shell.execute_reply":"2025-06-07T06:42:48.862213Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_1['brightness'].plot(kind='hist', bins=100)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:42:48.863797Z","iopub.execute_input":"2025-06-07T06:42:48.864378Z","iopub.status.idle":"2025-06-07T06:42:49.133816Z","shell.execute_reply.started":"2025-06-07T06:42:48.864352Z","shell.execute_reply":"2025-06-07T06:42:49.133032Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_1['blur'].plot(kind='hist', bins=100)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:42:49.134913Z","iopub.execute_input":"2025-06-07T06:42:49.135231Z","iopub.status.idle":"2025-06-07T06:42:49.389364Z","shell.execute_reply.started":"2025-06-07T06:42:49.135207Z","shell.execute_reply":"2025-06-07T06:42:49.388718Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_0['brightness'].plot(kind='hist', bins=100)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:42:49.390232Z","iopub.execute_input":"2025-06-07T06:42:49.390441Z","iopub.status.idle":"2025-06-07T06:42:49.644016Z","shell.execute_reply.started":"2025-06-07T06:42:49.390425Z","shell.execute_reply":"2025-06-07T06:42:49.643341Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_0['blur'].plot(kind='hist', bins=100)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:42:49.644694Z","iopub.execute_input":"2025-06-07T06:42:49.644882Z","iopub.status.idle":"2025-06-07T06:42:49.925475Z","shell.execute_reply.started":"2025-06-07T06:42:49.644867Z","shell.execute_reply":"2025-06-07T06:42:49.924680Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"---\n## Models","metadata":{}},{"cell_type":"code","source":"predictor = agmm.MultiModalPredictor(label='label', eval_metric='roc_auc')\npredictor.fit(train, hyperparameters={'env.num_gpus': 0})\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T06:42:49.926406Z","iopub.execute_input":"2025-06-07T06:42:49.926699Z","iopub.status.idle":"2025-06-07T07:01:41.038851Z","shell.execute_reply.started":"2025-06-07T06:42:49.926682Z","shell.execute_reply":"2025-06-07T07:01:41.038226Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"preds = predictor.predict(test.drop(columns='label'), as_pandas=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T07:01:41.039808Z","iopub.execute_input":"2025-06-07T07:01:41.040677Z","iopub.status.idle":"2025-06-07T07:01:47.341598Z","shell.execute_reply.started":"2025-06-07T07:01:41.040650Z","shell.execute_reply":"2025-06-07T07:01:47.340630Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub['label'] = preds\nsub.to_csv('submission_extract_many_features.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T07:02:41.722517Z","iopub.execute_input":"2025-06-07T07:02:41.722828Z","iopub.status.idle":"2025-06-07T07:02:41.728564Z","shell.execute_reply.started":"2025-06-07T07:02:41.722805Z","shell.execute_reply":"2025-06-07T07:02:41.727754Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sub['label'].plot(kind='hist',bins=100)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-07T07:02:42.944732Z","iopub.execute_input":"2025-06-07T07:02:42.945001Z","iopub.status.idle":"2025-06-07T07:02:43.178140Z","shell.execute_reply.started":"2025-06-07T07:02:42.944981Z","shell.execute_reply":"2025-06-07T07:02:43.177422Z"}},"outputs":[],"execution_count":null}]}