Improvements in documentation and tests for perceptron classifier

### Describe the issue linked to the documentation

The documentation and tests for the Perceptron classifier ```sklearn/linear_model/tests/test_perceptron.py``` require enhancements to improve clarity, completeness, and usability. Currently, the documentation lacks detailed explanations of the classifier's usage, parameter descriptions, and examples illustrating its functionality. This hinders users and contributors in understanding the Perceptron classifier's behavior and effectively utilizing it for their tasks.

### Suggest a potential alternative/fix

To address these issues, it is recommended to enhance the documentation and tests for the Perceptron classifier in scikit-learn. The documentation can be improved by providing comprehensive explanations of the classifier's purpose, underlying algorithm, parameter details, and their impact on the model's behavior. Additionally, practical code examples that showcase the classifier's usage with different options and datasets would greatly benefit users in understanding and applying it correctly.

Furthermore, the existing test suite should be expanded to cover a wider range of scenarios, including edge cases, corner cases, and potential pitfalls. This will help ensure the robustness and reliability of the Perceptron classifier implementation. By strengthening the test coverage, potential issues and regressions can be identified and resolved, resulting in a more stable and trustworthy classifier.

COMMENT:
It's true that the [docstring](
https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Perceptron.html#sklearn.linear_model.Perceptron) of the Perceptron class if very minimal:

> Linear perceptron classifier.
> Read more in the User Guide.

The user doc is not much more detailed:

> The Perceptron is another simple classification algorithm suitable for large scale learning. By default:
> It does not require a learning rate.
> It is not regularized (penalized).
> It updates its model only on mistakes.
> The last characteristic implies that the Perceptron is slightly faster to train than SGD with the hinge loss and that the resulting models are sparser.

We should probably at least make it explicit that `Perceptron(eta0=1.0)` is a short hand for `SGDClassifier(loss="perceptron", penalty=None, learning_rate="constant", eta0=1.0)`.

and reference the following section: https://scikit-learn.org/stable/modules/sgd.html#mathematical-formulation to give the definition of the perceptron loss function in the narrative doc.

Also the point "It does not require a learning rate." is a bit confusing. The perceptron algorithm uses a constant learning rate of 1.0 by default (the `eta0` parameter) but Wikipedia does not imply that a learning rate of 1.0 is necessary:

https://en.wikipedia.org/wiki/Perceptron#Learning_algorithm

Maybe we could add a sentence to explain that the Perceptron algorithm does not necessarily converge on non-linearly separable data. Furthermore, the minimized loss does not favor large margins contrary to the loss functions of logistic regression and linear support vector machines (the hinge or squared hinge loss) combined with regularization. As a result the learned decision boundary of the perceptron can be arbitrarily close to the training points which is a potential source of overfitting in high dimensional feature spaces.

It might therefore be beneficial to make the learning more stable to random resampling of the training set by averaging several perceptron instances that scan the training points in independent order by wrapping it into a `BaggingClassifier` estimator (with or without boostrap resampling).

Alternatively, it's also possible to implement the "Average Perceptron" algorithm using:

```python
>>> from sklearn.linear_model import SGDClassifier
>>> SGDClassifier(
...    loss="perceptron", penalty=None, learning_rate="constant", eta0=1.0, average=True
... )
```

In this case the model would directly use a form of Polyak–Ruppert averaging of the iterates.

Labels: Documentation, module:linear_model