guohanghui commited on
Commit
e2f87ea
·
verified ·
1 Parent(s): 0a4014e

Update auto-sklearn/mcp_output/mcp_plugin/mcp_service.py

Browse files
auto-sklearn/mcp_output/mcp_plugin/mcp_service.py CHANGED
@@ -1,5 +1,7 @@
1
  import os
2
  import sys
 
 
3
 
4
  # Add the local source directory to sys.path
5
  source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source")
@@ -7,114 +9,448 @@ if source_path not in sys.path:
7
  sys.path.insert(0, source_path)
8
 
9
  from fastmcp import FastMCP
 
10
 
11
  # Import core modules from the local source directory
12
- from autosklearn.automl import AutoML
13
- from autosklearn.ensembles.ensemble_selection import EnsembleSelection
14
  from autosklearn.estimators import AutoSklearnClassifier, AutoSklearnRegressor
15
- from autosklearn.smbo import AutoMLSMBO
16
 
17
  # Create the FastMCP service application
18
  mcp = FastMCP("auto_sklearn_service")
19
 
20
- @mcp.tool(name="automl_fit", description="Fit the AutoML model with the given data.")
21
- def automl_fit(X_train: list, y_train: list, time_left_for_this_task: int) -> dict:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  """
23
- Fit the AutoML model with the given training data.
24
 
25
  Parameters:
26
- - X_train: list of training data features
27
- - y_train: list of training data labels
28
- - time_left_for_this_task: time budget in seconds for the task
 
 
 
 
 
29
 
30
  Returns:
31
- - dict: containing success, result, or error fields
32
  """
33
  try:
34
- automl = AutoML(time_left_for_this_task=time_left_for_this_task)
35
- automl.fit(X_train, y_train)
36
- return {"success": True, "result": "Model fitted successfully"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  except Exception as e:
38
- return {"success": False, "error": str(e)}
39
 
40
- @mcp.tool(name="ensemble_selection", description="Select the best ensemble from the given models.")
41
- def ensemble_selection(models: list) -> dict:
 
 
 
 
 
 
 
 
 
 
42
  """
43
- Select the best ensemble from the given models.
44
 
45
  Parameters:
46
- - models: list of models to select from
 
 
 
 
 
 
 
47
 
48
  Returns:
49
- - dict: containing success, result, or error fields
50
  """
51
  try:
52
- ensemble = EnsembleSelection(models)
53
- best_ensemble = ensemble.select()
54
- return {"success": True, "result": "Ensemble selected successfully"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  except Exception as e:
56
- return {"success": False, "error": str(e)}
 
57
 
58
- @mcp.tool(name="classifier_predict", description="Predict using the AutoSklearnClassifier.")
59
- def classifier_predict(X_test: list) -> dict:
60
  """
61
- Predict using the AutoSklearnClassifier.
62
 
63
  Parameters:
64
- - X_test: list of test data features
 
 
65
 
66
  Returns:
67
- - dict: containing success, result, or error fields
68
  """
69
  try:
70
- classifier = AutoSklearnClassifier()
71
- predictions = classifier.predict(X_test)
72
- return {"success": True, "result": predictions}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  except Exception as e:
74
- return {"success": False, "error": str(e)}
 
75
 
76
- @mcp.tool(name="regressor_predict", description="Predict using the AutoSklearnRegressor.")
77
- def regressor_predict(X_test: list) -> dict:
78
  """
79
- Predict using the AutoSklearnRegressor.
80
 
81
  Parameters:
82
- - X_test: list of test data features
 
 
83
 
84
  Returns:
85
- - dict: containing success, result, or error fields
86
  """
87
  try:
88
- regressor = AutoSklearnRegressor()
89
- predictions = regressor.predict(X_test)
90
- return {"success": True, "result": predictions}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  except Exception as e:
92
- return {"success": False, "error": str(e)}
93
 
94
- @mcp.tool(name="smbo_optimize", description="Optimize hyperparameters using SMBO.")
95
- def smbo_optimize(config_space: dict, max_evals: int) -> dict:
 
96
  """
97
- Optimize hyperparameters using SMBO.
98
 
99
  Parameters:
100
- - config_space: dictionary defining the configuration space
101
- - max_evals: maximum number of evaluations
102
 
103
  Returns:
104
- - dict: containing success, result, or error fields
105
  """
106
  try:
107
- smbo = AutoMLSMBO(config_space=config_space, max_evals=max_evals)
108
- best_config = smbo.optimize()
109
- return {"success": True, "result": best_config}
 
 
 
 
 
 
 
 
 
 
 
 
 
110
  except Exception as e:
111
- return {"success": False, "error": str(e)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
  def create_app() -> FastMCP:
114
  """
115
  Create and return the FastMCP application instance.
116
 
117
  Returns:
118
- - FastMCP: the FastMCP application instance
119
  """
120
- return mcp
 
1
  import os
2
  import sys
3
+ from typing import Dict, Any, List, Optional
4
+ import json
5
 
6
  # Add the local source directory to sys.path
7
  source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source")
 
9
  sys.path.insert(0, source_path)
10
 
11
  from fastmcp import FastMCP
12
+ import numpy as np
13
 
14
  # Import core modules from the local source directory
 
 
15
  from autosklearn.estimators import AutoSklearnClassifier, AutoSklearnRegressor
 
16
 
17
  # Create the FastMCP service application
18
  mcp = FastMCP("auto_sklearn_service")
19
 
20
+ # Store models by ID
21
+ _classifiers: Dict[str, AutoSklearnClassifier] = {}
22
+ _regressors: Dict[str, AutoSklearnRegressor] = {}
23
+
24
+
25
+ @mcp.tool(name="get_library_info")
26
+ def get_library_info() -> dict:
27
+ """
28
+ Get information about the auto-sklearn library.
29
+
30
+ Returns:
31
+ dict: Version and configuration information.
32
+ """
33
+ try:
34
+ from autosklearn import __version__
35
+
36
+ return {
37
+ "success": True,
38
+ "result": {
39
+ "library": "auto-sklearn",
40
+ "version": __version__,
41
+ "estimators": ["AutoSklearnClassifier", "AutoSklearnRegressor"],
42
+ "features": [
43
+ "Automated Machine Learning",
44
+ "Ensemble Learning",
45
+ "Meta-learning",
46
+ "Hyperparameter Optimization (SMAC)",
47
+ ],
48
+ },
49
+ "error": None,
50
+ }
51
+ except Exception as e:
52
+ return {"success": False, "result": None, "error": str(e)}
53
+
54
+
55
+ @mcp.tool(name="create_classifier")
56
+ def create_classifier(
57
+ classifier_id: str,
58
+ time_left_for_this_task: int = 3600,
59
+ per_run_time_limit: Optional[int] = None,
60
+ ensemble_size: int = 50,
61
+ ensemble_nbest: int = 50,
62
+ seed: int = 1,
63
+ memory_limit: int = 3072,
64
+ n_jobs: Optional[int] = None,
65
+ ) -> dict:
66
  """
67
+ Create a new AutoSklearnClassifier.
68
 
69
  Parameters:
70
+ classifier_id (str): Unique identifier for the classifier.
71
+ time_left_for_this_task (int): Total time budget in seconds.
72
+ per_run_time_limit (Optional[int]): Time limit per model evaluation.
73
+ ensemble_size (int): Number of models in the final ensemble.
74
+ ensemble_nbest (int): Consider only the best n models for ensemble.
75
+ seed (int): Random seed.
76
+ memory_limit (int): Memory limit in MB.
77
+ n_jobs (Optional[int]): Number of parallel jobs.
78
 
79
  Returns:
80
+ dict: Success status and classifier information.
81
  """
82
  try:
83
+ if classifier_id in _classifiers:
84
+ return {"success": False, "result": None, "error": f"Classifier '{classifier_id}' already exists"}
85
+
86
+ clf = AutoSklearnClassifier(
87
+ time_left_for_this_task=time_left_for_this_task,
88
+ per_run_time_limit=per_run_time_limit,
89
+ ensemble_size=ensemble_size,
90
+ ensemble_nbest=ensemble_nbest,
91
+ seed=seed,
92
+ memory_limit=memory_limit,
93
+ n_jobs=n_jobs,
94
+ )
95
+
96
+ _classifiers[classifier_id] = clf
97
+
98
+ return {
99
+ "success": True,
100
+ "result": {
101
+ "classifier_id": classifier_id,
102
+ "time_budget": time_left_for_this_task,
103
+ "ensemble_size": ensemble_size,
104
+ "message": "Classifier created successfully",
105
+ },
106
+ "error": None,
107
+ }
108
  except Exception as e:
109
+ return {"success": False, "result": None, "error": str(e)}
110
 
111
+
112
+ @mcp.tool(name="create_regressor")
113
+ def create_regressor(
114
+ regressor_id: str,
115
+ time_left_for_this_task: int = 3600,
116
+ per_run_time_limit: Optional[int] = None,
117
+ ensemble_size: int = 50,
118
+ ensemble_nbest: int = 50,
119
+ seed: int = 1,
120
+ memory_limit: int = 3072,
121
+ n_jobs: Optional[int] = None,
122
+ ) -> dict:
123
  """
124
+ Create a new AutoSklearnRegressor.
125
 
126
  Parameters:
127
+ regressor_id (str): Unique identifier for the regressor.
128
+ time_left_for_this_task (int): Total time budget in seconds.
129
+ per_run_time_limit (Optional[int]): Time limit per model evaluation.
130
+ ensemble_size (int): Number of models in the final ensemble.
131
+ ensemble_nbest (int): Consider only the best n models for ensemble.
132
+ seed (int): Random seed.
133
+ memory_limit (int): Memory limit in MB.
134
+ n_jobs (Optional[int]): Number of parallel jobs.
135
 
136
  Returns:
137
+ dict: Success status and regressor information.
138
  """
139
  try:
140
+ if regressor_id in _regressors:
141
+ return {"success": False, "result": None, "error": f"Regressor '{regressor_id}' already exists"}
142
+
143
+ reg = AutoSklearnRegressor(
144
+ time_left_for_this_task=time_left_for_this_task,
145
+ per_run_time_limit=per_run_time_limit,
146
+ ensemble_size=ensemble_size,
147
+ ensemble_nbest=ensemble_nbest,
148
+ seed=seed,
149
+ memory_limit=memory_limit,
150
+ n_jobs=n_jobs,
151
+ )
152
+
153
+ _regressors[regressor_id] = reg
154
+
155
+ return {
156
+ "success": True,
157
+ "result": {
158
+ "regressor_id": regressor_id,
159
+ "time_budget": time_left_for_this_task,
160
+ "ensemble_size": ensemble_size,
161
+ "message": "Regressor created successfully",
162
+ },
163
+ "error": None,
164
+ }
165
  except Exception as e:
166
+ return {"success": False, "result": None, "error": str(e)}
167
+
168
 
169
+ @mcp.tool(name="fit_classifier")
170
+ def fit_classifier(classifier_id: str, X_train: List[List[float]], y_train: List) -> dict:
171
  """
172
+ Fit a classifier with training data.
173
 
174
  Parameters:
175
+ classifier_id (str): ID of the classifier to fit.
176
+ X_train (List[List[float]]): Training features.
177
+ y_train (List): Training labels.
178
 
179
  Returns:
180
+ dict: Success status and fitting information.
181
  """
182
  try:
183
+ if classifier_id not in _classifiers:
184
+ return {"success": False, "result": None, "error": f"Classifier '{classifier_id}' not found"}
185
+
186
+ clf = _classifiers[classifier_id]
187
+ X_train_np = np.array(X_train)
188
+ y_train_np = np.array(y_train)
189
+
190
+ clf.fit(X_train_np, y_train_np)
191
+
192
+ return {
193
+ "success": True,
194
+ "result": {
195
+ "classifier_id": classifier_id,
196
+ "num_samples": len(X_train),
197
+ "num_features": len(X_train[0]) if X_train else 0,
198
+ "message": "Classifier fitted successfully",
199
+ },
200
+ "error": None,
201
+ }
202
  except Exception as e:
203
+ return {"success": False, "result": None, "error": str(e)}
204
+
205
 
206
+ @mcp.tool(name="fit_regressor")
207
+ def fit_regressor(regressor_id: str, X_train: List[List[float]], y_train: List[float]) -> dict:
208
  """
209
+ Fit a regressor with training data.
210
 
211
  Parameters:
212
+ regressor_id (str): ID of the regressor to fit.
213
+ X_train (List[List[float]]): Training features.
214
+ y_train (List[float]): Training targets.
215
 
216
  Returns:
217
+ dict: Success status and fitting information.
218
  """
219
  try:
220
+ if regressor_id not in _regressors:
221
+ return {"success": False, "result": None, "error": f"Regressor '{regressor_id}' not found"}
222
+
223
+ reg = _regressors[regressor_id]
224
+ X_train_np = np.array(X_train)
225
+ y_train_np = np.array(y_train)
226
+
227
+ reg.fit(X_train_np, y_train_np)
228
+
229
+ return {
230
+ "success": True,
231
+ "result": {
232
+ "regressor_id": regressor_id,
233
+ "num_samples": len(X_train),
234
+ "num_features": len(X_train[0]) if X_train else 0,
235
+ "message": "Regressor fitted successfully",
236
+ },
237
+ "error": None,
238
+ }
239
  except Exception as e:
240
+ return {"success": False, "result": None, "error": str(e)}
241
 
242
+
243
+ @mcp.tool(name="predict_classifier")
244
+ def predict_classifier(classifier_id: str, X_test: List[List[float]]) -> dict:
245
  """
246
+ Make predictions using a fitted classifier.
247
 
248
  Parameters:
249
+ classifier_id (str): ID of the classifier.
250
+ X_test (List[List[float]]): Test features.
251
 
252
  Returns:
253
+ dict: Predictions.
254
  """
255
  try:
256
+ if classifier_id not in _classifiers:
257
+ return {"success": False, "result": None, "error": f"Classifier '{classifier_id}' not found"}
258
+
259
+ clf = _classifiers[classifier_id]
260
+ X_test_np = np.array(X_test)
261
+
262
+ predictions = clf.predict(X_test_np)
263
+
264
+ return {
265
+ "success": True,
266
+ "result": {
267
+ "predictions": predictions.tolist(),
268
+ "num_predictions": len(predictions),
269
+ },
270
+ "error": None,
271
+ }
272
  except Exception as e:
273
+ return {"success": False, "result": None, "error": str(e)}
274
+
275
+
276
+ @mcp.tool(name="predict_regressor")
277
+ def predict_regressor(regressor_id: str, X_test: List[List[float]]) -> dict:
278
+ """
279
+ Make predictions using a fitted regressor.
280
+
281
+ Parameters:
282
+ regressor_id (str): ID of the regressor.
283
+ X_test (List[List[float]]): Test features.
284
+
285
+ Returns:
286
+ dict: Predictions.
287
+ """
288
+ try:
289
+ if regressor_id not in _regressors:
290
+ return {"success": False, "result": None, "error": f"Regressor '{regressor_id}' not found"}
291
+
292
+ reg = _regressors[regressor_id]
293
+ X_test_np = np.array(X_test)
294
+
295
+ predictions = reg.predict(X_test_np)
296
+
297
+ return {
298
+ "success": True,
299
+ "result": {
300
+ "predictions": predictions.tolist(),
301
+ "num_predictions": len(predictions),
302
+ },
303
+ "error": None,
304
+ }
305
+ except Exception as e:
306
+ return {"success": False, "result": None, "error": str(e)}
307
+
308
+
309
+ @mcp.tool(name="get_classifier_model_performance")
310
+ def get_classifier_model_performance(classifier_id: str) -> dict:
311
+ """
312
+ Get performance statistics of explored models.
313
+
314
+ Parameters:
315
+ classifier_id (str): ID of the classifier.
316
+
317
+ Returns:
318
+ dict: Performance statistics.
319
+ """
320
+ try:
321
+ if classifier_id not in _classifiers:
322
+ return {"success": False, "result": None, "error": f"Classifier '{classifier_id}' not found"}
323
+
324
+ clf = _classifiers[classifier_id]
325
+
326
+ # Get leaderboard information
327
+ leaderboard = clf.leaderboard()
328
+
329
+ return {
330
+ "success": True,
331
+ "result": {
332
+ "classifier_id": classifier_id,
333
+ "num_models": len(leaderboard) if leaderboard is not None else 0,
334
+ "leaderboard_summary": leaderboard.head(10).to_dict() if leaderboard is not None else {},
335
+ },
336
+ "error": None,
337
+ }
338
+ except Exception as e:
339
+ return {"success": False, "result": None, "error": str(e)}
340
+
341
+
342
+ @mcp.tool(name="get_regressor_model_performance")
343
+ def get_regressor_model_performance(regressor_id: str) -> dict:
344
+ """
345
+ Get performance statistics of explored models.
346
+
347
+ Parameters:
348
+ regressor_id (str): ID of the regressor.
349
+
350
+ Returns:
351
+ dict: Performance statistics.
352
+ """
353
+ try:
354
+ if regressor_id not in _regressors:
355
+ return {"success": False, "result": None, "error": f"Regressor '{regressor_id}' not found"}
356
+
357
+ reg = _regressors[regressor_id]
358
+
359
+ # Get leaderboard information
360
+ leaderboard = reg.leaderboard()
361
+
362
+ return {
363
+ "success": True,
364
+ "result": {
365
+ "regressor_id": regressor_id,
366
+ "num_models": len(leaderboard) if leaderboard is not None else 0,
367
+ "leaderboard_summary": leaderboard.head(10).to_dict() if leaderboard is not None else {},
368
+ },
369
+ "error": None,
370
+ }
371
+ except Exception as e:
372
+ return {"success": False, "result": None, "error": str(e)}
373
+
374
+
375
+ @mcp.tool(name="list_models")
376
+ def list_models() -> dict:
377
+ """
378
+ List all stored classifiers and regressors.
379
+
380
+ Returns:
381
+ dict: List of model IDs.
382
+ """
383
+ try:
384
+ return {
385
+ "success": True,
386
+ "result": {
387
+ "classifiers": list(_classifiers.keys()),
388
+ "regressors": list(_regressors.keys()),
389
+ "total": len(_classifiers) + len(_regressors),
390
+ },
391
+ "error": None,
392
+ }
393
+ except Exception as e:
394
+ return {"success": False, "result": None, "error": str(e)}
395
+
396
+
397
+ @mcp.tool(name="delete_classifier")
398
+ def delete_classifier(classifier_id: str) -> dict:
399
+ """
400
+ Delete a stored classifier.
401
+
402
+ Parameters:
403
+ classifier_id (str): ID of the classifier to delete.
404
+
405
+ Returns:
406
+ dict: Confirmation of deletion.
407
+ """
408
+ try:
409
+ if classifier_id not in _classifiers:
410
+ return {"success": False, "result": None, "error": f"Classifier '{classifier_id}' not found"}
411
+
412
+ del _classifiers[classifier_id]
413
+
414
+ return {
415
+ "success": True,
416
+ "result": {"message": f"Classifier '{classifier_id}' deleted"},
417
+ "error": None,
418
+ }
419
+ except Exception as e:
420
+ return {"success": False, "result": None, "error": str(e)}
421
+
422
+
423
+ @mcp.tool(name="delete_regressor")
424
+ def delete_regressor(regressor_id: str) -> dict:
425
+ """
426
+ Delete a stored regressor.
427
+
428
+ Parameters:
429
+ regressor_id (str): ID of the regressor to delete.
430
+
431
+ Returns:
432
+ dict: Confirmation of deletion.
433
+ """
434
+ try:
435
+ if regressor_id not in _regressors:
436
+ return {"success": False, "result": None, "error": f"Regressor '{regressor_id}' not found"}
437
+
438
+ del _regressors[regressor_id]
439
+
440
+ return {
441
+ "success": True,
442
+ "result": {"message": f"Regressor '{regressor_id}' deleted"},
443
+ "error": None,
444
+ }
445
+ except Exception as e:
446
+ return {"success": False, "result": None, "error": str(e)}
447
+
448
 
449
  def create_app() -> FastMCP:
450
  """
451
  Create and return the FastMCP application instance.
452
 
453
  Returns:
454
+ FastMCP: the FastMCP application instance
455
  """
456
+ return mcp