This project applies a complete Data Science pipeline on a messy student dataset to analyze and predict final exam scores using Linear Regression. The dataset contains 205 rows and 14 columns with real-world data quality issues that were cleaned and processed before modeling.
| Column | Type | Description |
|---|---|---|
| Student_ID | Numerical | Unique ID — dropped before modeling |
| Name | Text | Student name — casing issues fixed |
| Age | Numerical | Student age — wrong dtype fixed |
| Gender | Categorical | Male/Female — casing standardized |
| City | Categorical | Student city |
| Department | Categorical | CS / EE / ME / BBA / SE |
| Education_Level | Categorical | Intermediate / Bachelors / Masters |
| Attendance_% | Numerical | Attendance percentage |
| Study_Hours_Daily | Numerical | Daily study hours |
| Assignments | Numerical | Assignment score out of 10 |
| Quizzes | Numerical | Quiz score out of 20 |
| Midterm | Numerical | Midterm score |
| Internet_Access | Categorical | Yes / No |
| Final_Score | Numerical | TARGET — what we predict |
- Loaded dataset using
pd.read_excel() - Checked shape, dtypes, missing values, head/tail, describe
Fixed all 7 problems in the dataset:
- ✅ Gender casing →
.str.title() - ✅ Name casing →
.str.title() - ✅ Department inconsistencies →
.str.upper().str.strip() - ✅ Age wrong dtype →
pd.to_numeric(errors='coerce')+ median fill - ✅ Impossible Attendance values → replaced with NaN
- ✅ Impossible Final_Score values → replaced with NaN
- ✅ Missing values → filled with median (robust to outliers)
- ✅ Duplicate rows → removed with
drop_duplicates()
7 charts with written interpretations:
- Distribution of Final_Score (histplot)
- Attendance % vs Final_Score (scatter)
- Study Hours vs Final_Score (scatter)
- Midterm vs Final_Score (scatter)
- Correlation Heatmap
- Final_Score by Department (boxplot)
- Students per Department (countplot)
New features created:
Total_Academic= Midterm + Assignments×5 + Quizzes×2Attendance_Category= Low / Medium / High (binned)Study_Efficiency= Study_Hours × (Attendance / 100)
Encoding decisions:
- OneHot → Gender, Internet_Access, City, Department (no order)
- Ordinal → Education_Level, Attendance_Category (order exists)
- StandardScaler → all numerical columns
- Model: Linear Regression via sklearn Pipeline
- Train/Test Split: 80/20, random_state=42
| Metric | Value |
|---|---|
| MAE | ~2.45 |
| RMSE | ~3.27 |
| R² | ~0.59 |
The model explains 59% of the variation in Final_Score. The strongest predictor was Midterm score, followed by the engineered Total_Academic feature.
- Try Random Forest / XGBoost to capture non-linear patterns
- Collect more data — 200 rows is small for ML
- Add stronger features like previous GPA or assignment submission rate
- Python 3.10
- Pandas, NumPy
- Scikit-learn (Pipeline, ColumnTransformer, LinearRegression)
- Matplotlib, Seaborn
- Google Colab
- Clone this repo
git clone https://github.com/your-username/student-performance-prediction-
Upload notebook to Google Colab
-
Upload dataset to Google Drive at:
/content/drive/MyDrive/gdg project/student_performance_dataset.xlsx
- Run all cells top to bottom
Muhammad Majid Ali COMSATS University Islamabad, Wah Campus GDGoC DECODE Data Science Bootcamp 2026