Electric Motor Temperature Estimation using regression models

Abigail Sixto
6 min readMay 28, 2020

--

The electric motors industry is growing exponentially and technologies used are in constant evolution. Data scientists can play a part during this development. I came across this dataset in a Kaggle competition with the challenge to estimate motor variables like the motor temperatures using other measurables variables from the same motor like currents, voltages, motor speed, and coolant and ambient temperatures. Keeping the temperature inside the motor parts under control is important as the permanent magnet could demagnetize or the rotor windings could melt and both lead to motor failure.

Where machine learning could be helpful in this process?

Let me show you some graphics to explain it better.

This part of the process was performed in a university lab where the data set was obtained and then loaded to Kaggle.

As data scientists, we obtained this data and try to estimate the temperatures with the best machine learning model. Previously this step required highly specialized field knowledge of materials and thermodynamics.

Then the machine learning model can be implemented and embedded with the control systems of the motor where the new data is read constantly and the model will provide accurate estimations.

First I have downloaded the data set from Kaggle and start to do some exploration. The data is provided normalized to try to anonymize it. The motor used is a real working model from a German manufacturer and they would not like to give away any design details. The data is cleaned and no missing values, ready to start visualizations and gather more information.

But first, what each column represents:

  • ambient: Ambient temperature as measured by a thermal sensor located closely to the stator.
  • coolant: Coolant temperature. The motor is water-cooled. Measurement is taken at the outflow.
  • u_d : Voltage d-component
  • u_q : Voltage q-component
  • motor_speed: Motor speed
  • torque: Torque induced by current
  • i_d: Current d-component
  • i_q : Current q-component
  • pm: Permanent Magnet surface temperature representing the rotor temperature. This was measured with an infrared
  • stator_yoke : Stator yoke temperature measured with a thermal sensor.
  • stator_winding : Stator tooth temperature measured with a thermal sensor.
  • profile_id : Each measurement session has a unique ID.

The data set consists of 11 variables and an extra column providing an identification number of the recording session. At each session, they push the motor at very different driving conditions. Here the measurements of temperatures at one of those profiles.

As you can see all 4 variables relating to internal motor temperatures follow the same pattern although permanent magnet temperature (‘pm’) is slightly delayed. This temperature will be my target and I drop the other 3 variables as they are highly correlated and it cannot be measured in normal driving conditions of the car. Another variable I decided to drop was ‘Torque” as is not measurable either and this could be a target variable for another project.

Here is the heatmap for the dataset

Let’s prepare data for modeling!

First, I drop the unwanted columns from the data frame which I already mentioned the 3 other temperatures ‘stator_yoke’, ‘stator_winding’, ‘stator_tooth’, ‘torque’, and ‘profile_id’. Separated the data in predictors and target variable and use train_test_split to separate the train and test sets. I’ll be using Crossvalidation then I will not need a validation set.

I will be using a linear regression model as my baseline model.

# assign model to variable
regression = LinearRegression(fit_intercept=False)crossvalidation = KFold(n_splits=5, shuffle=True, random_state= 42)
regression.fit(X_train,y_train)
baseline = cross_validate(regression, X_train, y_train,
scoring=('r2','neg_mean_squared_error'),
cv = crossvalidation, return_train_score=True)

And the scores were:

train_r2: 0.4708
test_r2: 0.4708
train_MSE: 0.5246 (+/- 0.0009)
test_MSE: 0.5246 (+/- 0.0038)

Not bad results but for our application, they are not good enough.

I have tried adding extra columns using feature engineering, my background in Electrical Engineering would be handy at this point.

Derived_features = {
‘i_s’: lambda x: np.sqrt(x[‘i_d’]**2 + x[‘i_q’]**2), # Current vector
‘u_s’: lambda x: np.sqrt(x[‘u_d’]**2 + x[‘u_q’]**2), # Voltage vector
‘S_elec’: lambda x: x[‘i_s’]*x[‘u_s’], # Apparent power
‘P_elec’: lambda x: x[‘i_d’] * x[‘u_d’] + x[‘i_q’] *x[‘u_q’], # Effective power
‘i_s_x_w’: lambda x: x[‘i_s’]*x[‘motor_speed’],
‘S_x_w’: lambda x: x[‘S_elec’]*x[‘motor_speed’],
}
X_train_xfeat.assign(**Derived_features)

The results for the linear model with these extra predictors it was very similar to the baseline model then I decided to use a different repressor. The data has a non-linear shape, then a linear model cannot capture the non-linear features. I decided to try Random Forest Regressor.

Rfr = RandomForestRegressor(n_estimators = 20, random_state = 0)
Rfr.fit(X_train,y_train)
RandomFR_model = cross_validate(Rfr, X_train, y_train,
scoring=(‘r2’,’neg_mean_squared_error’),
cv = crossvalidation, return_train_score=True)

And the results were:

train_r2: 0.9972
test_r2: 0.983
train_MSE: 0.0028 (+/- 0.0)
test_MSE: 0.0168 (+/- 0.001)

The results are a big improvement from the baseline model. Now using GridsearchCV I tried to optimize the hyperparameters of the RandomForest regressor and find the best model. The results were:

param_grid = {‘n_estimators’: [3,10,20],’max_features’: [2,4,7]}

forest_reg = RandomForestRegressor()
gs_forest = GridSearchCV(forest_reg, param_grid, cv=5,scoring= ‘neg_mean_squared_error’,return_train_score = True)
gs_forest.fit(X_train, y_train)
gs_forest.best_params_>> {'max_features': 4, 'n_estimators': 20}

We can check MSE values for the different models

cvres = gs_forest.cv_results_
for mean_score,params in zip(cvres[“mean_test_score”],cvres[“params”]):
print(round(-mean_score.mean(),4),params)
>>0.0413 {'max_features': 2, 'n_estimators': 3}
0.0266 {'max_features': 2, 'n_estimators': 10}
0.0237 {'max_features': 2, 'n_estimators': 20}
0.0255 {'max_features': 4, 'n_estimators': 3}
0.0172 {'max_features': 4, 'n_estimators': 10}
0.0155 {'max_features': 4, 'n_estimators': 20}
0.0243 {'max_features': 7, 'n_estimators': 3}
0.0182 {'max_features': 7, 'n_estimators': 10}
0.0168 {'max_features': 7, 'n_estimators': 20}

Our best model has an MSE value of 0.0155 which is less than the original RandomForest MSE = 0.0168

I could extract Feature Importances from this model and these are the results :

The next step would be to use the test data on the best model and the results were:

final_mse = mean_squared_error(y_test,final_predictions)
final_mse
>> 0.013361251762329635

Visualizing some observations of our predicted and actual values for the PM temperature we can show:

I haven’t finished yet, most of the values look pretty good prediction and are close enough but before we validate our model we need to check the residuals.

Conclusions:

Ultimately if our data cannot be capture using regression then we can still use other machine learning models like deep learning.

Keep posted! I will update this blog when I finally can find a model that is able to give the best estimation for our target variable: Permanent magnet Temperature of an electric motor.

--

--