aigroup-econ-mcp 1.3.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.
Files changed (198) hide show
  1. .gitignore +253 -0
  2. PKG-INFO +732 -0
  3. README.md +687 -0
  4. __init__.py +14 -0
  5. aigroup_econ_mcp-2.0.1.dist-info/METADATA +732 -0
  6. aigroup_econ_mcp-2.0.1.dist-info/RECORD +170 -0
  7. aigroup_econ_mcp-2.0.1.dist-info/entry_points.txt +2 -0
  8. aigroup_econ_mcp-2.0.1.dist-info/licenses/LICENSE +21 -0
  9. cli.py +32 -0
  10. econometrics/README.md +18 -0
  11. econometrics/__init__.py +191 -0
  12. econometrics/advanced_methods/modern_computing_machine_learning/__init__.py +30 -0
  13. econometrics/advanced_methods/modern_computing_machine_learning/causal_forest.py +253 -0
  14. econometrics/advanced_methods/modern_computing_machine_learning/double_ml.py +268 -0
  15. econometrics/advanced_methods/modern_computing_machine_learning/gradient_boosting.py +249 -0
  16. econometrics/advanced_methods/modern_computing_machine_learning/hierarchical_clustering.py +243 -0
  17. econometrics/advanced_methods/modern_computing_machine_learning/kmeans_clustering.py +293 -0
  18. econometrics/advanced_methods/modern_computing_machine_learning/neural_network.py +264 -0
  19. econometrics/advanced_methods/modern_computing_machine_learning/random_forest.py +195 -0
  20. econometrics/advanced_methods/modern_computing_machine_learning/support_vector_machine.py +226 -0
  21. econometrics/advanced_methods/modern_computing_machine_learning/test_all_modules.py +329 -0
  22. econometrics/advanced_methods/modern_computing_machine_learning/test_report.md +107 -0
  23. econometrics/basic_parametric_estimation/__init__.py +31 -0
  24. econometrics/basic_parametric_estimation/gmm/__init__.py +13 -0
  25. econometrics/basic_parametric_estimation/gmm/gmm_model.py +256 -0
  26. econometrics/basic_parametric_estimation/mle/__init__.py +13 -0
  27. econometrics/basic_parametric_estimation/mle/mle_model.py +241 -0
  28. econometrics/basic_parametric_estimation/ols/__init__.py +13 -0
  29. econometrics/basic_parametric_estimation/ols/ols_model.py +141 -0
  30. econometrics/causal_inference/__init__.py +66 -0
  31. econometrics/causal_inference/causal_identification_strategy/__init__.py +104 -0
  32. econometrics/causal_inference/causal_identification_strategy/control_function.py +112 -0
  33. econometrics/causal_inference/causal_identification_strategy/difference_in_differences.py +107 -0
  34. econometrics/causal_inference/causal_identification_strategy/event_study.py +119 -0
  35. econometrics/causal_inference/causal_identification_strategy/first_difference.py +89 -0
  36. econometrics/causal_inference/causal_identification_strategy/fixed_effects.py +103 -0
  37. econometrics/causal_inference/causal_identification_strategy/hausman_test.py +69 -0
  38. econometrics/causal_inference/causal_identification_strategy/instrumental_variables.py +145 -0
  39. econometrics/causal_inference/causal_identification_strategy/mediation_analysis.py +121 -0
  40. econometrics/causal_inference/causal_identification_strategy/moderation_analysis.py +109 -0
  41. econometrics/causal_inference/causal_identification_strategy/propensity_score_matching.py +140 -0
  42. econometrics/causal_inference/causal_identification_strategy/random_effects.py +100 -0
  43. econometrics/causal_inference/causal_identification_strategy/regression_discontinuity.py +98 -0
  44. econometrics/causal_inference/causal_identification_strategy/synthetic_control.py +111 -0
  45. econometrics/causal_inference/causal_identification_strategy/triple_difference.py +86 -0
  46. econometrics/distribution_analysis/__init__.py +28 -0
  47. econometrics/distribution_analysis/oaxaca_blinder.py +184 -0
  48. econometrics/distribution_analysis/time_series_decomposition.py +152 -0
  49. econometrics/distribution_analysis/variance_decomposition.py +179 -0
  50. econometrics/missing_data/__init__.py +18 -0
  51. econometrics/missing_data/imputation_methods.py +219 -0
  52. econometrics/missing_data/missing_data_measurement_error/__init__.py +0 -0
  53. econometrics/model_specification_diagnostics_robust_inference/README.md +173 -0
  54. econometrics/model_specification_diagnostics_robust_inference/__init__.py +78 -0
  55. econometrics/model_specification_diagnostics_robust_inference/diagnostic_tests/__init__.py +20 -0
  56. econometrics/model_specification_diagnostics_robust_inference/diagnostic_tests/diagnostic_tests_model.py +149 -0
  57. econometrics/model_specification_diagnostics_robust_inference/generalized_least_squares/__init__.py +15 -0
  58. econometrics/model_specification_diagnostics_robust_inference/generalized_least_squares/gls_model.py +130 -0
  59. econometrics/model_specification_diagnostics_robust_inference/model_selection/__init__.py +18 -0
  60. econometrics/model_specification_diagnostics_robust_inference/model_selection/model_selection_model.py +286 -0
  61. econometrics/model_specification_diagnostics_robust_inference/regularization/__init__.py +15 -0
  62. econometrics/model_specification_diagnostics_robust_inference/regularization/regularization_model.py +177 -0
  63. econometrics/model_specification_diagnostics_robust_inference/robust_errors/__init__.py +15 -0
  64. econometrics/model_specification_diagnostics_robust_inference/robust_errors/robust_errors_model.py +122 -0
  65. econometrics/model_specification_diagnostics_robust_inference/simultaneous_equations/__init__.py +15 -0
  66. econometrics/model_specification_diagnostics_robust_inference/simultaneous_equations/simultaneous_equations_model.py +246 -0
  67. econometrics/model_specification_diagnostics_robust_inference/weighted_least_squares/__init__.py +15 -0
  68. econometrics/model_specification_diagnostics_robust_inference/weighted_least_squares/wls_model.py +127 -0
  69. econometrics/nonparametric/__init__.py +35 -0
  70. econometrics/nonparametric/gam_model.py +117 -0
  71. econometrics/nonparametric/kernel_regression.py +161 -0
  72. econometrics/nonparametric/nonparametric_semiparametric_methods/__init__.py +0 -0
  73. econometrics/nonparametric/quantile_regression.py +249 -0
  74. econometrics/nonparametric/spline_regression.py +100 -0
  75. econometrics/spatial_econometrics/__init__.py +68 -0
  76. econometrics/spatial_econometrics/geographically_weighted_regression.py +211 -0
  77. econometrics/spatial_econometrics/gwr_simple.py +154 -0
  78. econometrics/spatial_econometrics/spatial_autocorrelation.py +356 -0
  79. econometrics/spatial_econometrics/spatial_durbin_model.py +177 -0
  80. econometrics/spatial_econometrics/spatial_econometrics_new/__init__.py +0 -0
  81. econometrics/spatial_econometrics/spatial_regression.py +315 -0
  82. econometrics/spatial_econometrics/spatial_weights.py +226 -0
  83. econometrics/specific_data_modeling/micro_discrete_limited_data/README.md +164 -0
  84. econometrics/specific_data_modeling/micro_discrete_limited_data/__init__.py +40 -0
  85. econometrics/specific_data_modeling/micro_discrete_limited_data/count_data_models.py +311 -0
  86. econometrics/specific_data_modeling/micro_discrete_limited_data/discrete_choice_models.py +294 -0
  87. econometrics/specific_data_modeling/micro_discrete_limited_data/limited_dependent_variable_models.py +282 -0
  88. econometrics/specific_data_modeling/survival_duration_data/__init__.py +0 -0
  89. econometrics/specific_data_modeling/time_series_panel_data/__init__.py +143 -0
  90. econometrics/specific_data_modeling/time_series_panel_data/arima_model.py +104 -0
  91. econometrics/specific_data_modeling/time_series_panel_data/cointegration_vecm.py +334 -0
  92. econometrics/specific_data_modeling/time_series_panel_data/dynamic_panel_models.py +653 -0
  93. econometrics/specific_data_modeling/time_series_panel_data/exponential_smoothing.py +176 -0
  94. econometrics/specific_data_modeling/time_series_panel_data/garch_model.py +198 -0
  95. econometrics/specific_data_modeling/time_series_panel_data/panel_diagnostics.py +125 -0
  96. econometrics/specific_data_modeling/time_series_panel_data/panel_var.py +60 -0
  97. econometrics/specific_data_modeling/time_series_panel_data/structural_break_tests.py +87 -0
  98. econometrics/specific_data_modeling/time_series_panel_data/time_varying_parameter_models.py +106 -0
  99. econometrics/specific_data_modeling/time_series_panel_data/unit_root_tests.py +204 -0
  100. econometrics/specific_data_modeling/time_series_panel_data/var_svar_model.py +372 -0
  101. econometrics/statistical_inference/__init__.py +21 -0
  102. econometrics/statistical_inference/bootstrap_methods.py +162 -0
  103. econometrics/statistical_inference/permutation_test.py +177 -0
  104. econometrics/statistical_inference/statistical_inference_techniques/__init__.py +0 -0
  105. econometrics/statistics/distribution_decomposition_methods/__init__.py +0 -0
  106. econometrics/survival_analysis/__init__.py +18 -0
  107. econometrics/survival_analysis/survival_models.py +259 -0
  108. econometrics/tests/basic_parametric_estimation_tests/__init__.py +3 -0
  109. econometrics/tests/basic_parametric_estimation_tests/test_gmm.py +128 -0
  110. econometrics/tests/basic_parametric_estimation_tests/test_mle.py +127 -0
  111. econometrics/tests/basic_parametric_estimation_tests/test_ols.py +100 -0
  112. econometrics/tests/causal_inference_tests/__init__.py +3 -0
  113. econometrics/tests/causal_inference_tests/detailed_test.py +441 -0
  114. econometrics/tests/causal_inference_tests/test_all_methods.py +418 -0
  115. econometrics/tests/causal_inference_tests/test_causal_identification_strategy.py +202 -0
  116. econometrics/tests/causal_inference_tests/test_difference_in_differences.py +53 -0
  117. econometrics/tests/causal_inference_tests/test_instrumental_variables.py +44 -0
  118. econometrics/tests/model_specification_diagnostics_tests/__init__.py +3 -0
  119. econometrics/tests/model_specification_diagnostics_tests/test_diagnostic_tests.py +86 -0
  120. econometrics/tests/model_specification_diagnostics_tests/test_robust_errors.py +89 -0
  121. econometrics/tests/specific_data_modeling_tests/__init__.py +3 -0
  122. econometrics/tests/specific_data_modeling_tests/test_arima.py +98 -0
  123. econometrics/tests/specific_data_modeling_tests/test_dynamic_panel.py +198 -0
  124. econometrics/tests/specific_data_modeling_tests/test_exponential_smoothing.py +105 -0
  125. econometrics/tests/specific_data_modeling_tests/test_garch.py +118 -0
  126. econometrics/tests/specific_data_modeling_tests/test_micro_discrete_limited_data.py +189 -0
  127. econometrics/tests/specific_data_modeling_tests/test_unit_root.py +156 -0
  128. econometrics/tests/specific_data_modeling_tests/test_var.py +124 -0
  129. 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
  130. prompts/__init__.py +0 -0
  131. prompts/analysis_guides.py +43 -0
  132. pyproject.toml +85 -0
  133. resources/MCP_MASTER_GUIDE.md +422 -0
  134. resources/MCP_TOOLS_DATA_FORMAT_GUIDE.md +185 -0
  135. resources/__init__.py +0 -0
  136. server.py +97 -0
  137. tools/README.md +88 -0
  138. tools/__init__.py +119 -0
  139. tools/causal_inference_adapter.py +658 -0
  140. tools/data_loader.py +213 -0
  141. tools/decorators.py +38 -0
  142. tools/distribution_analysis_adapter.py +121 -0
  143. tools/econometrics_adapter.py +286 -0
  144. tools/gwr_simple_adapter.py +54 -0
  145. tools/machine_learning_adapter.py +567 -0
  146. tools/mcp_tool_groups/__init__.py +15 -0
  147. tools/mcp_tool_groups/basic_parametric_tools.py +173 -0
  148. tools/mcp_tool_groups/causal_inference_tools.py +643 -0
  149. tools/mcp_tool_groups/distribution_analysis_tools.py +169 -0
  150. tools/mcp_tool_groups/machine_learning_tools.py +422 -0
  151. tools/mcp_tool_groups/microecon_tools.py +325 -0
  152. tools/mcp_tool_groups/missing_data_tools.py +117 -0
  153. tools/mcp_tool_groups/model_specification_tools.py +402 -0
  154. tools/mcp_tool_groups/nonparametric_tools.py +225 -0
  155. tools/mcp_tool_groups/spatial_econometrics_tools.py +323 -0
  156. tools/mcp_tool_groups/statistical_inference_tools.py +131 -0
  157. tools/mcp_tool_groups/time_series_tools.py +494 -0
  158. tools/mcp_tools_registry.py +124 -0
  159. tools/microecon_adapter.py +412 -0
  160. tools/missing_data_adapter.py +73 -0
  161. tools/model_specification_adapter.py +369 -0
  162. tools/nonparametric_adapter.py +190 -0
  163. tools/output_formatter.py +563 -0
  164. tools/spatial_econometrics_adapter.py +318 -0
  165. tools/statistical_inference_adapter.py +90 -0
  166. tools/survival_analysis_adapter.py +46 -0
  167. tools/time_series_panel_data_adapter.py +858 -0
  168. tools/time_series_panel_data_tools.py +65 -0
  169. aigroup_econ_mcp/__init__.py +0 -19
  170. aigroup_econ_mcp/cli.py +0 -82
  171. aigroup_econ_mcp/config.py +0 -561
  172. aigroup_econ_mcp/server.py +0 -452
  173. aigroup_econ_mcp/tools/__init__.py +0 -19
  174. aigroup_econ_mcp/tools/base.py +0 -470
  175. aigroup_econ_mcp/tools/cache.py +0 -533
  176. aigroup_econ_mcp/tools/data_loader.py +0 -195
  177. aigroup_econ_mcp/tools/file_parser.py +0 -1027
  178. aigroup_econ_mcp/tools/machine_learning.py +0 -60
  179. aigroup_econ_mcp/tools/ml_ensemble.py +0 -210
  180. aigroup_econ_mcp/tools/ml_evaluation.py +0 -272
  181. aigroup_econ_mcp/tools/ml_models.py +0 -54
  182. aigroup_econ_mcp/tools/ml_regularization.py +0 -186
  183. aigroup_econ_mcp/tools/monitoring.py +0 -555
  184. aigroup_econ_mcp/tools/optimized_example.py +0 -229
  185. aigroup_econ_mcp/tools/panel_data.py +0 -619
  186. aigroup_econ_mcp/tools/regression.py +0 -214
  187. aigroup_econ_mcp/tools/statistics.py +0 -154
  188. aigroup_econ_mcp/tools/time_series.py +0 -698
  189. aigroup_econ_mcp/tools/timeout.py +0 -283
  190. aigroup_econ_mcp/tools/tool_descriptions.py +0 -410
  191. aigroup_econ_mcp/tools/tool_handlers.py +0 -1016
  192. aigroup_econ_mcp/tools/tool_registry.py +0 -478
  193. aigroup_econ_mcp/tools/validation.py +0 -482
  194. aigroup_econ_mcp-1.3.3.dist-info/METADATA +0 -525
  195. aigroup_econ_mcp-1.3.3.dist-info/RECORD +0 -30
  196. aigroup_econ_mcp-1.3.3.dist-info/entry_points.txt +0 -2
  197. /aigroup_econ_mcp-1.3.3.dist-info/licenses/LICENSE → /LICENSE +0 -0
  198. {aigroup_econ_mcp-1.3.3.dist-info → aigroup_econ_mcp-2.0.1.dist-info}/WHEEL +0 -0
@@ -1,619 +0,0 @@
1
- """
2
- 面板数据分析工具
3
- """
4
-
5
- import numpy as np
6
- import pandas as pd
7
- import statsmodels.api as sm
8
- from linearmodels import PanelOLS, RandomEffects
9
- from typing import List, Dict, Any, Optional, Tuple
10
- from pydantic import BaseModel, Field
11
- import warnings
12
-
13
-
14
- class PanelDataResult(BaseModel):
15
- """面板数据模型结果基类"""
16
- rsquared: float = Field(description="R²")
17
- rsquared_adj: float = Field(description="调整R²")
18
- f_statistic: float = Field(description="F统计量")
19
- f_pvalue: float = Field(description="F检验p值")
20
- aic: float = Field(description="AIC信息准则")
21
- bic: float = Field(description="BIC信息准则")
22
- n_obs: int = Field(description="观测数量")
23
- coefficients: Dict[str, Dict[str, float]] = Field(description="回归系数详情")
24
-
25
-
26
- class FixedEffectsResult(PanelDataResult):
27
- """固定效应模型结果"""
28
- entity_effects: bool = Field(description="是否包含个体效应")
29
- time_effects: bool = Field(description="是否包含时间效应")
30
- within_rsquared: float = Field(description="组内R²")
31
-
32
-
33
- class RandomEffectsResult(PanelDataResult):
34
- """随机效应模型结果"""
35
- entity_effects: bool = Field(description="是否包含个体效应")
36
- time_effects: bool = Field(description="是否包含时间效应")
37
- between_rsquared: float = Field(description="组间R²")
38
-
39
-
40
- class HausmanTestResult(BaseModel):
41
- """Hausman检验结果"""
42
- statistic: float = Field(description="检验统计量")
43
- p_value: float = Field(description="p值")
44
- significant: bool = Field(description="是否显著(5%水平)")
45
- recommendation: str = Field(description="模型选择建议")
46
-
47
-
48
- class PanelUnitRootResult(BaseModel):
49
- """面板单位根检验结果"""
50
- statistic: float = Field(description="检验统计量")
51
- p_value: float = Field(description="p值")
52
- stationary: bool = Field(description="是否平稳")
53
- test_type: str = Field(description="检验类型")
54
-
55
-
56
- def prepare_panel_data(
57
- y_data: List[float],
58
- X_data: List[List[float]],
59
- entity_ids: List[str],
60
- time_periods: List[str],
61
- feature_names: Optional[List[str]] = None
62
- ) -> pd.DataFrame:
63
- """
64
- 准备面板数据格式
65
-
66
- 📊 数据格式要求:
67
- - 因变量(y_data): 数值列表,如 [1.2, 3.4, 5.6, ...]
68
- - 自变量(X_data): 二维数值列表,如 [[1, 2], [3, 4], [5, 6], ...]
69
- - 实体ID(entity_ids): 字符串列表,标识不同个体,如 ['A', 'A', 'B', 'B', ...]
70
- - 时间标识符(time_periods): 字符串或数值列表,标识时间点,如 ['2020', '2020', '2021', '2021', ...]
71
-
72
- 💡 使用示例:
73
- y_data = [10, 12, 8, 9] # 4个观测值
74
- X_data = [[1, 2], [2, 3], [1, 1], [2, 2]] # 2个自变量,4个观测值
75
- entity_ids = ['A', 'A', 'B', 'B'] # 2个实体,每个实体2个时间点
76
- time_periods = ['2020', '2021', '2020', '2021'] # 2个时间点
77
-
78
- ⚠️ 注意事项:
79
- - 确保每个实体有相同的时间点数量(平衡面板)
80
- - 实体ID和时间标识符的组合必须唯一
81
- - 建议至少3个实体,每个实体至少2个时间点
82
-
83
- Args:
84
- y_data: 因变量数据
85
- X_data: 自变量数据,二维列表
86
- entity_ids: 个体标识符列表
87
- time_periods: 时间标识符列表
88
- feature_names: 自变量名称列表
89
-
90
- Returns:
91
- pd.DataFrame: 面板数据格式的DataFrame
92
- """
93
- # 数据验证 - 提供更详细的错误信息
94
- if not y_data or not X_data or not entity_ids or not time_periods:
95
- raise ValueError("所有输入数据都不能为空。请提供:因变量(y_data)、自变量(X_data)、实体ID(entity_ids)、时间标识符(time_periods)")
96
-
97
- if len(y_data) != len(X_data):
98
- raise ValueError(f"因变量和自变量的观测数量不一致:因变量有{len(y_data)}个观测值,自变量有{len(X_data)}个观测值")
99
-
100
- if len(y_data) != len(entity_ids):
101
- raise ValueError(f"因变量和个体标识符数量不一致:因变量有{len(y_data)}个观测值,实体ID有{len(entity_ids)}个")
102
-
103
- if len(y_data) != len(time_periods):
104
- raise ValueError(f"因变量和时间标识符数量不一致:因变量有{len(y_data)}个观测值,时间标识符有{len(time_periods)}个")
105
-
106
- # 检查自变量维度一致性
107
- if len(X_data) > 0:
108
- first_dim = len(X_data[0])
109
- for i, x_row in enumerate(X_data):
110
- if len(x_row) != first_dim:
111
- raise ValueError(f"自变量维度不一致:第{i}行有{len(x_row)}个变量,但第一行有{first_dim}个变量")
112
-
113
- # 检查面板数据平衡性
114
- entity_time_counts = {}
115
- for entity, time_period in zip(entity_ids, time_periods):
116
- key = (entity, time_period)
117
- if key in entity_time_counts:
118
- raise ValueError(f"重复的实体-时间组合:实体 '{entity}' 在时间 '{time_period}' 有多个观测值")
119
- entity_time_counts[key] = True
120
-
121
- # 检查每个实体的时间点数量
122
- entity_counts = {}
123
- for entity in entity_ids:
124
- entity_counts[entity] = entity_counts.get(entity, 0) + 1
125
-
126
- unique_entities = len(entity_counts)
127
- if unique_entities < 2:
128
- raise ValueError(f"面板数据需要至少2个不同的实体,当前只有{unique_entities}个")
129
-
130
- # 检查时间点数量
131
- time_counts = {}
132
- for time_period in time_periods:
133
- time_counts[time_period] = time_counts.get(time_period, 0) + 1
134
-
135
- unique_times = len(time_counts)
136
- if unique_times < 2:
137
- raise ValueError(f"面板数据需要至少2个不同的时间点,当前只有{unique_times}个")
138
-
139
- # 检查是否为平衡面板
140
- time_counts_per_entity = {}
141
- for entity in set(entity_ids):
142
- entity_times = [time for e, time in zip(entity_ids, time_periods) if e == entity]
143
- time_counts_per_entity[entity] = len(set(entity_times))
144
-
145
- min_times = min(time_counts_per_entity.values())
146
- max_times = max(time_counts_per_entity.values())
147
- if min_times != max_times:
148
- warnings.warn(f"⚠️ 警告:面板数据不平衡。不同实体的时间点数量不同(最少{min_times}个,最多{max_times}个)。建议使用平衡面板数据以获得更可靠的结果。")
149
-
150
- # 处理时间标识符格式兼容性
151
- processed_time_periods = []
152
- for time_period in time_periods:
153
- # 尝试将时间标识符转换为可排序的格式
154
- if isinstance(time_period, str):
155
- # 如果是字符串,尝试转换为数值或保持原样
156
- try:
157
- # 尝试转换为数值
158
- processed_time_periods.append(float(time_period))
159
- except ValueError:
160
- # 如果无法转换为数值,尝试解析季度格式
161
- if 'Q' in time_period:
162
- try:
163
- # 处理季度格式,如 "2020Q1"
164
- year, quarter = time_period.split('Q')
165
- processed_time_periods.append(float(year) + float(quarter) / 10)
166
- except:
167
- # 如果无法解析,保持原样
168
- processed_time_periods.append(time_period)
169
- else:
170
- # 如果无法转换为数值,保持原样
171
- processed_time_periods.append(time_period)
172
- else:
173
- processed_time_periods.append(time_period)
174
-
175
- # 创建DataFrame
176
- data_dict = {
177
- 'entity': entity_ids,
178
- 'time': processed_time_periods,
179
- 'y': y_data
180
- }
181
-
182
- # 添加自变量
183
- if feature_names is None:
184
- feature_names = [f'x{i}' for i in range(len(X_data[0]))]
185
-
186
- for i, name in enumerate(feature_names):
187
- data_dict[name] = [x[i] for x in X_data]
188
-
189
- df = pd.DataFrame(data_dict)
190
-
191
- # 设置多级索引
192
- df = df.set_index(['entity', 'time'])
193
-
194
- return df
195
-
196
-
197
- def fixed_effects_model(
198
- y_data: List[float],
199
- X_data: List[List[float]],
200
- entity_ids: List[str],
201
- time_periods: List[str],
202
- feature_names: Optional[List[str]] = None,
203
- entity_effects: bool = True,
204
- time_effects: bool = False
205
- ) -> FixedEffectsResult:
206
- """
207
- 固定效应模型
208
-
209
- 📊 功能说明:
210
- 固定效应模型假设个体间存在不可观测的固定差异,通过组内变换消除这些固定效应。
211
- 适用于个体特征不随时间变化的情况。
212
-
213
- 📈 模型形式:
214
- y_it = α_i + βX_it + ε_it
215
-
216
- 💡 使用场景:
217
- - 研究个体内部随时间变化的影响
218
- - 控制个体固定特征的影响
219
- - 面板数据中个体间存在系统性差异
220
-
221
- ⚠️ 注意事项:
222
- - 无法估计不随时间变化的变量的系数
223
- - 需要较大的时间维度以获得可靠估计
224
- - 对个体异质性敏感
225
-
226
- Args:
227
- y_data: 因变量数据
228
- X_data: 自变量数据
229
- entity_ids: 个体标识符
230
- time_periods: 时间标识符
231
- feature_names: 自变量名称
232
- entity_effects: 是否包含个体效应
233
- time_effects: 是否包含时间效应
234
-
235
- Returns:
236
- FixedEffectsResult: 固定效应模型结果
237
- """
238
- try:
239
- # 准备面板数据
240
- df = prepare_panel_data(y_data, X_data, entity_ids, time_periods, feature_names)
241
-
242
- # 分离因变量和自变量
243
- y = df['y']
244
- X = df.drop('y', axis=1)
245
-
246
- # 添加常数项
247
- X = sm.add_constant(X)
248
-
249
- # 简化实现:使用OLS作为基础
250
- # 在实际应用中,应该使用专门的固定效应模型
251
- model = sm.OLS(y, X)
252
- fitted_model = model.fit()
253
-
254
- # 构建系数详情
255
- coefficients = {}
256
- conf_int = fitted_model.conf_int()
257
-
258
- for i, coef_name in enumerate(fitted_model.params.index):
259
- coefficients[coef_name] = {
260
- "coef": float(fitted_model.params.iloc[i]),
261
- "std_err": float(fitted_model.bse.iloc[i]),
262
- "t_value": float(fitted_model.tvalues.iloc[i]),
263
- "p_value": float(fitted_model.pvalues.iloc[i]),
264
- "ci_lower": float(conf_int.iloc[i, 0]),
265
- "ci_upper": float(conf_int.iloc[i, 1])
266
- }
267
-
268
- # 构建结果
269
- result = FixedEffectsResult(
270
- rsquared=float(fitted_model.rsquared),
271
- rsquared_adj=float(fitted_model.rsquared_adj),
272
- f_statistic=float(fitted_model.fvalue),
273
- f_pvalue=float(fitted_model.f_pvalue),
274
- aic=float(fitted_model.aic),
275
- bic=float(fitted_model.bic),
276
- n_obs=int(fitted_model.nobs),
277
- coefficients=coefficients,
278
- entity_effects=entity_effects,
279
- time_effects=time_effects,
280
- within_rsquared=float(fitted_model.rsquared) # 简化实现
281
- )
282
-
283
- return result
284
-
285
- except Exception as e:
286
- raise ValueError("固定效应模型拟合失败: {}".format(str(e)))
287
-
288
-
289
- def random_effects_model(
290
- y_data: List[float],
291
- X_data: List[List[float]],
292
- entity_ids: List[str],
293
- time_periods: List[str],
294
- feature_names: Optional[List[str]] = None,
295
- entity_effects: bool = True,
296
- time_effects: bool = False
297
- ) -> RandomEffectsResult:
298
- """
299
- 随机效应模型
300
-
301
- 📊 功能说明:
302
- 随机效应模型假设个体间差异是随机的,通过GLS估计同时利用组内和组间变异。
303
- 适用于个体特征与解释变量不相关的情况。
304
-
305
- 📈 模型形式:
306
- y_it = α + βX_it + μ_i + ε_it
307
-
308
- 💡 使用场景:
309
- - 个体特征与解释变量不相关
310
- - 希望估计不随时间变化的变量的系数
311
- - 样本来自更大的总体
312
-
313
- ⚠️ 注意事项:
314
- - 需要满足个体效应与解释变量不相关的假设
315
- - 如果假设不成立,估计可能不一致
316
- - 比固定效应模型更有效率
317
-
318
- Args:
319
- y_data: 因变量数据
320
- X_data: 自变量数据
321
- entity_ids: 个体标识符
322
- time_periods: 时间标识符
323
- feature_names: 自变量名称
324
- entity_effects: 是否包含个体效应
325
- time_effects: 是否包含时间效应
326
-
327
- Returns:
328
- RandomEffectsResult: 随机效应模型结果
329
- """
330
- try:
331
- # 准备面板数据
332
- df = prepare_panel_data(y_data, X_data, entity_ids, time_periods, feature_names)
333
-
334
- # 分离因变量和自变量
335
- y = df['y']
336
- X = df.drop('y', axis=1)
337
-
338
- # 添加常数项
339
- X = sm.add_constant(X)
340
-
341
- # 简化实现:使用OLS作为基础
342
- # 在实际应用中,应该使用专门的随机效应模型
343
- model = sm.OLS(y, X)
344
- fitted_model = model.fit()
345
-
346
- # 构建系数详情
347
- coefficients = {}
348
- conf_int = fitted_model.conf_int()
349
-
350
- for i, coef_name in enumerate(fitted_model.params.index):
351
- coefficients[coef_name] = {
352
- "coef": float(fitted_model.params.iloc[i]),
353
- "std_err": float(fitted_model.bse.iloc[i]),
354
- "t_value": float(fitted_model.tvalues.iloc[i]),
355
- "p_value": float(fitted_model.pvalues.iloc[i]),
356
- "ci_lower": float(conf_int.iloc[i, 0]),
357
- "ci_upper": float(conf_int.iloc[i, 1])
358
- }
359
-
360
- # 构建结果
361
- result = RandomEffectsResult(
362
- rsquared=float(fitted_model.rsquared),
363
- rsquared_adj=float(fitted_model.rsquared_adj),
364
- f_statistic=float(fitted_model.fvalue),
365
- f_pvalue=float(fitted_model.f_pvalue),
366
- aic=float(fitted_model.aic),
367
- bic=float(fitted_model.bic),
368
- n_obs=int(fitted_model.nobs),
369
- coefficients=coefficients,
370
- entity_effects=entity_effects,
371
- time_effects=time_effects,
372
- between_rsquared=float(fitted_model.rsquared) # 简化实现
373
- )
374
-
375
- return result
376
-
377
- except Exception as e:
378
- raise ValueError("随机效应模型拟合失败: {}".format(str(e)))
379
-
380
-
381
- def hausman_test(
382
- y_data: List[float],
383
- X_data: List[List[float]],
384
- entity_ids: List[str],
385
- time_periods: List[str],
386
- feature_names: Optional[List[str]] = None
387
- ) -> HausmanTestResult:
388
- """
389
- Hausman检验
390
-
391
- 📊 功能说明:
392
- Hausman检验用于比较固定效应模型和随机效应模型,判断个体效应是否与解释变量相关。
393
- 原假设:随机效应模型是一致的(个体效应与解释变量不相关)
394
- 备择假设:固定效应模型是一致的
395
-
396
- 💡 使用场景:
397
- - 在固定效应和随机效应模型之间选择
398
- - 检验个体效应是否与解释变量相关
399
- - 验证随机效应模型的假设
400
-
401
- ⚠️ 注意事项:
402
- - p值 < 0.05:拒绝原假设,选择固定效应模型
403
- - p值 >= 0.05:不能拒绝原假设,选择随机效应模型
404
- - 检验统计量服从卡方分布
405
-
406
- Args:
407
- y_data: 因变量数据
408
- X_data: 自变量数据
409
- entity_ids: 个体标识符
410
- time_periods: 时间标识符
411
- feature_names: 自变量名称
412
-
413
- Returns:
414
- HausmanTestResult: Hausman检验结果
415
- """
416
- try:
417
- # 拟合固定效应模型
418
- fe_result = fixed_effects_model(y_data, X_data, entity_ids, time_periods, feature_names)
419
-
420
- # 拟合随机效应模型
421
- re_result = random_effects_model(y_data, X_data, entity_ids, time_periods, feature_names)
422
-
423
- # 提取系数(排除常数项)
424
- fe_coefs = np.array([fe_result.coefficients[name]["coef"] for name in fe_result.coefficients if name != "const"])
425
- re_coefs = np.array([re_result.coefficients[name]["coef"] for name in re_result.coefficients if name != "const"])
426
-
427
- # 计算差异
428
- diff = fe_coefs - re_coefs
429
-
430
- # 简化Hausman检验统计量计算
431
- # 在实际应用中,应该使用更精确的方差-协方差矩阵计算
432
- statistic = np.sum(diff ** 2)
433
-
434
- # 自由度
435
- df = len(fe_coefs)
436
-
437
- # 计算p值
438
- from scipy import stats
439
- p_value = 1 - stats.chi2.cdf(statistic, df)
440
-
441
- # 判断显著性
442
- significant = p_value < 0.05
443
-
444
- # 给出建议
445
- if significant:
446
- recommendation = "拒绝原假设,建议使用固定效应模型(个体效应与解释变量相关)"
447
- else:
448
- recommendation = "不能拒绝原假设,建议使用随机效应模型(个体效应与解释变量不相关)"
449
-
450
- return HausmanTestResult(
451
- statistic=float(statistic),
452
- p_value=float(p_value),
453
- significant=significant,
454
- recommendation=recommendation
455
- )
456
-
457
- except Exception as e:
458
- raise ValueError(f"Hausman检验失败: {str(e)}")
459
-
460
-
461
- def panel_unit_root_test(
462
- data: List[float],
463
- entity_ids: List[str],
464
- time_periods: List[str],
465
- test_type: str = "levinlin",
466
- **kwargs # 接受并忽略额外参数(如y_data, x_data等)
467
- ) -> PanelUnitRootResult:
468
- """
469
- 面板单位根检验
470
-
471
- 📊 功能说明:
472
- 检验面板数据是否存在单位根,判断序列是否平稳。
473
- 常用的检验方法包括Levin-Lin-Chu检验、Im-Pesaran-Shin检验等。
474
-
475
- 💡 使用场景:
476
- - 面板数据建模前的平稳性检验
477
- - 判断是否需要差分处理
478
- - 验证面板数据的协整关系
479
-
480
- ⚠️ 注意事项:
481
- - p值 < 0.05:拒绝原假设,序列平稳
482
- - p值 >= 0.05:不能拒绝原假设,序列非平稳
483
- - 不同检验方法适用于不同的数据特征
484
-
485
- Args:
486
- data: 面板数据序列
487
- entity_ids: 个体标识符
488
- time_periods: 时间标识符
489
- test_type: 检验类型 ("levinlin", "ips", "fisher")
490
- **kwargs: 额外参数(忽略)
491
-
492
- Returns:
493
- PanelUnitRootResult: 面板单位根检验结果
494
- """
495
- try:
496
- # 准备数据
497
- df = pd.DataFrame({
498
- 'entity': entity_ids,
499
- 'time': time_periods,
500
- 'value': data
501
- })
502
-
503
- # 设置面板格式
504
- df = df.set_index(['entity', 'time'])
505
-
506
- # 简化实现:使用ADF检验的扩展版本
507
- # 在实际应用中,应该使用专门的panel unit root测试库
508
-
509
- # 对每个个体分别进行ADF检验
510
- entities = df.index.get_level_values('entity').unique()
511
- p_values = []
512
-
513
- for entity in entities:
514
- entity_data = df.xs(entity, level='entity')['value'].values
515
- # 降低要求:只需要5个以上数据点即可
516
- if len(entity_data) >= 5: # ADF检验最低要求
517
- from statsmodels.tsa.stattools import adfuller
518
- try:
519
- adf_result = adfuller(entity_data, maxlag=min(2, len(entity_data)//2))
520
- p_values.append(adf_result[1])
521
- except Exception as e:
522
- # 记录但继续处理其他实体
523
- print(f"实体 {entity} ADF检验失败: {e}")
524
- continue
525
-
526
- if not p_values:
527
- raise ValueError(f"无法进行面板单位根检验。需要至少{len(entities)}个实体,每个实体至少5个时间点。当前有{len(entities)}个实体,但可成功检验的实体数为0")
528
-
529
- # 使用Fisher组合检验方法(简化版)
530
- from scipy import stats
531
- combined_stat = -2 * np.sum(np.log(p_values))
532
- df_fisher = 2 * len(p_values)
533
- p_value = 1 - stats.chi2.cdf(combined_stat, df_fisher)
534
-
535
- # 判断平稳性
536
- stationary = p_value < 0.05
537
-
538
- return PanelUnitRootResult(
539
- statistic=float(combined_stat),
540
- p_value=float(p_value),
541
- stationary=stationary,
542
- test_type=f"fisher_{test_type}"
543
- )
544
-
545
- except Exception as e:
546
- raise ValueError(f"面板单位根检验失败: {str(e)}")
547
-
548
-
549
- def compare_panel_models(
550
- y_data: List[float],
551
- X_data: List[List[float]],
552
- entity_ids: List[str],
553
- time_periods: List[str],
554
- feature_names: Optional[List[str]] = None
555
- ) -> Dict[str, Any]:
556
- """
557
- 比较不同面板数据模型
558
-
559
- Args:
560
- y_data: 因变量数据
561
- X_data: 自变量数据
562
- entity_ids: 个体标识符
563
- time_periods: 时间标识符
564
- feature_names: 自变量名称
565
-
566
- Returns:
567
- Dict[str, Any]: 模型比较结果
568
- """
569
- try:
570
- # 拟合不同模型
571
- fe_result = fixed_effects_model(y_data, X_data, entity_ids, time_periods, feature_names)
572
- re_result = random_effects_model(y_data, X_data, entity_ids, time_periods, feature_names)
573
- hausman_result = hausman_test(y_data, X_data, entity_ids, time_periods, feature_names)
574
-
575
- # 模型比较
576
- comparison = {
577
- "fixed_effects": {
578
- "rsquared": fe_result.rsquared,
579
- "aic": fe_result.aic,
580
- "bic": fe_result.bic,
581
- "within_rsquared": fe_result.within_rsquared
582
- },
583
- "random_effects": {
584
- "rsquared": re_result.rsquared,
585
- "aic": re_result.aic,
586
- "bic": re_result.bic,
587
- "between_rsquared": re_result.between_rsquared
588
- },
589
- "hausman_test": hausman_result.model_dump(),
590
- "recommendation": hausman_result.recommendation
591
- }
592
-
593
- # 根据AIC和BIC选择最佳模型
594
- if fe_result.aic < re_result.aic and fe_result.bic < re_result.bic:
595
- comparison["aic_bic_recommendation"] = "根据AIC和BIC,固定效应模型更优"
596
- elif re_result.aic < fe_result.aic and re_result.bic < fe_result.bic:
597
- comparison["aic_bic_recommendation"] = "根据AIC和BIC,随机效应模型更优"
598
- else:
599
- comparison["aic_bic_recommendation"] = "AIC和BIC结果不一致,建议参考Hausman检验"
600
-
601
- return comparison
602
-
603
- except Exception as e:
604
- raise ValueError(f"模型比较失败: {str(e)}")
605
-
606
-
607
- # 导出所有函数
608
- __all__ = [
609
- "FixedEffectsResult",
610
- "RandomEffectsResult",
611
- "HausmanTestResult",
612
- "PanelUnitRootResult",
613
- "fixed_effects_model",
614
- "random_effects_model",
615
- "hausman_test",
616
- "panel_unit_root_test",
617
- "compare_panel_models",
618
- "prepare_panel_data"
619
- ]