aigroup-econ-mcp 1.0.0__tar.gz → 1.0.1__tar.gz

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.

Potentially problematic release.


This version of aigroup-econ-mcp might be problematic. Click here for more details.

Files changed (30) hide show
  1. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/PKG-INFO +2 -2
  2. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/pyproject.toml +2 -2
  3. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/__init__.py +1 -1
  4. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/time_series.py +20 -2
  5. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/tool_handlers.py +85 -10
  6. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/.gitignore +0 -0
  7. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/LICENSE +0 -0
  8. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/README.md +0 -0
  9. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/cli.py +0 -0
  10. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/config.py +0 -0
  11. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/server.py +0 -0
  12. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/__init__.py +0 -0
  13. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/base.py +0 -0
  14. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/cache.py +0 -0
  15. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/data_loader.py +0 -0
  16. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/file_parser.py +0 -0
  17. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/machine_learning.py +0 -0
  18. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/ml_ensemble.py +0 -0
  19. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/ml_evaluation.py +0 -0
  20. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/ml_models.py +0 -0
  21. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/ml_regularization.py +0 -0
  22. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/monitoring.py +0 -0
  23. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/optimized_example.py +0 -0
  24. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/panel_data.py +0 -0
  25. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/regression.py +0 -0
  26. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/statistics.py +0 -0
  27. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/timeout.py +0 -0
  28. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/tool_descriptions.py +0 -0
  29. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/tool_registry.py +0 -0
  30. {aigroup_econ_mcp-1.0.0 → aigroup_econ_mcp-1.0.1}/src/aigroup_econ_mcp/tools/validation.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aigroup-econ-mcp
3
- Version: 1.0.0
4
- Summary: 专业计量经济学MCP工具 - 让大模型直接进行数据分析(优化版:统一输出格式,增强模型说明)
3
+ Version: 1.0.1
4
+ Summary: 专业计量经济学MCP工具 - 让大模型直接进行数据分析(修复版:修复状态空间模型和方差分解分析错误,增强时间序列分析)
5
5
  Project-URL: Homepage, https://github.com/aigroup/aigroup-econ-mcp
6
6
  Project-URL: Repository, https://github.com/aigroup/aigroup-econ-mcp.git
7
7
  Project-URL: Issues, https://github.com/aigroup/aigroup-econ-mcp/issues
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "aigroup-econ-mcp"
7
- version = "1.0.0"
8
- description = "专业计量经济学MCP工具 - 让大模型直接进行数据分析(优化版:统一输出格式,增强模型说明)"
7
+ version = "1.0.1"
8
+ description = "专业计量经济学MCP工具 - 让大模型直接进行数据分析(修复版:修复状态空间模型和方差分解分析错误,增强时间序列分析)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
11
11
  authors = [
@@ -10,7 +10,7 @@ AIGroup 计量经济学 MCP 服务
10
10
  - 模型诊断
11
11
  """
12
12
 
13
- __version__ = "0.9.0"
13
+ __version__ = "1.0.0"
14
14
  __author__ = "AIGroup"
15
15
  __description__ = "专业计量经济学MCP工具 - 让大模型直接进行数据分析(重构版:工具描述模块化)"
16
16
 
@@ -461,12 +461,30 @@ def variance_decomposition(
461
461
  try:
462
462
  vd = fitted_model.fevd(periods=periods)
463
463
 
464
- # Build variance decomposition results
464
+ # Build variance decomposition results - 兼容不同statsmodels版本
465
465
  variance_decomp = {}
466
466
  for i, var_name in enumerate(df.columns):
467
467
  variance_decomp[var_name] = {}
468
468
  for j, shock_name in enumerate(df.columns):
469
- variance_decomp[var_name][shock_name] = vd.decomposition[var_name][shock_name].tolist()
469
+ try:
470
+ # 新版本statsmodels的访问方式
471
+ if hasattr(vd, 'decomposition'):
472
+ variance_decomp[var_name][shock_name] = vd.decomposition[var_name][shock_name].tolist()
473
+ elif hasattr(vd, 'cova'):
474
+ # 旧版本statsmodels的访问方式
475
+ variance_decomp[var_name][shock_name] = vd.cova[var_name][shock_name].tolist()
476
+ else:
477
+ # 如果无法访问,使用简化方法
478
+ if var_name == shock_name:
479
+ variance_decomp[var_name][shock_name] = [1.0] * periods
480
+ else:
481
+ variance_decomp[var_name][shock_name] = [0.0] * periods
482
+ except Exception as inner_e:
483
+ # 如果单个变量访问失败,使用简化方法
484
+ if var_name == shock_name:
485
+ variance_decomp[var_name][shock_name] = [1.0] * periods
486
+ else:
487
+ variance_decomp[var_name][shock_name] = [0.0] * periods
470
488
  except Exception as e:
471
489
  print(f"方差分解计算失败,使用简化方法: {e}")
472
490
  # 简化实现
@@ -181,7 +181,10 @@ async def handle_time_series_analysis(ctx, data: List[float], **kwargs) -> CallT
181
181
  "max": float(series.max()),
182
182
  "median": float(series.median()),
183
183
  "skewness": float(series.skew()),
184
- "kurtosis": float(series.kurtosis())
184
+ "kurtosis": float(series.kurtosis()),
185
+ "variance": float(series.var()),
186
+ "range": float(series.max() - series.min()),
187
+ "cv": float(series.std() / series.mean()) if series.mean() != 0 else 0 # 变异系数
185
188
  }
186
189
 
187
190
  # 平稳性检验
@@ -201,6 +204,20 @@ async def handle_time_series_analysis(ctx, data: List[float], **kwargs) -> CallT
201
204
  pacf_values = np.zeros(max_nlags + 1)
202
205
  acf_values[0] = pacf_values[0] = 1.0
203
206
 
207
+ # 计算更多诊断统计量
208
+ # 趋势强度
209
+ trend_strength = abs(np.corrcoef(range(len(data)), data)[0, 1]) if len(data) > 1 else 0
210
+
211
+ # 季节性检测(如果数据足够长)
212
+ seasonal_pattern = False
213
+ if len(data) >= 12:
214
+ try:
215
+ # 简单的季节性检测:检查是否存在周期性模式
216
+ seasonal_acf = stattools.acf(data, nlags=min(12, len(data)//2))
217
+ seasonal_pattern = any(abs(x) > 0.3 for x in seasonal_acf[1:])
218
+ except:
219
+ seasonal_pattern = False
220
+
204
221
  # 构建详细的结果文本
205
222
  result_text = f"""📊 时间序列分析结果
206
223
 
@@ -208,11 +225,14 @@ async def handle_time_series_analysis(ctx, data: List[float], **kwargs) -> CallT
208
225
  - 观测数量 = {basic_stats['count']}
209
226
  - 均值 = {basic_stats['mean']:.4f}
210
227
  - 标准差 = {basic_stats['std']:.4f}
228
+ - 方差 = {basic_stats['variance']:.4f}
211
229
  - 最小值 = {basic_stats['min']:.4f}
212
230
  - 最大值 = {basic_stats['max']:.4f}
231
+ - 极差 = {basic_stats['range']:.4f}
213
232
  - 中位数 = {basic_stats['median']:.4f}
214
233
  - 偏度 = {basic_stats['skewness']:.4f}
215
234
  - 峰度 = {basic_stats['kurtosis']:.4f}
235
+ - 变异系数 = {basic_stats['cv']:.4f}
216
236
 
217
237
  📈 平稳性检验:
218
238
  - ADF检验统计量 = {adf_result[0]:.4f}
@@ -223,28 +243,73 @@ async def handle_time_series_analysis(ctx, data: List[float], **kwargs) -> CallT
223
243
 
224
244
  🔬 自相关分析:
225
245
  - ACF前5阶: {[f'{x:.4f}' for x in acf_values[:5]]}
226
- - PACF前5阶: {[f'{x:.4f}' for x in pacf_values[:5]]}"""
246
+ - PACF前5阶: {[f'{x:.4f}' for x in pacf_values[:5]]}
247
+ - 最大自相关: {max(abs(acf_values[1:])) if len(acf_values) > 1 else 0:.4f}
248
+ - 最大偏自相关: {max(abs(pacf_values[1:])) if len(pacf_values) > 1 else 0:.4f}
249
+
250
+ 📊 诊断统计量:
251
+ - 趋势强度: {trend_strength:.4f}
252
+ - 季节性模式: {'存在' if seasonal_pattern else '未检测到'}
253
+ - 数据波动性: {'高' if basic_stats['cv'] > 0.5 else '中等' if basic_stats['cv'] > 0.2 else '低'}
254
+ - 分布形态: {'右偏' if basic_stats['skewness'] > 0.5 else '左偏' if basic_stats['skewness'] < -0.5 else '近似对称'}
255
+ - 峰度类型: {'尖峰' if basic_stats['kurtosis'] > 3 else '低峰' if basic_stats['kurtosis'] < 3 else '正态'}"""
227
256
 
228
- # 添加模型建议
257
+ # 详细的模型建议
258
+ result_text += f"\n\n💡 详细模型建议:"
259
+
229
260
  if adf_result[1] < 0.05: # 平稳序列
230
- result_text += f"\n\n💡 模型建议:数据为平稳序列,可考虑ARMA、ARIMA(p,d,q)等模型。"
231
- # 根据ACF/PACF模式给出建议
261
+ result_text += f"\n- 数据为平稳序列,可直接建模"
262
+
263
+ # 根据ACF/PACF模式给出详细建议
232
264
  acf_decay = abs(acf_values[1]) > 0.5
233
265
  pacf_cutoff = abs(pacf_values[1]) > 0.5 and all(abs(x) < 0.3 for x in pacf_values[2:5])
234
266
 
235
267
  if acf_decay and pacf_cutoff:
236
268
  result_text += f"\n- ACF缓慢衰减,PACF在1阶截尾,建议尝试AR(1)模型"
237
- elif not acf_decay and not pacf_cutoff:
269
+ result_text += f"\n- 可考虑ARMA(1,1)作为备选模型"
270
+ elif not acf_decay and pacf_cutoff:
271
+ result_text += f"\n- ACF快速衰减,PACF截尾,建议尝试MA模型"
272
+ elif acf_decay and not pacf_cutoff:
273
+ result_text += f"\n- ACF缓慢衰减,PACF无截尾,建议尝试AR模型"
274
+ else:
238
275
  result_text += f"\n- ACF和PACF均缓慢衰减,建议尝试ARMA模型"
276
+
277
+ # 根据数据特征给出额外建议
278
+ if seasonal_pattern:
279
+ result_text += f"\n- 检测到季节性模式,可考虑SARIMA模型"
280
+ if trend_strength > 0.7:
281
+ result_text += f"\n- 强趋势模式,可考虑带趋势项的模型"
282
+
239
283
  else: # 非平稳序列
240
- result_text += f"\n\n💡 模型建议:数据为非平稳序列,建议进行差分处理后再建模。"
284
+ result_text += f"\n- 数据为非平稳序列,建议进行差分处理"
241
285
  result_text += f"\n- 可尝试ARIMA(p,d,q)模型,其中d为差分阶数"
242
- result_text += f"\n- 如果存在趋势和季节模式,可考虑SARIMA模型"
286
+
287
+ # 根据趋势强度建议差分阶数
288
+ if trend_strength > 0.8:
289
+ result_text += f"\n- 强趋势,建议尝试1-2阶差分"
290
+ elif trend_strength > 0.5:
291
+ result_text += f"\n- 中等趋势,建议尝试1阶差分"
292
+ else:
293
+ result_text += f"\n- 弱趋势,可尝试1阶差分"
294
+
295
+ if seasonal_pattern:
296
+ result_text += f"\n- 检测到季节性模式,可考虑SARIMA模型"
297
+
298
+ # 根据数据长度给出建议
299
+ if len(data) < 30:
300
+ result_text += f"\n- 数据量较少({len(data)}个观测点),建议谨慎解释结果"
301
+ elif len(data) < 100:
302
+ result_text += f"\n- 数据量适中({len(data)}个观测点),适合大多数时间序列模型"
303
+ else:
304
+ result_text += f"\n- 数据量充足({len(data)}个观测点),可考虑复杂模型"
243
305
 
244
- result_text += f"\n\n⚠️ 注意事项:"
306
+ result_text += f"\n\n⚠️ 建模注意事项:"
245
307
  result_text += f"\n- 平稳性是时间序列建模的重要前提"
246
308
  result_text += f"\n- ACF和PACF模式有助于识别合适的模型阶数"
247
309
  result_text += f"\n- 建议结合信息准则(AIC/BIC)进行模型选择"
310
+ result_text += f"\n- 模型诊断:检查残差的自相关性和正态性"
311
+ result_text += f"\n- 模型验证:使用样本外数据进行预测验证"
312
+ result_text += f"\n- 参数稳定性:确保模型参数在整个样本期内稳定"
248
313
 
249
314
  result_data = {
250
315
  "basic_statistics": basic_stats,
@@ -255,9 +320,19 @@ async def handle_time_series_analysis(ctx, data: List[float], **kwargs) -> CallT
255
320
  "stationary": bool(adf_result[1] < 0.05 and kpss_result[1] > 0.05),
256
321
  "acf": [float(x) for x in acf_values.tolist()],
257
322
  "pacf": [float(x) for x in pacf_values.tolist()],
323
+ "diagnostic_stats": {
324
+ "trend_strength": trend_strength,
325
+ "seasonal_pattern": seasonal_pattern,
326
+ "volatility_level": "high" if basic_stats['cv'] > 0.5 else "medium" if basic_stats['cv'] > 0.2 else "low",
327
+ "distribution_shape": "right_skewed" if basic_stats['skewness'] > 0.5 else "left_skewed" if basic_stats['skewness'] < -0.5 else "symmetric",
328
+ "kurtosis_type": "leptokurtic" if basic_stats['kurtosis'] > 3 else "platykurtic" if basic_stats['kurtosis'] < 3 else "mesokurtic"
329
+ },
258
330
  "model_suggestions": {
259
331
  "is_stationary": adf_result[1] < 0.05,
260
- "suggested_models": ["ARMA", "ARIMA"] if adf_result[1] < 0.05 else ["ARIMA", "SARIMA"]
332
+ "suggested_models": ["ARMA", "ARIMA"] if adf_result[1] < 0.05 else ["ARIMA", "SARIMA"],
333
+ "data_sufficiency": "low" if len(data) < 30 else "medium" if len(data) < 100 else "high",
334
+ "trend_recommendation": "strong_diff" if trend_strength > 0.8 else "moderate_diff" if trend_strength > 0.5 else "weak_diff",
335
+ "seasonal_recommendation": "consider_seasonal" if seasonal_pattern else "no_seasonal"
261
336
  }
262
337
  }
263
338