2
$\begingroup$

After using sklearn library for Partial Least Squares, I have doubts about the interpretation of the "intercept" of the model.

As you can see in the code that follows, and its corresponding ouput, the intercept_ and the prediction when all the predictors are zero differ.

From the documentation here https://scikit-learn.org/stable/modules/generated/sklearn.cross_decomposition.PLSRegression.html

intercept_ndarray of shape (n_targets,) The intercepts of the linear model such that Y is approximated as Y = X @ coef_.T + intercept_.

Both values should be the same, I'm right?

pd: I verified that I'm using scikit-learn version 1.5.0

Code

import pandas as pd
from sklearn.cross_decomposition import PLSRegression
import numpy as np

data = pd.DataFrame(data = [
[6.0,10.086797,3.535027,0.341043,8.3502],
[6.0,10.088014,3.535453,0.341084,5.8764],
[6.0,10.272183,2.704227,0.199019,3.7959],
[6.0,10.507442,3.169033,0.228000,4.6900],
[6.0,11.086873,3.693520,0.225735,1.0480],
[0.0,10.131321,3.526459,0.347951,2.0241],
[0.0,10.103844,3.516895,0.347008,2.8899],
[0.0,10.167639,3.539101,0.349199,1.4600],
[0.0,10.236161,3.562951,0.351552,1.4361],
[15.0,7.576252,3.859195,0.356888,8.6559],
[15.0,7.842521,3.851668,0.357062,7.8487]
], columns = ['q','x', 'y', 'z', 'u'])

plsModel = PLSRegression(n_components = 3, scale = False)
plsReg = plsModel.fit(data[['q','x', 'y', 'z']], data['u'])
 
print(f'Intercept value: {plsReg.intercept_[0]:.4f}')

p0 = pd.DataFrame(data = [[0,0,0,0]], columns = ['q','x', 'y', 'z'])
uPredicted = plsReg.predict(p0)

print(f'Predicted value: {uPredicted[0]:.4f}')

Output

Intercept value: 4.3705
Predicted value: 14.7594
$\endgroup$

1 Answer 1

1
$\begingroup$

Both values should be the same, I'm right?

Yeah I'd think so too, but apparently this method always mean centers even with scale = False. This kind of makes sense because the mean doesn't have a natural place in the transformations that happen here.

Anyway 4.3705 is just the mean of data['u'] and the prediction values agree if we mean center the fit.

#how to mean center:  https://stackoverflow.com/a/34954441/7840119
plsReg = plsModel.fit(data[['q','x', 'y', 'z']].apply(lambda x: x-x.mean()), data['u'])
 #I had problems with your print-statements. I don't know why
print('Intercept value:' + str(plsReg.intercept_))
print('coefs value:' + str(plsReg.coef_))
print('mean value:' + str(np.mean(data['u'])))
p0 = pd.DataFrame(data = [[0,0,0,0]], columns = ['q','x', 'y', 'z'])
print('transform value:' + str(plsReg.transform(p0)))
uPredicted = plsReg.predict(p0)
print('Predicted value:' + str(uPredicted))

result

Intercept value:[4.37047273]
coefs value:[[ 0.31427577 -0.84705601 -1.13213912  0.5839974 ]]
mean value:4.370472727272728
transform value:[[-7.01497764e-16  1.92786050e-16 -4.46294642e-16]]
Predicted value:[[4.37047273]]
$\endgroup$
2
  • $\begingroup$ It's a shame that you are kind of "forced" to mean center to obtain a value of intercept_ that makes sense. $\endgroup$ Commented Jun 25 at 15:07
  • $\begingroup$ @FranciscoAngel The mean of the response always has some meaning and is necessarily the prediction at the mean values of the "$X$", while the intercept at 0 is sometimes an extreme extrapolation from the data that has no real value. If you want to calculate predictions by hand you can use your code predict at 0. Also if you fell the question is answered, please mark it. I love the green on my User-Page :) $\endgroup$ Commented Jun 27 at 12:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.