API: Simplification of `PairwiseDistanceReductions` backend class names.

## Problem

The current backend class names are a bit confusing:

<details>
<summary>Current Names</summary>

```
# High-level diagram
# ------------------
#
#    Legend:
#
#      A ---⊳ B: A inherits from B
#      A ---x B: A dispatches to B
#
#
#                               (base dispatcher)
#                           PairwiseDistancesReduction
#                                       ∆
#                                       |
#                                       |
#                     +-----------------+-----------------+
#                     |                                   |
#               (dispatcher)                        (dispatcher)
#         PairwiseDistancesArgKmin           PairwiseDistancesRadiusNeighbors
#               |                                              |
#               |                                              |
#               |                                              |
#               |                  (64bit implem.)             |
#               |          PairwiseDistancesReduction64        |
#               |                       ∆                      |
#               |                       |                      |
#               |                       |                      |
#               |     +-----------------+-----------------+    |
#               |     |                                   |    |
#               |     |                                   |    |
#               x     |                                   |    x
#        PairwiseDistancesArgKmin64       PairwiseDistancesRadiusNeighbors64
#               |     ∆                                   ∆    |
#               |     |                                   |    |
#               x     |                                   |    |
#     FastEuclideanPairwiseDistancesArgKmin64             |    |
#                                                         |    |
#                                                         |    x
#                                  FastEuclideanPairwiseDistancesRadiusNeighbors64
```
</details>

The length of the names, especially the further down the hierarchy you go, I think impede the readability of the code as well as make it a bit more confusing to determine the specific roles of everything. For example, it is not obvious to me in the code that `PairwiseDistancesReduction64` and `PairwiseDistancesArgKmin` are wildly different, and while the diagram is helpful I don't think it should be as necessary as it is right now.


## Proposed Solution 1
Edit: Changed `Agent` to `Core` per discussion w/ @jjerphan

With the recent refactoring into a proper submodule, I think we can greatly simplify the namespace. See proposed naming scheme:
<details>
<summary>Proposed Names</summary>

```
# High-level diagram
# ------------------
#
#    Legend:
#
#      A ---⊳ B: A inherits from B
#      A ---x B: A dispatches to B
#
#
#                               (base dispatcher)
#                                   Dispatcher
#                                       ∆
#                                       |
#                                       |
#               +-----------------------+----------------------+
#               |                                              | 
#          (dispatcher)                                   (dispatcher)
#       ArgKminDispatcher                          RadiusNeighborsDispatcher
#               |                                              |
#               |                                              |
#               |                                              |
#               |                (64bit implem.)               |
#               |                     Core                     |
#               |                       ∆                      |
#               |                       |                      |
#               |                       |                      |
#               |     +-----------------+-----------------+    |
#               |     |                                   |    |
#               |     |                                   |    |
#               x     |                                   |    x
#            ArgKminCore64                         RadiusNeighborsCore64
#               |     ∆                                   ∆    |
#               |     |                                   |    |
#               x     |                                   |    |
#        EuclideanArgKminCore64                           |    |
#                                                         |    |
#                                                         |    x
#                                               EuclideanRadiusNeighborsCore64
```
</details>

This draws a more literal connection between the different classes and makes it easily inferred from the code itself, making the diagram a helpful resource rather than a necessary guide.

In general, I think if we follow the current implementation plan of only exposing the dispatchers and implementing each dispatch branch in a separate file (e.g. the branch following `ArgKminDispatcher` lives in `_argkmin.pyx`) we could be a bit more aggressive in trimming the names (i.e. no more explicit `Agent` in name, so `RadiusNeighborsAgent64-->RadiusNeighbors64`) but I can see why some people may not enjoy that.

## Proposed Solution 2

Edit: I added a bar for `Specializations` just to make it more obvious that there isn't necessarily semantic changes below that point, just overwriting relevant methods with faster, more specialized implementations. Optional, but I think it's nice. I also removed the `Agent` suffix to demonstrate a more minimal namespace:

<details>
<summary>More Drastic Change</summary>

```
# High-level diagram
# ------------------
#
#    Legend:
#
#      A ---⊳ B: A inherits from B
#      A ---x B: A dispatches to B
#
#
#                               (base dispatcher)
#                                   Dispatcher
#                                       ∆
#                                       |
#                                       |
#               +-----------------------+----------------------+
#               |                                              | 
#          (dispatcher)                                   (dispatcher)
#       ArgKminDispatcher                          RadiusNeighborsDispatcher
#               |                                              |
#               |                                              |
#               |                (64bit implem.)               |
#               |                     Core                     |
#               |                       ∆                      |
#               |                       |                      |
#               |                       |                      |
#               |     +-----------------+-----------------+    |
#               |     |                                   |    |
#               |     |                                   |    |
#               x     |                                   |    x
#              ArgKmin64                            RadiusNeighbors64
#               |     ∆                                   ∆    |
#               |     |                                   |    |
#      ========================= Specializations ==============================
#               |     |                                   |    |
#               |     |                                   |    |
#               x     |                                   |    x
#          EuclideanArgKmin64                    EuclideanRadiusNeighbors64
```
</details>

cc: @jjerphan

COMMENT:
> Thus, I would prefer coming up with a more exact naming than `Agent` or even `PairwiseDistancesReduction`, yet I am not inspired

How about `Core`, or `PDRCore`? `Core` is less ambiguous than `Agent` and if needed It can carry the `PDR` name but is still short. If we can't unanimously decide on a great name them I'm happy with `PDR64`, or even keeping `PairwiseDistanceReduction64` if needed. It's not worth blocking the other names imo :)

> I think it's important to carry the meaning of "reduction" (also previously referred to as "aggregation") over "pairwise distances (matrices)" Potentially in the future this could be extended to other matrices (e.g. Gram, dissimilarity and similarity matrices), but we have time for that.

Yeah making sure this is extensible and doesn't "lose" the semantics of what each class is doing is important. For example, for implementing `KNeighborsClassifier.predict` I think I'll need to create a new dispatcher and "core" class).

- Under the current name scheme they would be `PairwiseDistancesArgKminLabels` and `PairwiseDistancesArgKminLabels64`.
- Under proposal 1, they would be `ArgKminLabelsDispatcher` and `ArgKminLabelsCore64` (using `Core` instead of `Agent`). 
- Under proposal 2, they would be `ArgKminLabelsDispatcher` and `ArgKminLabels64` (regardless of what the abstract class is called). 

In that sense, I think both proposals help significantly, with proposal 2 being the most dramatic.

If we're talking about a whole new paradigm of functionality, e.g. Gram matrix reductions, I would rather those semantics be addressed through module/directory structure than being repeated and carried in the individual class names. Not sure what everyone else's thoughts on that are. For the Gram matrix reductions example, I would rather a namespace /module structure like `_pairwise_reductions.{distances, gram}.Dispatcher` rather than `_pairwise_reductions.{Distance, Gram}Dispatcher`. This keeps the file namespaces more locally coherent and makes it rather obvious where/how to extend the backend with new functionality.

Labels: Documentation, API