code: def test_given_more_complex_categorical_data_when_estimate_intrinsic_causal_influence_then_returns_expected_results():
      causal_model = StructuralCausalModel(
          nx.DiGraph([("X0", "X1"), ("X1", "X2"), ("X2", "X3")])
      )
      N1 = np.random.normal(0, 0.001, 10000)
      N2 = np.random.normal(0, 2, 10000)
      X0 = np.random.normal(0, 1, 10000)
      X1 = X0 + N1
      X2 = X1 + N2
  
      X3 = []
      for i in range(10000):
          rand_val = np.random.choice(3, 1).squeeze()
          if rand_val == 0:
              X3.append(X2[i] + np.random.normal(-5, 0.5, 1))
          elif rand_val == 1:
              X3.append(X2[i] + np.random.normal(10, 0.5, 1))
          else:
              X3.append(X2[i] + np.random.normal(5, 0.5, 1))
  
      X3 = np.array(X3)
      X3 = (X3 > np.median(X3)).astype(str)
      training_data = pd.DataFrame(
          {"X0": X0, "X1": X1, "X2": X2, "X3": X3.reshape(-1)}
      )
      auto.assign_causal_mechanisms(
          causal_model, training_data, auto.AssignmentQuality.GOOD
      )
  
      fit(causal_model, training_data)
  
      data_samples, noise_samples = noise_samples_of_ancestors(
          StructuralCausalModel(
              node_connected_subgraph_view(causal_model.graph, "X3")
          ),
          "X3",
          100000,
      )
      X = apply_one_hot_encoding(
          noise_samples.to_numpy(),
          fit_one_hot_encoders(noise_samples.to_numpy()),
      )
      log_mdl = LogisticRegression()
      log_mdl.fit(X, data_samples["X3"].to_numpy())
  
      expected_output_full_subset = -estimate_entropy_of_probabilities(
          log_mdl.predict_proba(X)
      )
      expected_output_empty_subset = -estimate_entropy_of_probabilities(
          np.array([[0.5, 0.5]])
      )
  
      iccs = intrinsic_causal_influence(
          causal_model,
          "X3",
          prediction_model="approx",
          num_samples_baseline=100,
      )
      assert iccs["X0"] == approx(0.05, abs=0.05)
      assert iccs["X1"] == approx(0.03, abs=0.05)
      assert iccs["X2"] == approx(0.1, abs=0.05)
      assert iccs["X3"] == approx(0.5, abs=0.1)
  
      assert np.sum([iccs[key] for key in iccs]) == approx(
          expected_output_full_subset - expected_output_empty_subset,
          abs=0.1,
      )
  
      iccs = intrinsic_causal_influence(
          causal_model,
          "X3",
          prediction_model="exact",
          num_samples_baseline=100,
      )
      assert iccs["X0"] == approx(0.05, abs=0.05)
      assert iccs["X1"] == approx(0.03, abs=0.05)
      assert iccs["X2"] == approx(0.1, abs=0.05)
      assert iccs["X3"] == approx(0.5, abs=0.1)
  
      assert np.sum([iccs[key] for key in iccs]) == approx(
          -expected_output_empty_subset, abs=0.1
      )
  
imports: import networkx
  import numpy
  import pandas
  from flaky import flaky
  from pytest import approx
  from scipy import stats
  from sklearn.linear_model import LogisticRegression
  from dowhy.gcm import AdditiveNoiseModel, InvertibleStructuralCausalModel, ScipyDistribution, StructuralCausalModel, auto, fit, intrinsic_causal_influence
  from dowhy.gcm._noise import noise_samples_of_ancestors
  from dowhy.gcm.influence import intrinsic_causal_influence_sample
  from dowhy.gcm.ml import create_hist_gradient_boost_classifier, create_hist_gradient_boost_regressor, create_linear_regressor, create_linear_regressor_with_given_parameters
  from dowhy.gcm.uncertainty import estimate_entropy_of_probabilities, estimate_variance
  from dowhy.gcm.util.general import apply_one_hot_encoding, fit_one_hot_encoders
  from dowhy.graph import node_connected_subgraph_view
  from tests.gcm.test_noise import _persist_parents
label_desc: Use image node_id 3 for calling a global function with example usage: test_given_more_complex_categorical_data_when_estimate_intrinsic_causal_influence_then_returns_expected_results() without return types