メモ > 技術 > プログラミング言語: Python > scikit-learn(機械学習)で気象データを解析
scikit-learn(機械学習)で気象データを解析
気象庁|過去の気象データ・ダウンロード
https://www.data.jma.go.jp/gmd/risk/obsdl/
東京の10年分の平均気温を取得する。
地点を選ぶ ... 東京 → 東京
項目を選ぶ ... 日別値 → 日平均気温
期間を選ぶ ... 2006年1月1日〜2016年12月31日
として「CSVファイルダウンロード」をクリック。
余計な項目も含まれているので、以下のプログラムでデータを整形する。
in_file = "data.csv"
out_file = "temperature.csv"
# CSVファイルを一行ずつ読み込み
with open(in_file, "rt", encoding="Shift_JIS") as fr:
lines = fr.readlines()
# ヘッダをそぎ落として、新たなヘッダをつける
lines = ["年,月,日,気温,品質,均質\n"] + lines[5:]
lines = map(lambda v: v.replace('/', ','), lines)
result = "".join(lines).strip()
print(result)
# 結果をファイルへ出力
with open(out_file, "wt", encoding="utf-8") as fw:
fw.write(result)
print("saved.")
以下のプログラムで平均を表示できる。
import pandas as pd
# PandasでCSVを読み込む
df = pd.read_csv("temperature.csv", encoding="utf-8")
# 日付ごとに気温をリストにまとめる
md = {}
for i, row in df.iterrows():
m, d, v = (int(row['月']), int(row['日']), float(row['気温']))
key = str(m) + "/" + str(d)
if not(key in md): md[key] = []
md[key] += [v]
# 日付ごとに平均を求める
avs = {}
for key in md:
v = avs[key] = sum(md[key]) / len(md[key])
print("{0} : {1}".format(key, v))
# 11月3日の平均気温を表示
print(avs["11/3"])
以下のようにすれば、よりかんたんに平均を求めることができる。
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import pandas as pd
# CSVを読み込む
df = pd.read_csv("temperature.csv", encoding="utf-8")
# 月ごとに平均を求める
g = df.groupby(['月'])["気温"]
gg = g.sum() / g.count()
# 結果を出力
print(gg)
gg.plot()
plt.savefig("average.png")
plt.show()
以下のようにすれば、年ごとに30度超えの日数を表示できる。
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import pandas as pd
# CSVを読み込む
df = pd.read_csv("temperature.csv", encoding="utf-8")
# 気温が30度超えのデータを調べる
bool_30 = (df["気温"] > 30)
# データを抜き出す
over_30 = df[bool_30]
# 年ごとにカウント
count = over_30.groupby(["年"])["年"].count()
# 結果を出力
print(count)
count.plot()
plt.savefig("over30.png")
plt.show()
以下のようにすれば、過去6日の気温から翌日の気温を予測できる。
from sklearn.linear_model import LinearRegression
import pandas as pd
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
# 気温データ10年分の読み込み
df = pd.read_csv('temperature.csv', encoding="utf-8")
# データを学習用とテスト用に分割する
train_year = (df["年"] <= 2015)
test_year = (df["年"] >= 2016)
interval = 6
# 過去6日分を学習するデータを作成
def make_data(data):
x = [] # 学習データ(過去6日分の気温)
y = [] # 結果(翌日の気温)
temps = list(data["気温"])
for i in range(len(temps)):
if i < interval: continue
y.append(temps[i])
xa = []
for p in range(interval):
d = i + p - interval
xa.append(temps[d])
x.append(xa)
return (x, y)
train_x, train_y = make_data(df[train_year])
test_x, test_y = make_data(df[test_year])
# 直線回帰分析を行う
lr = LinearRegression(normalize=True)
lr.fit(train_x, train_y) # 学習
pre_y = lr.predict(test_x) # 予測
# 結果を図にプロット
plt.figure(figsize=(10, 6), dpi=100)
plt.plot(test_y, c='r')
plt.plot(pre_y, c='b')
plt.savefig('predict.png')
plt.show()