code: def test_finite_differences(lm, dataset):
      """Checks the gradient of a linear model via finite differences.
  
      References
      ----------
      [^1]: [How to test gradient implementations](https://timvieira.github.io/blog/post/2017/04/21/how-to-test-gradient-implementations/)
      [^2]: [Stochastic Gradient Descent Tricks](https://cilvr.cs.nyu.edu/diglib/lsml/bottou-sgd-tricks-2012.pdf)
  
      """
  
      scaler = preprocessing.StandardScaler()
      eps = 1e-6
  
      for x, y in dataset:
          scaler.learn_one(x)
          x = scaler.transform_one(x)
  
          # Store the current gradient and weights
          gradient, _ = lm._eval_gradient_one(x, y, 1)
          weights = copy.deepcopy(lm._weights)
  
          # d is a set of weight perturbations
          for d in iter_perturbations(weights.keys()):
              # Pertubate the weights and obtain the loss with the new weights
              lm._weights = utils.VectorDict(
                  {i: weights[i] + eps * di for i, di in d.items()}
              )
              forward = lm.loss(y_true=y, y_pred=lm._raw_dot_one(x))
              lm._weights = utils.VectorDict(
                  {i: weights[i] - eps * di for i, di in d.items()}
              )
              backward = lm.loss(y_true=y, y_pred=lm._raw_dot_one(x))
  
              # We expect g and h to be equal
              g = utils.math.dot(d, gradient)
              h = (forward - backward) / (2 * eps)
  
              # Compare signs
              # TODO: reactivate this check
              # assert np.sign(g) == np.sign(h)
  
              # Check absolute difference
              # TODO: decrease the tolerance
              assert abs(g - h) < 1e-5
  
          # Reset the weights to their original values in order not to influence
          # the training loop, even though it doesn't really matter.
          lm._weights = weights
          lm.learn_one(x, y)
  
imports: from __future__ import annotations
  import copy
  import itertools
  import math
  import random
  import numpy
  import pandas
  import pytest
  from sklearn import linear_model
  from sklearn.datasets import make_classification, make_regression
  from sklearn.metrics import log_loss
  from river import datasets, optim, preprocessing, stream, utils
  from river import linear_model
label_desc: Use image node_id 2 for calling a global function with example usage: test_finite_differences(lm, dataset) without return types