python 機械学習初級 ~「 LinearRegression(sklearn)」を使って天気予報させてみる編~

・概要

機械学習やAIなど、ニュースを見ていると頻出するワードになりつつあります。pythonを使えるのであればいったいどのようなものなのかを体験しておいてもよいと思うので、是非このページを参考にしていただければと思います。

身近なネタで分かり易くいきたいので、天気予報・気温を予測で行こうと思います。


・やってみること

今回は「重回帰」という内容で進めようと思います。簡単に言うと、複数の情報を元に一つの予測を立てるということです。やることは、過去の天気情報を元に未来の天気を予想してみます。教師あり、教師なしと種類はありますが、今回は教師ありで進めます。


・データの準備

まずは、元となる天気情報を取得するところからです。過去データを大量に取得したいのですが手動でやっていたら相当時間がかかりそうなので、スクレイピングを利用してデータを取得します。

 実行環境

 pythonバージョン
  python 3.8.5

 ライブラリ
  beautifulsoup4
  requests
  openpyxl

 準備するファイル
  wes_list.txt

  ※上記リストをコピペして利用ください
 

#過去一年分の天気情報を取得

#各ライブラリをインポート
from bs4 import BeautifulSoup as bs
import requests as rq
import openpyxl as xl
import pandas as pd
import re

#取得する天気情報の日付を読み込む
wes_list = open(r"c:\py\wes_list.txt") #パスは環境に合わせて適宜変更


#Excelを起動
book = xl.Workbook()
book.create_sheet()

#ExcelへIndexの書き込み
sheet1 = book.worksheets[0]
sheet1.title = "tenki"
sheet1.cell(row=1, column=1).value = "date"
sheet1.cell(row=1, column=2).value = "tenki"
sheet1.cell(row=1, column=3).value = "kion"

#変数の定義
rows = 2

#天気情報を一行ずつExcelへ書き込む処理
for i in wes_list:
    url = i.rstrip()
    html = rq.get(url)
    soup = bs(html.content, "html.parser")
    tenki0 = soup.find_all(class_="weather-entry")
    tenki1 = re.sub(u'.*<br/>|</td>','',str(tenki0[5]))
    tenki = tenki1.replace(u'快晴','sunny').replace(u'晴れ','sunny')\
    .replace(u'曇り','cloudy').replace(u'雨','rain')\
    .replace(u'にわかrain','shower').replace(u'みぞれ','sleet')\
    .replace(u'雪','snow').replace(u'雷','thunder').replace(u'不明','0')
    kion0 = soup.find_all(class_="temp-entry")
    kion = re.sub(u'.*">|</td>','',str(kion0[5]))
    sheet1.cell(row=rows, column=1).value = (str(url[27:32]))
    sheet1.cell(row=rows, column=2).value = (str(tenki))
    sheet1.cell(row=rows, column=3).value = (str(kion))
    rows += 1

#Excelファイルを保存する処理
book.save(r"c:\py\tenki.xlsx") #パスは環境に合わせて適宜変更
book.close()

以下のようなファイルが作成されます。

 ・date 日付
 ・tenki その日の天気(sunny=晴れ、cloudy=曇り、rain=雨)
 ・kion その日の気温


・早速やってみる

では早速やってみましょう。以下のようにコードを打ち込みます。

各ライブラリをインポート
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score

#上記で作成したExcelを読み込む
test1 = pd.read_excel(r"c:\py\tenki.xlsx")

#tenki列を0、1の数値へ置き換える処理
test2 = pd.get_dummies(test1,columns=['tenki'])

#予測したいIndexの指定
Y = np.array(test2['kion'])

#Index名の取得
print(test2.columns.values)
#['date' 'kion' 'tenki_cloudy' 'tenki_rain' 'tenki_sunny']

#学習するデータのIndexを指定
X = np.array(test2[['tenki_cloudy','tenki_rain','tenki_sunny']])

#各データを学習用データと、検証用データに分ける
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.1, random_state=0)

#学習させるモデルを指定
model = LinearRegression()

#学習開始
model.fit(X_train, Y_train)

#学習した結果を表示
Y_pred = model.predict(X_test)
print(Y_pred)

#以下が今後の予測値
#[19.09548872 19.09548872 19.09548872 13.855      16.23931034 19.09548872
# 19.09548872 19.09548872 16.23931034 13.855      16.23931034 13.855
# 19.09548872 16.23931034 16.23931034 19.09548872 16.23931034 19.09548872
# 16.23931034 13.855      18.67419355 18.67419355 19.09548872 16.23931034
# 16.23931034 19.09548872 19.09548872 16.23931034 16.23931034 19.09548872
# 19.09548872 13.855      19.09548872 16.23931034 16.23931034 19.09548872
# 19.09548872]

#予測結果と正解をみてみる
print(Y_test)
#[11.4 26.1 14.4  6.  17.4 10.4 11.1 19.  29.6  5.6 19.5 13.5 21.7 22.2
# 16.3 23.1 16.2 13.6 30.8 12.9 15.9 21.3 11.3 17.3 17.1 29.2 17.1 10.6
# 13.2 26.4 20.1 12.1  7.1  3.7 11.8  9.1 13.3]

print(Y_pred)
#[19.09548872 19.09548872 19.09548872 13.855      16.23931034 19.09548872
# 19.09548872 19.09548872 16.23931034 13.855      16.23931034 13.855
# 19.09548872 16.23931034 16.23931034 19.09548872 16.23931034 19.09548872
# 16.23931034 13.855      18.67419355 18.67419355 19.09548872 16.23931034
# 16.23931034 19.09548872 19.09548872 16.23931034 16.23931034 19.09548872
# 19.09548872 13.855      19.09548872 16.23931034 16.23931034 19.09548872
# 19.09548872]

#学習した結果がどの程度正確な物かスコアで表示
r2_score = r2_score(Y_test, Y_pred)
print(r2_score)

#0.023739938190100562

出力された予測値に対するスコアを見る限り、予測値は今回は全く信頼性がないものと考えられます。

根拠はスコアの値が0.5以下である場合、モデルとして意味をなさないとされているからです。

また、予測結果と正解からみても数値が近い値を指してはいませんでした。


・まとめ

今回はとりあえず一通り学習させることを目標としたため、結果はほぼ意味のないものとなりました。

以下を考慮して何度かデータをまとめればスコア値アップが望めそうです。

 ・入力する天気情報を1年分とするのではなく、1か月単位で3年分入力

 ・入力する情報を変化させる(気温に関係がありそうなものを厳選する)

 ・予測モデルを変更してみる(今回は重回帰だったが、時系列モデルでやってみるなど)

上記内容が少しでも参考になれば幸いです。


返信を残す

メールアドレスが公開されることはありません。

CAPTCHA