LoginSignup
0
4

More than 1 year has passed since last update.

適応領域の設定

気象予測を量子機械学習をつかって解きます。
具体的には、大阪市の天気予測をします。

データの入手・確認

気象庁から大阪市の直近一ヶ月分のCSVデータをダウンロードします。(2022/9/27日時点)

ダウンロードしたCSVは以下です。(2022年8月30日 ~ 2022年9月30日)
天気に関係のある項目を抽出しました。

ダウンロードした時刻:2022/10/01 14:38:59

,大阪,大阪,大阪,大阪,大阪
,平均現地気圧(hPa),合計全天日射量(MJ/㎡),平均雲量(10分比),降水量の合計(mm),天気概況(昼:06時~18時)
2022年8月30日,1002.8,13.01,10.0,6.5,曇一時雨
2022年8月31日,998.8,23.13,6.3,0.0,晴時々薄曇
2022年9月1日,1001.1,8.88,10.0,20.5,曇時々雨
2022年9月2日,1004.8,20.43,8.5,21.5,晴時々曇一時雨、雷を伴う
2022年9月3日,1005.0,15.35,9.3,17.5,晴後曇一時雨
2022年9月4日,1004.6,19.90,3.5,0.0,晴後一時曇
2022年9月5日,1002.9,19.27,3.3,0.0,晴一時曇
2022年9月6日,998.4,14.47,9.5,1.0,晴後曇一時雨
2022年9月7日,1003.6,17.47,9.8,2.5,曇一時晴
2022年9月8日,1004.8,7.79,10.0,39.0,曇後一時雨
2022年9月9日,1004.6,9.35,10.0,5.0,曇時々雨
2022年9月10日,1005.1,19.87,7.5,0.5,晴時々曇
2022年9月11日,1004.2,22.28,2.8,--,晴
2022年9月12日,1003.4,21.10,5.0,--,晴一時薄曇
2022年9月13日,1004.3,21.74,6.8,--,薄曇後晴
2022年9月14日,1004.5,19.19,7.0,--,薄曇時々晴
2022年9月15日,1003.0,19.31,7.0,--,薄曇後晴
2022年9月16日,1002.1,22.04,7.3,--,晴後薄曇
2022年9月17日,1000.4,8.23,10.0,3.5,曇
2022年9月18日,994.8,11.89,10.0,--,曇
2022年9月19日,984.1,7.09,9.8,16.0,曇一時雨
2022年9月20日,995.8,12.89,9.8,16.0,曇
2022年9月21日,1004.9,13.43,9.3,0.0,曇時々晴
2022年9月22日,1005.5,15.15,10.0,2.0,曇一時雨
2022年9月23日,1000.9,2.62,9.8,17.0,雨後曇
2022年9月24日,1002.8,19.63,5.3,--,晴
2022年9月25日,1005.6,21.19,2.3,--,晴
2022年9月26日,1005.8,20.74,1.0,--,晴
2022年9月27日,1003.7,10.36,9.5,18.5,曇後雨
2022年9月28日,1001.3,12.33,10.0,0.0,曇
2022年9月29日,1003.4,11.88,9.5,0.0,曇一時晴後一時雨
2022年9月30日,1005.4,19.61,0.5,--,晴

※APIで取得するなら

気象データの入手は
Intertrustから
Pythonのライブラリrequestsを使ってもできるみたいです。

Intertrustは世界各地の気象データが集積されています。
APIも提供されています。

14日無料トライアルの期間ではデータの取得が可能です。

実装

インポート

from blueqat import Circuit
from blueqat.pauli import Z
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

データ加工

# 気象データ(2022年08月26日 ~ 2022年09月26日)
data = np.array(
    [
        [1002.8,13.01,10.0,6.5],
        [998.8,23.13,6.3,0.0],
        [1001.1,8.88,10.0,20.5],
        [1004.8,20.43,8.5,21.5],
        [1005.0,15.35,9.3,17.5],
        [1004.6,19.90,3.5,0.0],
        [1002.9,19.27,3.3,0.0],
        [998.4,14.47,9.5,1.0],
        [1003.6,17.47,9.8,2.5],
        [1004.8,7.79,10.0,39.0],
        [1004.6,9.35,10.0,5.0],
        [1005.1,19.87,7.5,0.5],
        [1004.2,22.28,2.8,0.0],
        [1003.4,21.10,5.0,0.0],
        [1004.3,21.74,6.8,0.0],
        [1004.5,19.19,7.0,0.0],
        [1003.0,19.31,7.0,0.0],
        [1002.1,22.04,7.3,0.0],
        [1000.4,8.23,10.0,3.5],
        [994.8,11.89,10.0,0.0],
        [984.1,7.09,9.8,16.0],
        [995.8,12.89,9.8,16.0],
        [1004.9,13.43,9.3,0.0],
        [1005.5,15.15,10.0,2.0],
        [1000.9,2.62,9.8,17.0],
        [1002.8,19.63,5.3,0.0],
        [1005.6,21.19,2.3,0.0],
        [1005.8,20.74,1.0,0.0],
        [1003.7,10.36,9.5,18.5],
        [1001.3,12.33,10.0,0.0],
        [1003.4,11.88,9.5,0.0],
        [1005.4,19.61,0.5,0.0],
    ]
)

df = pd.DataFrame(data, columns=['hPa','MJ','cloud','precipitation']) # 平均現地気圧(hPa),合計全天日射量(MJ/㎡),平均雲量(10分比),降水量の合計(mm)

# 雲量で天気を判断
y = df["cloud"]
X = df.drop(columns=["cloud"], axis=1)

X_train, X_val, y_train, y_val = train_test_split(
    X,
    y,
    test_size=0.2,
    random_state=1
)

モデル開発

3量子ビットでやります。

N = 3

シードを1に、パラメーターは18個用意します。

np.random.seed = 1
params = [np.random.rand() for _ in range(N*6)] # param*18

ハミルトニアン

hamiltonian = 1*Z[0]*Z[1]*Z[2]

微分用の誤差と学習率。

h = 1e-6
e = 0.1
arr_loss = []

for k in range(100):

    for item, answer in zip(X_train.values, y_train.values):
        circuit = Circuit()
        print(item)
        for i in range(N):
            circuit.rx(params[i*3+0])[i].ry(params[i*3+1])[i].rz(params[i*3+2])[i]

        circuit.cz[0,1].cz[1,2].cz[2,3].cz[3,0]
        
        for i in range(N):
            circuit.rx(np.pi*2*item[i]/100)[i]
    
        for i in range(N):
            circuit.rx(params[i*3+N*3])[i].ry(params[i*3+N*3+1])[i].rz(params[i*3+N*3+2])[i]
        
        expt = circuit.run(hamiltonian = hamiltonian)
        loss = (expt - answer/100)**2
        
        grad_temp = np.zeros(N*6)
        
        for j in range(N*6):
            params_temp = params[:]
            angle_temp = params_temp[j]
            params_temp[j] += h
            
            circuit = Circuit()
        
            for i in range(N):
                circuit.rx(params_temp[i*3+0])[i].ry(params_temp[i*3+1])[i].rz(params_temp[i*3+2])[i]

            circuit.cz[0,1].cz[1,2].cz[2,3].cz[3,0]

            for i in range(N):
                circuit.rx(np.pi*2*item[i]/100)[i]
    
            for i in range(N):
                circuit.rx(params_temp[i*3+N*3])[i].ry(params_temp[i*3+N*3+1])[i].rz(params_temp[i*3+N*3+2])[i]
        
            expt_temp = circuit.run(hamiltonian = hamiltonian)
            loss_temp = (expt_temp - answer/100)**2
            
            grad_temp[j] = (loss_temp - loss)/h
            
        params -= grad_temp*e
        
    arr_loss.append(loss)
    print(loss)

評価/予測

plt.plot(arr_loss)
plt.show()

適当な日の天気を予測してみます。

# 2003年8月18日のデータ。雲量は8.8で一応晴れ。
X_test = [1004.8,18.6,0.5] 

circuit = Circuit()
        
for i in range(N):
    circuit.rx(params[i*3+0])[i].ry(params[i*3+1])[i].rz(params[i*3+2])[i]

circuit.cz[0,1].cz[1,2].cz[2,3].cz[3,0]

for i in range(N):
    circuit.rx(np.pi*2*X_test[i]/100)[i]
    
for i in range(N):
    circuit.rx(params[i*3+N*3])[i].ry(params[i*3+N*3+1])[i].rz(params[i*3+N*3+2])[i]
        
expt = circuit.run(hamiltonian = hamiltonian)
print(expt*100)

6.25270091561785とでました。

雲の量が1割以下(0~1割)の状態を「快晴」、
2割から8割の状態を「晴れ」、
9割以上の状態を「曇り」といいます。

一応、2003年8月18日は晴れ、予測結果も晴れということで良いのではないでしょうか。

結論

入力値が安牌すぎて使いものにならない。
画像(QCNN)か、GSWRシステムとQMLのハイブリッドか(よくわかってない)を調べないといけない。


▼ ワンコインAI無料お試し

▼ DeepRecommendから限定情報を受け取る

0
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
4