493 KiB
493 KiB
In [ ]:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import KFold
from sklearn.linear_model import Ridge
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import PolynomialFeatures
# A seed just to ensure that the random numbers are the same for every run.
# Useful for eventual debugging.
np.random.seed(3155)
# Generate the data.
nsamples = 100
x = np.random.randn(nsamples)
y = 3*x**2 + np.random.randn(nsamples)
## Cross-validation on Ridge regression using KFold only
# Decide degree on polynomial to fit
poly = PolynomialFeatures(degree = 6)
# Decide which values of lambda to use
nlambdas = 500
lambdas = np.logspace(-3, 5, nlambdas)
# Initialize a KFold instance
k = 5
kfold = KFold(n_splits = k)
# Perform the cross-validation to estimate MSE
scores_KFold = np.zeros((nlambdas, k))
i = 0
for lmb in lambdas:
ridge = Ridge(alpha = lmb)
j = 0
for train_inds, test_inds in kfold.split(x):
xtrain = x[train_inds]
ytrain = y[train_inds]
xtest = x[test_inds]
ytest = y[test_inds]
Xtrain = poly.fit_transform(xtrain[:, np.newaxis])
ridge.fit(Xtrain, ytrain[:, np.newaxis])
Xtest = poly.fit_transform(xtest[:, np.newaxis])
ypred = ridge.predict(Xtest)
scores_KFold[i,j] = np.sum((ypred - ytest[:, np.newaxis])**2)/np.size(ypred)
j += 1
i += 1
estimated_mse_KFold = np.mean(scores_KFold, axis = 1)
## Cross-validation using cross_val_score from sklearn along with KFold
# kfold is an instance initialized above as:
# kfold = KFold(n_splits = k)
estimated_mse_sklearn = np.zeros(nlambdas)
i = 0
for lmb in lambdas:
ridge = Ridge(alpha = lmb)
X = poly.fit_transform(x[:, np.newaxis])
estimated_mse_folds = cross_val_score(ridge, X, y[:, np.newaxis], scoring='neg_mean_squared_error', cv=kfold)
# cross_val_score return an array containing the estimated negative mse for every fold.
# we have to the the mean of every array in order to get an estimate of the mse of the model
estimated_mse_sklearn[i] = np.mean(-estimated_mse_folds)
i += 1
## Plot and compare the slightly different ways to perform cross-validation
plt.figure()
plt.plot(np.log10(lambdas), estimated_mse_sklearn, label = 'cross_val_score')
plt.plot(np.log10(lambdas), estimated_mse_KFold, 'r--', label = 'KFold')
plt.xlabel('log10(lambda)')
plt.ylabel('mse')
plt.legend()
plt.show()In [ ]:
#Model training, we compute the mean value of y and X
y_train_mean = np.mean(y_train)
X_train_mean = np.mean(X_train,axis=0)
X_train = X_train - X_train_mean
y_train = y_train - y_train_mean
# The we fit our model with the training data
trained_model = some_model.fit(X_train,y_train)
#Model prediction, we need also to transform our data set used for the prediction.
X_test = X_test - X_train_mean #Use mean from training data
y_pred = trained_model(X_test)
y_pred = y_pred + y_train_meanIn [ ]:
X = X - np.mean(X,axis=0)In [ ]:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
np.random.seed(2021)
def MSE(y_data,y_model):
n = np.size(y_model)
return np.sum((y_data-y_model)**2)/n
def fit_beta(X, y):
return np.linalg.pinv(X.T @ X) @ X.T @ y
true_beta = [2, 0.5, 3.7]
x = np.linspace(0, 1, 11)
y = np.sum(
np.asarray([x ** p * b for p, b in enumerate(true_beta)]), axis=0
) + 0.1 * np.random.normal(size=len(x))
degree = 3
X = np.zeros((len(x), degree))
# Include the intercept in the design matrix
for p in range(degree):
X[:, p] = x ** p
beta = fit_beta(X, y)
# Intercept is included in the design matrix
skl = LinearRegression(fit_intercept=False).fit(X, y)
print(f"True beta: {true_beta}")
print(f"Fitted beta: {beta}")
print(f"Sklearn fitted beta: {skl.coef_}")
ypredictOwn = X @ beta
ypredictSKL = skl.predict(X)
print(f"MSE with intercept column")
print(MSE(y,ypredictOwn))
print(f"MSE with intercept column from SKL")
print(MSE(y,ypredictSKL))
plt.figure()
plt.scatter(x, y, label="Data")
plt.plot(x, X @ beta, label="Fit")
plt.plot(x, skl.predict(X), label="Sklearn (fit_intercept=False)")
# Do not include the intercept in the design matrix
X = np.zeros((len(x), degree - 1))
for p in range(degree - 1):
X[:, p] = x ** (p + 1)
# Intercept is not included in the design matrix
skl = LinearRegression(fit_intercept=True).fit(X, y)
# Use centered values for X and y when computing coefficients
y_offset = np.average(y, axis=0)
X_offset = np.average(X, axis=0)
beta = fit_beta(X - X_offset, y - y_offset)
intercept = np.mean(y_offset - X_offset @ beta)
print(f"Manual intercept: {intercept}")
print(f"Fitted beta (wiothout intercept): {beta}")
print(f"Sklearn intercept: {skl.intercept_}")
print(f"Sklearn fitted beta (without intercept): {skl.coef_}")
ypredictOwn = X @ beta
ypredictSKL = skl.predict(X)
print(f"MSE with Manual intercept")
print(MSE(y,ypredictOwn+intercept))
print(f"MSE with Sklearn intercept")
print(MSE(y,ypredictSKL))
plt.plot(x, X @ beta + intercept, "--", label="Fit (manual intercept)")
plt.plot(x, skl.predict(X), "--", label="Sklearn (fit_intercept=True)")
plt.grid()
plt.legend()
plt.show()In [ ]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn import linear_model
def MSE(y_data,y_model):
n = np.size(y_model)
return np.sum((y_data-y_model)**2)/n
# A seed just to ensure that the random numbers are the same for every run.
# Useful for eventual debugging.
np.random.seed(3155)
n = 100
x = np.random.rand(n)
y = np.exp(-x**2) + 1.5 * np.exp(-(x-2)**2)
Maxpolydegree = 20
X = np.zeros((n,Maxpolydegree))
#We include explicitely the intercept column
for degree in range(Maxpolydegree):
X[:,degree] = x**degree
# We split the data in test and training data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
p = Maxpolydegree
I = np.eye(p,p)
# Decide which values of lambda to use
nlambdas = 6
MSEOwnRidgePredict = np.zeros(nlambdas)
MSERidgePredict = np.zeros(nlambdas)
lambdas = np.logspace(-4, 2, nlambdas)
for i in range(nlambdas):
lmb = lambdas[i]
OwnRidgeBeta = np.linalg.pinv(X_train.T @ X_train+lmb*I) @ X_train.T @ y_train
# Note: we include the intercept column and no scaling
RegRidge = linear_model.Ridge(lmb,fit_intercept=False)
RegRidge.fit(X_train,y_train)
# and then make the prediction
ytildeOwnRidge = X_train @ OwnRidgeBeta
ypredictOwnRidge = X_test @ OwnRidgeBeta
ytildeRidge = RegRidge.predict(X_train)
ypredictRidge = RegRidge.predict(X_test)
MSEOwnRidgePredict[i] = MSE(y_test,ypredictOwnRidge)
MSERidgePredict[i] = MSE(y_test,ypredictRidge)
print("Beta values for own Ridge implementation")
print(OwnRidgeBeta)
print("Beta values for Scikit-Learn Ridge implementation")
print(RegRidge.coef_)
print("MSE values for own Ridge implementation")
print(MSEOwnRidgePredict[i])
print("MSE values for Scikit-Learn Ridge implementation")
print(MSERidgePredict[i])
# Now plot the results
plt.figure()
plt.plot(np.log10(lambdas), MSEOwnRidgePredict, 'r', label = 'MSE own Ridge Test')
plt.plot(np.log10(lambdas), MSERidgePredict, 'g', label = 'MSE Ridge Test')
plt.xlabel('log10(lambda)')
plt.ylabel('MSE')
plt.legend()
plt.show()In [6]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn import linear_model
from sklearn.preprocessing import StandardScaler
def MSE(y_data,y_model):
n = np.size(y_model)
return np.sum((y_data-y_model)**2)/n
# A seed just to ensure that the random numbers are the same for every run.
# Useful for eventual debugging.
np.random.seed(315)
n = 100
x = np.random.rand(n)
y = np.exp(-x**2) + 1.5 * np.exp(-(x-2)**2)
Maxpolydegree = 20
X = np.zeros((n,Maxpolydegree-1))
for degree in range(1,Maxpolydegree): #No intercept column
X[:,degree-1] = x**(degree)
# We split the data in test and training data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
#For our own implementation, we will need to deal with the intercept by centering the design matrix and the target variable
X_train_mean = np.mean(X_train,axis=0)
#Center by removing mean from each feature
X_train_scaled = X_train - X_train_mean
X_test_scaled = X_test - X_train_mean
#The model intercept (called y_scaler) is given by the mean of the target variable (IF X is centered)
#Remove the intercept from the training data.
y_scaler = np.mean(y_train)
y_train_scaled = y_train - y_scaler
p = Maxpolydegree-1
I = np.eye(p,p)
# Decide which values of lambda to use
nlambdas = 6
MSEOwnRidgePredict = np.zeros(nlambdas)
MSERidgePredict = np.zeros(nlambdas)
lambdas = np.logspace(-4, 2, nlambdas)
for i in range(nlambdas):
lmb = lambdas[i]
OwnRidgeBeta = np.linalg.pinv(X_train_scaled.T @ X_train_scaled+lmb*I) @ X_train_scaled.T @ (y_train_scaled)
intercept_ = y_scaler - X_train_mean@OwnRidgeBeta #The intercept can be shifted so the model can predict on uncentered data
#Add intercept to prediction
ypredictOwnRidge = X_test @ OwnRidgeBeta + intercept_
#Add intercept to prediction
ypredictOwnRidge = X_test_scaled @ OwnRidgeBeta + y_scaler
RegRidge = linear_model.Ridge(lmb)
RegRidge.fit(X_train,y_train)
ypredictRidge = RegRidge.predict(X_test)
MSEOwnRidgePredict[i] = MSE(y_test,ypredictOwnRidge)
MSERidgePredict[i] = MSE(y_test,ypredictRidge)
print("Beta values for own Ridge implementation")
print(OwnRidgeBeta) #Intercept is given by mean of target variable
print("Beta values for Scikit-Learn Ridge implementation")
print(RegRidge.coef_)
print('Intercept from own implementation:')
print(intercept_)
print('Intercept from Scikit-Learn Ridge implementation')
print(RegRidge.intercept_)
print("MSE values for own Ridge implementation")
print(MSEOwnRidgePredict[i])
print("MSE values for Scikit-Learn Ridge implementation")
print(MSERidgePredict[i])
# Now plot the results
plt.figure()
plt.plot(np.log10(lambdas), MSEOwnRidgePredict, 'b--', label = 'MSE own Ridge Test')
plt.plot(np.log10(lambdas), MSERidgePredict, 'g--', label = 'MSE SL Ridge Test')
plt.xlabel('log10(lambda)')
plt.ylabel('MSE')
plt.legend()
plt.show()Beta values for own Ridge implementation [ 3.43579948e-02 -5.43330971e-01 -3.10141414e-03 2.47116868e-01 2.18613217e-01 1.02054837e-01 -4.25617662e-04 -5.90475506e-02 -7.68534263e-02 -6.68929213e-02 -4.24906604e-02 -1.40927184e-02 1.11482289e-02 2.88529063e-02 3.67047975e-02 3.38135733e-02 2.02198702e-02 -3.46383924e-03 -3.63025821e-02] Beta values for Scikit-Learn Ridge implementation [ 3.43579948e-02 -5.43330971e-01 -3.10141413e-03 2.47116868e-01 2.18613217e-01 1.02054837e-01 -4.25617658e-04 -5.90475506e-02 -7.68534263e-02 -6.68929213e-02 -4.24906604e-02 -1.40927184e-02 1.11482289e-02 2.88529063e-02 3.67047975e-02 3.38135733e-02 2.02198702e-02 -3.46383925e-03 -3.63025821e-02] Intercept from own implementation: 1.0330308045181225 Intercept from Scikit-Learn Ridge implementation 1.033030804518383 MSE values for own Ridge implementation 3.139255958275475e-06 MSE values for Scikit-Learn Ridge implementation 3.139255958572018e-06 Beta values for own Ridge implementation [-0.05807125 -0.29822833 -0.08551306 0.08156108 0.13679863 0.12333649 0.08251519 0.03815288 0.00111756 -0.02498832 -0.04010697 -0.04566964 -0.04355837 -0.03562355 -0.02348765 -0.00848904 0.00831018 0.0260906 0.04423486] Beta values for Scikit-Learn Ridge implementation [-0.05807125 -0.29822833 -0.08551306 0.08156108 0.13679863 0.12333649 0.08251519 0.03815288 0.00111756 -0.02498832 -0.04010697 -0.04566964 -0.04355837 -0.03562355 -0.02348765 -0.00848904 0.00831018 0.0260906 0.04423486] Intercept from own implementation: 1.0411487294305548 Intercept from Scikit-Learn Ridge implementation 1.0411487294305266 MSE values for own Ridge implementation 1.9601304850163794e-05 MSE values for Scikit-Learn Ridge implementation 1.9601304850085328e-05 Beta values for own Ridge implementation [-0.1416398 -0.14021063 -0.05383795 0.01367553 0.04784395 0.05796251 0.05447415 0.044613 0.03267527 0.02098261 0.01066519 0.00217499 -0.00440346 -0.00917248 -0.01231917 -0.01405935 -0.0146081 -0.01416528 -0.01290947] Beta values for Scikit-Learn Ridge implementation [-0.1416398 -0.14021063 -0.05383795 0.01367553 0.04784395 0.05796251 0.05447415 0.044613 0.03267527 0.02098261 0.01066519 0.00217499 -0.00440346 -0.00917248 -0.01231917 -0.01405935 -0.0146081 -0.01416528 -0.01290947] Intercept from own implementation: 1.0495569966278282 Intercept from Scikit-Learn Ridge implementation 1.0495569966278269 MSE values for own Ridge implementation 5.4959161509370406e-05 MSE values for Scikit-Learn Ridge implementation 5.4959161509366834e-05 Beta values for own Ridge implementation [-0.13535942 -0.08593216 -0.03568439 -0.0036367 0.01397146 0.02229529 0.02503753 0.0245528 0.02228115 0.01908936 0.01549377 0.01179792 0.00817631 0.00472512 0.00149311 -0.00149956 -0.00424967 -0.00676387 -0.00905423] Beta values for Scikit-Learn Ridge implementation [-0.13535942 -0.08593216 -0.03568439 -0.0036367 0.01397146 0.02229529 0.02503753 0.0245528 0.02228115 0.01908936 0.01549377 0.01179792 0.00817631 0.00472512 0.00149311 -0.00149956 -0.00424967 -0.00676387 -0.00905423] Intercept from own implementation: 1.039967668952797 Intercept from Scikit-Learn Ridge implementation 1.0399676689527975 MSE values for own Ridge implementation 7.571105947979326e-05 MSE values for Scikit-Learn Ridge implementation 7.57110594797945e-05 Beta values for own Ridge implementation [-0.05100875 -0.04063602 -0.02723445 -0.01713366 -0.0100706 -0.00517114 -0.00174276 0.00068734 0.00243186 0.00369758 0.00462287 0.0053018 0.00579953 0.006162 0.00642221 0.00660427 0.00672607 0.0068011 0.00683964] Beta values for Scikit-Learn Ridge implementation [-0.05100875 -0.04063602 -0.02723445 -0.01713366 -0.0100706 -0.00517114 -0.00174276 0.00068734 0.00243186 0.00369758 0.00462287 0.0053018 0.00579953 0.006162 0.00642221 0.00660427 0.00672607 0.0068011 0.00683964] Intercept from own implementation: 0.999955585168597 Intercept from Scikit-Learn Ridge implementation 0.999955585168597 MSE values for own Ridge implementation 0.0007698473260556339 MSE values for Scikit-Learn Ridge implementation 0.000769847326055633 Beta values for own Ridge implementation [-0.00834567 -0.00803064 -0.00673407 -0.00554552 -0.00458878 -0.0038335 -0.00323332 -0.00274989 -0.0023548 -0.00202756 -0.00175331 -0.00152117 -0.001323 -0.0011526 -0.00100519 -0.00087697 -0.00076495 -0.00066668 -0.00058016] Beta values for Scikit-Learn Ridge implementation [-0.00834567 -0.00803064 -0.00673407 -0.00554552 -0.00458878 -0.0038335 -0.00323332 -0.00274989 -0.0023548 -0.00202756 -0.00175331 -0.00152117 -0.001323 -0.0011526 -0.00100519 -0.00087697 -0.00076495 -0.00066668 -0.00058016] Intercept from own implementation: 0.9637117593816477 Intercept from Scikit-Learn Ridge implementation 0.9637117593816477 MSE values for own Ridge implementation 0.0023813163025848865 MSE values for Scikit-Learn Ridge implementation 0.002381316302584886
In [ ]:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import seaborn as sns
import scipy.linalg as scl
from sklearn.model_selection import train_test_split
import tqdm
sns.set(color_codes=True)
cmap_args=dict(vmin=-1., vmax=1., cmap='seismic')
L = 40
n = int(1e4)
spins = np.random.choice([-1, 1], size=(n, L))
J = 1.0
energies = np.zeros(n)
for i in range(n):
energies[i] = - J * np.dot(spins[i], np.roll(spins[i], 1))In [ ]:
X = np.zeros((n, L ** 2))
for i in range(n):
X[i] = np.outer(spins[i], spins[i]).ravel()
y = energies
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)In [ ]:
X_train_own = np.concatenate(
(np.ones(len(X_train))[:, np.newaxis], X_train),
axis=1
)
X_test_own = np.concatenate(
(np.ones(len(X_test))[:, np.newaxis], X_test),
axis=1
)In [ ]:
def ols_inv(x: np.ndarray, y: np.ndarray) -> np.ndarray:
return scl.inv(x.T @ x) @ (x.T @ y)
beta = ols_inv(X_train_own, y_train)In [ ]:
def ols_svd(x: np.ndarray, y: np.ndarray) -> np.ndarray:
u, s, v = scl.svd(x)
return v.T @ scl.pinv(scl.diagsvd(s, u.shape[0], v.shape[0])) @ u.T @ yIn [ ]:
beta = ols_svd(X_train_own,y_train)In [ ]:
J = beta[1:].reshape(L, L)In [ ]:
fig = plt.figure(figsize=(20, 14))
im = plt.imshow(J, **cmap_args)
plt.title("OLS", fontsize=18)
plt.xticks(fontsize=18)
plt.yticks(fontsize=18)
cb = fig.colorbar(im)
cb.ax.set_yticklabels(cb.ax.get_yticklabels(), fontsize=18)
plt.show()In [ ]:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import seaborn as sns
import scipy.linalg as scl
from sklearn.model_selection import train_test_split
import sklearn.linear_model as skl
import tqdm
sns.set(color_codes=True)
cmap_args=dict(vmin=-1., vmax=1., cmap='seismic')
L = 40
n = int(1e4)
spins = np.random.choice([-1, 1], size=(n, L))
J = 1.0
energies = np.zeros(n)
for i in range(n):
energies[i] = - J * np.dot(spins[i], np.roll(spins[i], 1))Warning:
Output truncated. This notebook contains too many cells to display efficiently.