OneHotEncoder creates non unique column names, when values None (NoneType) and "None" (str) are both present

### Describe the bug

OneHotEncoder creates non unique column names when values None (NoneType) and "None" (str) are both present in the same column.

Such policy creates downstream problems (e.g. ColumnTransformer raising because of non unique column names).

It's not 100% clear to me what's the expectation of a transformer.
Should every transformer emit unique names for features?
Why does the ColumnTransformer raise if there are non-unique names?

### Steps/Code to Reproduce

Just one hot encoder.
```py
from sklearn.preprocessing import OneHotEncoder

X = [['None'], [None]]
t = OneHotEncoder().fit(X)
feature_names = t.get_feature_names_out()
# ['x0_None' 'x0_None']

assert len(feature_names) == len(set(feature_names))
```


With ColumnTransformer
```py
import pandas as pd
from sklearn.compose import make_column_selector, make_column_transformer
from sklearn.preprocessing import OneHotEncoder

t = make_column_transformer(
    (OneHotEncoder(), make_column_selector("x0")),
    verbose_feature_names_out=False,
)
t.fit(pd.DataFrame({"x0": [None, "None"]}))
print(t.get_feature_names_out(["x0"]))
```

There's a subtle bug in the ColumnTransformer as well. If `verbose_feature_names_out` is True, it will not check names and will emit non-unique names without raising.

### Expected Results

I'd expect different feature names being generated.

### Actual Results

First code snippet
```py
['x0_None' 'x0_None']
```

Second code snippet
```py
Traceback (most recent call last):
  File "src/ohe_bug.py", line 10, in <module>
    print(t.get_feature_names_out(["x0"]))
  File "/home/pilotuser/.local/lib/python3.8/site-packages/sklearn/compose/_column_transformer.py", line 518, in get_feature_names_out
    raise ValueError(
ValueError: Output feature names: ['x0_None'] are not unique. Please set verbose_feature_names_out=True to add prefixes to feature names
```

### Versions

```shell
System:
    python: 3.8.12 (default, Sep 28 2021, 19:23:30)  [GCC 8.3.0]
executable: /usr/local/bin/python
   machine: Linux-4.14.238-182.422.amzn2.x86_64-x86_64-with-glibc2.2.5

Python dependencies:
          pip: 21.2.4
   setuptools: 46.0.0
      sklearn: 1.0.2
        numpy: 1.18.5
        scipy: 1.5.4
       Cython: None
       pandas: 1.1.1
   matplotlib: 3.2.2
       joblib: 1.0.1
threadpoolctl: 2.1.0

Built with OpenMP: True
```
```

COMMENT:
@glemaitre that's a good point on repr. 

I've gone around the issue (in private codebase) by prepending the `type(v).__name__`, but it's not great since it adds many characters, and often very little/no information. It's not bulletproof by any means (two types could have the same name).

Another way to go around it would be to allow passing a function to transform `(column, value)` tuple into feature name. The default implementation would be `feature_name + "_" + str(v)`, but the consumer could override it with something else (e.g. using repr, adding type, anything). That seems too generic and something that wouldn't be used very often.

How would a change from `str` to `repr` be treated? Would it be considered as a breaking change?

> However, I don't know if we should error or make some magic under the hood.

Is there a clear expectation from the transformer, regarding feature names? Should they be unique? 

> It should be possible to detect the collision since the repr of None and "None" will differ.

That's true. Given that OneHotEncoder knows all the values after `fit` finishes, it could apply different logic if there are some collisions. It does seem a bit hacky, though - it'd encode some values differently based on whether there are collisions or not.

Btw I could do the fix once we agree on the direction.

Labels: Bug, module:compose