Title: Add script csv datasets
Author: jplu (CONTRIBUTOR)
State: closed
Created: 2020-04-30T08:28:08Z

This is a PR allowing to create datasets from local CSV files. A usage might be:

```python
import nlp
ds = nlp.load(
    path="csv",
    name="bbc",
    dataset_files={
        nlp.Split.TRAIN: ["datasets/dummy_data/csv/train.csv"],
        nlp.Split.TEST: [""datasets/dummy_data/csv/test.csv""]
    },
    csv_kwargs={
        "skip_rows": 0,
        "delimiter": ",",
        "quote_char": "\"",
        "header_as_column_names": True
    }
)
```

```
Downloading and preparing dataset bbc/1.0.0 (download: Unknown size, generated: Unknown size, total: Unknown size) to /home/jplu/.cache/huggingface/datasets/bbc/1.0.0...
Dataset bbc downloaded and prepared to /home/jplu/.cache/huggingface/datasets/bbc/1.0.0. Subsequent calls will reuse this data.
{'test': Dataset(schema: {'category': 'string', 'text': 'string'}, num_rows: 49), 'train': Dataset(schema: {'category': 'string', 'text': 'string'}, num_rows: 99), 'validation': Dataset(schema: {'category': 'string', 'text': 'string'}, num_rows: 0)}
```

How it is read:

- `path`: the `csv` word means "I want to create a CSV dataset"
- `name`: the name of this dataset is `bbc`
- `dataset_files`: this is a dictionary where each key is the list of files corresponding to the key split.
- `csv_kwargs`: this is the keywords arguments to "explain" how to read the CSV files
  * `skip_rows`: number of rows have to be skipped, starting from the beginning of the file
  * `delimiter`: which delimiter is used to separate the columns
  * `quote_char`: which quote char is used to represent a column where the delimiter appears in one of them
  * `header_as_column_names`: will use the first row (header) of the file as name for the features. Otherwise the names will be automatically generated as `f1`, `f2`, etc... Will be applied after the `skip_rows` parameter.

**TODO**:  for now the `csv.py` is copied each time we create a new dataset as `ds_name.py`, this behavior will be modified to have only the `csv.py` script copied only once and not for all the CSV datasets.

Comments:
Very interesting thoughts, we should think deeper about all what you raised indeed.

Ok here is a proposal for a more general API and workflow.

# New `ArrowBasedBuilder`

For all the formats that can be directly and efficiently loaded by Arrow (CSV, JSON, Parquet, Arrow), we don't really want to have to go through a conversion to python and back to Arrow. This new builder has a `_generate_tables` method to yield `Arrow.Tables` instead of single examples.
The tables can be directly casted in Arrow so it's not necessary to supply  `Features`, they can be deduced from the `Table` column.

# Central role of the `BuilderConfig` to store all the arguments necessary for the Dataset creation.
 
`BuilderConfig` provide a few defaults fields `name`, `version`,  `description`,  `data_files` and `data_dir` which can be used to store values necessary for the creation of the dataset. It can be freely extended to store additional information (see the example for `CsvConfig`).

On the contrary, `DatasetInfo` is designed as an organized and delimited information storage class with predefined fields.

`DatasetInfo` now store two names:
- `builder_name`: Name of the builder script used to create the dataset
- `config_name`: Name of the configuration used to create the dataset.

# Refactoring `load()` arguments and all the chain of processing including the `DownloadManager`

`load()` now accept a selection of arguments which are used to update the `BuilderConfig` and some kwargs which are used to handle the download process.

Supplying a `BuilderConfig` as `config` will override the config provided in the dataset. Supplying a `str` will get the associated config from the dataset. Default is to fetch the first config of the dataset.

Giving additional arguments to `load()` will override the arguments in the `BuilderConfig`.

# CSV script

The `csv.py` script is provided as an example, usage is:
```python
bbc = nlp.load('/Users/thomwolf/Documents/GitHub/datasets/datasets/nlp/csv',
               name='bbc',
               version="1.0.1",
               split='train',
               data_files={'train': ['/Users/thomwolf/Documents/GitHub/datasets/datasets/dummy_data/csv/test.csv']},
               skip_rows=10,
               download_mode='force_redownload')
```

# Checksums

We now don't raise an error if the checksum file is not found.

# `DownloadConfig`

We now have a download configuration class to handle all the specific arguments for file caching like proxies, using only local files or user-agents.

Ok merging this for now.

One general note is that it's a bit hard to handle the `ClassLabel` generally in both `nlp` and `Arrow` since a class label typically need some metadata for the class names. For now, I raise a `NotImplementedError` when an `ArrowBuilder` output a table with a `DictionaryType` is encountered (which could be a simple equivalent for a `ClassLabel` Feature in Arrow tables).

In general and if we need this in the future for some Beam Datasets for instance, I think we should use one of the `metadata` fields in the `Arrow` type or table's schema to store the relation with indices and class names.

So ping me if you meet Beam datasets which uses `ClassLabels` (cc @lhoestq @patrickvonplaten @mariamabarham).