aigroup-econ-mcp 1.4.3__py3-none-any.whl → 2.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PKG-INFO +344 -322
- README.md +335 -320
- __init__.py +1 -1
- aigroup_econ_mcp-2.0.1.dist-info/METADATA +732 -0
- aigroup_econ_mcp-2.0.1.dist-info/RECORD +170 -0
- cli.py +4 -0
- econometrics/advanced_methods/modern_computing_machine_learning/__init__.py +30 -0
- econometrics/advanced_methods/modern_computing_machine_learning/causal_forest.py +253 -0
- econometrics/advanced_methods/modern_computing_machine_learning/double_ml.py +268 -0
- econometrics/advanced_methods/modern_computing_machine_learning/gradient_boosting.py +249 -0
- econometrics/advanced_methods/modern_computing_machine_learning/hierarchical_clustering.py +243 -0
- econometrics/advanced_methods/modern_computing_machine_learning/kmeans_clustering.py +293 -0
- econometrics/advanced_methods/modern_computing_machine_learning/neural_network.py +264 -0
- econometrics/advanced_methods/modern_computing_machine_learning/random_forest.py +195 -0
- econometrics/advanced_methods/modern_computing_machine_learning/support_vector_machine.py +226 -0
- econometrics/advanced_methods/modern_computing_machine_learning/test_all_modules.py +329 -0
- econometrics/advanced_methods/modern_computing_machine_learning/test_report.md +107 -0
- econometrics/causal_inference/__init__.py +66 -0
- econometrics/causal_inference/causal_identification_strategy/__init__.py +104 -0
- econometrics/causal_inference/causal_identification_strategy/control_function.py +112 -0
- econometrics/causal_inference/causal_identification_strategy/difference_in_differences.py +107 -0
- econometrics/causal_inference/causal_identification_strategy/event_study.py +119 -0
- econometrics/causal_inference/causal_identification_strategy/first_difference.py +89 -0
- econometrics/causal_inference/causal_identification_strategy/fixed_effects.py +103 -0
- econometrics/causal_inference/causal_identification_strategy/hausman_test.py +69 -0
- econometrics/causal_inference/causal_identification_strategy/instrumental_variables.py +145 -0
- econometrics/causal_inference/causal_identification_strategy/mediation_analysis.py +121 -0
- econometrics/causal_inference/causal_identification_strategy/moderation_analysis.py +109 -0
- econometrics/causal_inference/causal_identification_strategy/propensity_score_matching.py +140 -0
- econometrics/causal_inference/causal_identification_strategy/random_effects.py +100 -0
- econometrics/causal_inference/causal_identification_strategy/regression_discontinuity.py +98 -0
- econometrics/causal_inference/causal_identification_strategy/synthetic_control.py +111 -0
- econometrics/causal_inference/causal_identification_strategy/triple_difference.py +86 -0
- econometrics/distribution_analysis/__init__.py +28 -0
- econometrics/distribution_analysis/oaxaca_blinder.py +184 -0
- econometrics/distribution_analysis/time_series_decomposition.py +152 -0
- econometrics/distribution_analysis/variance_decomposition.py +179 -0
- econometrics/missing_data/__init__.py +18 -0
- econometrics/missing_data/imputation_methods.py +219 -0
- econometrics/nonparametric/__init__.py +35 -0
- econometrics/nonparametric/gam_model.py +117 -0
- econometrics/nonparametric/kernel_regression.py +161 -0
- econometrics/nonparametric/quantile_regression.py +249 -0
- econometrics/nonparametric/spline_regression.py +100 -0
- econometrics/spatial_econometrics/__init__.py +68 -0
- econometrics/spatial_econometrics/geographically_weighted_regression.py +211 -0
- econometrics/spatial_econometrics/gwr_simple.py +154 -0
- econometrics/spatial_econometrics/spatial_autocorrelation.py +356 -0
- econometrics/spatial_econometrics/spatial_durbin_model.py +177 -0
- econometrics/spatial_econometrics/spatial_regression.py +315 -0
- econometrics/spatial_econometrics/spatial_weights.py +226 -0
- econometrics/specific_data_modeling/micro_discrete_limited_data/README.md +164 -0
- econometrics/specific_data_modeling/micro_discrete_limited_data/__init__.py +40 -0
- econometrics/specific_data_modeling/micro_discrete_limited_data/count_data_models.py +311 -0
- econometrics/specific_data_modeling/micro_discrete_limited_data/discrete_choice_models.py +294 -0
- econometrics/specific_data_modeling/micro_discrete_limited_data/limited_dependent_variable_models.py +282 -0
- econometrics/statistical_inference/__init__.py +21 -0
- econometrics/statistical_inference/bootstrap_methods.py +162 -0
- econometrics/statistical_inference/permutation_test.py +177 -0
- econometrics/survival_analysis/__init__.py +18 -0
- econometrics/survival_analysis/survival_models.py +259 -0
- econometrics/tests/causal_inference_tests/__init__.py +3 -0
- econometrics/tests/causal_inference_tests/detailed_test.py +441 -0
- econometrics/tests/causal_inference_tests/test_all_methods.py +418 -0
- econometrics/tests/causal_inference_tests/test_causal_identification_strategy.py +202 -0
- econometrics/tests/causal_inference_tests/test_difference_in_differences.py +53 -0
- econometrics/tests/causal_inference_tests/test_instrumental_variables.py +44 -0
- econometrics/tests/specific_data_modeling_tests/test_micro_discrete_limited_data.py +189 -0
- econometrics//321/206/320/254/320/272/321/205/342/225/235/320/220/321/205/320/237/320/241/321/205/320/264/320/267/321/207/342/226/222/342/225/227/321/204/342/225/235/320/250/321/205/320/225/320/230/321/207/342/225/221/320/267/321/205/320/230/320/226/321/206/320/256/320/240.md +544 -0
- pyproject.toml +9 -2
- server.py +15 -1
- tools/__init__.py +75 -1
- tools/causal_inference_adapter.py +658 -0
- tools/distribution_analysis_adapter.py +121 -0
- tools/gwr_simple_adapter.py +54 -0
- tools/machine_learning_adapter.py +567 -0
- tools/mcp_tool_groups/__init__.py +15 -1
- tools/mcp_tool_groups/causal_inference_tools.py +643 -0
- tools/mcp_tool_groups/distribution_analysis_tools.py +169 -0
- tools/mcp_tool_groups/machine_learning_tools.py +422 -0
- tools/mcp_tool_groups/microecon_tools.py +325 -0
- tools/mcp_tool_groups/missing_data_tools.py +117 -0
- tools/mcp_tool_groups/nonparametric_tools.py +225 -0
- tools/mcp_tool_groups/spatial_econometrics_tools.py +323 -0
- tools/mcp_tool_groups/statistical_inference_tools.py +131 -0
- tools/mcp_tools_registry.py +13 -3
- tools/microecon_adapter.py +412 -0
- tools/missing_data_adapter.py +73 -0
- tools/nonparametric_adapter.py +190 -0
- tools/spatial_econometrics_adapter.py +318 -0
- tools/statistical_inference_adapter.py +90 -0
- tools/survival_analysis_adapter.py +46 -0
- aigroup_econ_mcp-1.4.3.dist-info/METADATA +0 -710
- aigroup_econ_mcp-1.4.3.dist-info/RECORD +0 -92
- {aigroup_econ_mcp-1.4.3.dist-info → aigroup_econ_mcp-2.0.1.dist-info}/WHEEL +0 -0
- {aigroup_econ_mcp-1.4.3.dist-info → aigroup_econ_mcp-2.0.1.dist-info}/entry_points.txt +0 -0
- {aigroup_econ_mcp-1.4.3.dist-info → aigroup_econ_mcp-2.0.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
"""
|
|
2
|
+
空间计量经济学工具组
|
|
3
|
+
包含空间权重、空间自相关检验和空间回归模型
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import List, Optional, Dict, Any, Tuple
|
|
7
|
+
from mcp.server.fastmcp import Context
|
|
8
|
+
from mcp.server.session import ServerSession
|
|
9
|
+
|
|
10
|
+
from ..mcp_tools_registry import ToolGroup
|
|
11
|
+
from ..spatial_econometrics_adapter import (
|
|
12
|
+
spatial_weights_adapter,
|
|
13
|
+
morans_i_adapter,
|
|
14
|
+
gearys_c_adapter,
|
|
15
|
+
local_moran_adapter,
|
|
16
|
+
spatial_regression_adapter,
|
|
17
|
+
gwr_adapter
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class SpatialEconometricsTools(ToolGroup):
|
|
22
|
+
"""空间计量经济学工具组"""
|
|
23
|
+
|
|
24
|
+
name = "SPATIAL ECONOMETRICS"
|
|
25
|
+
description = "空间计量经济学分析工具"
|
|
26
|
+
version = "1.0.0"
|
|
27
|
+
|
|
28
|
+
@classmethod
|
|
29
|
+
def get_tools(cls) -> List[Dict[str, Any]]:
|
|
30
|
+
"""返回工具列表"""
|
|
31
|
+
return [
|
|
32
|
+
{
|
|
33
|
+
"name": "spatial_weights_matrix",
|
|
34
|
+
"handler": cls.spatial_weights_tool,
|
|
35
|
+
"description": "Spatial Weights Matrix Construction"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"name": "spatial_morans_i_test",
|
|
39
|
+
"handler": cls.morans_i_tool,
|
|
40
|
+
"description": "Moran's I Spatial Autocorrelation Test"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "spatial_gearys_c_test",
|
|
44
|
+
"handler": cls.gearys_c_tool,
|
|
45
|
+
"description": "Geary's C Spatial Autocorrelation Test"
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "spatial_local_moran_lisa",
|
|
49
|
+
"handler": cls.local_moran_tool,
|
|
50
|
+
"description": "Local Moran's I (LISA) Analysis"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "spatial_regression_model",
|
|
54
|
+
"handler": cls.spatial_regression_tool,
|
|
55
|
+
"description": "Spatial Regression Models (SAR/SEM/SDM)"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"name": "spatial_gwr_model",
|
|
59
|
+
"handler": cls.gwr_tool,
|
|
60
|
+
"description": "Geographically Weighted Regression (GWR)"
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def get_help_text(cls) -> str:
|
|
66
|
+
"""返回帮助文档"""
|
|
67
|
+
return """
|
|
68
|
+
空间计量经济学工具组 - 6个工具
|
|
69
|
+
|
|
70
|
+
1. Spatial Weights Matrix (spatial_weights_matrix)
|
|
71
|
+
- 空间权重矩阵构建
|
|
72
|
+
- 支持类型: Queen, Rook, KNN, Distance Band, Kernel
|
|
73
|
+
- 基于: libpysal库
|
|
74
|
+
|
|
75
|
+
2. Moran's I Test (spatial_morans_i_test)
|
|
76
|
+
- Moran's I空间自相关检验
|
|
77
|
+
- 全局空间聚集性分析
|
|
78
|
+
- 基于: esda库
|
|
79
|
+
|
|
80
|
+
3. Geary's C Test (spatial_gearys_c_test)
|
|
81
|
+
- Geary's C空间自相关检验
|
|
82
|
+
- 另一种全局空间相关性度量
|
|
83
|
+
- 基于: esda库
|
|
84
|
+
|
|
85
|
+
4. Local Moran's I - LISA (spatial_local_moran_lisa)
|
|
86
|
+
- 局部空间自相关分析
|
|
87
|
+
- 识别HH, LL, HL, LH聚类
|
|
88
|
+
- 基于: esda库
|
|
89
|
+
|
|
90
|
+
5. Spatial Regression (spatial_regression_model)
|
|
91
|
+
- 空间滞后模型 (SAR)
|
|
92
|
+
- 空间误差模型 (SEM)
|
|
93
|
+
- 空间杜宾模型 (SDM)
|
|
94
|
+
- 基于: spreg库
|
|
95
|
+
|
|
96
|
+
6. Geographically Weighted Regression (spatial_gwr_model)
|
|
97
|
+
- 地理加权回归
|
|
98
|
+
- 局部回归系数估计
|
|
99
|
+
- 捕捉空间异质性
|
|
100
|
+
- 基于: mgwr库
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
@staticmethod
|
|
104
|
+
async def spatial_weights_tool(
|
|
105
|
+
coordinates: Optional[List[Tuple[float, float]]] = None,
|
|
106
|
+
adjacency_matrix: Optional[List[List[int]]] = None,
|
|
107
|
+
weight_type: str = "queen",
|
|
108
|
+
k: int = 4,
|
|
109
|
+
distance_threshold: Optional[float] = None,
|
|
110
|
+
bandwidth: Optional[float] = None,
|
|
111
|
+
kernel_type: str = "triangular",
|
|
112
|
+
row_standardize: bool = True,
|
|
113
|
+
output_format: str = "json",
|
|
114
|
+
save_path: Optional[str] = None,
|
|
115
|
+
ctx: Context[ServerSession, None] = None
|
|
116
|
+
) -> str:
|
|
117
|
+
"""空间权重矩阵构建"""
|
|
118
|
+
try:
|
|
119
|
+
if ctx:
|
|
120
|
+
await ctx.info(f"Starting spatial weights construction ({weight_type})...")
|
|
121
|
+
|
|
122
|
+
result = spatial_weights_adapter(
|
|
123
|
+
coordinates=coordinates,
|
|
124
|
+
adjacency_matrix=adjacency_matrix,
|
|
125
|
+
weight_type=weight_type,
|
|
126
|
+
k=k,
|
|
127
|
+
distance_threshold=distance_threshold,
|
|
128
|
+
bandwidth=bandwidth,
|
|
129
|
+
kernel_type=kernel_type,
|
|
130
|
+
row_standardize=row_standardize,
|
|
131
|
+
output_format=output_format,
|
|
132
|
+
save_path=save_path
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
if ctx:
|
|
136
|
+
await ctx.info("Spatial weights construction complete")
|
|
137
|
+
|
|
138
|
+
return result
|
|
139
|
+
except Exception as e:
|
|
140
|
+
if ctx:
|
|
141
|
+
await ctx.error(f"Error: {str(e)}")
|
|
142
|
+
raise
|
|
143
|
+
|
|
144
|
+
@staticmethod
|
|
145
|
+
async def morans_i_tool(
|
|
146
|
+
values: List[float],
|
|
147
|
+
neighbors: dict,
|
|
148
|
+
weights: Optional[dict] = None,
|
|
149
|
+
permutations: int = 999,
|
|
150
|
+
two_tailed: bool = True,
|
|
151
|
+
output_format: str = "json",
|
|
152
|
+
save_path: Optional[str] = None,
|
|
153
|
+
ctx: Context[ServerSession, None] = None
|
|
154
|
+
) -> str:
|
|
155
|
+
"""Moran's I空间自相关检验"""
|
|
156
|
+
try:
|
|
157
|
+
if ctx:
|
|
158
|
+
await ctx.info("Starting Moran's I test...")
|
|
159
|
+
|
|
160
|
+
result = morans_i_adapter(
|
|
161
|
+
values=values,
|
|
162
|
+
neighbors=neighbors,
|
|
163
|
+
weights=weights,
|
|
164
|
+
permutations=permutations,
|
|
165
|
+
two_tailed=two_tailed,
|
|
166
|
+
output_format=output_format,
|
|
167
|
+
save_path=save_path
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
if ctx:
|
|
171
|
+
await ctx.info("Moran's I test complete")
|
|
172
|
+
|
|
173
|
+
return result
|
|
174
|
+
except Exception as e:
|
|
175
|
+
if ctx:
|
|
176
|
+
await ctx.error(f"Error: {str(e)}")
|
|
177
|
+
raise
|
|
178
|
+
|
|
179
|
+
@staticmethod
|
|
180
|
+
async def gearys_c_tool(
|
|
181
|
+
values: List[float],
|
|
182
|
+
neighbors: dict,
|
|
183
|
+
weights: Optional[dict] = None,
|
|
184
|
+
permutations: int = 999,
|
|
185
|
+
output_format: str = "json",
|
|
186
|
+
save_path: Optional[str] = None,
|
|
187
|
+
ctx: Context[ServerSession, None] = None
|
|
188
|
+
) -> str:
|
|
189
|
+
"""Geary's C空间自相关检验"""
|
|
190
|
+
try:
|
|
191
|
+
if ctx:
|
|
192
|
+
await ctx.info("Starting Geary's C test...")
|
|
193
|
+
|
|
194
|
+
result = gearys_c_adapter(
|
|
195
|
+
values=values,
|
|
196
|
+
neighbors=neighbors,
|
|
197
|
+
weights=weights,
|
|
198
|
+
permutations=permutations,
|
|
199
|
+
output_format=output_format,
|
|
200
|
+
save_path=save_path
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
if ctx:
|
|
204
|
+
await ctx.info("Geary's C test complete")
|
|
205
|
+
|
|
206
|
+
return result
|
|
207
|
+
except Exception as e:
|
|
208
|
+
if ctx:
|
|
209
|
+
await ctx.error(f"Error: {str(e)}")
|
|
210
|
+
raise
|
|
211
|
+
|
|
212
|
+
@staticmethod
|
|
213
|
+
async def local_moran_tool(
|
|
214
|
+
values: List[float],
|
|
215
|
+
neighbors: dict,
|
|
216
|
+
weights: Optional[dict] = None,
|
|
217
|
+
permutations: int = 999,
|
|
218
|
+
significance_level: float = 0.05,
|
|
219
|
+
output_format: str = "json",
|
|
220
|
+
save_path: Optional[str] = None,
|
|
221
|
+
ctx: Context[ServerSession, None] = None
|
|
222
|
+
) -> str:
|
|
223
|
+
"""局部Moran's I (LISA) 分析"""
|
|
224
|
+
try:
|
|
225
|
+
if ctx:
|
|
226
|
+
await ctx.info("Starting Local Moran's I (LISA) analysis...")
|
|
227
|
+
|
|
228
|
+
result = local_moran_adapter(
|
|
229
|
+
values=values,
|
|
230
|
+
neighbors=neighbors,
|
|
231
|
+
weights=weights,
|
|
232
|
+
permutations=permutations,
|
|
233
|
+
significance_level=significance_level,
|
|
234
|
+
output_format=output_format,
|
|
235
|
+
save_path=save_path
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
if ctx:
|
|
239
|
+
await ctx.info("Local Moran's I analysis complete")
|
|
240
|
+
|
|
241
|
+
return result
|
|
242
|
+
except Exception as e:
|
|
243
|
+
if ctx:
|
|
244
|
+
await ctx.error(f"Error: {str(e)}")
|
|
245
|
+
raise
|
|
246
|
+
|
|
247
|
+
@staticmethod
|
|
248
|
+
async def spatial_regression_tool(
|
|
249
|
+
y_data: List[float],
|
|
250
|
+
x_data: List[List[float]],
|
|
251
|
+
neighbors: dict,
|
|
252
|
+
weights: Optional[dict] = None,
|
|
253
|
+
feature_names: Optional[List[str]] = None,
|
|
254
|
+
model_type: str = "sar",
|
|
255
|
+
method: str = "ml",
|
|
256
|
+
output_format: str = "json",
|
|
257
|
+
save_path: Optional[str] = None,
|
|
258
|
+
ctx: Context[ServerSession, None] = None
|
|
259
|
+
) -> str:
|
|
260
|
+
"""空间回归模型(SAR/SEM/SDM)"""
|
|
261
|
+
try:
|
|
262
|
+
if ctx:
|
|
263
|
+
await ctx.info(f"Starting {model_type.upper()} spatial regression ({method.upper()})...")
|
|
264
|
+
|
|
265
|
+
result = spatial_regression_adapter(
|
|
266
|
+
y_data=y_data,
|
|
267
|
+
x_data=x_data,
|
|
268
|
+
neighbors=neighbors,
|
|
269
|
+
weights=weights,
|
|
270
|
+
feature_names=feature_names,
|
|
271
|
+
model_type=model_type,
|
|
272
|
+
method=method,
|
|
273
|
+
output_format=output_format,
|
|
274
|
+
save_path=save_path
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
if ctx:
|
|
278
|
+
await ctx.info(f"{model_type.upper()} spatial regression complete")
|
|
279
|
+
|
|
280
|
+
return result
|
|
281
|
+
except Exception as e:
|
|
282
|
+
if ctx:
|
|
283
|
+
await ctx.error(f"Error: {str(e)}")
|
|
284
|
+
raise
|
|
285
|
+
|
|
286
|
+
@staticmethod
|
|
287
|
+
async def gwr_tool(
|
|
288
|
+
y_data: List[float],
|
|
289
|
+
x_data: List[List[float]],
|
|
290
|
+
coordinates: List[Tuple[float, float]],
|
|
291
|
+
feature_names: Optional[List[str]] = None,
|
|
292
|
+
kernel_type: str = "bisquare",
|
|
293
|
+
bandwidth: Optional[float] = None,
|
|
294
|
+
fixed: bool = False,
|
|
295
|
+
output_format: str = "json",
|
|
296
|
+
save_path: Optional[str] = None,
|
|
297
|
+
ctx: Context[ServerSession, None] = None
|
|
298
|
+
) -> str:
|
|
299
|
+
"""地理加权回归 (GWR)"""
|
|
300
|
+
try:
|
|
301
|
+
if ctx:
|
|
302
|
+
await ctx.info(f"Starting GWR analysis ({kernel_type} kernel)...")
|
|
303
|
+
|
|
304
|
+
result = gwr_adapter(
|
|
305
|
+
y_data=y_data,
|
|
306
|
+
x_data=x_data,
|
|
307
|
+
coordinates=coordinates,
|
|
308
|
+
feature_names=feature_names,
|
|
309
|
+
kernel_type=kernel_type,
|
|
310
|
+
bandwidth=bandwidth,
|
|
311
|
+
fixed=fixed,
|
|
312
|
+
output_format=output_format,
|
|
313
|
+
save_path=save_path
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
if ctx:
|
|
317
|
+
await ctx.info("GWR analysis complete")
|
|
318
|
+
|
|
319
|
+
return result
|
|
320
|
+
except Exception as e:
|
|
321
|
+
if ctx:
|
|
322
|
+
await ctx.error(f"Error: {str(e)}")
|
|
323
|
+
raise
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""
|
|
2
|
+
统计推断技术工具组
|
|
3
|
+
包含Bootstrap和置换检验
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import List, Optional, Dict, Any
|
|
7
|
+
from mcp.server.fastmcp import Context
|
|
8
|
+
from mcp.server.session import ServerSession
|
|
9
|
+
|
|
10
|
+
from ..mcp_tools_registry import ToolGroup
|
|
11
|
+
from ..statistical_inference_adapter import (
|
|
12
|
+
bootstrap_adapter,
|
|
13
|
+
permutation_test_adapter
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class StatisticalInferenceTools(ToolGroup):
|
|
18
|
+
"""统计推断技术工具组"""
|
|
19
|
+
|
|
20
|
+
name = "STATISTICAL INFERENCE TECHNIQUES"
|
|
21
|
+
description = "统计推断和重采样方法工具"
|
|
22
|
+
version = "1.0.0"
|
|
23
|
+
|
|
24
|
+
@classmethod
|
|
25
|
+
def get_tools(cls) -> List[Dict[str, Any]]:
|
|
26
|
+
"""返回工具列表"""
|
|
27
|
+
return [
|
|
28
|
+
{
|
|
29
|
+
"name": "inference_bootstrap",
|
|
30
|
+
"handler": cls.bootstrap_tool,
|
|
31
|
+
"description": "Bootstrap Resampling Inference"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"name": "inference_permutation_test",
|
|
35
|
+
"handler": cls.permutation_test_tool,
|
|
36
|
+
"description": "Permutation Test (Nonparametric)"
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
@classmethod
|
|
41
|
+
def get_help_text(cls) -> str:
|
|
42
|
+
"""返回帮助文档"""
|
|
43
|
+
return """
|
|
44
|
+
统计推断技术工具组 - 2个工具
|
|
45
|
+
|
|
46
|
+
1. Bootstrap Inference (inference_bootstrap)
|
|
47
|
+
- Bootstrap重采样推断
|
|
48
|
+
- 置信区间估计
|
|
49
|
+
- 支持多种统计量和置信区间方法
|
|
50
|
+
- 基于: scipy.stats
|
|
51
|
+
|
|
52
|
+
2. Permutation Test (inference_permutation_test)
|
|
53
|
+
- 置换检验(非参数)
|
|
54
|
+
- 两样本比较
|
|
55
|
+
- 均值/中位数/方差比检验
|
|
56
|
+
- 基于: scipy.stats
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
@staticmethod
|
|
60
|
+
async def bootstrap_tool(
|
|
61
|
+
data: List[float],
|
|
62
|
+
statistic_func: str = "mean",
|
|
63
|
+
n_bootstrap: int = 1000,
|
|
64
|
+
confidence_level: float = 0.95,
|
|
65
|
+
method: str = "percentile",
|
|
66
|
+
random_state: Optional[int] = None,
|
|
67
|
+
output_format: str = "json",
|
|
68
|
+
save_path: Optional[str] = None,
|
|
69
|
+
ctx: Context[ServerSession, None] = None
|
|
70
|
+
) -> str:
|
|
71
|
+
"""Bootstrap重采样推断"""
|
|
72
|
+
try:
|
|
73
|
+
if ctx:
|
|
74
|
+
await ctx.info(f"Starting Bootstrap inference ({statistic_func})...")
|
|
75
|
+
|
|
76
|
+
result = bootstrap_adapter(
|
|
77
|
+
data=data,
|
|
78
|
+
statistic_func=statistic_func,
|
|
79
|
+
n_bootstrap=n_bootstrap,
|
|
80
|
+
confidence_level=confidence_level,
|
|
81
|
+
method=method,
|
|
82
|
+
random_state=random_state,
|
|
83
|
+
output_format=output_format,
|
|
84
|
+
save_path=save_path
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
if ctx:
|
|
88
|
+
await ctx.info("Bootstrap inference complete")
|
|
89
|
+
|
|
90
|
+
return result
|
|
91
|
+
except Exception as e:
|
|
92
|
+
if ctx:
|
|
93
|
+
await ctx.error(f"Error: {str(e)}")
|
|
94
|
+
raise
|
|
95
|
+
|
|
96
|
+
@staticmethod
|
|
97
|
+
async def permutation_test_tool(
|
|
98
|
+
sample_a: List[float],
|
|
99
|
+
sample_b: List[float],
|
|
100
|
+
test_type: str = "mean_difference",
|
|
101
|
+
alternative: str = "two-sided",
|
|
102
|
+
n_permutations: int = 10000,
|
|
103
|
+
random_state: Optional[int] = None,
|
|
104
|
+
output_format: str = "json",
|
|
105
|
+
save_path: Optional[str] = None,
|
|
106
|
+
ctx: Context[ServerSession, None] = None
|
|
107
|
+
) -> str:
|
|
108
|
+
"""置换检验"""
|
|
109
|
+
try:
|
|
110
|
+
if ctx:
|
|
111
|
+
await ctx.info(f"Starting permutation test ({test_type})...")
|
|
112
|
+
|
|
113
|
+
result = permutation_test_adapter(
|
|
114
|
+
sample_a=sample_a,
|
|
115
|
+
sample_b=sample_b,
|
|
116
|
+
test_type=test_type,
|
|
117
|
+
alternative=alternative,
|
|
118
|
+
n_permutations=n_permutations,
|
|
119
|
+
random_state=random_state,
|
|
120
|
+
output_format=output_format,
|
|
121
|
+
save_path=save_path
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
if ctx:
|
|
125
|
+
await ctx.info("Permutation test complete")
|
|
126
|
+
|
|
127
|
+
return result
|
|
128
|
+
except Exception as e:
|
|
129
|
+
if ctx:
|
|
130
|
+
await ctx.error(f"Error: {str(e)}")
|
|
131
|
+
raise
|
tools/mcp_tools_registry.py
CHANGED
|
@@ -67,27 +67,37 @@ class ToolRegistry:
|
|
|
67
67
|
# 扫描 mcp_tool_groups 目录
|
|
68
68
|
groups_dir = Path(base_path) / "mcp_tool_groups"
|
|
69
69
|
if not groups_dir.exists():
|
|
70
|
+
print(f"工具组目录不存在: {groups_dir}")
|
|
70
71
|
return
|
|
71
72
|
|
|
73
|
+
print(f"扫描工具组目录: {groups_dir}")
|
|
74
|
+
|
|
72
75
|
# 导入所有工具组模块
|
|
73
76
|
for module_file in groups_dir.glob("*_tools.py"):
|
|
74
77
|
module_name = module_file.stem
|
|
78
|
+
print(f"发现工具组模块: {module_name}")
|
|
75
79
|
try:
|
|
76
80
|
module = importlib.import_module(f"tools.mcp_tool_groups.{module_name}")
|
|
77
81
|
|
|
78
82
|
# 查找工具组类
|
|
83
|
+
found_groups = []
|
|
79
84
|
for name, obj in inspect.getmembers(module):
|
|
80
|
-
if (inspect.isclass(obj) and
|
|
81
|
-
issubclass(obj, ToolGroup) and
|
|
85
|
+
if (inspect.isclass(obj) and
|
|
86
|
+
issubclass(obj, ToolGroup) and
|
|
82
87
|
obj != ToolGroup and
|
|
83
88
|
hasattr(obj, 'get_tools')):
|
|
84
89
|
|
|
90
|
+
found_groups.append(name)
|
|
85
91
|
# 实例化并注册
|
|
86
92
|
group_instance = obj()
|
|
87
93
|
self.register_group(group_instance)
|
|
94
|
+
print(f" 注册工具组: {name}")
|
|
95
|
+
|
|
96
|
+
if not found_groups:
|
|
97
|
+
print(f" 在模块 {module_name} 中未找到工具组类")
|
|
88
98
|
|
|
89
99
|
except Exception as e:
|
|
90
|
-
print(f"
|
|
100
|
+
print(f"加载工具组 {module_name} 失败: {e}")
|
|
91
101
|
|
|
92
102
|
def get_all_tools(self) -> Dict[str, Dict[str, Any]]:
|
|
93
103
|
"""获取所有已注册的工具"""
|