Mobile Price
Classification: Predict
Phone Price Ranges.
Dive into the Mobile Price Classification dataset on Kaggle. We’ll train two machine-learning models โ Logistic Regression and Random Forest โ on 2,000 phones with 20 hardware features to predict one of 4 price ranges (Low / Medium / High / Very High). Every line of code is explained for beginners โ with copy buttons on every block.
# Mobile Price Classification from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import accuracy_score rf = RandomForestClassifier(n_estimators=100, random_state=42) rf.fit(X_train, y_train) acc = accuracy_score(y_test, rf.predict(X_test))
Six steps from raw data
to ML predictions.
The complete pipeline for the Mobile Price Classification Python project. Click any step to jump straight to its code and beginner-friendly explanation.
Data Loading
Stream the Mobile Price Classification dataset straight into a pandas DataFrame using KaggleHub.
Data Exploration
Explore shape, target balance, correlations, and how RAM separates the four price ranges.
Data Preprocessing
Split features from target, create train/test sets, and scale features for the linear model.
Train Classifiers
Train two scikit-learn models โ Logistic Regression and Random Forest โ on the same dataset.
Model Evaluation
Compare accuracy, print classification reports, plot confusion matrix, and rank feature importance.
Prediction & Conclusion
Predict the price range for a brand-new phone and recap what you learned in the project.
Load the dataset with KaggleHub.
Stream the Mobile Price Classification dataset straight into a pandas DataFrame โ no manual download needed.
What is this dataset? The Mobile Price Classification dataset contains 2,000 fictional phones described by 20 hardware features โ battery power, RAM, screen size, pixel resolution, number of cores, Wi-Fi, Bluetooth, and so on. The target column price_range has four classes: 0 (Low Cost), 1 (Medium Cost), 2 (High Cost), 3 (Very High Cost). Your model’s job is to learn which feature combination maps to which class.
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 download, no manual CSV path.
Important: The file_path is the CSV filename inside the dataset. Visit the Kaggle dataset page โ Files tab to confirm. For this dataset, the file with the target column is train.csv.
# Install dependencies as needed: # pip install kagglehub[pandas-datasets] pandas numpy matplotlib seaborn scikit-learn import kagglehub from kagglehub import KaggleDatasetAdapter import pandas as pd # Set the path to the file you'd like to load # For this dataset, the labeled file is train.csv file_path = "train.csv" # Load the latest version df = kagglehub.load_dataset( KaggleDatasetAdapter.PANDAS, "iabhishekofficial/mobile-price-classification", file_path, ) print("Shape:", df.shape) print("First 5 records:", df.head())Explore the data with Pandas & Seaborn.
Before training, we need to understand the data: how many phones per price class, which features correlate with price, and how RAM separates the categories.
Why explore first? If you train a model blindly, you might feed it garbage. EDA answers three questions: Is the data balanced? (same number of samples per class), Which features matter? (high correlation with target), and Are there patterns? (e.g., higher RAM โ higher price).
What is a correlation heatmap? A grid where each cell shows how strongly two columns move together. Values range from -1 (opposite) to +1 (same direction). In this dataset, you’ll see ram glow bright red next to price_range โ that’s the strongest signal in the entire dataset.
What is a boxplot? A boxplot shows the distribution of a numeric column grouped by a category. The box represents the middle 50% of values, the line inside is the median, and the “whiskers” extend to typical min/max. We’ll use it to see RAM distribution per price class โ the boxes will rise like a staircase from class 0 to class 3.
import matplotlib.pyplot as plt import seaborn as sns # Quick numeric summary (mean, min, max, std for every column) print(df.describe()) # Is the target balanced? 500 in each class is perfect print("\nTarget distribution:\n", df['price_range'].value_counts()) # Correlation heatmap โ find the strongest signals plt.figure(figsize=(12, 10)) sns.heatmap(df.corr(), cmap='coolwarm', annot=False) plt.title('Feature Correlation Heatmap') plt.show() # Boxplot of RAM per price range โ expect a clear staircase plt.figure(figsize=(8, 5)) sns.boxplot(x='price_range', y='ram', data=df) plt.title('RAM Distribution by Price Range') plt.show()Split & scale with scikit-learn.
Before training, we separate the features (X) from the target (y), hold out 20% of the data for testing, and scale features for the linear model.
Why separate X and y? The model needs to learn a rule: “given these features, predict this target”. We put all input columns into X and the column we want to predict (price_range) into y. The .drop() method removes price_range from X so the model can’t “cheat” by seeing the answer.
Why train/test split? If we train and test on the same data, the model can just memorize. We split 80% for training and 20% for testing. The model only sees the training portion. We then check its accuracy on the unseen 20% โ this simulates how it would perform on real-world new phones. The stratify=y argument keeps the four price classes balanced in both splits.
Why scale features? Logistic Regression uses gradient descent, which is sensitive to feature magnitudes. battery_power ranges from 500 to 2000, while wifi is just 0 or 1 โ the larger numbers would dominate. StandardScaler transforms every column to have mean 0 and standard deviation 1, putting all features on equal footing. We fit_transform on the training set and only transform on the test set (never fit on test data โ that would leak information).
from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # Features (X) = all 20 hardware columns # Target (y) = price_range (0/1/2/3) X = df.drop('price_range', axis=1) y = df['price_range'] # 80% training, 20% testing โ stratify keeps 4 classes balanced X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y ) # Standardize features for Logistic Regression scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) print("Training set:", X_train.shape) print("Test set:", X_test.shape)Train Logistic Regression & Random Forest.
We’ll train two scikit-learn classifiers on the same data so we can compare them. Different algorithms have different strengths, and seeing both is the best way to learn.
Logistic Regression is a linear model. It draws straight decision boundaries between the four price classes. It’s fast, interpretable, and works best when the relationship between features and target is roughly linear. It needs scaled features because it uses gradient descent โ large numbers like battery_power would otherwise dwarf binary flags like wifi. We feed it X_train_scaled.
Random Forest is an ensemble model. It builds 100 decision trees (n_estimators=100), each on a random subset of the data, and lets them vote. The majority prediction wins. This makes it powerful for non-linear patterns and resistant to overfitting. Trees split on raw feature thresholds, so scaling isn’t required โ we feed it X_train directly. The random_state=42 argument makes the result reproducible.
Why train both? Logistic Regression gives you a clean baseline. If Random Forest is dramatically better, that tells you the relationship between features and price is non-linear. If they’re similar, the problem is mostly linear. Comparing them is one of the most educational things you can do as a beginner.
from sklearn.linear_model import LogisticRegression from sklearn.ensemble import RandomForestClassifier # --- Model 1: Logistic Regression (needs scaled features) --- lr = LogisticRegression(max_iter=1000) lr.fit(X_train_scaled, y_train) # --- Model 2: Random Forest (tree-based, no scaling needed) --- rf = RandomForestClassifier(n_estimators=100, random_state=42) rf.fit(X_train, y_train) print("Logistic Regression trained on", X_train_scaled.shape[0], "samples") print("Random Forest uses", rf.n_estimators, "trees")Evaluate with confusion matrix & feature importance.
Training is only half the job. We now compare the two models on the unseen 20% test set and visualize where they shine โ and where they get confused.
Accuracy is the simplest metric: the percentage of phones the model classified correctly. For this dataset, both models usually score between 85% and 97% โ Logistic Regression often edges out Random Forest here because the relationship between RAM and price is largely linear.
Confusion Matrix is a 4ร4 grid (we have 4 classes). Rows = actual class, columns = predicted class. The diagonal cells show correct predictions. Off-diagonal cells show mistakes. A bright diagonal with dim off-diagonals = a good model. In our heatmap, you’ll likely see a few phones from class 1 mistakenly predicted as class 2 โ that’s the boundary where Medium and High Cost overlap.
Classification Report gives three numbers per class: precision (out of all phones predicted as “High”, how many were actually High?), recall (out of all actually-High phones, how many did we find?), and f1-score (a balance of the two). The support column shows how many true samples each class has in the test set.
Feature Importance is a Random Forest superpower. After training, the model tells you which features it actually used most often when splitting. We’ll plot the top 10 โ expect ram to dominate, with battery_power, px_width, and px_height following.
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report import matplotlib.pyplot as plt import seaborn as sns # Predict on the unseen test set lr_pred = lr.predict(X_test_scaled) rf_pred = rf.predict(X_test) # Compare accuracy print("Logistic Regression Accuracy:", accuracy_score(y_test, lr_pred)) print("Random Forest Accuracy:", accuracy_score(y_test, rf_pred)) # Detailed per-class report print("\nClassification Report (Random Forest):\n", classification_report(y_test, rf_pred)) # Confusion matrix heatmap cm = confusion_matrix(y_test, rf_pred) plt.figure(figsize=(7, 5)) sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=['Low', 'Medium', 'High', 'Very High'], yticklabels=['Low', 'Medium', 'High', 'Very High']) plt.xlabel('Predicted') plt.ylabel('Actual') plt.title('Random Forest Confusion Matrix') plt.show() # Top 10 most important features importances = pd.Series( rf.feature_importances_, index=X.columns ).sort_values(ascending=False)[:10] plt.figure(figsize=(8, 5)) sns.barplot(x=importances.values, y=importances.index, palette='viridis') plt.title('Top 10 Most Important Features') plt.show()Predict a new phone & wrap up.
The final test: can our trained model predict the price range for a phone it has never seen? Let’s give it a single new phone spec and see what it says.
How to predict for one phone? Build a one-row DataFrame with the exact same 20 columns the model was trained on. Then call rf.predict(new_phone) โ the model returns a single integer (0, 1, 2, or 3) representing the predicted price class. We map it to a human-readable label like “High Cost”.
Which model to use? Since Logistic Regression scored higher in step 5, we’d technically use lr.predict() with scaled input for production. But for the demo we use Random Forest because it doesn’t need a scaler โ the same new_phone DataFrame can be passed directly. If you wanted to use Logistic Regression, you’d just run scaler.transform(new_phone) first.
The phone we’ll predict: A mid-range phone with 1500 mAh battery, 2.5 GB RAM, 8 MP camera, 16 GB storage, 1400ร800 screen. The model should predict class 1 or 2 โ let’s see.
# Define a brand-new phone with all 20 features new_phone = pd.DataFrame([{ 'battery_power': 1500, 'blue': 1, 'clock_speed': 1.8, 'dual_sim': 1, 'fc': 4, 'four_g': 1, 'int_memory': 16, 'm_dep': 0.5, 'mobile_wt': 140, 'n_cores': 4, 'pc': 8, 'px_height': 800, 'px_width': 1400, 'ram': 2500, 'sc_h': 12, 'sc_w': 6, 'talk_time': 14, 'three_g': 1, 'touch_screen': 1, 'wifi': 1 }]) # Predict with Random Forest (no scaling needed) predicted = rf.predict(new_phone)[0] # Map the integer class to a human-readable label labels = {0: 'Low Cost', 1: 'Medium Cost', 2: 'High Cost', 3: 'Very High Cost'} print(f"Predicted price range: {labels[predicted]}") print(f"RAM = 2500 MB, Battery = 1500 mAh")By completing this project, you’ve built a complete supervised machine-learning pipeline โ the same shape used in real production systems:
- Data Loading with
kagglehubโ pulling a Kaggle dataset straight into a DataFrame. - Exploratory Data Analysis with
pandas&seabornโ describing, balancing, and visualizing the dataset. - Preprocessing with
train_test_split&StandardScalerโ splitting, stratifying, and standardizing features. - Model Training with
LogisticRegression&RandomForestClassifierโ comparing a linear baseline against an ensemble. - Evaluation with
accuracy_score,confusion_matrix,classification_reportโ measuring precision, recall, and feature importance. - Inference on a brand-new data point โ turning a one-row DataFrame into a price-range label.
Happy coding, Love you, my lovely developers! ๐
๐ Ideas to extend the project
- Try more classifiers:
SVC,KNeighborsClassifier,GradientBoostingClassifier, orXGBoostand rank them all. - Hyperparameter tuning with
GridSearchCVโ find the bestn_estimators,max_depth, andmin_samples_splitfor Random Forest. - Drop the obvious features (RAM is too dominant) and see how much accuracy falls โ a great lesson in feature dependence.
- Build a Streamlit web app where users pick phone specs in a form and get a live price prediction.
- Use
test.csvfrom the same Kaggle dataset as a real submission set and write predictions to a CSV file.
Frequently Asked Questions
What ML algorithms are used in this mobile price classification project? +
This project trains and compares two classifiers from scikit-learn: Logistic Regression (a fast, linear model that needs scaled features) and Random Forest (an ensemble of 100 decision trees that handles non-linear patterns without scaling). Both predict the price_range target with 4 classes: 0 (Low), 1 (Medium), 2 (High), 3 (Very High).
What features are most important for predicting mobile price? +
According to the Random Forest feature_importances_ attribute, RAM is by far the strongest predictor, followed by battery_power, pixel width, pixel height, and mobile weight. Together these five features usually account for over 70% of the model’s decision power โ which is why the EDA heatmap shows the brightest correlation cell at the intersection of ram and price_range.
Do I need to scale features for mobile price classification? +
Yes for Logistic Regression, because it uses gradient descent and is sensitive to the magnitude of features like RAM (in megabytes) versus dual_sim (0 or 1). Random Forest is tree-based and does not require scaling, but you should still split your data into train and test sets with stratify=y to keep the four price classes balanced.
Why does Logistic Regression often beat Random Forest here? +
The relationship between RAM and price_range in this dataset is mostly linear and well-separated. Random Forest shines when the decision boundary is non-linear or when features interact in complex ways. For this clean dataset, the linear model’s bias is actually an advantage โ it generalizes better and avoids the small over-fitting penalty trees can suffer.
Run the project
yourself.
Open a terminal, install the required libraries, and run the file end-to-end. Or click “Copy Full Project Code” at the top of this page.
Share this Project
If you found this walkthrough helpful, share it with your friends and fellow developers!
