2024-05-16

QLCDNumber と QTimer ~ PySide6

PySide (Qt for Python) は、Qt(キュート)の Python バインディングで、GUI などを構築するためのクロスプラットフォームなライブラリです。Linux/X11, macOS および Microsoft Windows をサポートしています。配布ライセンスは LGPL で公開されています。

GUI アプリで決まった間隔で表示の更新などの処理をさせたい場合、QTimer を利用すると簡単に処理を実装できます。

今回のテーマ
  • PySide6 の QLCDNumber と QTimer クラスを利用して、シンプルなデジタル時計アプリを作ります。

下記の OS 環境で動作確認をしています。

RHEL 9.4 x86_64
Python 3.12.1
PySide6 6.7.0

メインの PC に Fedora Linux を利用していましたが、今月初めに dnf update でパッケージを更新した後、Fedora Linux 40 上 venv で利用している PySide6 アプリがコアダンプを吐いて利用できなくなりました。原因がわからず、日々利用している自作アプリに支障が出たので、やむなく RHEL に切り替えています [3]

サンプルと実行例を以下に示しました。

qt_lcdnumber.py
qt_lcdnumber.py の実行例

QTimer クラスを使用するには、QTimer のインスタンスを作成し、timeout() シグナルを適切なスロット(処理するメソッド)に接続し、msec で間隔を指定した start() メソッドを呼び出します。以降、指定された間隔で timeout() シグナルが発せられます。

        timer = QTimer(self)
        timer.timeout.connect(self.update_time)
        timer.start(1000)

本サンプルでは 1000 msec = 1 sec 間隔で timeout() シグナルが発せられるようにして self.update_time() メソッドで QLCDNumber クラスのインスタンスの時刻表示を更新しています。

参考サイト

  1. QLCDNumber - Qt for Python
  2. QTimer - Qt for Python
  3. After updating fedora 40 PySide6 in Python it does not work - Fedora Discussion

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加

2024-05-11

Prophet を使ってみた

Prophet は、R および Python 用に実装した時系列データの予測手法で、非線形のトレンドに年間、週間、日次の季節性、さらに休日効果をフィッティングする加法モデルに基づいています。強い季節効果と数シーズンの過去データを持つ時系列データの解析に最適です。Prophet は欠損値やトレンドのシフトに対してロバストで、一般的に外れ値に対してもうまく対処できます。

Prophet は Facebook の Core Data Science チームによってリリースされたオープンソースのソフトウェアです。CRANPyPI からダウンロード可能です。

Prophet のプロジェクトサイトより引用、翻訳・編集

最近、思っているような時系列解析ができずに苦しんでいます。あれこれ試している中で、Python の statsmodels パッケージの Unobserved components models [1] を試した結果を本ブログでまとめましたが [2]、今回は Prophet を試してみました。

下記の OS 環境で動作確認をしています。

Fedora Workstation 40 x86_64
Python 3.12.2
jupyterlab 4.1.8
matplotlib 3.8.4
pandas 2.2.2
prophet 1.1.5
statsmodels 0.14.2

statsmodels パッケージは、今回はデータセットを利用するためだけに必要になります。

今回の解析は JupyterLab を使用しています。

必要なライブラリーの読み込み

最初に、必要なライブラリーを読み込んでおきます。

import matplotlib.pyplot as plt
import pandas as pd
from prophet import Prophet
 
import statsmodels.datasets.co2 as co2

データセット

今回も過去記事 [2] と同じ、statsmodels に用意されている CO2 濃度のデータセットを利用します。

co2_raw = co2.load().data
co2_raw

 

Prophet へ入力するには、ds(datestamp = 時刻情報)カラムと y カラムにデータフレームを整形する必要があります。y は予測したい測定値です。今回は次のようにしました。

df = co2_raw.reset_index()
df.columns=['ds', 'y']
df

 

過去記事 [2] では、欠損値の少ない期間を選んで、月平均を算出して、そのデータを使用しましたが、今回は欠損値を気にせず、すべてのデータを使います。

モデルの作成と学習

モデルを作成して、用意したデータフレームで学習します。

model = Prophet()
model.fit(df)

予測

過去記事 [2] と同じ期間の予測をしてみます。モデルの make_future_dataframe メソッドで期間(日)を指定して予測用のデータフレームを作成します。

future = model.make_future_dataframe(periods=365 * 4 + 3)
future.tail()

 

モデルの predict メソッドで予測します。

forecast = model.predict(future)
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()

 

予測結果をプロットします。

fig1 = model.plot(forecast)
# plt.savefig('trend_analysis_11/fig-001.png')

 

plot_components メソッドで成分を確認できます。

fig2 = model.plot_components(forecast)
# plt.savefig('trend_analysis_11/fig-002.png')

 

今回の解析では、トレンド成分と月別の成分がプロットされましたが、Prophet ではカレンダー情報を持っているようで、もし曜日依存するようであれば、曜日毎のプロットも表示されます。

まとめ

Prophet の基本的な使い方は scikit-learn のモデルと同じで、個人的には使いやすいと感じました。なにより欠損値に強く、周期変動を指定しなくとも解析してくれるのが嬉しいです。ただ、まだ全然使い込んでいません。まずは具体的なデータ解析を通じて使いこなせるようにしたいです。

参考サイト

  1. statsmodels.tsa.statespace.structural.UnobservedComponents - statsmodels
  2. bitWalk's: 【備忘録】Unobserved components モデル [2024-05-06]
  3. Prophet | Forecasting at scale.
  4. Prophetを使ってサクッと時系列データ予測をやる #Python - Qiita [2023-04-08]
  5. 将来予測で用いられるライブラリ「Prophet」 | スキルアップAI Journal [2023-06-13]
  6. Prophetによる時系列データ予測: Analyst-in-the-Loop [2024-01-04]
  7. 【Python 入門】Prophet を使った時系列データ分析と Plotly による可視化! | キカガクブログ [2024-04-15]

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加

2024-05-06

【備忘録】Unobserved components モデル

Statsmodels は、データの探索、統計モデルの推定、統計検定を算出できる Python パッケージです。様々なタイプのデータや各推定量に対して、広範な記述統計量,統計検定,プロット関数、そして(サンプルに利用できる)統計データを利用できます。SciPy パッケージの stats モジュールを補完します。

Wikipedia より引用、翻訳・編集

最近、思っているような時系列解析ができずに苦しんでいます。あれこれ試している中で、Python の statsmodels パッケージで Unobserved components models [1] を試して見たところ、大したチューニングもしていないのに、いかにももっともらしい予測が出たことに衝撃を受けたので、試したことを備忘録にしました。

下記の OS 環境で動作確認をしています。

Fedora Workstation 40 x86_64
Python 3.12.2
jupyterlab 4.1.8
matplotlib 3.8.4
pandas 2.2.2
statsmodels 0.14.2

今回の解析は JupyterLab を使用しています。

必要なライブラリーの読み込み

最初に、必要なライブラリーを読み込んでおきます。またプロットに共通な設定もしておきます。

import pandas as pd
import statsmodels.api as sm
import matplotlib.pyplot as plt
plt.rcParams.update({
    'font.size'      : 14,
    'axes.grid'      : True,
    'grid.linestyle' : '--',
    'figure.figsize' : [12, 6]
})

import statsmodels.datasets.co2 as co2

データセット

ちょうど参考サイト [2] で紹介されているサンプルを試していたので、そこで使用していたデータセットと同じく statsmodels に用意されている CO2 濃度のデータセットを利用して、同じように加工します。

co2_raw = co2.load().data
co2_raw

 

欠損が少ない 1965 年以降のデータから月次平均を算出して使用します。

df = co2_raw.loc['1965-01-01':]
df = df.resample('ME').mean() # 月の最終日で月次データに変換
df.index.name = "YEAR"
df

 

集計したデータをプロットします。

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.plot(df)

ax.set_title('CO2 Concentration')
ax.set_xlabel('Year')
ax.set_ylabel('ppmv')

# plt.savefig('trend_analysis_08/fig-001.png')
plt.show()

 

Unobserved components モデル

ここからは、参考サイト [3] で紹介されているやり方を、加工した CO2 濃度のデータセットをあてはめてみます。

※「空間状態モデル」というべきかもしれませんが、まだ全然理解できていないので知ったかぶりができず、さりとて、Unobserved components について(定着しているような)日本語の訳語を確認できなかったので、控えめに、そのままの表記にしています。

最初にモデルを定義して、(カルマンフィルダーで)フィッティングします。

model = sm.tsa.UnobservedComponents(
    df,
    level='local linear trend',
    seasonal=12,
)

results = model.fit()
RUNNING THE L-BFGS-B CODE

           * * *

Machine precision = 2.220D-16
 N =            4     M =           10

At X0         0 variables are exactly at the bounds

At iterate    0    f=  3.80232D+00    |proj g|=  8.88849D-02

At iterate    5    f=  2.31489D+00    |proj g|=  8.31771D-01
  ys=-1.847E+00  -gs= 2.050E-01 BFGS update SKIPPED

At iterate   10    f=  4.99810D-01    |proj g|=  1.27619D+00

 This problem is unconstrained.


At iterate   15    f=  3.45421D-01    |proj g|=  3.76042D-01

At iterate   20    f=  2.46012D-01    |proj g|=  8.57193D-02

At iterate   25    f=  2.45718D-01    |proj g|=  1.68724D-02

           * * *

Tit   = total number of iterations
Tnf   = total number of function evaluations
Tnint = total number of segments explored during Cauchy searches
Skip  = number of BFGS updates skipped
Nact  = number of active bounds at final generalized Cauchy point
Projg = norm of the final projected gradient
F     = final function value

           * * *

   N    Tit     Tnf  Tnint  Skip  Nact     Projg        F
    4     27     76      1     1     0   3.247D-03   2.457D-01
  F =  0.24571746957084589     

CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH             

フィッティング結果のサマリーを表示できますが、経験不足で詳細を評価できません。

results.summary()

 

解析で分離した成分のプロットをします。

out = results.plot_components(figsize=(12, 20))
# plt.savefig('trend_analysis_08/fig-002.png')

 

1つ目のグラフは、観測値と予測値とその95%信頼区間を表しています。2つ目のグラフは、レベル成分(観測できない状態?)、3つ目のグラフは、トレンド成分とその信頼区間、4つ目のグラフは、季節成分(周期的変動)を表しています。

作成したモデルで未来を予測してみます。敢えて、一部の期間を学習データと予測データが重なるように設定しています。

# Prediction
prediction = results.predict('2000-01-31', '2005-12-31')

学習データ (Original) と予測データ (Predicted) を色を変えてプロットします。

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)

ax.plot(df, label='Original', color="C0")
ax.plot(prediction, label='Predicted', color="C1")

ax.set_title('CO2 Concentration')
ax.set_xlabel('Year')
ax.set_ylabel('ppmv')
ax.legend()

# plt.savefig('trend_analysis_08/fig-003.png')
plt.show()

 

学習データとテストデータを分けてモデルの予測精度を検証していませんが、なんとなく自然な予測ができているように見えます。あくまで視覚的な印象に過ぎません。もしかすると CO2 濃度は、周期的な変化を把握しておけば素直に上昇を予測できるのかもしれません。

まとめ

今回使ったデータセットではたまたま季節性(周期的な変動)をうまく表現できただけかもしれません。それに、実際に解析したいデータにはこれほど強い季節性がないので、自分がやりたい時系列解析では、このモデルをそれほど有望視する必要がないかもしれません。しかし、参考サイト [4] を読んで、「外生変数」とよばれる、時間によって変化しない情報を複数加えられることを知り、俄然もっと使ってみたくなりました。

参考サイト

  1. statsmodels.tsa.statespace.structural.UnobservedComponents - statsmodels
  2. Pythonで時系列予測に使える機械学習モデルの実行例まとめ #Python - Qiita [2023-09-19]
  3. 時系列解析の重要手法、状態空間モデルについて解説 | pipon AI Trend 最新AI情報をわかりやすく届けるメディア [2020-04-29]
  4. Pythonで時系列分析(状態空間モデル) - deepblue [2022-10-12]

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加