---
title: "Manual for the package: linearreg"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Manual for the package: linearreg}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
library(ProxReg)
```

------
## What you'll find
* Introduction
* Functions
    + ols
    + k_fold_cross
    + ols_KCV
* L1 and L2 regularization
    + ridge
    + lasso_ista
    + lasso_ista_back
    + l_CV

## Introduction 

This is the introduction to the package "linearreg", which is used for linear regression model's construction such as
OLS (Ordinary Least Squares regression), Ridge regression and Lasso regression implemented through ISTA algorithm. 
Moreover, the package also contains functions that realize the K-fold cross validation, a helpful procedure in choosing 
lambda values. 

## Functions

### ols

The Ordinary Least Square (OLS) regression is one of the most common and simple techniques to estimate parametersof a linear regression model. It basically find the line that fits better to observations by minimizing the sum of square errors between the predicted and observed values.

```{r,echo=FALSE , out.width="50%"}

knitr::include_graphics(system.file("extdata", "ols.jpg", package = "ProxReg"))


```

However, it presents some disadvantages, since it is sensitive to Outliers, it may not be appropriate its applications to datasets with bounds of extreme values. Furthermore, **overfitting** and **multicollinearity** are as well two factors that undermine the model's credibility. For this reason, OLS regression is no recommended for high-dimensional data. 

The function generate by default a table that provides information about a ordinary least square regression. 
Here is a example below :

Given a dataset named *df* with its dependent variable: hours, and independent variables: scores and entertain_hours, 
we get the following table : 


```{r}
df = data.frame("hours"=c(1, 2, 4, 5, 5, 6, 6, 7, 8, 10, 11, 11, 12, 12, 14),
"score"=c(64, 66, 76, 73, 74, 81, 83, 82, 80, 88, 84, 82, 91, 93, 89),
"entertain_hours"=c(6,5,3,2,2,2,1,1,0.5,1,0.3,0.3,0.2,0.2,0.1))
ols(df,"score",c("hours","entertain_hours"),alpha = 0.025,verbose = FALSE)
```

The superior part is a general information about the regression model, where :

* **model** : current linear regression model

* **Df** : degree of freedom

* **F-statistic** : Is a statistical measure and indicates whether at least one independent variable explains the variation                     in the dependent variable. When it is true, the regression model has significance.
                    The more large is F-statistic, the less is the probability of *Type-I error*.
                
* **R-squared** :  coefficient of determination,is the ratio of Sum of squares due to regression (SSreg)to total sum of                       squares(SYY).  
                   $R^2 = \frac {SSreg}{SYY}$ \
                   This number is a summary of the strength of the relation between the x and the y in the data.
                   For instance,
                   $R^2=0.84$ explains that about 84% of the variability in the observed values is explained by the model. 

* **R.S-ajusted**:It is a modified version of $R^2$, it takes into account the number of independent variables in the
                  model, since the value of $R^2$ generally increases when independent variables are added event if they                     contribute little to the explanation of dependent variable. This can lead to a misunderstanding and                        people think the model fits better than it really does.
                  The objective of $R^2$ adjusted is to penalize the addition of the less relevant independent variables in                   the model.

* **prob(F-statsictic)** : p-value of F test, when it is lower than a established value (generally 0.05),we shall reject                              the null hypothesis (all the regression coefficients are equal to 0), in other words, we may                               consider there's a relations between X and Y .
                         
* **Residual standard error**: Is a measure that indicates the dispersion between the observed values and predicted values.

Under the lines, we have information about the coefficients, where:

* **coefficients**: Is the estimated value of the coefficients

* **standard error**: Standard error of each coefficient

* **t value**:Is a statistical measure calculated from t-test with null hypothesis: $\beta_i = 0$, which means that the i                coefficient does not contribute to the explanation of Y values.

* **p(>|t|)**: P-value obtained from t-test of each coefficient, when it is lower than a pre-fixed value (0.025 in general                case) we should reject the null hypothesis and accept the alternative one.

* **confidence interval**: It presents an confidence interval of each coefficient given a value of alpha, which is by                                  default 0,025. 


## k_fold_cross

In some cases, we might front situations when we have to compare linear models and choose the best-fitting one. The most popular method for estimating prediction error is cross validation. 

The K-fold cross validations is a method consisted in divided the dataset into k independent training sets and one test set. 

```{r,echo=FALSE , out.width="70%"}

knitr::include_graphics(system.file("extdata", "k_fold.png", package = "ProxReg"))

```

The following function $\color{blue}{ k_-fold_-cross}$ create k different versions of the dataset , each has k-1 training subsets and one test set.
```{r}
df = data.frame("hours"=c(1, 2, 4, 5, 5, 6, 6, 7, 8, 10, 11, 11, 12, 12, 14),
"score"=c(64, 66, 76, 73, 74, 81, 83, 82, 80, 88, 84, 82, 91, 93, 89),
"entertain_hours"=c(6,5,3,2,2,2,1,1,0.5,1,0.3,0.3,0.2,0.2,0.1))

k_fold_cross(df,k=3)

```

## ols_KCV

This function realize k-fold cross validation for ordinary least square regression. 
In each k circle, a linear regression is obtained from a learning set , then , it is evaluated with the test set to calculate the prediction error, finally, we estimate the mean squared error (MSE) through the k prediction errors.

For instance, suppose k equals to 5, and the dataset is the same *df* that we have been using throughout the document.
Applying the function we get the mean square error (MSE) and its squared value (RMSE).

```{r}
ols_KCV(df,k=5,"hours",c("score","entertain_hours"))
```

# L1 and L2 regularization

When a dataset is immense, it can lead to multicollinearity or ,the relation between the dependent variables we include in our linear regression model, can augment the model's complexity and generate overfitting. L1 and L2 regularization are methods to create less complex model and prevent overfitting by adding penalty term to the loss function of the model.
Both techniques add bias to the estimators but tend to have smaller mean square error and more stable than OLS estimators.

L1 regularization is known as Lasso regression, and L2 as Ridge regression. The main difference between them is the penalty term. 

In Ridge regression, it adds squared magnitude of coefficient as the penalty term to the loss function, where $\lambda$ is
a real number choosed by ourselves.
```{r,echo=FALSE , out.width="70%"}

knitr::include_graphics(system.file("extdata", "ridge.png", package = "ProxReg"))

```

meanwhiles in Lasso regression, the penalty term is instead absolute magnitude of coefficients.
```{r,echo=FALSE , out.width="70%"}

knitr::include_graphics(system.file("extdata", "lasso.png", package = "ProxReg"))
```

AS a consequence, L2 regularizationt tend to shrinkage some coefficients toward zero ans remains all features in model althought with smaller weight one respect to another. However, L2 regularization drive some coefficients to exactly zero, these zero coefficients are considered irrelevant and do not contribute to the model's prediction.

```{r,echo=FALSE , out.width="70%"}
knitr::include_graphics(system.file("extdata", "ridge_lasso.png", package = "ProxReg"))

```


## ridge

Suppose we have a dataframe named *test* , we generate the coefficients of ridge regression with the function $\color{blue}{ridge}$ given some values of lambda.

```{r}
library("glmnet")
data("QuickStartExample")
test<-as.data.frame(cbind(QuickStartExample$y,QuickStartExample$x))
ridge(data=test,y="V1",x=colnames(test)[2:21],lambda=c(0.01,0.1))
```

