Coverage for src\time_series_analyzer\api.py: 94%

64 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-23 11:57 +0800

1""" 

2Python库API接口 

3 

4提供简洁易用的Python API,方便其他项目集成使用。 

5""" 

6 

7from typing import Dict, Any, Optional, Union, List, Tuple 

8from pathlib import Path 

9 

10from .models import ARIMAModel, SeasonalARIMAModel 

11from .transfer_function import TransferFunction, TransferFunctionDeriver 

12from .parsers import ModelParser 

13from .formatters import OutputFormatter 

14 

15 

16class TimeSeriesAnalyzer: 

17 """ 

18 时间序列模型分析器主类 

19  

20 提供统一的API接口用于ARIMA/SARIMA模型的传递函数分析。 

21 """ 

22 

23 def __init__(self, precision: int = 4): 

24 """ 

25 初始化分析器 

26  

27 Args: 

28 precision: 数值精度 

29 """ 

30 self.precision = precision 

31 self.deriver = TransferFunctionDeriver() 

32 self.formatter = OutputFormatter(precision=precision) 

33 

34 def create_arima_model(self, p: int, d: int, q: int, 

35 ar_params: Optional[List[float]] = None, 

36 ma_params: Optional[List[float]] = None, 

37 constant: float = 0.0, 

38 name: Optional[str] = None) -> ARIMAModel: 

39 """ 

40 创建ARIMA模型 

41  

42 Args: 

43 p: 自回归阶数 

44 d: 差分阶数 

45 q: 移动平均阶数 

46 ar_params: 自回归参数 

47 ma_params: 移动平均参数 

48 constant: 常数项 

49 name: 模型名称 

50  

51 Returns: 

52 ARIMA模型对象 

53 """ 

54 return ARIMAModel( 

55 p=p, d=d, q=q, 

56 ar_params=ar_params, 

57 ma_params=ma_params, 

58 constant=constant, 

59 name=name 

60 ) 

61 

62 def create_sarima_model(self, p: int, d: int, q: int, 

63 P: int, D: int, Q: int, m: int, 

64 ar_params: Optional[List[float]] = None, 

65 ma_params: Optional[List[float]] = None, 

66 seasonal_ar_params: Optional[List[float]] = None, 

67 seasonal_ma_params: Optional[List[float]] = None, 

68 constant: float = 0.0, 

69 name: Optional[str] = None) -> SeasonalARIMAModel: 

70 """ 

71 创建SARIMA模型 

72  

73 Args: 

74 p, d, q: 非季节性参数 

75 P, D, Q, m: 季节性参数 

76 ar_params: 自回归参数 

77 ma_params: 移动平均参数 

78 seasonal_ar_params: 季节性自回归参数 

79 seasonal_ma_params: 季节性移动平均参数 

80 constant: 常数项 

81 name: 模型名称 

82  

83 Returns: 

84 SARIMA模型对象 

85 """ 

86 return SeasonalARIMAModel( 

87 p=p, d=d, q=q, 

88 P=P, D=D, Q=Q, m=m, 

89 ar_params=ar_params, 

90 ma_params=ma_params, 

91 seasonal_ar_params=seasonal_ar_params, 

92 seasonal_ma_params=seasonal_ma_params, 

93 constant=constant, 

94 name=name 

95 ) 

96 

97 def parse_model_string(self, model_str: str) -> Union[ARIMAModel, SeasonalARIMAModel]: 

98 """ 

99 从字符串解析模型 

100  

101 Args: 

102 model_str: 模型字符串,如 "ARIMA(2,1,1)" 或 "SARIMA(2,1,1)(1,1,1,12)" 

103  

104 Returns: 

105 模型对象 

106 """ 

107 return ModelParser.parse_from_string(model_str) 

108 

109 def load_model_from_file(self, file_path: Union[str, Path]) -> Union[ARIMAModel, SeasonalARIMAModel]: 

110 """ 

111 从文件加载模型 

112  

113 Args: 

114 file_path: 配置文件路径 (JSON/YAML) 

115  

116 Returns: 

117 模型对象 

118 """ 

119 return ModelParser.parse_from_file(file_path) 

120 

121 def derive_transfer_function(self, model: Union[ARIMAModel, SeasonalARIMAModel]) -> TransferFunction: 

122 """ 

123 推导传递函数 

124  

125 Args: 

126 model: 时间序列模型 

127  

128 Returns: 

129 传递函数对象 

130 """ 

131 return self.deriver.derive_transfer_function(model) 

132 

133 def analyze_stability(self, model: Union[ARIMAModel, SeasonalARIMAModel]) -> Dict[str, Any]: 

134 """ 

135 分析模型稳定性 

136  

137 Args: 

138 model: 时间序列模型 

139  

140 Returns: 

141 稳定性分析结果 

142 """ 

143 return self.deriver.analyze_stability(model) 

144 

145 def compute_impulse_response(self, model: Union[ARIMAModel, SeasonalARIMAModel], 

146 max_lag: int = 20) -> Dict[int, Any]: 

147 """ 

148 计算脉冲响应函数 

149  

150 Args: 

151 model: 时间序列模型 

152 max_lag: 最大滞后阶数 

153  

154 Returns: 

155 脉冲响应系数字典 

156 """ 

157 return self.deriver.derive_impulse_response(model, max_lag) 

158 

159 def compute_frequency_response(self, model: Union[ARIMAModel, SeasonalARIMAModel], 

160 frequencies: List[float]) -> Dict[str, List]: 

161 """ 

162 计算频率响应 

163  

164 Args: 

165 model: 时间序列模型 

166 frequencies: 频率列表 

167  

168 Returns: 

169 频率响应数据 

170 """ 

171 return self.deriver.get_frequency_response(model, frequencies) 

172 

173 def generate_report(self, model: Union[ARIMAModel, SeasonalARIMAModel], 

174 format: str = 'text', 

175 include_analysis: bool = True, 

176 output_file: Optional[Union[str, Path]] = None) -> str: 

177 """ 

178 生成分析报告 

179  

180 Args: 

181 model: 时间序列模型 

182 format: 输出格式 ('text', 'latex', 'json') 

183 include_analysis: 是否包含稳定性分析 

184 output_file: 输出文件路径 

185  

186 Returns: 

187 报告内容 

188 """ 

189 if format.lower() == 'latex': 

190 content = self.formatter.format_latex( 

191 model, 

192 include_transfer_function=True, 

193 include_analysis=include_analysis 

194 ) 

195 elif format.lower() == 'json': 

196 content = self.formatter.format_json( 

197 model, 

198 include_transfer_function=True, 

199 include_analysis=include_analysis 

200 ) 

201 else: # text 

202 content = self.formatter.format_plain_text( 

203 model, 

204 include_transfer_function=True, 

205 include_analysis=include_analysis 

206 ) 

207 

208 if output_file: 

209 with open(output_file, 'w', encoding='utf-8') as f: 

210 f.write(content) 

211 

212 return content 

213 

214 def quick_analyze(self, model_str: str, 

215 include_stability: bool = True, 

216 include_impulse: bool = False, 

217 include_frequency: bool = False, 

218 max_lag: int = 20, 

219 frequencies: Optional[List[float]] = None) -> Dict[str, Any]: 

220 """ 

221 快速分析接口 

222  

223 Args: 

224 model_str: 模型字符串 

225 include_stability: 是否包含稳定性分析 

226 include_impulse: 是否包含脉冲响应 

227 include_frequency: 是否包含频率响应 

228 max_lag: 脉冲响应最大滞后 

229 frequencies: 频率列表 

230  

231 Returns: 

232 完整分析结果 

233 """ 

234 # 解析模型 

235 model = self.parse_model_string(model_str) 

236 

237 # 推导传递函数 

238 transfer_func = self.derive_transfer_function(model) 

239 

240 result = { 

241 "model": model.to_dict(), 

242 "transfer_function": { 

243 "numerator": str(transfer_func.numerator.as_expr()), 

244 "denominator": str(transfer_func.denominator.as_expr()), 

245 "poles": [{"real": pole.real, "imag": pole.imag} for pole in transfer_func.get_poles()], 

246 "zeros": [{"real": zero.real, "imag": zero.imag} for zero in transfer_func.get_zeros()] 

247 } 

248 } 

249 

250 # 稳定性分析 

251 if include_stability: 

252 stability = self.analyze_stability(model) 

253 result["stability"] = { 

254 "is_stable": stability["is_stable"], 

255 "max_pole_magnitude": stability["max_pole_magnitude"], 

256 "stability_margin": stability["stability_margin"] 

257 } 

258 

259 # 脉冲响应 

260 if include_impulse: 

261 impulse_response = self.compute_impulse_response(model, max_lag) 

262 result["impulse_response"] = {str(k): str(v) for k, v in impulse_response.items()} 

263 

264 # 频率响应 

265 if include_frequency: 

266 if frequencies is None: 

267 frequencies = [i * 0.1 for i in range(6)] # 0, 0.1, 0.2, 0.3, 0.4, 0.5 

268 

269 freq_response = self.compute_frequency_response(model, frequencies) 

270 result["frequency_response"] = { 

271 "frequencies": freq_response["frequencies"], 

272 "magnitudes": [float(m) for m in freq_response["magnitudes"]], 

273 "phases": [float(p) for p in freq_response["phases"]] 

274 } 

275 

276 return result 

277 

278 

279# 便捷函数 

280def analyze_arima(p: int, d: int, q: int, 

281 ar_params: Optional[List[float]] = None, 

282 ma_params: Optional[List[float]] = None, 

283 **kwargs) -> Dict[str, Any]: 

284 """ 

285 快速分析ARIMA模型的便捷函数 

286  

287 Args: 

288 p, d, q: ARIMA参数 

289 ar_params: 自回归参数 

290 ma_params: 移动平均参数 

291 **kwargs: 其他分析选项 

292  

293 Returns: 

294 分析结果 

295 """ 

296 analyzer = TimeSeriesAnalyzer() 

297 model = analyzer.create_arima_model(p, d, q, ar_params, ma_params) 

298 

299 return analyzer.quick_analyze( 

300 str(model).split(':')[0], # 提取模型字符串 

301 **kwargs 

302 ) 

303 

304 

305def analyze_sarima(p: int, d: int, q: int, P: int, D: int, Q: int, m: int, 

306 ar_params: Optional[List[float]] = None, 

307 ma_params: Optional[List[float]] = None, 

308 seasonal_ar_params: Optional[List[float]] = None, 

309 seasonal_ma_params: Optional[List[float]] = None, 

310 **kwargs) -> Dict[str, Any]: 

311 """ 

312 快速分析SARIMA模型的便捷函数 

313  

314 Args: 

315 p, d, q, P, D, Q, m: SARIMA参数 

316 ar_params: 自回归参数 

317 ma_params: 移动平均参数 

318 seasonal_ar_params: 季节性自回归参数 

319 seasonal_ma_params: 季节性移动平均参数 

320 **kwargs: 其他分析选项 

321  

322 Returns: 

323 分析结果 

324 """ 

325 analyzer = TimeSeriesAnalyzer() 

326 model = analyzer.create_sarima_model( 

327 p, d, q, P, D, Q, m, 

328 ar_params, ma_params, 

329 seasonal_ar_params, seasonal_ma_params 

330 ) 

331 

332 return analyzer.quick_analyze( 

333 str(model).split(':')[0], # 提取模型字符串 

334 **kwargs 

335 ) 

336 

337 

338def parse_and_analyze(model_str: str, **kwargs) -> Dict[str, Any]: 

339 """ 

340 解析模型字符串并分析的便捷函数 

341  

342 Args: 

343 model_str: 模型字符串 

344 **kwargs: 分析选项 

345  

346 Returns: 

347 分析结果 

348 """ 

349 analyzer = TimeSeriesAnalyzer() 

350 return analyzer.quick_analyze(model_str, **kwargs)