{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":20270,"databundleVersionId":1222630,"sourceType":"competition"}],"dockerImageVersionId":31154,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# SIIM-ISIC Melanoma Classification - EDA Setup\n# Import necessary libraries\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport os\nfrom pathlib import Path\n\n# Set display options\npd.set_option('display.max_columns', None)\npd.set_option('display.max_rows', 100)\nsns.set_style('whitegrid')\n\n# Define paths\nbase_path = Path('/kaggle/input/siim-isic-melanoma-classification')\n\nprint(\"Available files in the dataset:\")\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-11-04T16:57:17.277257Z","iopub.status.idle":"2025-11-04T16:57:17.277587Z","shell.execute_reply.started":"2025-11-04T16:57:17.277421Z","shell.execute_reply":"2025-11-04T16:57:17.277434Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Load metadata CSV\ntrain_df = pd.read_csv('/kaggle/input/siim-isic-melanoma-classification/train.csv')\n\nprint(\"\\n=== Dataset Overview ===\")\nprint(f\"Dataset shape: {train_df.shape}\")\nprint(f\"Number of rows: {train_df.shape[0]}\")\nprint(f\"Number of columns: {train_df.shape[1]}\")\nprint(\"\\nColumn names and types:\")\nprint(train_df.dtypes)\nprint(\"\\nFirst few rows:\")\nprint(train_df.head())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-04T16:57:17.278780Z","iopub.status.idle":"2025-11-04T16:57:17.279002Z","shell.execute_reply.started":"2025-11-04T16:57:17.278905Z","shell.execute_reply":"2025-11-04T16:57:17.278916Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Class Distribution Analysis\nprint(\"\\n=== Class Distribution ===\")\nclass_counts = train_df['target'].value_counts()\nprint(f\"\\nClass counts:\")\nprint(class_counts)\nprint(f\"\\nClass percentages:\")\nprint(train_df['target'].value_counts(normalize=True) * 100)\n\n# Calculate class imbalance ratio\nimbalance_ratio = class_counts[0] / class_counts[1]\nprint(f\"\\nClass imbalance ratio (negative/positive): {imbalance_ratio:.2f}:1\")\nprint(f\"Positive class (melanoma): {class_counts[1]} ({(class_counts[1]/len(train_df)*100):.2f}%)\")\nprint(f\"Negative class (benign): {class_counts[0]} ({(class_counts[0]/len(train_df)*100):.2f}%)\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-04T16:57:17.280344Z","iopub.status.idle":"2025-11-04T16:57:17.280603Z","shell.execute_reply.started":"2025-11-04T16:57:17.280491Z","shell.execute_reply":"2025-11-04T16:57:17.280504Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Data Quality Checks\nprint(\"\\n=== Data Quality Assessment ===\")\n\n# Check for missing values\nprint(\"\\nMissing values per column:\")\nmissing_vals = train_df.isnull().sum()\nprint(missing_vals[missing_vals > 0])\nprint(f\"\\nTotal missing values: {train_df.isnull().sum().sum()}\")\nprint(f\"Percentage of missing data: {(train_df.isnull().sum().sum() / (train_df.shape[0] * train_df.shape[1]) * 100):.2f}%\")\n\n# Check for duplicates\nprint(f\"\\nDuplicate rows: {train_df.duplicated().sum()}\")\nprint(f\"Duplicate image_names: {train_df['image_name'].duplicated().sum()}\")\nif train_df['image_name'].duplicated().sum() > 0:\n    print(\"\\nSample duplicate image_names:\")\n    print(train_df[train_df['image_name'].duplicated(keep=False)].sort_values('image_name').head(10))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-04T16:57:17.281333Z","iopub.status.idle":"2025-11-04T16:57:17.281528Z","shell.execute_reply.started":"2025-11-04T16:57:17.281435Z","shell.execute_reply":"2025-11-04T16:57:17.281444Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Visualization Setup - Class Distribution and Demographics\nprint(\"\\n=== Preparing Visualizations ===\")\n\n# Setup for visualizations\nfig, axes = plt.subplots(1, 2, figsize=(15, 5))\n\n# Plot 1: Class count bar chart\nax1 = axes[0]\nclass_counts.plot(kind='bar', ax=ax1, color=['skyblue', 'salmon'])\nax1.set_title('Class Distribution (Count)', fontsize=14, fontweight='bold')\nax1.set_xlabel('Target Class', fontsize=12)\nax1.set_ylabel('Count', fontsize=12)\nax1.set_xticklabels(['Benign (0)', 'Melanoma (1)'], rotation=0)\nax1.grid(axis='y', alpha=0.3)\n\n# Add count labels on bars\nfor i, v in enumerate(class_counts):\n    ax1.text(i, v + 1000, str(v), ha='center', va='bottom', fontweight='bold')\n\n# Plot 2: Demographics analysis (age if available)\nax2 = axes[1]\nif 'age_approx' in train_df.columns:\n    train_df['age_approx'].hist(bins=30, ax=ax2, color='steelblue', edgecolor='black')\n    ax2.set_title('Age Distribution', fontsize=14, fontweight='bold')\n    ax2.set_xlabel('Age (Approximate)', fontsize=12)\n    ax2.set_ylabel('Frequency', fontsize=12)\n    ax2.grid(axis='y', alpha=0.3)\nelse:\n    ax2.text(0.5, 0.5, 'Age data not available', ha='center', va='center', transform=ax2.transAxes)\n    ax2.set_title('Demographics', fontsize=14, fontweight='bold')\n\nplt.tight_layout()\nprint(\"\\nVisualization setup complete. Ready for EDA execution.\")","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}