aigroup-econ-mcp 1.0.0__py3-none-any.whl → 1.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.
Potentially problematic release.
This version of aigroup-econ-mcp might be problematic. Click here for more details.
- aigroup_econ_mcp/__init__.py +1 -1
- aigroup_econ_mcp/tools/time_series.py +20 -2
- aigroup_econ_mcp/tools/tool_handlers.py +85 -10
- {aigroup_econ_mcp-1.0.0.dist-info → aigroup_econ_mcp-1.0.1.dist-info}/METADATA +2 -2
- {aigroup_econ_mcp-1.0.0.dist-info → aigroup_econ_mcp-1.0.1.dist-info}/RECORD +8 -8
- {aigroup_econ_mcp-1.0.0.dist-info → aigroup_econ_mcp-1.0.1.dist-info}/WHEEL +0 -0
- {aigroup_econ_mcp-1.0.0.dist-info → aigroup_econ_mcp-1.0.1.dist-info}/entry_points.txt +0 -0
- {aigroup_econ_mcp-1.0.0.dist-info → aigroup_econ_mcp-1.0.1.dist-info}/licenses/LICENSE +0 -0
aigroup_econ_mcp/__init__.py
CHANGED
|
@@ -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
|
-
|
|
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
|
|
231
|
-
|
|
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
|
-
|
|
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
|
|
284
|
+
result_text += f"\n- 数据为非平稳序列,建议进行差分处理"
|
|
241
285
|
result_text += f"\n- 可尝试ARIMA(p,d,q)模型,其中d为差分阶数"
|
|
242
|
-
|
|
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
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aigroup-econ-mcp
|
|
3
|
-
Version: 1.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
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
aigroup_econ_mcp/__init__.py,sha256=
|
|
1
|
+
aigroup_econ_mcp/__init__.py,sha256=Emzv62DUuziInXIYpCLshyqDmrqPZBsFBiFSrIiUiWU,511
|
|
2
2
|
aigroup_econ_mcp/cli.py,sha256=7yeNXWNwMdpUswAO4LsqAvb0EmCO3S6Bs6sl483uSXI,3363
|
|
3
3
|
aigroup_econ_mcp/config.py,sha256=ab5X4-H8isIe2nma0c0AOqlyYgwhf5kfe9Zx5XRrzIo,18876
|
|
4
4
|
aigroup_econ_mcp/server.py,sha256=jEcEMhwiWCr_9QziqW4nvV2z8Eg807iT6do2C6mjpo8,30899
|
|
@@ -17,14 +17,14 @@ aigroup_econ_mcp/tools/optimized_example.py,sha256=tZVQ2jTzHY_zixTynm4Sq8gj5hz6e
|
|
|
17
17
|
aigroup_econ_mcp/tools/panel_data.py,sha256=qFZICvt9Plt2bOvCCgAveVncb_QpHvWzDssdQntKf5M,22696
|
|
18
18
|
aigroup_econ_mcp/tools/regression.py,sha256=uMGRGUQo4mU1sb8fwpP2FpkCqt_e9AtqEtUpInACtJo,6443
|
|
19
19
|
aigroup_econ_mcp/tools/statistics.py,sha256=2cHgNSUXwPYPLxntVOEOL8yF-x92mrgjK-R8kkxDihg,4239
|
|
20
|
-
aigroup_econ_mcp/tools/time_series.py,sha256=
|
|
20
|
+
aigroup_econ_mcp/tools/time_series.py,sha256=ZlkYn0HMm_jRn0LuxIEC4VegM3vNFPCOfdQXh5AayvA,22911
|
|
21
21
|
aigroup_econ_mcp/tools/timeout.py,sha256=vNnGsR0sXW1xvIbKCF-qPUU3QNDAn_MaQgSxbGxkfW4,8404
|
|
22
22
|
aigroup_econ_mcp/tools/tool_descriptions.py,sha256=Oj_14_79AB8Ku64mV0cdoV5f2-UFx-0NY3Xxjj6L-1A,32506
|
|
23
|
-
aigroup_econ_mcp/tools/tool_handlers.py,sha256=
|
|
23
|
+
aigroup_econ_mcp/tools/tool_handlers.py,sha256=lPBSOeKPJLD1-u0nBZEXMbMg9j4Yp0DG3GtFWbjhiS0,41717
|
|
24
24
|
aigroup_econ_mcp/tools/tool_registry.py,sha256=4SFpMnReZyGfEHCCDnojwHIUEpuQICS9M2u_9xuoUck,4413
|
|
25
25
|
aigroup_econ_mcp/tools/validation.py,sha256=F7LHwog5xtFIMjD9D48kd8jAF5MsZb7wjdrgaOg8EKo,16657
|
|
26
|
-
aigroup_econ_mcp-1.0.
|
|
27
|
-
aigroup_econ_mcp-1.0.
|
|
28
|
-
aigroup_econ_mcp-1.0.
|
|
29
|
-
aigroup_econ_mcp-1.0.
|
|
30
|
-
aigroup_econ_mcp-1.0.
|
|
26
|
+
aigroup_econ_mcp-1.0.1.dist-info/METADATA,sha256=kWS3Gb9uK7CJZboVmQG7acTtUoDEI3T2zBNoabqFSvk,10896
|
|
27
|
+
aigroup_econ_mcp-1.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
28
|
+
aigroup_econ_mcp-1.0.1.dist-info/entry_points.txt,sha256=j5ZJYOc4lAZV-X3XkAuGhzHtIRcJtZ6Gz8ZKPY_QTrM,62
|
|
29
|
+
aigroup_econ_mcp-1.0.1.dist-info/licenses/LICENSE,sha256=DoyCJUWlDzKbqc5KRbFpsGYLwLh-XJRHKQDoITjb1yc,1083
|
|
30
|
+
aigroup_econ_mcp-1.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|