Skip to content

Repository files navigation

Battery State of Charge Prediction using Random Forest

This project predicts the State of Charge (SOC) of a lithium-ion battery using a Random Forest Regression model implemented in Python.

The model is trained using battery operating parameters such as voltage, current, elapsed time, energy, and remaining capacity. The reference SOC is calculated from the remaining battery capacity and nominal battery capacity.

Project Objective

The objective of this project is to develop a machine learning model that predicts battery SOC from charge or discharge data.

The project includes:

  • Reading battery data from an Excel file
  • Calculating reference SOC
  • Selecting input features
  • Splitting the data into training and testing datasets
  • Training a Random Forest Regression model
  • Evaluating the model using RMSE and R² score
  • Comparing actual and predicted SOC
  • Exporting prediction results to Excel
  • Visualizing the results using Matplotlib

SOC Calculation

The reference SOC is calculated using:

[ SOC(%) = \frac{\text{Remaining Capacity (Ah)}}{\text{Nominal Capacity (Ah)}} \times 100 ]

In this project, the nominal capacity is defined as:

nominal_capacity = 30

Therefore:

[ SOC(%) = \frac{\text{Remaining Capacity (Ah)}}{30} \times 100 ]

Dataset Columns

The input Excel file is expected to contain the following columns:

Voltage (V)
Current (A)
Time (Sec)
Energy (Wh)
Remaining Capacity (Ah)

A new target column is created in the program:

SOC(%)

Input Features

The Random Forest model uses the following input features:

x = df[
    [
        'Voltage (V)',
        'Current (A)',
        'Time (Sec)',
        'Energy (Wh)',
        'Remaining Capacity (Ah)'
    ]
]

The prediction target is:

y = df['SOC(%)']

Machine Learning Algorithm

The project uses the RandomForestRegressor algorithm from Scikit-learn.

Random Forest is an ensemble machine learning method that trains multiple decision trees. Each decision tree generates an SOC prediction, and the final prediction is obtained by averaging the outputs of all trees.

The model is configured as:

model = RandomForestRegressor(
    n_estimators=100,
    random_state=42
)

Where:

  • n_estimators=100 creates 100 decision trees.
  • random_state=42 ensures reproducible results.

Train-Test Split

The dataset is divided into:

  • 80% training data
  • 20% testing data
x_train, x_test, y_train, y_test = train_test_split(
    x,
    y,
    test_size=0.2,
    random_state=42
)

The training dataset is used to teach the model, while the testing dataset is used to evaluate its prediction performance.

Model Training

The Random Forest model is trained using:

model.fit(x_train, y_train)

During training, the model learns the relationship between the battery parameters and the calculated SOC.

SOC Prediction

After training, SOC is predicted for the test dataset:

y_pred = model.predict(x_test)

The predicted SOC values are compared with the actual SOC values calculated from remaining capacity.

Model Evaluation

The model is evaluated using:

  • Root Mean Squared Error
  • Coefficient of Determination

Root Mean Squared Error

[ RMSE = \sqrt{ \frac{1}{n} \sum_{i=1}^{n} (y_i-\hat{y}_i)^2 } ]

RMSE measures the average prediction error. A lower RMSE indicates better model performance.

The code calculates RMSE using:

rmse = np.sqrt(
    mean_squared_error(y_test, y_pred)
)

R² Score

[ R^2 = 1 - \frac{ \sum(y_i-\hat{y}_i)^2 }{ \sum(y_i-\bar{y})^2 } ]

The R² score measures how well the model explains the variation in SOC.

Typical interpretation:

R² close to 1.0  → Very strong prediction
R² close to 0.0  → Poor predictive performance
R² below 0.0     → Worse than predicting the mean SOC

The evaluation results are printed as:

print(f"RMSE: {rmse:.2f}")
print(f"R2: {r2:.2f}")

Output Excel File

The program creates an output Excel file containing:

Voltage (V)
Current (A)
Time (Sec)
Energy (Wh)
Remaining Capacity (Ah)
Actual SOC
Predicted SOC

The results are sorted by elapsed time:

results_sorted = results.sort_values(
    by='Time (Sec)'
)

The output file is saved as:

SOC_predictions_sorted_9.xlsx

Result Visualization

The program generates a line plot comparing:

  • Actual SOC
  • Random Forest predicted SOC

The results are sorted by time before plotting.

plt.plot(
    results_sorted['Actual SOC'],
    label='Actual SOC',
    marker='o'
)

plt.plot(
    results_sorted['Predicted SOC'],
    label='Predicted SOC',
    linestyle='--',
    marker='x'
)

The graph helps visually evaluate how closely the predicted SOC follows the actual SOC.

Technologies Used

  • Python
  • Pandas
  • NumPy
  • Scikit-learn
  • Matplotlib
  • OpenPyXL
  • Joblib

Installation

Clone the repository:

git clone https://github.com/your-username/SOC-estimation.git

Navigate to the project folder:

cd SOC-estimation

Create a virtual environment:

python -m venv .venv

Activate the environment on Windows:

.venv\Scripts\activate

Install the required libraries:

pip install pandas numpy scikit-learn matplotlib openpyxl joblib

Running the Program

Update the Excel file path in the Python code:

df = pd.read_excel(
    'path/to/your/battery_dataset.xlsx'
)

Run the program:

python soc_estimation.py

The program will:

  1. Read the Excel dataset.
  2. Display the first five rows.
  3. Calculate actual SOC.
  4. Split the data into training and testing datasets.
  5. Train the Random Forest model.
  6. Predict SOC for the test dataset.
  7. Print RMSE and R².
  8. Export prediction results to Excel.
  9. Display the actual-versus-predicted SOC graph.

Saving the Trained Model

The model-saving section is currently commented out:

# from joblib import dump, load
# dump(
#     model,
#     'SOC_predictor_Shriram_Kumar_6.joblib'
# )

To save the trained model, remove the comment symbols:

from joblib import dump

dump(
    model,
    'SOC_predictor_Shriram_Kumar_6.joblib'
)

The saved model can later be loaded using:

from joblib import load

model = load(
    'SOC_predictor_Shriram_Kumar_6.joblib'
)

Recommended Improved Feature Selection

For an independent SOC estimator, the following features can be used:

x = df[
    [
        'Voltage (V)',
        'Current (A)',
        'Time (Sec)',
        'Energy (Wh)'
    ]
]

Repository Structure

SOC-estimation/
│
├── data/
│   └── SOC_predictions_sorted_1.xlsx
│
├── results/
│   └── SOC_predictions_sorted_9.xlsx
│
├── models/
│   └── SOC_predictor_Shriram_Kumar_6.joblib
│
├── soc_estimation.py
├── requirements.txt
├── .gitignore
└── README.md

Author

Shrinithi Sellam

MSc Data Science student with hands-on professional and project experience in data pipelines, machine learning and business intelligence. Proficient in detecting anomalies, building forecasting models and delivering structured analyses.

About

Machine learning-based battery State of Charge estimation using charge–discharge data, Coulomb counting, and Random Forest regression in Python.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages