周辺地点の気象情報からの気温予測 チュートリアル

はじめに

このコンペティションでは、同じ時刻の周辺10地点の気象情報と各地点の情報が与えられ、目標地点の1時間ごとの気温の予測を目指します。気象情報としては気温、降水量、日照時間が与えられますが、このチュートリアルではベースラインとして、周辺地点の気温だけを使って予測する方法を解説します。

掲載コードの実行には下記の環境が必要です:

データの読み込み

まず、データを読み込みます:

temperaturetrainfeaturefile = './Temperature_Train_Feature.tsv'
temperaturetraintargetfile = './Temperature_Train_Target.tsv'
temperaturetestfeaturefile = './Temperature_Test_Feature.tsv'

trainfeature = readfeature(temperaturetrainfeaturefile, True)
traintarget = readtarget(temperaturetraintargetfile, False)
testfeature = readfeature(temperaturetestfeaturefile, True)

データを読み込む関数は以下のようになります:

def readfeature(featurefile, has_header):
    feature = read_tsv_data(featurefile, has_header)
    featurefilled = fillmissingbyplacebyhour(feature)

    totalnum = len(featurefilled)
    data = []
    for i in range(0,totalnum):
        data.append(featurefilled[i][3:NUM_PLACE+3])
    return data

def readtarget(targetfilename, has_header):
    with open(targetfilename) as targetfile:
        if has_header: targetfile.readline()
        data = []
        for line in targetfile:
            value = line.strip()
            data.append(float(value))
    return data

def read_tsv_data(file_path, has_header):
    with open(file_path) as f:
        if has_header: f.readline()
        data = []
        for line in f:
            values = line.strip().split("\t")
            rowdata = []
            for x in values:
                 rowdata.append(float(x))
            data.append(rowdata)
    return data

欠損値補完

データには、nanで表現されている欠損値があります。予測手法を適用するためには、欠損値を補完する必要があります。様々な補完方法がありますが、このチュートリアルでは、同時刻の値の中央値で補完する方法を紹介します。欠損値補完を行う関数は以下のようになります。この関数は、readfeature()関数から呼ばれます。

import math
from numpy import nanmedian

NUM_PLACE = 10
NUM_HOUR = 24

def fillmissingbyplacebyhour(databyhour):
    databyhourfilled = databyhour
    for j in range(3,NUM_PLACE+3): # for each place (column in data)
        valuebyhour = []
        medianbyhour = []
        for i in range(0,NUM_HOUR): # for each hour (row in data, 24 rows per day)
            valuebyhour.append([])

        # store the values of each hour for a place respectively, real value or NaN
        hourid = 0
        for row in databyhour:  # for each hour (row in data, 24 rows per day)
            valuebyhour[hourid].append(row[j])
            hourid += 1
            if (hourid % 24 == 0):
                hourid = 0
        # compute the median value of each hour (except NaN)
        for hourid in range(0,NUM_HOUR):
            median = nanmedian(valuebyhour[hourid])
            medianbyhour.append(median)
        medianofplace = nanmedian(medianbyhour)
        for hourid in range(0,NUM_HOUR):
            if math.isnan(medianbyhour[hourid]):
                medianbyhour[hourid] = medianofplace

        # assign the NaN with median value of that hour
        num = len(databyhour)
        for k in range(0,num):
            if math.isnan(databyhour[k][j]):
                databyhourfilled[k][j] = medianbyhour[k%24]

    return databyhourfilled

予測モデル学習

データの準備ができたので、次は予測モデルの学習に移ります。今回は、線形回帰モデルを利用します。

from sklearn.linear_model import LinearRegression

model = LinearRegression()
model = model.fit(trainfeature, traintarget)

予測結果の出力と提出

最後に、予測結果をファイルに出力します。

def writetarget(targetdata,targetfilename):
    targetfile = open(targetfilename,'w')
    for value in targetdata:
        targetfile.write('%f\n' % value)
    targetfile.close()

testpred = model.predict(testfeature)
temperaturetesttargetsamplefile = './Temperature_Test_Target_Sample.tsv'
writetarget(testpred, temperaturetesttargetsamplefile)