Uno de los ejemplos en el libro de Los Elementos de Aprendizaje Estadístico por Hastie, Tibshirani y Friedman (de aquí en adelante referida como HTF) utiliza cáncer de próstata de datos (disponible aquí y se describe aquí) de un estudio realizado por Stamey et al. (1989).
Estoy tratando de reproducir los resultados citados en la (segunda edición) HTF para el común de la regresión lineal, para que se informe acerca de los siguientes coeficientes (tabla 3.2, página 50):
Intercept: 2.45
lcavol : 0.72
weight : 0.29
age : -0.14
lbph : 0.21
svi : 0.31
lip : -0.29
gleason : -0.02
egg45 : 0.28
Sin embargo, mi propio análisis da muy diferentes números (usando scikit-learn
's LinearRegression
, statsmodels
's OLS
y cómputo de los coeficientes de forma manual utilizando la fórmula 3.6 en HTF). Puedo conseguir
Intercept: 0.429
lcavol : 0.577
lweight : 0.614
age : -0.019
lbph : 0.145
svi : 0.737
lcp : -0.206
gleason : -0.030
pgg45 : 0.009
mediante el siguiente (en Python 3) código:
# Import data
# -----------
import pandas as pd
df = pd.read_csv('prostate.data', sep='\t', usecols=range(1, 11))
# Extract training set used by HTF
# --------------------------------
train_mask = (df['train'] == 'T')
cols_X = [col for col in df.columns if col not in ['lpsa', 'train']]
cols_y = ['lpsa']
X_train = df.loc[train_mask, cols_X]
y_train = df.loc[train_mask, cols_y]
# Use scikit-learn's LinearRegression
# -----------------------------------
from sklearn import linear_model
ols = linear_model.LinearRegression(normalize=True)
ols.fit(X_train, y_train)
print('Intercept: {:6.3f}'.format(ols.intercept_[0]))
for i, col in enumerate(X_train.columns):
print('{:9s}: {:6.3f}'.format(col, ols.coef_[0, i]))
# Use statsmodels OLS
# -------------------
import statsmodels.api as sm
result = sm.OLS(y_train, sm.add_constant(X_train)).fit()
print(result.summary())
# Use formula 3.6 of HTF
# ----------------------
X_ext = np.hstack([np.ones((X_train.shape[0], 1)), X_train.values])
np.matmul(np.matmul(np.linalg.inv(np.matmul(X_ext.T, X_ext)), X_ext.T), y_train)
Estoy haciendo algo mal, o son las cifras reportadas en el libro que están equivocados?
EDIT: la Redefinición de
X_train = (X_train - X_train.mean(axis=0)) / (X_train.std(axis=0))
antes de que cualquiera de los ajustes conduce a los coeficientes que son consistentes con los reportados en HTF:
Intercept: 2.4523
lcavol: 0.7164
weight: 0.2926
age: -0.1425
lbph: 0.2120
svi: 0.3096
lip: -0.2890
gleason: -0.0209
pgg45: 0.2773
El libro probablemente beneficiaría de hacer esto más claro (he visto que otras personas confundido por este mismo problema). Gracias a todos los que respondieron!