from sklearn.model_selection import GridSearchCV
from xgboost import XGBRegressor
# Initialize the XGBoost model
xgb_regressor = XGBRegressor(objective='reg:squarederror', tree_method='gpu_hist')

# Wrap XGBoost model with MultiOutputRegressor
multioutput_regressor = MultiOutputRegressor(xgb_regressor)

# Define the parameter grid for XGBoost
param_grid = {
    'estimator__n_estimators': [400,800],  # Number of trees
    'estimator__learning_rate': [0.2],  # Step size shrinkage used to prevent overfitting
    'estimator__max_depth': [16],  # Maximum depth of a tree
    # Add more parameters here based on your needs
}

# Initialize GridSearchCV
grid_search = GridSearchCV(estimator=multioutput_regressor, param_grid=param_grid, cv=3, n_jobs=-1, verbose=2, scoring='neg_mean_absolute_error')

# Train the model using grid search to find the best hyperparameters
grid_search.fit(X_train_scaled, Y_train_scaled)

# Print the best parameters and the best score
print(f"Best parameters: {grid_search.best_params_}")
print(f"Best score: {grid_search.best_score_}")


errror:
\{
	"name": "MemoryError",
	"message": "Unable to allocate 806. MiB for an array with shape (92496, 1142) and data type float64",
	"stack": "---------------------------------------------------------------------------
_RemoteTraceback                          Traceback (most recent call last)
_RemoteTraceback: 
\"\"\"
Traceback (most recent call last):
  File \"c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\joblib\\externals\\loky\\process_executor.py\", line 463, in _process_worker
    r = call_item()
  File \"c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\joblib\\externals\\loky\\process_executor.py\", line 291, in __call__
    return self.fn(*self.args, **self.kwargs)
  File \"c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\joblib\\parallel.py\", line 598, in __call__
    return [func(*args, **kwargs)
  File \"c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\joblib\\parallel.py\", line 598, in <listcomp>
    return [func(*args, **kwargs)
  File \"c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\sklearn\\utils\\parallel.py\", line 129, in __call__
    return self.function(*args, **kwargs)
  File \"c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\sklearn\\model_selection\\_validation.py\", line 888, in _fit_and_score
    X_test, y_test = _safe_split(estimator, X, y, test, train)
  File \"c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\sklearn\\utils\\metaestimators.py\", line 158, in _safe_split
    X_subset = _safe_indexing(X, indices)
  File \"c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\sklearn\\utils\\__init__.py\", line 411, in _safe_indexing
    return _array_indexing(X, indices, indices_dtype, axis=axis)
  File \"c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\sklearn\\utils\\__init__.py\", line 208, in _array_indexing
    return array[key, ...] if axis == 0 else array[:, key]
  File \"c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\
umpy\\core\\memmap.py\", line 335, in __getitem__
    res = super().__getitem__(index)
numpy.core._exceptions._ArrayMemoryError: Unable to allocate 806. MiB for an array with shape (92496, 1142) and data type float64
\"\"\"

The above exception was the direct cause of the following exception:

MemoryError                               Traceback (most recent call last)
Cell In[9], line 21
     18 grid_search = GridSearchCV(estimator=multioutput_regressor, param_grid=param_grid, cv=3, n_jobs=-1, verbose=2, scoring='neg_mean_absolute_error')
     20 # Train the model using grid search to find the best hyperparameters
---> 21 grid_search.fit(X_train_scaled, Y_train_scaled)
     23 # Print the best parameters and the best score
     24 print(f\"Best parameters: {grid_search.best_params_}\")

File c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\sklearn\\base.py:1474, in _fit_context.<locals>.decorator.<locals>.wrapper(estimator, *args, **kwargs)
   1467     estimator._validate_params()
   1469 with config_context(
   1470     skip_parameter_validation=(
   1471         prefer_skip_nested_validation or global_skip_validation
   1472     )
   1473 ):
-> 1474     return fit_method(estimator, *args, **kwargs)

File c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\sklearn\\model_selection\\_search.py:970, in BaseSearchCV.fit(self, X, y, **params)
    964     results = self._format_results(
    965         all_candidate_params, n_splits, all_out, all_more_results
    966     )
    968     return results
--> 970 self._run_search(evaluate_candidates)
    972 # multimetric is determined here because in the case of a callable
    973 # self.scoring the return type is only known after calling
    974 first_test_score = all_out[0][\"test_scores\"]

File c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\sklearn\\model_selection\\_search.py:1527, in GridSearchCV._run_search(self, evaluate_candidates)
   1525 def _run_search(self, evaluate_candidates):
   1526     \"\"\"Search all candidates in param_grid\"\"\"
-> 1527     evaluate_candidates(ParameterGrid(self.param_grid))

File c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\sklearn\\model_selection\\_search.py:916, in BaseSearchCV.fit.<locals>.evaluate_candidates(candidate_params, cv, more_results)
    908 if self.verbose > 0:
    909     print(
    910         \"Fitting {0} folds for each of {1} candidates,\"
    911         \" totalling {2} fits\".format(
    912             n_splits, n_candidates, n_candidates * n_splits
    913         )
    914     )
--> 916 out = parallel(
    917     delayed(_fit_and_score)(
    918         clone(base_estimator),
    919         X,
    920         y,
    921         train=train,
    922         test=test,
    923         parameters=parameters,
    924         split_progress=(split_idx, n_splits),
    925         candidate_progress=(cand_idx, n_candidates),
    926         **fit_and_score_kwargs,
    927     )
    928     for (cand_idx, parameters), (split_idx, (train, test)) in product(
    929         enumerate(candidate_params),
    930         enumerate(cv.split(X, y, **routed_params.splitter.split)),
    931     )
    932 )
    934 if len(out) < 1:
    935     raise ValueError(
    936         \"No fits were performed. \"
    937         \"Was the CV iterator empty? \"
    938         \"Were there no candidates?\"
    939     )

File c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\sklearn\\utils\\parallel.py:67, in Parallel.__call__(self, iterable)
     62 config = get_config()
     63 iterable_with_config = (
     64     (_with_config(delayed_func, config), args, kwargs)
     65     for delayed_func, args, kwargs in iterable
     66 )
---> 67 return super().__call__(iterable_with_config)

File c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\joblib\\parallel.py:2007, in Parallel.__call__(self, iterable)
   2001 # The first item from the output is blank, but it makes the interpreter
   2002 # progress until it enters the Try/Except block of the generator and
   2003 # reach the first `yield` statement. This starts the aynchronous
   2004 # dispatch of the tasks to the workers.
   2005 next(output)
-> 2007 return output if self.return_generator else list(output)

File c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\joblib\\parallel.py:1650, in Parallel._get_outputs(self, iterator, pre_dispatch)
   1647     yield
   1649     with self._backend.retrieval_context():
-> 1650         yield from self._retrieve()
   1652 except GeneratorExit:
   1653     # The generator has been garbage collected before being fully
   1654     # consumed. This aborts the remaining tasks if possible and warn
   1655     # the user if necessary.
   1656     self._exception = True

File c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\joblib\\parallel.py:1754, in Parallel._retrieve(self)
   1747 while self._wait_retrieval():
   1748 
   1749     # If the callback thread of a worker has signaled that its task
   1750     # triggered an exception, or if the retrieval loop has raised an
   1751     # exception (e.g. `GeneratorExit`), exit the loop and surface the
   1752     # worker traceback.
   1753     if self._aborting:
-> 1754         self._raise_error_fast()
   1755         break
   1757     # If the next job is not ready for retrieval yet, we just wait for
   1758     # async callbacks to progress.

File c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\joblib\\parallel.py:1789, in Parallel._raise_error_fast(self)
   1785 # If this error job exists, immediatly raise the error by
   1786 # calling get_result. This job might not exists if abort has been
   1787 # called directly or if the generator is gc'ed.
   1788 if error_job is not None:
-> 1789     error_job.get_result(self.timeout)

File c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\joblib\\parallel.py:745, in BatchCompletionCallBack.get_result(self, timeout)
    739 backend = self.parallel._backend
    741 if backend.supports_retrieve_callback:
    742     # We assume that the result has already been retrieved by the
    743     # callback thread, and is stored internally. It's just waiting to
    744     # be returned.
--> 745     return self._return_or_raise()
    747 # For other backends, the main thread needs to run the retrieval step.
    748 try:

File c:\\Users\\arisa\\.conda\\envs\\tf\\lib\\site-packages\\joblib\\parallel.py:763, in BatchCompletionCallBack._return_or_raise(self)
    761 try:
    762     if self.status == TASK_ERROR:
--> 763         raise self._result
    764     return self._result
    765 finally:

MemoryError: Unable to allocate 806. MiB for an array with shape (92496, 1142) and data type float64"
}