Skip to content
0

Predicting Industrial Machine Downtime: Level 2

๐Ÿ“– Background

You work for a manufacturer of high-precision metal components used in aerospace, automotive, and medical device applications. Your company operates three different machines on its shop floor that produce different-sized components, so minimizing the downtime of these machines is vital for meeting production deadlines. Choose your difficulty level! You decide how challenging this competition will be. Depending on your skill level, decide on which aspect you want to focus. Each difficulty level uses the same dataset, but each time with increasing difficulty.

๐Ÿ’พ The data

The company has stored the machine operating data in a single table, available in 'data/machine_downtime.csv'.

Each row in the table represents the operational data for a single machine on a given day:
  • "Date" - the date the reading was taken on.
  • "Machine_ID" - the unique identifier of the machine being read.
  • "Assembly_Line_No" - the unique identifier of the assembly line the machine is located on.
  • "Hydraulic_Pressure(bar)", "Coolant_Pressure(bar)", and "Air_System_Pressure(bar)" - pressure measurements at different points in the machine.
  • "Coolant_Temperature", "Hydraulic_Oil_Temperature", and "Spindle_Bearing_Temperature" - temperature measurements (in Celsius) at different points in the machine.
  • "Spindle_Vibration", "Tool_Vibration", and "Spindle_Speed(RPM)" - vibration (measured in micrometers) and rotational speed measurements for the spindle and tool.
  • "Voltage(volts)" - the voltage supplied to the machine.
  • "Torque(Nm)" - the torque being generated by the machine.
  • "Cutting(KN)" - the cutting force of the tool.
  • "Downtime" - an indicator of whether the machine was down or not on the given day.

๐Ÿ’ช Competition challenge

In this second level, you're going to visualize and examine the data in more detail. This level is aimed towards intermediate learners. If you want to challenge yourself a bit more, check out level three! Create a report that covers the following:

Explore correlations between the various operational data in the dataset. Do you see a pattern in machine downtime over time? Which factors (visually) seem to be connected to machine downtime?

EXECUTIVE SUMMARY

Our fundamental quest is to provide a guideline to minimize machine failure.

Cross plots among features provide a simple guideline to this fundamental quest. There is a control hierarchy among the numeric variables. Torque is at the top of the rank.

Keeping torque values within no-failure intervals is sufficient to reduce failures by at least 90%, regardless of the other features.

The cross plot also reveal an unusual pattern. Most features have double ranges that correspond to up and down states, their relation to failure is non_linear.

For this reason, methods based on linear correlation are of little use.

Random forest classifier achieves over 98 percent of accurate prediction given any set of feature values. However, the method cannot establish the control hierarcy among variables, even though it can provide relative importance of features.

Decision tree classifier has the potential to determine the control hierarchy but in this case it fails too, because of the double success/failure zones. Decision three can only use single less or greater comparison to chose binary branches.

DATA CLEANING


#############################
# DATA IMPORT AND CLEANING
#############################

# Import libraries
# Import required libraries
import pandas as pd
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV, KFold, train_test_split, cross_val_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix,classification_report,roc_auc_score
from sklearn.ensemble import VotingClassifier,AdaBoostClassifier

#import essential libraries too
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# Read datafile and display
downtime_original = pd.read_csv('data/machine_downtime.csv')
display(downtime_original.head(20))

#e Extract list of columns
columns = downtime_original.columns

# Cconvert columns of object type to category type
for col in columns:
    if downtime_original[col].dtype == 'object':
        downtime_original[col] = downtime_original[col].astype('category')

# Print info
print(downtime_original.info())

# Check missing values
print(downtime_original.isna().sum())

# Drop rows with missing values
downtime = downtime_original.dropna()

# Change date to datetime type
downtime['Date'] = pd.to_datetime(downtime['Date'])

# Print info once again to see modifications
print(downtime.info())

# Print unique values of categories
print(downtime.Downtime.unique())
print(downtime.Machine_ID.unique())
print(downtime.Assembly_Line_No.unique())

# Insert two additonal columns updown representing machine failure as 1
downtime['updown'] = np.where(downtime['Downtime'] == 'Machine_Failure', 1, 0)

# Also insert downup representing machine failure as 0
downtime['downup']=np.where(downtime['Downtime']=='No_Machine_failure',0,1)

EXPLORATORY DATA ANALYSIS

MACHINE DOWNTIME FREQUENCY OVER TIME

##########################
# MACHINE FAILURE VS TIME
##########################

# Calculate and plot machine downtime frequency over time.

#e Extract month and year columns from Date columm
downtime['month'] = downtime['Date'].dt.month
downtime['year'] = downtime['Date'].dt.year

# Count montly and yearly failures
monthly_failures = downtime.groupby(['year', 'month'])['updown'].sum().reset_index()

# Count montly no_failures
monthly_no_failures=downtime.groupby(['year','month'])['downup'].sum().reset_index()

# Plot montly failures colored by year
sns.barplot(data=monthly_failures, x='month', y='updown', hue='year', palette=['blue', 'green'])
plt.title(f'Number of failures over months')
plt.ylabel('Failures')
plt.show()

# Plot montly no_failures colored by year
sns.barplot(data=monthly_no_failures, x='month', y='downup', hue='year', palette=['blue', 'green'])
plt.title(f'Number of no-failures over months')
plt.ylabel('No-Failures')
plt.show()

REMARKS:

Number of failures of months increases until March 2022 and then declines.

Number of no_failures, thus total activity also increases until March 2022 and declines afterward.

Number of failures inreases with activity but the ratio of failure to no-failure remains nearly the same.

COMPARE FAILURE AND NO-FAILURE RATES FOR DIFFERT MACHINE TYPES


##############################
# COMPARISON OF MACHINE TYPES
##############################

# Compare faiure and no-failure rates for diffent machine typew

# Group by Machine_ID and Downtime, and count the dates
down_mac_time = downtime.groupby(['Machine_ID', 'Downtime'])['Date'].count()
print(down_mac_time)

# Create a dictionary to store machine type and corresponding failure fraction
mac_frac={}
l1sum=down_mac_time['Makino-L1-Unit1-2013'].sum()

l1_frac=down_mac_time['Makino-L1-Unit1-2013']['Machine_Failure']/l1sum
mac_frac['L1']=l1_frac

# Repeat for machine L2 
l2sum=down_mac_time['Makino-L2-Unit1-2015'].sum()

l2_frac=down_mac_time['Makino-L2-Unit1-2015']['Machine_Failure']/l2sum
mac_frac['L2']=l2_frac

# Repeat for machine L3
l3sum=down_mac_time['Makino-L3-Unit1-2015'].sum()

l3_frac=down_mac_time['Makino-L3-Unit1-2015']['Machine_Failure']/l2sum
mac_frac['L3']=l3_frac

# Print the results 
print(f'***** Failure fraction for machine types \n {mac_frac}')

# Generate a barplot of failure fractions for all three machines
sns.barplot(mac_frac)
plt.title('Fraction of failure for the three different machine types')
plt.xlabel('Machine groups')
plt.ylabel('Fraction of failure')
plt.show()

# Reset index of down+mac_time to convert to dataframe to use in seaborn
down_mac_time = down_mac_time.reset_index()

# Plot using seaborn color coded by downtime
sns.barplot(x='Machine_ID', y='Date', hue='Downtime', data=down_mac_time)
plt.title('Machine failure or no failure')
plt.show()

CORRELATION BETWEEN VARIOUS OPERATIONAL FEATURES


###############
# CORRELATIONS
###############


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

# Compute correlation matrix for operational features including downtime.

# Design a function to plot:
#(i) heatmap of correlation matrix among numeric variables
#(ii) bars for correlation of features with machine failure for each machine type
#(iii) heatmap of correlation between main features for each machine type with downtime
#(iv) heatmap of correlation between main features for each machine type for machine in failed state and operational state

###############################
def correlate_failure(df, title, flag,mac):
    # Drop unnecessary categorical columns. Use Machine ID L1 for
    #analysis 
    # The other machine must follow suite as there are very little difference     in performance
    downtime_cor_prep=df[df['Machine_ID']==mac]
    downtime_cor_prep = df.drop(['Date', 'Machine_ID', 'Assembly_Line_No', 'Downtime','downup'], axis=1)
    
    # Select numeric variables to be correlared
    downtime_cor_sel = downtime_cor_prep[['Torque(Nm)', 'Hydraulic_Pressure(bar)', 'Cutting(kN)', 'Spindle_Speed(RPM)', 'updown']]
    
    # Now select rows for only updown=0 (no failure)
    downtime_cor_nofail=downtime_cor_sel[downtime_cor_sel['updown']==0]
    # Drop the updown columns 
    downtime_cor_nofail=downtime_cor_nofail.drop(['updown'],axis=1)
    
    # Now select rows for only updown=1 (failure) and drop updown colummn
    downtime_cor_failure=downtime_cor_sel[downtime_cor_sel['updown']==1]
    downtime_cor_failure=downtime_cor_failure.drop(['updown'],axis=1)
    
    # Calculate the correlation of 'updown' with other columns
    # Updown = 1 for machine failure
    
    # Prepare general correlation matrix 
    correlation_matrix=downtime_cor_prep.corr()
    
    # Correlate main numeric variables
    correlation_matrix2 = downtime_cor_sel.corr()
    
    # Correlate main numeric variables for the case of no failure
    correlation_matrix3=downtime_cor_nofail.corr()
    
    # Correlate main numeric variables for the case of failures
    correlation_matrix4=downtime_cor_failure.corr()
    
    # Plot heatmap of general correlation matrix 
    if flag:
        print(f'Correlation matrix between various operational data')
        sns.heatmap(correlation_matrix,cmap='coolwarm')
        plt.title(f'Heatmap of correlation between features for {mac}, updown= 1: down, 0: up', y=1.05)
        plt.show()
        
    #####################
    
    # Barplot of correlation of numerical variables with failure
    print(title)
    print(correlation_matrix['updown'])
    sns.barplot(x=correlation_matrix.index, y=correlation_matrix['updown'])
    plt.xticks(rotation=90)
    plt.title(title)
    
    plt.ylabel('Machine_failure')
    plt.show()
    
    # Heatmap of correlation of main variables and downtime
    sns.heatmap(correlation_matrix2, annot=True, cmap='coolwarm')
    plt.title(f'Heatmap of correlation between main features for {mac} updown= 0: up, 1:down',y=1.05)
    plt.show()
    
    # Heatmap of correlation matrix for the machine L! operational state 
    plt.ylabel('Machine_failure')
    sns.heatmap(correlation_matrix3, annot=True, cmap='coolwarm')
    plt.title(f'Heatmap of correlation between main features for {mac} machine is up', y=1.05)
    plt.show()
    
    # Heatmap of correlation matrix for machine failure for machine L1
    plt.ylabel('Machine_failure')
    sns.heatmap(correlation_matrix4, annot=True, cmap='coolwarm')
    plt.title(f'Heatmap of correlation between main features. for {mac} machine down', y=1.05)
    plt.show()
    
#############################
mac_list=['Makino-L1-Unit1-2013', 'Makino-L3-Unit1-2015', 'Makino-L2-Unit1-2015']
for mac in mac_list:
    # Set title and call the correlation failure function
    flag = True
    title = f'Correlation of Machine_failure with operational data-for machine type {mac}'
    correlate_failure(downtime, title, flag,mac)
โ€Œ
โ€Œ
โ€Œ