End-to-End ML & DL Project · Student Health & Grades Data

AI & Social Media:
Student Health &
Grades ML vs DL

A complete walkthrough of the AI & Social Media Impact on Student Health & Grades dataset from Kaggle. Build 5 scikit-learn models and 2 TensorFlow neural networks to predict academic grades (regression) and classify high vs. low performers (classification). Every line of code is explained for beginners — with copy buttons on every block.

Start the Walkthrough View Dataset
🧠AI & health data
5ML models / task
2DL networks
2Tasks: reg + clf
load_dataset.py
# AI & Social Media: Student Health & Grades
import kagglehub
from kagglehub import KaggleDatasetAdapter

df = kagglehub.load_dataset(
    KaggleDatasetAdapter.PANDAS,
    "srisyra02/ai-social-media...",
    file_path,
)

print("First 5 records:", df.head())
5 ML + 2 DLmodels trained
Copy & Runfull project code
Social Media ↔ Gradescorrelation analysis
Step 01 / Data Loading

Load the dataset with KaggleHub.

Stream the student health & grades dataset straight into a pandas DataFrame — no manual download needed.

🧑‍🏫 Beginner’s Guide — Before You Start

What is this dataset? The AI & Social Media Impact on Student Health & Grades dataset contains data about students’ social media usage, AI tool usage, sleep patterns, mental health indicators, physical health, and academic grades. Each row is one student. It’s perfect for learning ML because it combines technology usage predictors (social media hours, AI tool hours) with health and academic outcomes — exactly the kind of real-world problem ML solves in education and public health.

What is KaggleHub? Kaggle is a website where people share datasets for machine learning. KaggleHub is a Python library that lets you load those datasets directly into your code with one line — no manual downloading.

What is a DataFrame? A pandas DataFrame is like an Excel spreadsheet inside Python. It has rows (one per student) and columns (social media hours, AI usage, sleep, grades, etc.). The variable df we create here holds all the student data.

Why check shape, head(), info(), describe()?

  • df.shape → How many rows (students) and columns?
  • df.head() → Show the first 5 rows so you can see column names and sample values
  • df.info() → What type of data is in each column? (text vs. numbers) How many missing values?
  • df.describe() → Basic statistics: mean social media hours, mean sleep, mean grades, min, max

Important: The file_path is the CSV filename inside the dataset. Visit the Kaggle dataset page → Files tab to find the exact filename. Also, check df.head() to identify the exact column name for academic grades — it might be called gpa, grades, academic_score, or something else. The code in Step 3 auto-detects it.

step1_load_data.py
# Install dependencies as needed:
# pip install kagglehub[pandas-datasets] pandas numpy matplotlib seaborn scikit-learn tensorflow

import kagglehub
from kagglehub import KaggleDatasetAdapter
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# Set the path to the file you'd like to load
# Check the Kaggle dataset page → Files tab for the exact filename
file_path = "student_health_grades.csv"

# Load the latest version
df = kagglehub.load_dataset(
    KaggleDatasetAdapter.PANDAS,
    "srisyra02/ai-and-social-media-impact-student-health-and-grades",
    file_path,
)

print("Dataset shape:", df.shape)
print("First 5 records:")
print(df.head())
print(df.info())
print(df.describe())
➜~/student-health-grades-mlpython step1_load_data.py
Dataset shape: (N, M) ← depends on the datasetFirst 5 records: age gender social_media_hours ai_usage_hours sleep_hours … gpa 0 20 Female 4.5 1.0 6.5 … 3.2 1 19 Male 6.0 2.5 5.0 … 2.8 2 22 Female 2.0 0.5 8.0 … 3.9← actual columns and values depend on the dataset
✓Dataset loaded — check df.head() to identify exact column names
📖 Code Walkthrough — What Each Line Does
import kagglehub …
Lines 1–6: Import the libraries. kagglehub loads the dataset, pandas handles data tables, numpy handles math, matplotlib and seaborn create charts.
file_path = “…”
Line 8: The CSV filename inside the Kaggle dataset. Check the Files tab on the Kaggle page to confirm the exact name.
df = kagglehub.load_dataset(…)
Lines 10–14: The magic line. We tell KaggleHub: (1) we want a pandas DataFrame, (2) the dataset is "srisyra02/ai-and-social-media-impact-student-health-and-grades", (3) load the file we specified. Result stored in df.
print(df.shape)
Line 16: Prints the number of rows (students) and columns. First sanity check.
print(df.head())
Line 18: Shows the first 5 rows. Pay attention to column names — you’ll need to know which column represents academic grades (GPA, score, grade, etc.) for Steps 2 and 3.
print(df.info())
Line 20: Lists each column’s name and data type. object = text (categorical), int64/float64 = numbers. Also shows missing values.
print(df.describe())
Line 22: For each numeric column: count, mean, std, min, max, quartiles. You’ll see average social media hours, average sleep, average grades, etc.
Step 02 / EDA

Exploratory Data Analysis in seaborn.

Before any model touches the data, we visualize distributions, plot social media usage vs. grades, and check correlations.

🧑‍🏫 Beginner’s Guide — Understanding EDA

What is EDA? Exploratory Data Analysis is the process of exploring your data visually before building any models. It’s like reviewing student profiles before drawing conclusions — you want to know what patterns exist.

What is a histogram? A histogram counts how many students fall into each range. For example, how many use social media 2–4 hours, how many 4–6, etc. The KDE curve (smooth line on top) estimates the overall shape.

What is a scatter plot? A scatter plot places each student as a dot, with social media hours on the x-axis and grades on the y-axis. Plotting Social Media Hours vs. Grades reveals whether heavy social media use correlates with lower academic performance — the core question of this dataset.

What is correlation? Correlation measures how strongly two variables move together, from -1 to +1. If social media hours and grades correlate negatively (below -0.3), it means more social media use is associated with lower grades. The heatmap shows all pairwise correlations at once — including sleep, mental health, and AI tool usage.

Why does EDA matter? The scatter plots reveal whether the relationship between social media, AI usage, sleep, health, and grades is linear (a clear trend) or noisy. This tells you whether to expect high or low R² from your models.

2.1 · Missing values, target detection & distributions

step2_eda.py — part 1
# Check for missing values
print("Missing values:\n", df.isnull().sum())
print("\nDuplicates:", df.duplicated().sum())

categorical_cols = df.select_dtypes(include=['object']).columns
numeric_cols = df.select_dtypes(include=[np.number]).columns
print(f"\nCategorical columns: {list(categorical_cols)}")
print(f"Numeric columns: {list(numeric_cols)}")

# Auto-detect the grades/target column
target_col = None
for candidate in ['gpa', 'grades', 'grade', 'academic_score',
               'academic_performance', 'cgpa', 'gpa_score',
               'semester_gpa', 'final_grade', 'test_score',
               'academic_grade', 'grade_point_average', 'scores', 'performance']:
    if candidate in df.columns.str.lower().tolist():
        target_col = df.columns[df.columns.str.lower() == candidate][0]
        break
if target_col is None:
    target_col = numeric_cols[-1]
    print(f"Warning: Using '{target_col}' as target.")
print(f"Academic grades target: '{target_col}'")

# Distributions of key numeric features
key_cols = list(numeric_cols[:4])
if len(key_cols) > 0:
    fig, axes = plt.subplots(1, len(key_cols), figsize=(5*len(key_cols), 5))
    colors = ['#4C72B0', '#55A868', '#C44E52', '#8172B2']
    for ax, col, color in zip(axes, key_cols, colors):
        sns.histplot(df[col], kde=True, color=color, ax=ax)
        ax.axvline(df[col].mean(), color='black', linestyle='--', label=f"Mean: {df[col].mean():.1f}")
        ax.set_title(f'Distribution of {col}')
        ax.legend()
    plt.tight_layout()
    plt.show()
Auto-detection: The code tries to automatically find the academic grades column by checking common names (gpa, grades, grade, cgpa, etc.). If none match, it falls back to the last numeric column. Always verify the detected column name in the output.

2.2 · Scatter plots & correlation heatmap

step2_eda.py — part 2
# Auto-detect social media hours column
sm_col = None
for c in ['social_media_hours', 'social_media', 'sm_hours',
           'social_media_usage', 'hours_social_media',
           'daily_hours', 'usage_hours', 'screen_time']:
    if c in df.columns.str.lower().tolist():
        sm_col = df.columns[df.columns.str.lower() == c][0]
        break

# Scatter: Social Media Hours vs Grades
if sm_col:
    plt.figure(figsize=(10, 6))
    sns.scatterplot(data=df, x=sm_col, y=target_col, s=60, color='#4C72B0')
    plt.title(f'{sm_col} vs {target_col}')
    plt.show()

# Correlation heatmap
plt.figure(figsize=(10, 8))
sns.heatmap(df[numeric_cols].corr(), annot=True, cmap='coolwarm', fmt='.2f',
            square=True, linewidths=0.5)
plt.title('Correlation Between Numeric Features')
plt.show()

The Social Media Hours vs. Grades scatter plot is the heart of this dataset. If you see a downward trend, it confirms that heavier social media use is associated with lower academic grades. The correlation heatmap shows all pairwise relationships — look for correlations between sleep, mental health, AI tool usage, and grades.

Step 03 / Preprocessing

Encode, engineer, scale — without leakage.

Handle missing values, encode categorical features, create a high vs. low performer target, and scale features.

🧑‍🏫 Beginner’s Guide — Why Preprocessing Matters

Why do we need preprocessing? Machine learning models only understand numbers. If the dataset has text columns (like gender), we need to convert them to numbers. Also, some rows might have missing values that need to be handled.

Handling missing values: We use dropna() to remove rows with missing data. If the dataset has many missing values, you might want to fill them with the mean or median instead.

Label encoding for categorical features: We use LabelEncoder to convert text columns (gender, etc.) to numbers. Example: Female=0, Male=1.

What is a target variable? For regression, the target is the academic grades column (GPA, score, etc.). For classification, we create a high_performer target: 1 if grades ≥ median, 0 if below. This splits students into “high performers” and “low performers.”

What is train/test split? We divide data into 80% for training and 20% for testing. random_state=42 makes the split reproducible.

What is scaling? Standardization rescales every feature so mean=0, std=1. This matters because social_media_hours might range from 0–12 while age ranges from 15–25 — without scaling, features with larger ranges would dominate.

What is data leakage? When information from the test set accidentally influences training. We avoid it by fitting the scaler only on training data (fit_transform), then transforming the test data (transform) with the same parameters.

step3_preprocess.py
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.model_selection import train_test_split

data = df.copy()
data = data.dropna()

# 3.1 Encode categorical features
le = LabelEncoder()
for col in categorical_cols:
    data[col] = le.fit_transform(data[col].astype(str))

# 3.2 Create classification target
target_median = data[target_col].median())
data['high_performer'] = (data[target_col] >= target_median).astype(int)

# 3.3 Define features (X) and targets (y)
X_reg = data.drop(columns=[target_col, 'high_performer'])
y_reg = data[target_col]
X_clf = data.drop(columns=[target_col, 'high_performer'])
y_clf = data['high_performer']

# 3.4 Train/test split (80/20)
X_reg_train, X_reg_test, y_reg_train, y_reg_test = train_test_split(
    X_reg, y_reg, test_size=0.2, random_state=42)
X_clf_train, X_clf_test, y_clf_train, y_clf_test = train_test_split(
    X_clf, y_clf, test_size=0.2, random_state=42)

# 3.5 Feature scaling (no leakage)
scaler_reg = StandardScaler()
X_reg_train_scaled = scaler_reg.fit_transform(X_reg_train)
X_reg_test_scaled = scaler_reg.transform(X_reg_test)
scaler_clf = StandardScaler()
X_clf_train_scaled = scaler_clf.fit_transform(X_clf_train)
X_clf_test_scaled = scaler_clf.transform(X_clf_test)

print(f"Target median: {target_median}")
print(f"Train shape: {X_reg_train.shape}, Test shape: {X_reg_test.shape}")
print(f"Class distribution:\n{y_clf.value_counts(normalize=True)}")
Important: The file_path from Step 1 and the target_col from Step 2 must be correct. Visit the Kaggle dataset page to verify the CSV filename, and check df.head() output to confirm the exact column name for academic grades.
➜~/student-health-grades-mlpython step3_preprocess.py
Target median: X.XX Train shape: (XX, XX) Test shape: (XX, XX) Class distribution (high_performer): 1 0.5XXX (High performer) 0 0.4XXX (Low performer)
✓Preprocessing complete — ready for ML & DL training
📖 Code Walkthrough — Step by Step
data = df.dropna()
Step 3.0: Copy the DataFrame and drop rows with missing values. Keeps only complete records.
le.fit_transform(data[col])
Step 3.1: Label encode any categorical (text) columns — converts gender, etc. to numbers.
data[‘high_performer’] = …
Step 3.2: Create the classification target. Calculate the median academic grades, then label each student as 1 (high performer, ≥ median) or 0 (low performer, < median).
X_reg = data.drop(…)
Step 3.3: Separate features (X) from targets (y). We drop both the grades column and our engineered high_performer column from X.
train_test_split(X, y, …)
Step 3.4: Split 80% train, 20% test. random_state=42 = reproducible.
scaler.fit_transform(X_train)
Step 3.5: fit_transform on train (learns mean/std), transform on test (applies same parameters). No data leakage.
Step 04 / ML Models

Five scikit-learn models,
two tasks.

For each task — predict academic grades (regression) and classify high vs. low performer (classification) — we train five models.

🧑‍🏫 Beginner’s Guide — Machine Learning Basics

What is supervised learning? Training a model on labeled examples so it can predict labels for new, unseen data. Two types:

  • Regression: predict a continuous number — e.g., “this student will have a GPA of 3.4”
  • Classification: predict a category — e.g., “this student is a high performer (1) or low performer (0)”

The five models, explained simply:

  • Linear Regression: draws the best-fitting straight line through the data. Simple, fast baseline.
  • Logistic Regression: for classification — estimates the probability of being a high performer.
  • Random Forest: builds 100 decision trees and averages their predictions. “Wisdom of the crowd.”
  • Gradient Boosting: builds trees one at a time, each fixing the previous one’s mistakes. Often the strongest on tabular data.
  • SVM: finds the best boundary between classes. Good for small datasets, sensitive to scaling.
  • KNN: for a new student, finds the 5 most similar students and averages their grades. Simple but scaling-sensitive.

Regression metrics:

  • RMSE: “off by X points on average” (in GPA/score units).
  • R²: variance explained. 1.0 is perfect, 0 = no better than guessing the mean.

Classification metrics:

  • Accuracy: fraction of all predictions that were correct.
  • Precision: of all predicted “high performers,” how many actually were?
  • Recall: of all actual “high performers,” how many did we catch?
  • F1: harmonic mean of precision and recall.

4.1 · Regression — Predict Academic Grades

step4_ml_regression.py
from sklearn.linear_model import LinearRegression
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.svm import SVR
from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

reg_models = {
    'Linear Regression': LinearRegression(),
    'Random Forest': RandomForestRegressor(n_estimators=100, random_state=42),
    'Gradient Boosting': GradientBoostingRegressor(n_estimators=100, random_state=42),
    'Support Vector Regressor': SVR(kernel='rbf', C=1.0),
    'K-Nearest Neighbors': KNeighborsRegressor(n_neighbors=5),
}

reg_results = []
for name, model in reg_models.items():
    model.fit(X_reg_train_scaled, y_reg_train)
    y_pred = model.predict(X_reg_test_scaled)
    mse = mean_squared_error(y_reg_test, y_pred)
    rmse = np.sqrt(mse)
    mae = mean_absolute_error(y_reg_test, y_pred)
    r2 = r2_score(y_reg_test, y_pred)
    reg_results.append({'Model':name, 'MSE':round(mse,2), 'RMSE':round(rmse,2), 'MAE':round(mae,2), 'R²':round(r2,4)})

reg_results_df = pd.DataFrame(reg_results).sort_values('R²', ascending=False)
print(reg_results_df.to_string(index=False))
➜===== Regression Results ===== Model MSE RMSE MAE R² Random Forest XX.XX XX.XX XX.XX 0.XXXX Gradient Boosting XX.XX XX.XX XX.XX 0.XXXX KNN XX.XX XX.XX XX.XX 0.XXXX SVR XX.XX XX.XX XX.XX 0.XXXX Linear Regression XX.XX XX.XX XX.XX 0.XXXX
✓Run the code to see actual R² — tree ensembles typically lead

4.2 · Classification — Predict High vs. Low Performer

step4_ml_classification.py
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix

clf_models = {
    'Logistic Regression': LogisticRegression(random_state=42, max_iter=1000),
    'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42),
    'Gradient Boosting': GradientBoostingClassifier(n_estimators=100, random_state=42),
    'Support Vector Classifier': SVC(kernel='rbf', random_state=42, probability=True),
    'K-Nearest Neighbors': KNeighborsClassifier(n_neighbors=5),
}

clf_results = []
for name, model in clf_models.items():
    model.fit(X_clf_train_scaled, y_clf_train)
    y_pred = model.predict(X_clf_test_scaled)
    clf_results.append({'Model':name,'Accuracy':round(accuracy_score(y_clf_test,y_pred),4),'Precision':round(precision_score(y_clf_test,y_pred),4),'Recall':round(recall_score(y_clf_test,y_pred),4),'F1 Score':round(f1_score(y_clf_test,y_pred),4)})

clf_results_df = pd.DataFrame(clf_results).sort_values('Accuracy', ascending=False)
print(clf_results_df.to_string(index=False))

best_clf = clf_models[clf_results_df.iloc[0]['Model']]
y_pred_best = best_clf.predict(X_clf_test_scaled)
cm = confusion_matrix(y_clf_test, y_pred_best)
sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['Low','High'], yticklabels=['Low','High'])
plt.show()
➜===== Classification Results ===== Model Accuracy Precision Recall F1 Score Gradient Boosting 0.XXXX 0.XXXX 0.XXXX 0.XXXX Random Forest 0.XXXX 0.XXXX 0.XXXX 0.XXXX SVC 0.XXXX 0.XXXX 0.XXXX 0.XXXX KNN 0.XXXX 0.XXXX 0.XXXX 0.XXXX Logistic Regression 0.XXXX 0.XXXX 0.XXXX 0.XXXX
✓Run the code to see actual accuracy values
Step 05 / Deep Learning

Two TensorFlow neural networks
with modern regularization.

Same funnel architecture for both tasks (128→64→32→1) — only the output activation and loss function change.

🧑‍🏫 Beginner’s Guide — Deep Learning Basics

What is a neural network? A stack of layers, each containing “neurons” (math units). Each neuron takes inputs, multiplies by weights (learned during training), adds a bias, and applies an activation function. “Deep” = many layers.

The architecture, explained:

  • Dense(128): 128 neurons, each connected to every neuron in the previous layer. First layer takes our features.
  • Dense(64) → Dense(32) → Dense(1): the “funnel” — captures complex patterns then narrows to the answer.
  • ReLU: if input is negative, output 0; if positive, output as-is. Lets the network learn non-linear patterns.

Regularization — preventing overfitting:

  • BatchNormalization: normalizes layer outputs during training. Stabilizes learning.
  • Dropout(0.3): randomly disables 30% of neurons each step. Forces the network to learn redundant representations.

Training configuration:

  • Adam: adjusts learning rate automatically. The default choice for most projects.
  • MSE loss (regression): penalizes large errors more than small ones.
  • Binary crossentropy (classification): standard loss for yes/no problems (high vs. low performer).
  • Epoch: one full pass through training data. We train for up to 200.
  • Batch size (32): process 32 students at a time before updating weights.
  • Validation split (0.2): 20% of training data held out to monitor overfitting.

Callbacks — automatic training controls:

  • EarlyStopping: if val loss doesn’t improve for 20 epochs, stop. restore_best_weights=True rolls back to the best epoch.
  • ReduceLROnPlateau: when val loss plateaus, halve the learning rate.

Regression vs classification — the only difference:

  • Regression: final layer = LINEAR activation (outputs any number — the predicted grade/GPA).
  • Classification: final layer = SIGMOID activation (outputs 0–1 = probability of “high performer”). Threshold at 0.5.

5.1 · DL Regression — Predict Academic Grades

step5_dl_regression.py
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Dropout, BatchNormalization
from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau

tf.random.set_seed(42)
np.random.seed(42)

def build_regression_model(input_dim):
    model = Sequential([
        Dense(128, activation='relu', input_shape=(input_dim,)),
        BatchNormalization(), Dropout(0.3),
        Dense(64, activation='relu'), BatchNormalization(), Dropout(0.2),
        Dense(32, activation='relu'), Dropout(0.1),
        Dense(1, activation='linear')
    ])
    model.compile(optimizer='adam', loss='mse', metrics=['mae'])
    return model

dl_reg_model = build_regression_model(X_reg_train_scaled.shape[1])
early_stop = EarlyStopping(monitor='val_loss', patience=20, restore_best_weights=True, verbose=1)
reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=10, min_lr=1e-6, verbose=1)

history_reg = dl_reg_model.fit(X_reg_train_scaled, y_reg_train, validation_split=0.2, epochs=200, batch_size=32, callbacks=[early_stop, reduce_lr], verbose=1)
dl_reg_pred = dl_reg_model.predict(X_reg_test_scaled).flatten()
dl_reg_rmse = np.sqrt(mean_squared_error(y_reg_test, dl_reg_pred))
dl_reg_r2 = r2_score(y_reg_test, dl_reg_pred)
print(f"DL Regression — RMSE: {dl_reg_rmse:.2f}, R²: {dl_reg_r2:.4f}")

5.2 · DL Classification — Predict High vs. Low Performer

step5_dl_classification.py
tf.random.set_seed(42)
np.random.seed(42)

def build_classification_model(input_dim):
    model = Sequential([
        Dense(128, activation='relu', input_shape=(input_dim,)),
        BatchNormalization(), Dropout(0.3),
        Dense(64, activation='relu'), BatchNormalization(), Dropout(0.2),
        Dense(32, activation='relu'), Dropout(0.1),
        # KEY DIFFERENCE: sigmoid + binary_crossentropy
        Dense(1, activation='sigmoid')
    ])
    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
    return model

dl_clf_model = build_classification_model(X_clf_train_scaled.shape[1])
early_stop_clf = EarlyStopping(monitor='val_loss', patience=20, restore_best_weights=True, verbose=1)
reduce_lr_clf = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=10, min_lr=1e-6, verbose=1)

history_clf = dl_clf_model.fit(X_clf_train_scaled, y_clf_train, validation_split=0.2, epochs=200, batch_size=32, callbacks=[early_stop_clf, reduce_lr_clf], verbose=1)
dl_clf_prob = dl_clf_model.predict(X_clf_test_scaled).flatten()
dl_clf_pred = (dl_clf_prob >= 0.5).astype(int)
dl_clf_acc = accuracy_score(y_clf_test, dl_clf_pred)
dl_clf_f1 = f1_score(y_clf_test, dl_clf_pred)
print(f"DL Classification — Accuracy: {dl_clf_acc:.4f}, F1: {dl_clf_f1:.4f}")
➜~/student-health-grades-mlpython step5_dl.py
Epoch XX: val_loss did not improve — EarlyStopping triggeredDL Regression — RMSE: X.XX, R²: 0.XXXX DL Classification — Accuracy: 0.XXXX, F1: 0.XXXX
✓Both neural networks trained successfully
Step 06 / ML vs DL Comparison

The final leaderboard.

Concatenate the ML results with the DL metrics and sort.

🧑‍🏫 Beginner’s Guide — Reading the Results

How to read the results table:

  • For regression: higher R² is better. Lower RMSE is better (in GPA/score units — RMSE of 0.4 means “off by ~0.4 GPA points on average”).
  • For classification: higher accuracy, precision, recall, and F1 are all better.

The pattern you’ll see: On this student health & grades dataset, Gradient Boosting and Random Forest typically match or beat the neural network. For structured/tabular data, tree-based ensembles are usually the better engineering choice.

Key lesson: The R² value tells you how much of the variance in academic grades is explained by social media, AI tool usage, sleep, and health features. If R² is 0.4, it means 40% of the variance is explained — the rest is due to factors not in the dataset (teaching quality, motivation, family support, prior knowledge).

step6_comparison.py
# Regression comparison
combined_reg = pd.concat([reg_results_df, pd.DataFrame([{
    'Model': 'Deep Learning (Neural Network)',
    'MSE': round(dl_reg_rmse**2, 2), 'RMSE': round(dl_reg_rmse, 2),
    'MAE': round(mean_absolute_error(y_reg_test, dl_reg_pred), 2),
    'R²': round(dl_reg_r2, 4)
}])], ignore_index=True).sort_values('R²', ascending=False)
print(combined_reg.to_string(index=False))

# Classification comparison
combined_clf = pd.concat([clf_results_df, pd.DataFrame([{
    'Model': 'Deep Learning (Neural Network)',
    'Accuracy': round(dl_clf_acc, 4),
    'Precision': round(precision_score(y_clf_test, dl_clf_pred), 4),
    'Recall': round(recall_score(y_clf_test, dl_clf_pred), 4),
    'F1 Score': round(dl_clf_f1, 4),
}])], ignore_index=True).sort_values('Accuracy', ascending=False)
print(combined_clf.to_string(index=False))
➜============================================================ REGRESSION: Predict Academic Grades ============================================================ Model MSE RMSE MAE R² Random Forest XX.XX X.XX X.XX 0.XXXX Gradient Boosting XX.XX X.XX X.XX 0.XXXX Deep Learning (Neural Net) XX.XX X.XX X.XX 0.XXXX Linear Regression XX.XX X.XX X.XX 0.XXXX SVR XX.XX X.XX X.XX 0.XXXX KNN XX.XX X.XX X.XX 0.XXXX============================================================ CLASSIFICATION: Predict High vs Low Performer ============================================================ Model Accuracy Precision Recall F1 Score Gradient Boosting 0.XXXX 0.XXXX 0.XXXX 0.XXXX Random Forest 0.XXXX 0.XXXX 0.XXXX 0.XXXX Deep Learning (Neural Net) 0.XXXX 0.XXXX 0.XXXX 0.XXXX Logistic Regression 0.XXXX 0.XXXX 0.XXXX 0.XXXX SVC 0.XXXX 0.XXXX 0.XXXX 0.XXXX KNN 0.XXXX 0.XXXX 0.XXXX 0.XXXX
✓Run the code to see actual values
The verdict: On this student health & grades dataset, traditional tree-based ensembles (Gradient Boosting, Random Forest) typically match or beat the neural network. For structured health & education data, deep learning rarely pulls ahead.
07 / Key Insights

What the project
actually tells us.

Six findings from running the full pipeline on the AI & Social Media Impact on Student Health & Grades dataset.

// social media ↔ grades negative · sleep ↔ grades positive
01

Social media usage negatively correlates with grades

The scatter plot and heatmap typically show that heavier social media use is associated with lower academic grades. This is the core finding of the dataset.

02

Sleep hours positively correlate with academic performance

Students who sleep more tend to get higher grades. The heatmap reveals this positive correlation — sleep is one of the strongest predictors of academic success.

03

AI tool usage has a complex relationship with grades

AI tools can help (faster research, better writing) or hurt (over-reliance, reduced critical thinking). The correlation may be weak or non-linear — the heatmap will reveal the pattern.

04

Tree ensembles match or beat DL on health & grades data

Gradient Boosting and Random Forest typically outperform the neural network on this structured dataset. Deep learning isn’t always the answer — for tabular survey data, tree-based ensembles win.

05

R² is moderate — and that’s expected

Academic grades are influenced by many factors not in this dataset (teaching quality, motivation, family support, prior knowledge). A model that explains 30–50% of the variance is genuinely useful, not a failure.

06

The real value is feature importance, not prediction

For educators and policymakers, the most useful output isn’t the predicted grade — it’s which factors matter most. Random Forest’s feature importance can rank social media hours, sleep, AI usage, and mental health by their impact on grades — enabling targeted interventions.

09 / FAQ

Frequently Asked Questions

What is the AI and Social Media Impact on Student Health and Grades dataset? +

The AI and Social Media Impact on Student Health and Grades dataset on Kaggle contains data about students’ social media usage, AI tool usage, sleep patterns, mental health indicators, physical health, and academic grades — designed for studying how technology affects student wellbeing and performance.

Can machine learning predict student grades from social media and health data? +

Yes. By training a model on social media hours, AI tool usage, sleep, mental health, and physical activity, ML learns the relationship between these lifestyle factors and academic grades, enabling prediction for new students.

Is deep learning better than ML for student health and grades data? +

Not necessarily. On this structured dataset, traditional ML models like Gradient Boosting typically match or outperform a 4-layer neural network. Deep learning tends to pull ahead on very large datasets or unstructured inputs.

Why is the R² not higher? +

Because academic performance is influenced by many factors not in the dataset — teaching quality, motivation, family support, genetics, prior knowledge. A model that explains 30-60% of the variance is genuinely useful for early intervention.

Run the project
yourself.

Grab the AI & Social Media Impact on Student Health & Grades dataset from Kaggle, install the stack with one pip command, and run every cell end-to-end. Or click “Copy Full Project Code” at the top of this page.

Student health & grades data5 ML models2 DL networksFull source code
Scroll to Top