@nahisaho/satori 0.1.0

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 (38) hide show
  1. package/LICENCE +0 -0
  2. package/README.md +191 -0
  3. package/bin/satori.js +95 -0
  4. package/package.json +29 -0
  5. package/src/.github/skills/scientific-academic-writing/SKILL.md +361 -0
  6. package/src/.github/skills/scientific-academic-writing/assets/acs_article.md +199 -0
  7. package/src/.github/skills/scientific-academic-writing/assets/elsevier_article.md +244 -0
  8. package/src/.github/skills/scientific-academic-writing/assets/ieee_transactions.md +212 -0
  9. package/src/.github/skills/scientific-academic-writing/assets/imrad_standard.md +181 -0
  10. package/src/.github/skills/scientific-academic-writing/assets/nature_article.md +179 -0
  11. package/src/.github/skills/scientific-academic-writing/assets/qiita_technical_article.md +385 -0
  12. package/src/.github/skills/scientific-academic-writing/assets/science_research_article.md +169 -0
  13. package/src/.github/skills/scientific-bioinformatics/SKILL.md +220 -0
  14. package/src/.github/skills/scientific-biosignal-processing/SKILL.md +357 -0
  15. package/src/.github/skills/scientific-causal-inference/SKILL.md +347 -0
  16. package/src/.github/skills/scientific-cheminformatics/SKILL.md +196 -0
  17. package/src/.github/skills/scientific-data-preprocessing/SKILL.md +413 -0
  18. package/src/.github/skills/scientific-data-simulation/SKILL.md +244 -0
  19. package/src/.github/skills/scientific-doe/SKILL.md +360 -0
  20. package/src/.github/skills/scientific-eda-correlation/SKILL.md +141 -0
  21. package/src/.github/skills/scientific-feature-importance/SKILL.md +208 -0
  22. package/src/.github/skills/scientific-image-analysis/SKILL.md +310 -0
  23. package/src/.github/skills/scientific-materials-characterization/SKILL.md +368 -0
  24. package/src/.github/skills/scientific-meta-analysis/SKILL.md +352 -0
  25. package/src/.github/skills/scientific-metabolomics/SKILL.md +326 -0
  26. package/src/.github/skills/scientific-ml-classification/SKILL.md +265 -0
  27. package/src/.github/skills/scientific-ml-regression/SKILL.md +215 -0
  28. package/src/.github/skills/scientific-multi-omics/SKILL.md +303 -0
  29. package/src/.github/skills/scientific-network-analysis/SKILL.md +257 -0
  30. package/src/.github/skills/scientific-pca-tsne/SKILL.md +235 -0
  31. package/src/.github/skills/scientific-pipeline-scaffold/SKILL.md +331 -0
  32. package/src/.github/skills/scientific-process-optimization/SKILL.md +215 -0
  33. package/src/.github/skills/scientific-publication-figures/SKILL.md +208 -0
  34. package/src/.github/skills/scientific-sequence-analysis/SKILL.md +389 -0
  35. package/src/.github/skills/scientific-spectral-signal/SKILL.md +227 -0
  36. package/src/.github/skills/scientific-statistical-testing/SKILL.md +240 -0
  37. package/src/.github/skills/scientific-survival-clinical/SKILL.md +239 -0
  38. package/src/.github/skills/scientific-time-series/SKILL.md +291 -0
@@ -0,0 +1,291 @@
1
+ ---
2
+ name: scientific-time-series
3
+ description: |
4
+ 時系列解析・予測スキル。ARIMA/SARIMA/Prophet モデリング、変化点検出(PELT/Bayesian)、
5
+ 周期解析(FFT/ウェーブレット)、季節分解(STL)、異常検出、Granger 因果性検定の
6
+ テンプレートを提供。実験データのトレンド解析・予測モデリングに適用。
7
+ ---
8
+
9
+ # Scientific Time Series Analysis
10
+
11
+ 時系列データの分解・モデリング・予測・異常検出パイプライン。
12
+ プロセスモニタリング、環境測定、臨床バイタルサイン、実験時系列データなどに適用する。
13
+
14
+ ## When to Use
15
+
16
+ - 時系列トレンドの分解・可視化が必要なとき
17
+ - ARIMA / Prophet による将来予測モデルを構築するとき
18
+ - 変化点や異常値をデータから検出するとき
19
+ - 周期性(季節性)を解析するとき
20
+ - Granger 因果性など時系列間の関係を調べるとき
21
+
22
+ ---
23
+
24
+ ## Quick Start
25
+
26
+ ## 1. STL 季節分解
27
+
28
+ ```python
29
+ import numpy as np
30
+ import pandas as pd
31
+ import matplotlib.pyplot as plt
32
+ from statsmodels.tsa.seasonal import STL
33
+
34
+ def stl_decomposition(series, period, robust=True, figsize=(12, 10)):
35
+ """
36
+ STL (Seasonal and Trend decomposition using Loess) による分解。
37
+
38
+ Components:
39
+ - Trend: 長期トレンド
40
+ - Seasonal: 周期成分
41
+ - Residual: 残差
42
+
43
+ Parameters:
44
+ series: pd.Series with DatetimeIndex
45
+ period: 季節周期(データポイント数)
46
+ """
47
+ stl = STL(series, period=period, robust=robust)
48
+ result = stl.fit()
49
+
50
+ fig, axes = plt.subplots(4, 1, figsize=figsize, sharex=True)
51
+ components = [("Observed", series), ("Trend", result.trend),
52
+ ("Seasonal", result.seasonal), ("Residual", result.resid)]
53
+
54
+ for ax, (name, data) in zip(axes, components):
55
+ ax.plot(data, linewidth=1)
56
+ ax.set_ylabel(name)
57
+ ax.grid(alpha=0.3)
58
+
59
+ plt.suptitle("STL Decomposition", fontweight="bold", y=1.01)
60
+ plt.tight_layout()
61
+ plt.savefig("figures/stl_decomposition.png", dpi=300, bbox_inches="tight")
62
+ plt.close()
63
+
64
+ return result
65
+ ```
66
+
67
+ ## 2. ARIMA / SARIMA モデリング
68
+
69
+ ```python
70
+ from statsmodels.tsa.statespace.sarimax import SARIMAX
71
+ from statsmodels.tsa.stattools import adfuller
72
+
73
+ def adf_stationarity_test(series, significance=0.05):
74
+ """ADF 検定による定常性チェック。"""
75
+ result = adfuller(series.dropna())
76
+ return {
77
+ "adf_statistic": result[0],
78
+ "p_value": result[1],
79
+ "used_lag": result[2],
80
+ "n_obs": result[3],
81
+ "is_stationary": result[1] < significance,
82
+ "critical_values": result[4],
83
+ }
84
+
85
+
86
+ def fit_sarima(series, order=(1, 1, 1), seasonal_order=(1, 1, 1, 12),
87
+ forecast_steps=24):
88
+ """
89
+ SARIMA モデルのフィッティングと予測。
90
+
91
+ Parameters:
92
+ order: (p, d, q) — AR次数, 差分次数, MA次数
93
+ seasonal_order: (P, D, Q, s) — 季節 AR/差分/MA 次数 + 周期
94
+ forecast_steps: 予測期間数
95
+ """
96
+ model = SARIMAX(series, order=order, seasonal_order=seasonal_order,
97
+ enforce_stationarity=False, enforce_invertibility=False)
98
+ fitted = model.fit(disp=False)
99
+
100
+ # 予測
101
+ forecast = fitted.get_forecast(steps=forecast_steps)
102
+ pred_mean = forecast.predicted_mean
103
+ conf_int = forecast.conf_int()
104
+
105
+ # 診断
106
+ diagnostics = {
107
+ "aic": fitted.aic,
108
+ "bic": fitted.bic,
109
+ "ljung_box_p": fitted.test_serial_correlation("ljungbox")[0][0, 1],
110
+ }
111
+
112
+ return fitted, pred_mean, conf_int, diagnostics
113
+
114
+
115
+ def plot_forecast(series, pred_mean, conf_int, title="SARIMA Forecast",
116
+ figsize=(12, 5)):
117
+ """時系列の実測値と予測を描画する。"""
118
+ fig, ax = plt.subplots(figsize=figsize)
119
+ ax.plot(series.index, series.values, "b-", label="Observed", linewidth=1)
120
+ ax.plot(pred_mean.index, pred_mean.values, "r--", label="Forecast",
121
+ linewidth=2)
122
+ ax.fill_between(conf_int.index, conf_int.iloc[:, 0], conf_int.iloc[:, 1],
123
+ color="red", alpha=0.1, label="95% CI")
124
+ ax.set_title(title, fontweight="bold")
125
+ ax.legend()
126
+ ax.grid(alpha=0.3)
127
+ plt.tight_layout()
128
+ plt.savefig("figures/time_series_forecast.png", dpi=300, bbox_inches="tight")
129
+ plt.close()
130
+ ```
131
+
132
+ ## 3. 変化点検出
133
+
134
+ ```python
135
+ def detect_changepoints(series, method="pelt", penalty="bic", min_size=10):
136
+ """
137
+ 変化点検出。
138
+
139
+ method:
140
+ "pelt" — PELT アルゴリズム (ruptures)
141
+ "cusum" — CUSUM ベース
142
+ "bayesian" — ベイズオンライン変化点検出
143
+
144
+ Returns:
145
+ list of changepoint indices
146
+ """
147
+ import ruptures as rpt
148
+
149
+ signal = series.values
150
+
151
+ if method == "pelt":
152
+ algo = rpt.Pelt(model="rbf", min_size=min_size).fit(signal)
153
+ cps = algo.predict(pen=10)
154
+ elif method == "cusum":
155
+ algo = rpt.Binseg(model="l2", min_size=min_size).fit(signal)
156
+ cps = algo.predict(n_bkps=5)
157
+ elif method == "bayesian":
158
+ algo = rpt.BottomUp(model="l2", min_size=min_size).fit(signal)
159
+ cps = algo.predict(n_bkps=5)
160
+
161
+ # 最後の要素 (n) を除去
162
+ cps = [cp for cp in cps if cp < len(signal)]
163
+
164
+ return cps
165
+
166
+
167
+ def plot_changepoints(series, changepoints, figsize=(12, 4)):
168
+ """変化点を時系列上に可視化する。"""
169
+ fig, ax = plt.subplots(figsize=figsize)
170
+ ax.plot(series.index, series.values, "b-", linewidth=1)
171
+ for cp in changepoints:
172
+ ax.axvline(series.index[cp], color="red", linestyle="--",
173
+ alpha=0.7, linewidth=1.5)
174
+ ax.set_title(f"Changepoint Detection ({len(changepoints)} points found)",
175
+ fontweight="bold")
176
+ ax.grid(alpha=0.3)
177
+ plt.tight_layout()
178
+ plt.savefig("figures/changepoints.png", dpi=300, bbox_inches="tight")
179
+ plt.close()
180
+ ```
181
+
182
+ ## 4. 周期解析(FFT / ウェーブレット)
183
+
184
+ ```python
185
+ def fft_periodicity(series, fs=1.0, top_n=5, figsize=(10, 5)):
186
+ """
187
+ FFT によるパワースペクトルと支配的周期の抽出。
188
+ """
189
+ signal = series.values - np.mean(series.values)
190
+ N = len(signal)
191
+ fft_vals = np.fft.rfft(signal)
192
+ fft_power = np.abs(fft_vals)**2
193
+ freqs = np.fft.rfftfreq(N, d=1/fs)
194
+
195
+ # DC成分除去
196
+ fft_power[0] = 0
197
+
198
+ # Top-N 周期
199
+ top_idx = np.argsort(fft_power)[::-1][:top_n]
200
+ dominant_periods = []
201
+ for idx in top_idx:
202
+ if freqs[idx] > 0:
203
+ dominant_periods.append({
204
+ "frequency": freqs[idx],
205
+ "period": 1 / freqs[idx],
206
+ "power": fft_power[idx],
207
+ })
208
+
209
+ fig, ax = plt.subplots(figsize=figsize)
210
+ ax.plot(freqs[1:], fft_power[1:], "b-", linewidth=1)
211
+ for dp in dominant_periods:
212
+ ax.axvline(dp["frequency"], color="red", linestyle="--", alpha=0.5)
213
+ ax.set_xlabel("Frequency")
214
+ ax.set_ylabel("Power")
215
+ ax.set_title("FFT Power Spectrum", fontweight="bold")
216
+ plt.tight_layout()
217
+ plt.savefig("figures/fft_spectrum.png", dpi=300, bbox_inches="tight")
218
+ plt.close()
219
+
220
+ return dominant_periods
221
+ ```
222
+
223
+ ## 5. Granger 因果性検定
224
+
225
+ ```python
226
+ from statsmodels.tsa.stattools import grangercausalitytests
227
+
228
+ def granger_causality(df, cause_col, effect_col, max_lag=10,
229
+ significance=0.05):
230
+ """
231
+ Granger 因果性検定: cause → effect の因果関係を検定する。
232
+
233
+ Returns:
234
+ dict with optimal_lag, p_values, is_causal
235
+ """
236
+ data = df[[effect_col, cause_col]].dropna()
237
+ results = grangercausalitytests(data, maxlag=max_lag, verbose=False)
238
+
239
+ p_values = {}
240
+ for lag in range(1, max_lag + 1):
241
+ p_val = results[lag][0]["ssr_ftest"][1]
242
+ p_values[lag] = p_val
243
+
244
+ optimal_lag = min(p_values, key=p_values.get)
245
+
246
+ return {
247
+ "cause": cause_col,
248
+ "effect": effect_col,
249
+ "optimal_lag": optimal_lag,
250
+ "p_value_at_optimal": p_values[optimal_lag],
251
+ "is_causal": p_values[optimal_lag] < significance,
252
+ "all_p_values": p_values,
253
+ }
254
+ ```
255
+
256
+ ## 6. 異常検出
257
+
258
+ ```python
259
+ def anomaly_detection_zscore(series, window=30, threshold=3.0):
260
+ """
261
+ 移動平均ベースの Z-score 異常検出。
262
+ """
263
+ rolling_mean = series.rolling(window=window, center=True).mean()
264
+ rolling_std = series.rolling(window=window, center=True).std()
265
+ z_scores = (series - rolling_mean) / (rolling_std + 1e-10)
266
+ anomalies = series[np.abs(z_scores) > threshold]
267
+ return anomalies, z_scores
268
+ ```
269
+
270
+ ## References
271
+
272
+ ### Output Files
273
+
274
+ | ファイル | 形式 |
275
+ |---|---|
276
+ | `results/stationarity_test.csv` | CSV |
277
+ | `results/forecast_results.csv` | CSV |
278
+ | `results/changepoints.csv` | CSV |
279
+ | `results/dominant_periods.csv` | CSV |
280
+ | `results/granger_causality.csv` | CSV |
281
+ | `figures/stl_decomposition.png` | PNG |
282
+ | `figures/time_series_forecast.png` | PNG |
283
+ | `figures/changepoints.png` | PNG |
284
+ | `figures/fft_spectrum.png` | PNG |
285
+
286
+ #### 依存パッケージ
287
+
288
+ ```
289
+ statsmodels>=0.14
290
+ ruptures>=1.1
291
+ ```