#Heatmap
sns.heatmap(df.corr(), square=True, cmap='RdYlGn')


# Import LinearRegression
from sklearn.linear_model import LinearRegression

# Create the regressor: reg
reg = LinearRegression()

# Create the prediction space
prediction_space = np.linspace(min(X_fertility), max(X_fertility)).reshape(-1,1)

# Fit the model to the data
reg.fit(X_fertility,y)

# Compute predictions over the prediction space: y_pred
y_pred = reg.predict(prediction_space)

# Print R^2 
print(reg.score(X_fertility, y))

# Plot regression line
plt.plot(prediction_space, y_pred, color='black', linewidth=3)
plt.show()


# Import necessary modules
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split

# Create training and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state=42)

# Create the regressor: reg_all
reg_all = LinearRegression()

# Fit the regressor to the training data
reg_all.fit(X_train, y_train)

# Predict on the test data: y_pred
y_pred = reg_all.predict(X_test)

# Compute and print R^2 and RMSE
print("R^2: {}".format(reg_all.score(X_test, y_test)))
rmse = np.sqrt(mean_squared_error(y_test, y_pred))
print("Root Mean Squared Error: {}".format(rmse))


##5-fold cross-validation

# Import the necessary modules
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score

# Create a linear regression object: reg
reg = LinearRegression()

# Compute 5-fold cross-validation scores: cv_scores
cv_scores = cross_val_score(reg, X, y, cv=5)

# Print the 5-fold cross-validation scores
print(cv_scores)

print("Average 5-Fold CV Score: {}".format(np.mean(cv_scores)))

## output :
#[ 0.81720569  0.82917058  0.90214134  0.80633989  0.94495637]
#    Average 5-Fold CV Score: 0.8599627722793232



# Import necessary modules
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import cross_val_score

# Create a linear regression object: reg
reg = LinearRegression()

# Perform 3-fold CV
cvscores_3 = cross_val_score(reg,X,y,cv=3)
print(np.mean(cvscores_3))

# Perform 10-fold CV
cvscores_10 = cross_val_score(reg,X,y,cv=10)
print(np.mean(cvscores_10))

##avoir les temps  %timeit cross_val_score(reg, X, y, cv = ____)
#0.87 --> 11.5 ms
#0.84 --> 37.3 ms



## Regularization LASSO
# Import Lasso
from sklearn.linear_model import Lasso
# Instantiate a lasso regressor: lasso
lasso = Lasso(alpha=0.4, normalize=True)
# Fit the regressor to the data
lasso.fit(X, y)
# Compute and print the coefficients
lasso_coef = lasso.coef_print(lasso_coef)
# Plot the coefficients
plt.plot(range(len(df_columns)), lasso_coef)plt.xticks(range(len(df_columns)), df_columns.values, rotation=60)
plt.margins(0.02)plt.show()

#Lasso is great for feature selection, but when building regression models, Ridge regression should be your first choice.
#Recall that lasso performs regularization by adding to the loss function a penalty term of the absolute value of each coefficient
#multiplied by some alpha. This is also known as L1 regularization because the regularization term is the L1 norm of the coefficients. 
#If instead you took the sum of the squared values of the coefficients multiplied by some alpha - like in Ridge regression -
#you would be computing the L2 

 norm. 
## Regularization RIDGE

# Import necessary modules
from sklearn.linear_model import Ridge
from sklearn.model_selection import cross_val_score
# Setup the array of alphas and lists to store scores
alpha_space = np.logspace(-4, 0, 50)
ridge_scores = []ridge_scores_std = []
# Create a ridge regressor: ridge
ridge = Ridge(normalize=True)
# Compute scores over range of alphas
for alpha in alpha_space:
    # Specify the alpha value to use: 
    ridge.alpha    ridge.alpha = alpha      
    # Perform 10-fold CV: ridge_cv_scores  
    ridge_cv_scores = cross_val_score(ridge, X,y,cv=10)       
    # Append the mean of ridge_cv_scores to ridge_scores  
    ridge_scores.append(np.mean(ridge_cv_scores))     
    # Append the std of ridge_cv_scores to ridge_scores_std    
    ridge_scores_std.append(np.std(ridge_cv_scores))
# Display the plot
display_plot(ridge_scores, ridge_scores_std)
