Estimating the compressive strength of concrete using Machine Learning
By: Sruthi Sivakumar
Tags: Predictions, Compressive Strength, Machinelerning, Regression, Concrete

Photo by Ben Allan on Unsplash

Concrete dates back to approximately 300 BC when the Romans packed a mixture of volcanic ash, lime and seawater into a wooden block and stacked them like bricks once hardened. I mean, sure the definition and the ingredients of concrete have changed along the way, but the durability and endurance of the material never fail to fascinate researchers. For any concrete to be durable, it must first be manufactured as a high-quality concrete. One of the many ways to evaluate the quality of concrete is in terms of its compressive strength.

What is compressive strength, anyway?

Compressive strength is a measure of the concrete’s capacity to resist loads that aim to compress it. How well a concrete can withstand load determines the quality of the concrete. Generally, the concrete is tested for a period of 28 days which can be cumbersome and could be subject to errors. To avoid all this mind-numbing work, we could automate the process using Machine Learning to predict the compressive strength and arrive at an estimate.

Dataset Description

The dataset was taken from the UCI Machine Learning Repository. It contains 1030 instances and 9 attributes with surprisingly no missing values. Among the 8 input variables, 7 represent the amount of raw materials needed and 1 represents age. The target variable is Concrete Compressive Strength (obviously) measured in Mega Pascal(MPa).

Raw materials

Cement (component 1)(kg in a m³ mixture)

Blast Furnace Slag (component 2)(kg in a m³ mixture)

Fly Ash (component 3)(kg in a m³ mixture)

Water (component 4)(kg in a m³ mixture)

Superplasticizer (component 5)(kg in a m³ mixture)

Coarse Aggregate (component 6)(kg in a m³ mixture)

Fine Aggregate (component 7)(kg in a m³ mixture)

Other stuff

Age (day)

Target variable

Concrete compressive strength(MPa, megapascals)

Importing the dependencies

Let us first import the libraries that we need.

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

import seaborn as sns

import pickle as pkl

from sklearn.model_selection import train_test_split

from sklearn.tree import DecisionTreeRegressor

from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

from sklearn.ensemble import RandomForestRegressor

%matplotlib inline

After importing the libraries and the dataset, we can see that the column names appear to be really messy, so we can rename those for better readability and easy access.

rename_cols = ["Cement", "Blast_Furnace_Slag", "Fly_Ash", "Water", "Superplasticizer","Coarse_Aggregate", "Fine_Aggregate", "Age", "CCS"]

cols = list(df.columns) map = {}

for i, name in enumerate(cols):

map[name] = rename_cols[i] df = df.rename(columns=map)

Exploratory Data Analysis (EDA)

To get a better understanding of what we’re dealing with, we ought to explore the dataset and get insights from it. Exploring the dataset involves looking for missing values, plotting pretty graphs between different variables etc. You don’t have to go all Dora on this, but a little bit of curiosity is appreciated.

Let us first print the first few rows of the dataset.

df.head()

Fig 1 : First four rows of the dataset

df.info()

Fig 2 : Overview of the dataset

A quick overview of the dataset tells us that all of the variables in the dataset are integer and float variables. And now, we check for missing values in the dataset (if any) to perform the missing value analysis.

df.isna().any()

Fig 3 : Checking for missing values

Fortunately, there are no missing values in the dataset. This makes our job much easier!

df.describe()

Fig 4 : Statistics of the dataset

The average age is 45.666 days and the lowest is 1 day.

Data Visualisation

And now, the fun part! To make pretty graphs we’re going to make use of a library called Seaborn in python. Seaborn is a data visualisation library based on matplotlib which provides a top-notch interface for drawing statistical graphs that are nice to look at.

dist = sns.distplot(df['CCS'], color = 'limegreen')

plt.title('Distribution of Compressive Strength')

Fig 5 : Distribution of Compressive Strength

To see how every feature affects another, we have to check for the correlation between them. In order to make use of the linear regression models, we must remove the correlated features.

corr = df.corr()

plt.figure(figsize=(13,8))

plt.title("Feature Correlation Heatmap")

sns.heatmap(corr,cmap= "Purples_r",annot=True)

Fig 6 : Feature Correlation Heatmap

From the above heatmap, we can infer that Cement is strongly correlated with CCS with a value of 0.5. Superplasticizer and Age are also highly correlated with CCS with values 0.37 and 0.33 respectively. Water does not influence Superplasticizer at all. These values allow us to comprehend the data in-depth as they provide an overview of how each feature affects the other.

Since Cement, Superplasticizer and Age are strongly correlated with CCS, we can draw scatter plots between the same.

plt.figure(figsize=(10,7))

sns.scatterplot(data =df,y="CCS",x="Cement",hue="Superplasticizer",size="Age",sizes=(50,300))

plt.title("CCS vs (Cement,Superplasticizer, Age)")

Fig 7 : CCS vs Cement, Superplasticizer, Age

Compressive strength increases with the amount of Cement.

Compressive strength increases with Superplasticizer as well.

Cement with low age requires more cement for higher strength

plt.figure(figsize=(10,7))

sns.scatterplot(data = df,y="CCS",x="Coarse_Aggregate",hue="Water",size="Superplasticizer",sizes=(50,300))

plt.title("CCS vs (Coarse_Aggregate,Water, Superplasticizer)")

Fig 8 : CCS vs Coarse_Aggregate, Water, Superplasticizer

Compressive strength decreases with increase in water but increases with increase in Superplasticizer ( since CCS and Superplasticizer are highly correlated)

The amount of coarse aggregate is larger when less amount of water and superplasticizer is used.

Data Preprocessing

Before we build the models, we need to split the data into testing and training sets.

x = df.iloc[:,:-1]

y = df.iloc[:,-1]

X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=2)

Building the model

Decision Tree Regressor

Decision Tree is a widely used supervised learning algorithm for decision-making problems. The model predicts the target variable values by learning simple decision rules obtained from the data features. It could however have an overfitting problem that can be overcome using the Random forest algorithm.

Fig 9 : Decision Tree Model

Random Forest Regressor

To get a more accurate and reliable prediction, Random Forest constructs several decision trees and merges them together. It uses averaging to improve the predictive accuracy and control overfitting. One of the significant advantages of a random forest is that it can be used for the majority of existing machine learning systems for both classification and regression problems.

Fig 10 : Random Forest Model

Comparing the models

Fig 11 : Decision Tree vs Random Forest based on their RMSE values

Now that we have analysed the dataset, created our models and picked a model to estimate the CCS values, it’s time to put them to test. Here, I’m initialising an array called random_values with the following:

Cement = 520

Blast Furnace Slag = 130

Fly Ash = 17.5

Water = 173

Superplasticizer = 2.5

Coarse Aggregate = 999

Fine Aggregate = 825

Age = 275 days

Fig 12 : Estimation of Compressive Strength

Conclusion

We’ve successfully analysed the dataset and estimated the compressive strength using Decision Tree Regressor and Random Forest Regressor. The Random Forest model provided the least RMSE. Hence, it is the relatively best model for predicting the strength of concrete. The accuracy of the model can be further improved by using ensemble learning and other techniques.

Kudos to you, if you have made it this far! Thanks for reading this article, I hope you find it helpful!

Resources

You can find the link to my Github repository with relevant files here :