aigroup-econ-mcp 1.3.3__py3-none-any.whl → 1.4.3__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.
- .gitignore +253 -0
- PKG-INFO +710 -0
- README.md +672 -0
- __init__.py +14 -0
- aigroup_econ_mcp-1.4.3.dist-info/METADATA +710 -0
- aigroup_econ_mcp-1.4.3.dist-info/RECORD +92 -0
- aigroup_econ_mcp-1.4.3.dist-info/entry_points.txt +2 -0
- aigroup_econ_mcp-1.4.3.dist-info/licenses/LICENSE +21 -0
- cli.py +28 -0
- econometrics/README.md +18 -0
- econometrics/__init__.py +191 -0
- econometrics/advanced_methods/modern_computing_machine_learning/__init__.py +0 -0
- econometrics/basic_parametric_estimation/__init__.py +31 -0
- econometrics/basic_parametric_estimation/gmm/__init__.py +13 -0
- econometrics/basic_parametric_estimation/gmm/gmm_model.py +256 -0
- econometrics/basic_parametric_estimation/mle/__init__.py +13 -0
- econometrics/basic_parametric_estimation/mle/mle_model.py +241 -0
- econometrics/basic_parametric_estimation/ols/__init__.py +13 -0
- econometrics/basic_parametric_estimation/ols/ols_model.py +141 -0
- econometrics/causal_inference/causal_identification_strategy/__init__.py +0 -0
- econometrics/missing_data/missing_data_measurement_error/__init__.py +0 -0
- econometrics/model_specification_diagnostics_robust_inference/README.md +173 -0
- econometrics/model_specification_diagnostics_robust_inference/__init__.py +78 -0
- econometrics/model_specification_diagnostics_robust_inference/diagnostic_tests/__init__.py +20 -0
- econometrics/model_specification_diagnostics_robust_inference/diagnostic_tests/diagnostic_tests_model.py +149 -0
- econometrics/model_specification_diagnostics_robust_inference/generalized_least_squares/__init__.py +15 -0
- econometrics/model_specification_diagnostics_robust_inference/generalized_least_squares/gls_model.py +130 -0
- econometrics/model_specification_diagnostics_robust_inference/model_selection/__init__.py +18 -0
- econometrics/model_specification_diagnostics_robust_inference/model_selection/model_selection_model.py +286 -0
- econometrics/model_specification_diagnostics_robust_inference/regularization/__init__.py +15 -0
- econometrics/model_specification_diagnostics_robust_inference/regularization/regularization_model.py +177 -0
- econometrics/model_specification_diagnostics_robust_inference/robust_errors/__init__.py +15 -0
- econometrics/model_specification_diagnostics_robust_inference/robust_errors/robust_errors_model.py +122 -0
- econometrics/model_specification_diagnostics_robust_inference/simultaneous_equations/__init__.py +15 -0
- econometrics/model_specification_diagnostics_robust_inference/simultaneous_equations/simultaneous_equations_model.py +246 -0
- econometrics/model_specification_diagnostics_robust_inference/weighted_least_squares/__init__.py +15 -0
- econometrics/model_specification_diagnostics_robust_inference/weighted_least_squares/wls_model.py +127 -0
- econometrics/nonparametric/nonparametric_semiparametric_methods/__init__.py +0 -0
- econometrics/spatial_econometrics/spatial_econometrics_new/__init__.py +0 -0
- econometrics/specific_data_modeling/micro_discrete_limited_data/__init__.py +0 -0
- econometrics/specific_data_modeling/survival_duration_data/__init__.py +0 -0
- econometrics/specific_data_modeling/time_series_panel_data/__init__.py +143 -0
- econometrics/specific_data_modeling/time_series_panel_data/arima_model.py +104 -0
- econometrics/specific_data_modeling/time_series_panel_data/cointegration_vecm.py +334 -0
- econometrics/specific_data_modeling/time_series_panel_data/dynamic_panel_models.py +653 -0
- econometrics/specific_data_modeling/time_series_panel_data/exponential_smoothing.py +176 -0
- econometrics/specific_data_modeling/time_series_panel_data/garch_model.py +198 -0
- econometrics/specific_data_modeling/time_series_panel_data/panel_diagnostics.py +125 -0
- econometrics/specific_data_modeling/time_series_panel_data/panel_var.py +60 -0
- econometrics/specific_data_modeling/time_series_panel_data/structural_break_tests.py +87 -0
- econometrics/specific_data_modeling/time_series_panel_data/time_varying_parameter_models.py +106 -0
- econometrics/specific_data_modeling/time_series_panel_data/unit_root_tests.py +204 -0
- econometrics/specific_data_modeling/time_series_panel_data/var_svar_model.py +372 -0
- econometrics/statistical_inference/statistical_inference_techniques/__init__.py +0 -0
- econometrics/statistics/distribution_decomposition_methods/__init__.py +0 -0
- econometrics/tests/basic_parametric_estimation_tests/__init__.py +3 -0
- econometrics/tests/basic_parametric_estimation_tests/test_gmm.py +128 -0
- econometrics/tests/basic_parametric_estimation_tests/test_mle.py +127 -0
- econometrics/tests/basic_parametric_estimation_tests/test_ols.py +100 -0
- econometrics/tests/model_specification_diagnostics_tests/__init__.py +3 -0
- econometrics/tests/model_specification_diagnostics_tests/test_diagnostic_tests.py +86 -0
- econometrics/tests/model_specification_diagnostics_tests/test_robust_errors.py +89 -0
- econometrics/tests/specific_data_modeling_tests/__init__.py +3 -0
- econometrics/tests/specific_data_modeling_tests/test_arima.py +98 -0
- econometrics/tests/specific_data_modeling_tests/test_dynamic_panel.py +198 -0
- econometrics/tests/specific_data_modeling_tests/test_exponential_smoothing.py +105 -0
- econometrics/tests/specific_data_modeling_tests/test_garch.py +118 -0
- econometrics/tests/specific_data_modeling_tests/test_unit_root.py +156 -0
- econometrics/tests/specific_data_modeling_tests/test_var.py +124 -0
- prompts/__init__.py +0 -0
- prompts/analysis_guides.py +43 -0
- pyproject.toml +78 -0
- resources/MCP_MASTER_GUIDE.md +422 -0
- resources/MCP_TOOLS_DATA_FORMAT_GUIDE.md +185 -0
- resources/__init__.py +0 -0
- server.py +83 -0
- tools/README.md +88 -0
- tools/__init__.py +45 -0
- tools/data_loader.py +213 -0
- tools/decorators.py +38 -0
- tools/econometrics_adapter.py +286 -0
- tools/mcp_tool_groups/__init__.py +1 -0
- tools/mcp_tool_groups/basic_parametric_tools.py +173 -0
- tools/mcp_tool_groups/model_specification_tools.py +402 -0
- tools/mcp_tool_groups/time_series_tools.py +494 -0
- tools/mcp_tools_registry.py +114 -0
- tools/model_specification_adapter.py +369 -0
- tools/output_formatter.py +563 -0
- tools/time_series_panel_data_adapter.py +858 -0
- tools/time_series_panel_data_tools.py +65 -0
- aigroup_econ_mcp/__init__.py +0 -19
- aigroup_econ_mcp/cli.py +0 -82
- aigroup_econ_mcp/config.py +0 -561
- aigroup_econ_mcp/server.py +0 -452
- aigroup_econ_mcp/tools/__init__.py +0 -19
- aigroup_econ_mcp/tools/base.py +0 -470
- aigroup_econ_mcp/tools/cache.py +0 -533
- aigroup_econ_mcp/tools/data_loader.py +0 -195
- aigroup_econ_mcp/tools/file_parser.py +0 -1027
- aigroup_econ_mcp/tools/machine_learning.py +0 -60
- aigroup_econ_mcp/tools/ml_ensemble.py +0 -210
- aigroup_econ_mcp/tools/ml_evaluation.py +0 -272
- aigroup_econ_mcp/tools/ml_models.py +0 -54
- aigroup_econ_mcp/tools/ml_regularization.py +0 -186
- aigroup_econ_mcp/tools/monitoring.py +0 -555
- aigroup_econ_mcp/tools/optimized_example.py +0 -229
- aigroup_econ_mcp/tools/panel_data.py +0 -619
- aigroup_econ_mcp/tools/regression.py +0 -214
- aigroup_econ_mcp/tools/statistics.py +0 -154
- aigroup_econ_mcp/tools/time_series.py +0 -698
- aigroup_econ_mcp/tools/timeout.py +0 -283
- aigroup_econ_mcp/tools/tool_descriptions.py +0 -410
- aigroup_econ_mcp/tools/tool_handlers.py +0 -1016
- aigroup_econ_mcp/tools/tool_registry.py +0 -478
- aigroup_econ_mcp/tools/validation.py +0 -482
- aigroup_econ_mcp-1.3.3.dist-info/METADATA +0 -525
- aigroup_econ_mcp-1.3.3.dist-info/RECORD +0 -30
- aigroup_econ_mcp-1.3.3.dist-info/entry_points.txt +0 -2
- /aigroup_econ_mcp-1.3.3.dist-info/licenses/LICENSE → /LICENSE +0 -0
- {aigroup_econ_mcp-1.3.3.dist-info → aigroup_econ_mcp-1.4.3.dist-info}/WHEEL +0 -0
aigroup_econ_mcp/tools/cache.py
DELETED
|
@@ -1,533 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
缓存机制模块
|
|
3
|
-
提供LRU缓存策略和结果缓存功能
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import time
|
|
7
|
-
import hashlib
|
|
8
|
-
import pickle
|
|
9
|
-
import threading
|
|
10
|
-
from typing import Any, Dict, List, Optional, Callable, Tuple
|
|
11
|
-
from collections import OrderedDict
|
|
12
|
-
from dataclasses import dataclass
|
|
13
|
-
from enum import Enum
|
|
14
|
-
import json
|
|
15
|
-
import warnings
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class CachePolicy(Enum):
|
|
19
|
-
"""缓存策略"""
|
|
20
|
-
LRU = "lru" # 最近最少使用
|
|
21
|
-
FIFO = "fifo" # 先进先出
|
|
22
|
-
LFU = "lfu" # 最不经常使用
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@dataclass
|
|
26
|
-
class CacheEntry:
|
|
27
|
-
"""缓存条目"""
|
|
28
|
-
key: str
|
|
29
|
-
value: Any
|
|
30
|
-
timestamp: float
|
|
31
|
-
access_count: int = 0
|
|
32
|
-
size: int = 0
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
class LRUCache:
|
|
36
|
-
"""
|
|
37
|
-
LRU缓存实现
|
|
38
|
-
使用最近最少使用策略管理缓存
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
def __init__(self, max_size: int = 1000, ttl: Optional[int] = None):
|
|
42
|
-
"""
|
|
43
|
-
初始化LRU缓存
|
|
44
|
-
|
|
45
|
-
Args:
|
|
46
|
-
max_size: 最大缓存条目数
|
|
47
|
-
ttl: 缓存生存时间(秒),None表示永不过期
|
|
48
|
-
"""
|
|
49
|
-
self.max_size = max_size
|
|
50
|
-
self.ttl = ttl
|
|
51
|
-
self._cache: OrderedDict[str, CacheEntry] = OrderedDict()
|
|
52
|
-
self._lock = threading.RLock()
|
|
53
|
-
self._hits = 0
|
|
54
|
-
self._misses = 0
|
|
55
|
-
self._evictions = 0
|
|
56
|
-
|
|
57
|
-
def get(self, key: str) -> Optional[Any]:
|
|
58
|
-
"""
|
|
59
|
-
获取缓存值
|
|
60
|
-
|
|
61
|
-
Args:
|
|
62
|
-
key: 缓存键
|
|
63
|
-
|
|
64
|
-
Returns:
|
|
65
|
-
Optional[Any]: 缓存值,如果不存在或过期则返回None
|
|
66
|
-
"""
|
|
67
|
-
with self._lock:
|
|
68
|
-
if key not in self._cache:
|
|
69
|
-
self._misses += 1
|
|
70
|
-
return None
|
|
71
|
-
|
|
72
|
-
entry = self._cache[key]
|
|
73
|
-
|
|
74
|
-
# 检查是否过期
|
|
75
|
-
if self.ttl and (time.time() - entry.timestamp) > self.ttl:
|
|
76
|
-
del self._cache[key]
|
|
77
|
-
self._misses += 1
|
|
78
|
-
return None
|
|
79
|
-
|
|
80
|
-
# 更新访问时间和计数
|
|
81
|
-
entry.timestamp = time.time()
|
|
82
|
-
entry.access_count += 1
|
|
83
|
-
self._cache.move_to_end(key)
|
|
84
|
-
|
|
85
|
-
self._hits += 1
|
|
86
|
-
return entry.value
|
|
87
|
-
|
|
88
|
-
def set(self, key: str, value: Any, size: int = 0) -> None:
|
|
89
|
-
"""
|
|
90
|
-
设置缓存值
|
|
91
|
-
|
|
92
|
-
Args:
|
|
93
|
-
key: 缓存键
|
|
94
|
-
value: 缓存值
|
|
95
|
-
size: 缓存大小(字节),用于大小限制
|
|
96
|
-
"""
|
|
97
|
-
with self._lock:
|
|
98
|
-
# 如果键已存在,先删除
|
|
99
|
-
if key in self._cache:
|
|
100
|
-
del self._cache[key]
|
|
101
|
-
|
|
102
|
-
# 创建新的缓存条目
|
|
103
|
-
entry = CacheEntry(
|
|
104
|
-
key=key,
|
|
105
|
-
value=value,
|
|
106
|
-
timestamp=time.time(),
|
|
107
|
-
size=size
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
self._cache[key] = entry
|
|
111
|
-
self._cache.move_to_end(key)
|
|
112
|
-
|
|
113
|
-
# 如果超过最大大小,移除最旧的条目
|
|
114
|
-
while len(self._cache) > self.max_size:
|
|
115
|
-
oldest_key, oldest_entry = next(iter(self._cache.items()))
|
|
116
|
-
del self._cache[oldest_key]
|
|
117
|
-
self._evictions += 1
|
|
118
|
-
|
|
119
|
-
def delete(self, key: str) -> bool:
|
|
120
|
-
"""
|
|
121
|
-
删除缓存条目
|
|
122
|
-
|
|
123
|
-
Args:
|
|
124
|
-
key: 缓存键
|
|
125
|
-
|
|
126
|
-
Returns:
|
|
127
|
-
bool: 是否成功删除
|
|
128
|
-
"""
|
|
129
|
-
with self._lock:
|
|
130
|
-
if key in self._cache:
|
|
131
|
-
del self._cache[key]
|
|
132
|
-
return True
|
|
133
|
-
return False
|
|
134
|
-
|
|
135
|
-
def clear(self) -> None:
|
|
136
|
-
"""清空缓存"""
|
|
137
|
-
with self._lock:
|
|
138
|
-
self._cache.clear()
|
|
139
|
-
self._hits = 0
|
|
140
|
-
self._misses = 0
|
|
141
|
-
self._evictions = 0
|
|
142
|
-
|
|
143
|
-
def contains(self, key: str) -> bool:
|
|
144
|
-
"""
|
|
145
|
-
检查缓存是否包含指定键
|
|
146
|
-
|
|
147
|
-
Args:
|
|
148
|
-
key: 缓存键
|
|
149
|
-
|
|
150
|
-
Returns:
|
|
151
|
-
bool: 是否包含
|
|
152
|
-
"""
|
|
153
|
-
with self._lock:
|
|
154
|
-
if key not in self._cache:
|
|
155
|
-
return False
|
|
156
|
-
|
|
157
|
-
# 检查是否过期
|
|
158
|
-
entry = self._cache[key]
|
|
159
|
-
if self.ttl and (time.time() - entry.timestamp) > self.ttl:
|
|
160
|
-
del self._cache[key]
|
|
161
|
-
return False
|
|
162
|
-
|
|
163
|
-
return True
|
|
164
|
-
|
|
165
|
-
def get_stats(self) -> Dict[str, Any]:
|
|
166
|
-
"""
|
|
167
|
-
获取缓存统计信息
|
|
168
|
-
|
|
169
|
-
Returns:
|
|
170
|
-
Dict[str, Any]: 统计信息
|
|
171
|
-
"""
|
|
172
|
-
with self._lock:
|
|
173
|
-
total_requests = self._hits + self._misses
|
|
174
|
-
hit_rate = self._hits / total_requests if total_requests > 0 else 0
|
|
175
|
-
|
|
176
|
-
return {
|
|
177
|
-
"size": len(self._cache),
|
|
178
|
-
"max_size": self.max_size,
|
|
179
|
-
"hits": self._hits,
|
|
180
|
-
"misses": self._misses,
|
|
181
|
-
"evictions": self._evictions,
|
|
182
|
-
"hit_rate": hit_rate,
|
|
183
|
-
"memory_usage": sum(entry.size for entry in self._cache.values())
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
def keys(self) -> List[str]:
|
|
187
|
-
"""
|
|
188
|
-
获取所有缓存键
|
|
189
|
-
|
|
190
|
-
Returns:
|
|
191
|
-
List[str]: 缓存键列表
|
|
192
|
-
"""
|
|
193
|
-
with self._lock:
|
|
194
|
-
return list(self._cache.keys())
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
class ResultCache:
|
|
198
|
-
"""
|
|
199
|
-
结果缓存管理器
|
|
200
|
-
提供函数结果缓存和智能缓存管理
|
|
201
|
-
"""
|
|
202
|
-
|
|
203
|
-
def __init__(self, max_size: int = 1000, ttl: int = 3600):
|
|
204
|
-
"""
|
|
205
|
-
初始化结果缓存
|
|
206
|
-
|
|
207
|
-
Args:
|
|
208
|
-
max_size: 最大缓存条目数
|
|
209
|
-
ttl: 缓存生存时间(秒)
|
|
210
|
-
"""
|
|
211
|
-
self.cache = LRUCache(max_size=max_size, ttl=ttl)
|
|
212
|
-
self._function_cache: Dict[str, LRUCache] = {}
|
|
213
|
-
|
|
214
|
-
def generate_key(self, func_name: str, *args, **kwargs) -> str:
|
|
215
|
-
"""
|
|
216
|
-
生成缓存键
|
|
217
|
-
|
|
218
|
-
Args:
|
|
219
|
-
func_name: 函数名称
|
|
220
|
-
*args: 位置参数
|
|
221
|
-
**kwargs: 关键字参数
|
|
222
|
-
|
|
223
|
-
Returns:
|
|
224
|
-
str: 缓存键
|
|
225
|
-
"""
|
|
226
|
-
# 序列化参数
|
|
227
|
-
try:
|
|
228
|
-
# 使用JSON序列化,处理基本数据类型
|
|
229
|
-
args_str = json.dumps(args, sort_keys=True, default=str)
|
|
230
|
-
kwargs_str = json.dumps(kwargs, sort_keys=True, default=str)
|
|
231
|
-
key_data = f"{func_name}:{args_str}:{kwargs_str}"
|
|
232
|
-
except (TypeError, ValueError):
|
|
233
|
-
# 如果JSON序列化失败,使用pickle
|
|
234
|
-
key_data = f"{func_name}:{pickle.dumps((args, kwargs))}"
|
|
235
|
-
|
|
236
|
-
# 生成哈希键
|
|
237
|
-
return hashlib.md5(key_data.encode()).hexdigest()
|
|
238
|
-
|
|
239
|
-
def cached(self, func: Callable = None, *, ttl: Optional[int] = None, max_size: int = 100):
|
|
240
|
-
"""
|
|
241
|
-
缓存装饰器
|
|
242
|
-
|
|
243
|
-
Args:
|
|
244
|
-
func: 被装饰的函数
|
|
245
|
-
ttl: 缓存生存时间(秒)
|
|
246
|
-
max_size: 函数特定的最大缓存大小
|
|
247
|
-
|
|
248
|
-
Returns:
|
|
249
|
-
Callable: 装饰后的函数
|
|
250
|
-
"""
|
|
251
|
-
def decorator(f):
|
|
252
|
-
func_name = f.__name__
|
|
253
|
-
|
|
254
|
-
# 为每个函数创建独立的缓存
|
|
255
|
-
if func_name not in self._function_cache:
|
|
256
|
-
self._function_cache[func_name] = LRUCache(
|
|
257
|
-
max_size=max_size,
|
|
258
|
-
ttl=ttl or self.cache.ttl
|
|
259
|
-
)
|
|
260
|
-
|
|
261
|
-
func_cache = self._function_cache[func_name]
|
|
262
|
-
|
|
263
|
-
def wrapper(*args, **kwargs):
|
|
264
|
-
# 生成缓存键
|
|
265
|
-
cache_key = self.generate_key(func_name, *args, **kwargs)
|
|
266
|
-
|
|
267
|
-
# 尝试从缓存获取结果
|
|
268
|
-
cached_result = func_cache.get(cache_key)
|
|
269
|
-
if cached_result is not None:
|
|
270
|
-
return cached_result
|
|
271
|
-
|
|
272
|
-
# 执行函数并缓存结果
|
|
273
|
-
result = f(*args, **kwargs)
|
|
274
|
-
func_cache.set(cache_key, result)
|
|
275
|
-
|
|
276
|
-
return result
|
|
277
|
-
|
|
278
|
-
# 保留原始函数的元数据
|
|
279
|
-
wrapper.__name__ = f.__name__
|
|
280
|
-
wrapper.__doc__ = f.__doc__
|
|
281
|
-
wrapper.__module__ = f.__module__
|
|
282
|
-
|
|
283
|
-
return wrapper
|
|
284
|
-
|
|
285
|
-
if func is None:
|
|
286
|
-
return decorator
|
|
287
|
-
else:
|
|
288
|
-
return decorator(func)
|
|
289
|
-
|
|
290
|
-
def get_function_cache_stats(self, func_name: str) -> Optional[Dict[str, Any]]:
|
|
291
|
-
"""
|
|
292
|
-
获取函数缓存统计信息
|
|
293
|
-
|
|
294
|
-
Args:
|
|
295
|
-
func_name: 函数名称
|
|
296
|
-
|
|
297
|
-
Returns:
|
|
298
|
-
Optional[Dict[str, Any]]: 统计信息,如果函数没有缓存则返回None
|
|
299
|
-
"""
|
|
300
|
-
if func_name in self._function_cache:
|
|
301
|
-
return self._function_cache[func_name].get_stats()
|
|
302
|
-
return None
|
|
303
|
-
|
|
304
|
-
def clear_function_cache(self, func_name: str) -> bool:
|
|
305
|
-
"""
|
|
306
|
-
清空指定函数的缓存
|
|
307
|
-
|
|
308
|
-
Args:
|
|
309
|
-
func_name: 函数名称
|
|
310
|
-
|
|
311
|
-
Returns:
|
|
312
|
-
bool: 是否成功清空
|
|
313
|
-
"""
|
|
314
|
-
if func_name in self._function_cache:
|
|
315
|
-
self._function_cache[func_name].clear()
|
|
316
|
-
return True
|
|
317
|
-
return False
|
|
318
|
-
|
|
319
|
-
def clear_all(self) -> None:
|
|
320
|
-
"""清空所有缓存"""
|
|
321
|
-
for cache in self._function_cache.values():
|
|
322
|
-
cache.clear()
|
|
323
|
-
|
|
324
|
-
def get_global_stats(self) -> Dict[str, Any]:
|
|
325
|
-
"""
|
|
326
|
-
获取全局缓存统计信息
|
|
327
|
-
|
|
328
|
-
Returns:
|
|
329
|
-
Dict[str, Any]: 全局统计信息
|
|
330
|
-
"""
|
|
331
|
-
total_hits = 0
|
|
332
|
-
total_misses = 0
|
|
333
|
-
total_size = 0
|
|
334
|
-
function_stats = {}
|
|
335
|
-
|
|
336
|
-
for func_name, cache in self._function_cache.items():
|
|
337
|
-
stats = cache.get_stats()
|
|
338
|
-
total_hits += stats["hits"]
|
|
339
|
-
total_misses += stats["misses"]
|
|
340
|
-
total_size += stats["memory_usage"]
|
|
341
|
-
function_stats[func_name] = stats
|
|
342
|
-
|
|
343
|
-
total_requests = total_hits + total_misses
|
|
344
|
-
global_hit_rate = total_hits / total_requests if total_requests > 0 else 0
|
|
345
|
-
|
|
346
|
-
return {
|
|
347
|
-
"total_functions": len(self._function_cache),
|
|
348
|
-
"total_hits": total_hits,
|
|
349
|
-
"total_misses": total_misses,
|
|
350
|
-
"global_hit_rate": global_hit_rate,
|
|
351
|
-
"total_memory_usage": total_size,
|
|
352
|
-
"function_stats": function_stats
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
class EconometricCache:
|
|
357
|
-
"""
|
|
358
|
-
计量经济学专用缓存
|
|
359
|
-
针对计量经济学计算结果的优化缓存
|
|
360
|
-
"""
|
|
361
|
-
|
|
362
|
-
def __init__(self):
|
|
363
|
-
self.result_cache = ResultCache(max_size=500, ttl=7200) # 2小时TTL
|
|
364
|
-
self._model_cache: Dict[str, Any] = {}
|
|
365
|
-
self._data_cache: Dict[str, Any] = {}
|
|
366
|
-
|
|
367
|
-
def cache_model_result(self, model_type: str, data_hash: str, parameters: Dict, result: Any) -> str:
|
|
368
|
-
"""
|
|
369
|
-
缓存模型结果
|
|
370
|
-
|
|
371
|
-
Args:
|
|
372
|
-
model_type: 模型类型
|
|
373
|
-
data_hash: 数据哈希
|
|
374
|
-
parameters: 模型参数
|
|
375
|
-
result: 模型结果
|
|
376
|
-
|
|
377
|
-
Returns:
|
|
378
|
-
str: 缓存键
|
|
379
|
-
"""
|
|
380
|
-
cache_key = f"{model_type}:{data_hash}:{hash(str(parameters))}"
|
|
381
|
-
self._model_cache[cache_key] = {
|
|
382
|
-
"result": result,
|
|
383
|
-
"timestamp": time.time(),
|
|
384
|
-
"model_type": model_type,
|
|
385
|
-
"parameters": parameters
|
|
386
|
-
}
|
|
387
|
-
return cache_key
|
|
388
|
-
|
|
389
|
-
def get_cached_model_result(self, model_type: str, data_hash: str, parameters: Dict) -> Optional[Any]:
|
|
390
|
-
"""
|
|
391
|
-
获取缓存的模型结果
|
|
392
|
-
|
|
393
|
-
Args:
|
|
394
|
-
model_type: 模型类型
|
|
395
|
-
data_hash: 数据哈希
|
|
396
|
-
parameters: 模型参数
|
|
397
|
-
|
|
398
|
-
Returns:
|
|
399
|
-
Optional[Any]: 缓存的结果,如果不存在则返回None
|
|
400
|
-
"""
|
|
401
|
-
cache_key = f"{model_type}:{data_hash}:{hash(str(parameters))}"
|
|
402
|
-
return self._model_cache.get(cache_key, {}).get("result")
|
|
403
|
-
|
|
404
|
-
def cache_data_analysis(self, data_hash: str, analysis_type: str, result: Any) -> str:
|
|
405
|
-
"""
|
|
406
|
-
缓存数据分析结果
|
|
407
|
-
|
|
408
|
-
Args:
|
|
409
|
-
data_hash: 数据哈希
|
|
410
|
-
analysis_type: 分析类型
|
|
411
|
-
result: 分析结果
|
|
412
|
-
|
|
413
|
-
Returns:
|
|
414
|
-
str: 缓存键
|
|
415
|
-
"""
|
|
416
|
-
cache_key = f"analysis:{analysis_type}:{data_hash}"
|
|
417
|
-
self._data_cache[cache_key] = {
|
|
418
|
-
"result": result,
|
|
419
|
-
"timestamp": time.time(),
|
|
420
|
-
"analysis_type": analysis_type
|
|
421
|
-
}
|
|
422
|
-
return cache_key
|
|
423
|
-
|
|
424
|
-
def get_cached_data_analysis(self, data_hash: str, analysis_type: str) -> Optional[Any]:
|
|
425
|
-
"""
|
|
426
|
-
获取缓存的数据分析结果
|
|
427
|
-
|
|
428
|
-
Args:
|
|
429
|
-
data_hash: 数据哈希
|
|
430
|
-
analysis_type: 分析类型
|
|
431
|
-
|
|
432
|
-
Returns:
|
|
433
|
-
Optional[Any]: 缓存的结果,如果不存在则返回None
|
|
434
|
-
"""
|
|
435
|
-
cache_key = f"analysis:{analysis_type}:{data_hash}"
|
|
436
|
-
return self._data_cache.get(cache_key, {}).get("result")
|
|
437
|
-
|
|
438
|
-
def clear_old_entries(self, max_age: int = 86400) -> int:
|
|
439
|
-
"""
|
|
440
|
-
清理过期的缓存条目
|
|
441
|
-
|
|
442
|
-
Args:
|
|
443
|
-
max_age: 最大年龄(秒)
|
|
444
|
-
|
|
445
|
-
Returns:
|
|
446
|
-
int: 清理的条目数量
|
|
447
|
-
"""
|
|
448
|
-
current_time = time.time()
|
|
449
|
-
removed_count = 0
|
|
450
|
-
|
|
451
|
-
# 清理模型缓存
|
|
452
|
-
keys_to_remove = []
|
|
453
|
-
for key, entry in self._model_cache.items():
|
|
454
|
-
if current_time - entry["timestamp"] > max_age:
|
|
455
|
-
keys_to_remove.append(key)
|
|
456
|
-
|
|
457
|
-
for key in keys_to_remove:
|
|
458
|
-
del self._model_cache[key]
|
|
459
|
-
removed_count += 1
|
|
460
|
-
|
|
461
|
-
# 清理数据缓存
|
|
462
|
-
keys_to_remove = []
|
|
463
|
-
for key, entry in self._data_cache.items():
|
|
464
|
-
if current_time - entry["timestamp"] > max_age:
|
|
465
|
-
keys_to_remove.append(key)
|
|
466
|
-
|
|
467
|
-
for key in keys_to_remove:
|
|
468
|
-
del self._data_cache[key]
|
|
469
|
-
removed_count += 1
|
|
470
|
-
|
|
471
|
-
return removed_count
|
|
472
|
-
|
|
473
|
-
def get_cache_info(self) -> Dict[str, Any]:
|
|
474
|
-
"""
|
|
475
|
-
获取缓存信息
|
|
476
|
-
|
|
477
|
-
Returns:
|
|
478
|
-
Dict[str, Any]: 缓存信息
|
|
479
|
-
"""
|
|
480
|
-
return {
|
|
481
|
-
"model_cache_size": len(self._model_cache),
|
|
482
|
-
"data_cache_size": len(self._data_cache),
|
|
483
|
-
"result_cache_stats": self.result_cache.get_global_stats()
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
# 全局缓存实例
|
|
488
|
-
global_econometric_cache = EconometricCache()
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
# 便捷缓存装饰器
|
|
492
|
-
def cache_result(ttl: int = 3600, max_size: int = 100):
|
|
493
|
-
"""
|
|
494
|
-
便捷的结果缓存装饰器
|
|
495
|
-
|
|
496
|
-
Args:
|
|
497
|
-
ttl: 缓存生存时间(秒)
|
|
498
|
-
max_size: 最大缓存大小
|
|
499
|
-
|
|
500
|
-
Returns:
|
|
501
|
-
Callable: 装饰器函数
|
|
502
|
-
"""
|
|
503
|
-
return global_econometric_cache.result_cache.cached(ttl=ttl, max_size=max_size)
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
def cache_model(ttl: int = 7200):
|
|
507
|
-
"""
|
|
508
|
-
模型结果缓存装饰器
|
|
509
|
-
|
|
510
|
-
Args:
|
|
511
|
-
ttl: 缓存生存时间(秒)
|
|
512
|
-
|
|
513
|
-
Returns:
|
|
514
|
-
Callable: 装饰器函数
|
|
515
|
-
"""
|
|
516
|
-
def decorator(func):
|
|
517
|
-
@cache_result(ttl=ttl, max_size=50)
|
|
518
|
-
def wrapper(*args, **kwargs):
|
|
519
|
-
return func(*args, **kwargs)
|
|
520
|
-
return wrapper
|
|
521
|
-
return decorator
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
# 导出主要类和函数
|
|
525
|
-
__all__ = [
|
|
526
|
-
"CachePolicy",
|
|
527
|
-
"LRUCache",
|
|
528
|
-
"ResultCache",
|
|
529
|
-
"EconometricCache",
|
|
530
|
-
"global_econometric_cache",
|
|
531
|
-
"cache_result",
|
|
532
|
-
"cache_model"
|
|
533
|
-
]
|