---
title: "Getting started"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Getting started}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
old <- options(width = 200)
```

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


# data and parameters

We will use the `mtcars` dataset, three input variables and one output variable.
The `params()` function has some defaults. 
Parameters with no value (NA) may also be automatically set by the **fuzzycoco** C++ library.

```{r preprocess}
x <- mtcars[c("mpg", "hp", "wt")]
y <- mtcars["qsec"]

pms <- params(
  nb_rules = 2, nb_max_var_per_rule = 3,        # structural parameters
  rules.pop_size = 100, mfs.pop_size = 100,     # coevolution population sizes
  ivars.nb_sets = 3, , ivars.nb_bits_pos = 8,   # input vars: 3 fuzzy sets, and 8 bits to discretize the values 
  ovars.nb_sets = 3, ovars.nb_bits_pos = 8,     # output vars: 3 fuzzy sets, and 8 bits to discretize the values 
  metricsw.sensitivity = 0, metricsw.specificity = 0, metricsw.rmse = 1, # we just use RMSE (root mean square error)
  output_vars_defuzz_thresholds = 17            # threshold for the qsec output variable
)

# the full list of generated parameters
str(pms)
```


# using the base R S3 interface

## model

Let's create a regression model, with our params, and set a `seed` for reproducibility.

```{r model}
model <- fuzzycoco("regression", pms, seed = 123)
class(model)
```

## fitting the model

### fit_xy(): using dataframes

```{r fit_xy}
# N.B: progress = FALSE because we are in a vignette
fit <- fit_xy(model, x, y, progress = FALSE)

# we get a "fuzzycoco_fit" object
class(fit)

# that has many components
names(fit)

# among which: the model fitting information 
str(fit$fit)

# the (best) fitted Fuzzy System 
str(fit$fuzzy_system)
```

### fit(): using a formula

There is a also a formula-based interface:

```{r fit}
df <- cbind(x, y)
# N.B: we use a different engine, and also overwrite `max_generations` and `seed` from the model parameters
fit <- fit(model, qsec ~ ., df, engine = "rcpp", seed = 456, max_generations = 20)

str(fit$fit)
```

## evaluating the model

When you get a Fuzzy System you can evaluate it on some complete data (input + output).
It will assess its performance on that data.

```{r evaluate}
# evaluating on the same data used to fit it should obviously get the same results
res <- evaluate(fit, df)
str(res)

# let's modify the data
df2 <- df
df2$qsec <- rnorm(nrow(df2), 17)
res2 <- evaluate(fit, df2)
str(res2)
```

## predicting data

You can use the Fuzzy System (from the fitted model) to predict the output variables based on some input data.

```{r predict}
y2 <- predict(fit, x)

# recompute rmse
rmse2 <- sqrt(mean((y2[[1]] - y[[1]])^2))
# compare it to what was reported
all.equal(rmse2,  fit$fit$metrics$rmse)
```

```{r cleanup, include = FALSE}
# restoring options
options(old)
```
