Cette entrée est une suite du précédent écrit J'ai essayé de prédire la présence ou l'absence de neige par apprentissage automatique. Pour le moment, je ne prévoyais que la présence ou l'absence de neige (1 ou 0), mais j'essayais un peu plus de prédire l'évolution de la quantité de neige.
Quand j'ai écrit le résultat en premier, ça ressemblait à ça. L'axe horizontal représente le nombre de jours et l'axe vertical la quantité de neige (cm).
Résultat 1 (le bleu est la quantité réelle de neige, la ligne rouge est la quantité de neige prévue)
Résultat 2 (le bleu est la quantité réelle de neige, la ligne rouge est la quantité de neige prévue)
Veuillez lire ce qui suit pour savoir ce que sont respectivement "Résultat 1" et "Résultat 2".
Auparavant, j'essayais de prédire la présence ou l'absence de chutes de neige en utilisant «scikit-learn» dans J'ai essayé de prédire la présence ou l'absence de chutes de neige par apprentissage automatique. Cependant, je suis devenu un peu gourmand et je voulais prédire la quantité réelle de neige (cm) pour une certaine période, pas la présence ou l'absence.
Plus précisément, nous allons acquérir des données météorologiques telles que la température de la vitesse du vent des chutes de neige fournies par l'Agence météorologique, et utiliser les données pour les 7500 premiers jours d'apprentissage et les 2 années restantes (365x2 = Prédire les changements de neige (730 jours) et comparer avec les changements réels de neige.
Les données de formation seront obtenues auprès de celle publiée par l'Agence météorologique. Plus précisément, veuillez vous référer au document précédemment écrit J'ai essayé de prédire la présence ou l'absence de neige par apprentissage automatique.
Les données CSV obtenues ressemblent à ceci. La cible était la ville de Sakai à Toyama, qui a beaucoup de neige.
data_2013_2015.csv
Temps de téléchargement: 2016/03/20 20:31:19
,Sakai,Sakai,Sakai,Sakai,Sakai,Sakai,Sakai,Sakai,Sakai,Sakai,Sakai,Sakai,Sakai,Sakai
Date et l'heure,Température(℃),Température(℃),Température(℃),La couverture de neige(cm),La couverture de neige(cm),La couverture de neige(cm),vitesse du vent(m/s),vitesse du vent(m/s),vitesse du vent(m/s),vitesse du vent(m/s),vitesse du vent(m/s),Précipitation(mm),Précipitation(mm),Précipitation(mm)
,,,,,,,,,Direction du vent,Direction du vent,,,,
,,information de qualité,Nombre homogène,,information de qualité,Nombre homogène,,information de qualité,,information de qualité,Nombre homogène,,information de qualité,Nombre homogène
2013/2/1 1:00:00,-3.3,8,1,3,8,1,0.4,8,Ouest,8,1,0.0,8,1
2013/2/1 2:00:00,-3.7,8,1,3,8,1,0.3,8,Nord,8,1,0.0,8,1
2013/2/1 3:00:00,-4.0,8,1,3,8,1,0.2,8,Silencieux,8,1,0.0,8,1
2013/2/1 4:00:00,-4.8,8,1,3,8,1,0.9,8,Sud-sud-est,8,1,0.0,8,1
...
L'idée est que ce type de prédiction est probablement standard, mais nous entraînons le modèle avec certains types de données périphériques et la quantité de neige résultante sous forme d'ensemble, et seules les données périphériques sont appliquées au modèle résultant. Il donne et obtient la valeur prévue de la quantité de neige. C'est ce que l'on appelle l ' "apprentissage enseigné" </ b>.
Dans ce cas, les données suivantes ont été utilisées comme données périphériques.
Cela ressemble à ça en termes d'image.
[Température,vitesse du vent,Chutes de neige d'hier,1日前のTempérature,2日前のTempérature,3日前のTempérature, 1日前のvitesse du vent, 2日前のvitesse du vent, 3日前のvitesse du vent]→ Chutes de neige le jour
[Température,vitesse du vent,Chutes de neige d'hier,1日前のTempérature,2日前のTempérature,3日前のTempérature, 1日前のvitesse du vent, 2日前のvitesse du vent, 3日前のvitesse du vent]→ Chutes de neige le jour
[Température,vitesse du vent,Chutes de neige d'hier,1日前のTempérature,2日前のTempérature,3日前のTempérature, 1日前のvitesse du vent, 2日前のvitesse du vent, 3日前のvitesse du vent]→ Chutes de neige le jour
....
[Température,vitesse du vent,Chutes de neige d'hier,1日前のTempérature,2日前のTempérature,3日前のTempérature, 1日前のvitesse du vent, 2日前のvitesse du vent, 3日前のvitesse du vent]→ Chutes de neige le jour
Donc, sur cette base, ne donnez que les données périphériques et obtenez la valeur prédite
[Température,vitesse du vent,Chutes de neige d'hier,1日前のTempérature,2日前のTempérature,3日前のTempérature, 1日前のvitesse du vent, 2日前のvitesse du vent, 3日前のvitesse du vent]→ (Chutes de neige prévues le jour)
Je l'ai fait comme ça. Fondamentalement, les données de la date cible de prévision sont données, mais une seule «chute de neige d'hier» correspond aux données un jour avant la date cible de prévision. Et cela semblait avoir le plus d'impact sur les données qu'il fournissait. Eh bien, quand on y pense, c'est naturel.
Comme je l'ai écrit au début, je vais utiliser les données pendant environ 7500 jours à partir des données obtenues de l'Agence météorologique pour la formation, prédire le changement de neige pour les 2 années restantes et le comparer avec le changement réel des chutes de neige.
Le code réel ressemble à ceci:
snow_forecaster.py
import csv
import numpy as np
from matplotlib import pyplot
from sklearn import linear_model
from sklearn import cross_validation
class SnowForecast:
def __init__(self):
u"""Initialiser chaque variable d'instance"""
self.model = None #Modèle d'apprentissage généré
self.data = [] #Tableau de données d'entraînement
self.target = [] #Disposition des chutes de neige réelles
self.predicts = [] #Disposition des valeurs prévues des chutes de neige
self.reals = [] #Disposition des chutes de neige réelles
self.day_counts = [] #Organisation des dates écoulées à partir de la date de début
self.date_list = []
self.record_count = 0
def load_csv(self):
u"""Lire un fichier CSV pour apprendre"""
with open("sample_data/data.csv", "r") as f:
reader = csv.reader(f)
accumulation_yesterday0 = 0
date_yesterday = ""
temp_3days = []
wind_speed_3days = []
for row in reader:
if row[4] == "":
continue
daytime = row[0] # "yyyy/mmdd HH:MM:SS"
date = daytime.split(" ")[0] # "yyyy/mm/dd"
temp = int(float(row[1])) #Température. Il y a un effet subtil
wind_speed = float(row[7]) #vitesse du vent. Il y a un effet subtil
precipitation = float(row[12]) #Précipitation. aucun effet
accumulation = int(row[4]) #La quantité de neige. La quantité de neige d'hier a un grand impact
if len(wind_speed_3days) == 3:
#Données d'entraînement
# [Température,vitesse du vent,Chutes de neige d'hier,1日前のTempérature,2日前のTempérature,3日前のTempérature, 1日前のvitesse du vent, 2日前のvitesse du vent, 3日前のvitesse du vent]
sample = [temp, wind_speed, accumulation_yesterday0]
sample.extend(temp_3days)
sample.extend(wind_speed_3days)
self.data.append(sample)
self.target.append(accumulation)
if date_yesterday != date:
accumulation_yesterday0 = accumulation
self.date_list.append(date)
wind_speed_3days.insert(0, wind_speed)
if len(wind_speed_3days) > 3:
wind_speed_3days.pop()
temp_3days.insert(0, temp)
if len(temp_3days) > 3:
temp_3days.pop()
date_yesterday = date
self.record_count = len(self.data)
return self.data
def train(self):
u"""Générez un modèle de formation. Utilisez jusqu'à environ 7500 jours des données d'origine pour les données d'entraînement"""
x = self.data
y = self.target
print(len(x))
# ElasticNetCV,LassoCV,Sélectionnez Elastic NetCV avec la plus petite erreur de RidgeCV
model = linear_model.ElasticNetCV(fit_intercept=True)
model.fit(x[0:self.training_data_count()], y[0:self.training_data_count()])
self.model = model
def predict(self):
u"""Prédire à l'aide d'un modèle d'apprentissage. Faites des prédictions pour les deux dernières années"""
x = self.data
y = self.target
model = self.model
for i, xi in enumerate(x):
real_val = y[i]
if i < self.training_data_count() + 1:
self.predicts.append(0)
self.reals.append(real_val)
self.day_counts.append(i)
continue
predict_val = int(model.predict([xi])[0])
#Si la prévision de neige est égale ou inférieure à 0, elle est définie sur 0.
if predict_val < 0:
predict_val = 0
self.predicts.append(predict_val)
self.reals.append(real_val)
self.day_counts.append(i)
def show_graph(self):
u"""Comparez les valeurs prédites et mesurées avec un graphique"""
pyplot.plot(self.day_counts[self.predict_start_num():], self.reals[self.predict_start_num():], "b")
pyplot.plot(self.day_counts[self.predict_start_num():], self.predicts[self.predict_start_num():], "r")
pyplot.show()
def check(self):
u"""Mesurer l'erreur entre les données d'entraînement et les données de prédiction"""
x = np.array(self.data[self.predict_start_num():])
y = np.array(self.target[self.predict_start_num():])
model = self.model
p = np.array(self.predicts[self.predict_start_num():])
e = p - np.array(self.reals[self.predict_start_num():])
error = np.sum(e * e)
rmse_10cv = np.sqrt(error / len(self.data[self.predict_start_num():]))
print("RMSE(10-fold CV: {})".format(rmse_10cv))
def training_data_count(self):
u"""Laissez les deux dernières années et utilisez les données antérieures comme données d'entraînement. Renvoie le nombre de données d'entraînement"""
return self.record_count - 365 * 2
def predict_start_num(self):
u"""Les deux dernières années sont prévues et utilisées pour mesurer l'erreur à partir de la valeur mesurée. Renvoie la position de départ prévue"""
return self.training_data_count() + 1
if __name__ == "__main__":
forecaster = SnowForecast()
forecaster.load_csv()
forecaster.train()
forecaster.predict()
forecaster.check()
forecaster.show_graph()
La partie la plus ennuyeuse a été de créer des données d'entraînement à partir de données brutes comme dans le chapitre précédent. Pourtant, c'est facile parce que c'est python.
Ainsi, le résultat de l'exécution est le suivant (le bleu est la quantité réelle de neige, la ligne rouge est la quantité de neige prévue). C'est le premier "résultat 1" affiché.
Je prédis quelque chose comme ça.
À ce stade, je me suis soudain demandé comment faire cela. "Mais je prédis en donnant la quantité de neige il y a un jour, donc quand j'essaye de l'utiliser pour des prévisions futures, je ne peux prédire la quantité de neige que demain…?" b>
Non, tu sais? Si vous dites cela, la température et la vitesse du vent seront les mêmes. Mais vous voyez, ce sont des prévisions météorologiques ... Gefun Gefun
Donc, j'ai immédiatement modifié le code comme ça.
Il n'y a pas de modifications particulières à la partie formation du modèle. Parmi les données fournies lors de la prédiction de la quantité de neige, remplaçons la quantité de neige d'hier
par la` valeur prévue un jour avant, qui a été prédite par lui-même, au lieu de la valeur de mesure réelle.
Le code est comme suit. Seule la fonction «prédire» a changé.
snow_forecaster.py
import csv
import numpy as np
from matplotlib import pyplot
from sklearn import linear_model
from sklearn import cross_validation
class SnowForecast:
def __init__(self):
u"""Initialiser chaque variable d'instance"""
self.model = None #Modèle d'apprentissage généré
self.data = [] #Tableau de données d'entraînement
self.target = [] #Disposition des chutes de neige réelles
self.predicts = [] #Disposition des valeurs prévues des chutes de neige
self.reals = [] #Disposition des chutes de neige réelles
self.day_counts = [] #Organisation des dates écoulées à partir de la date de début
self.date_list = []
self.record_count = 0
def load_csv(self):
u"""Lire un fichier CSV pour apprendre"""
with open("sample_data/data.csv", "r") as f:
reader = csv.reader(f)
accumulation_yesterday0 = 0
date_yesterday = ""
temp_3days = []
wind_speed_3days = []
for row in reader:
if row[4] == "":
continue
daytime = row[0] # "yyyy/mmdd HH:MM:SS"
date = daytime.split(" ")[0] # "yyyy/mm/dd"
temp = int(float(row[1])) #Température. Il y a un effet subtil
wind_speed = float(row[7]) #vitesse du vent. Il y a un effet subtil
precipitation = float(row[12]) #Précipitation. aucun effet
accumulation = int(row[4]) #La quantité de neige. La quantité de neige d'hier a un grand impact
if len(wind_speed_3days) == 3:
#Données d'entraînement
# [Température,vitesse du vent,Chutes de neige d'hier,1日前のTempérature,2日前のTempérature,3日前のTempérature, 1日前のvitesse du vent, 2日前のvitesse du vent, 3日前のvitesse du vent]
sample = [temp, wind_speed, accumulation_yesterday0]
sample.extend(temp_3days)
sample.extend(wind_speed_3days)
self.data.append(sample)
self.target.append(accumulation)
if date_yesterday != date:
accumulation_yesterday0 = accumulation
self.date_list.append(date)
wind_speed_3days.insert(0, wind_speed)
if len(wind_speed_3days) > 3:
wind_speed_3days.pop()
temp_3days.insert(0, temp)
if len(temp_3days) > 3:
temp_3days.pop()
date_yesterday = date
self.record_count = len(self.data)
return self.data
def train(self):
u"""Générez un modèle de formation. Utilisez jusqu'à environ 7500 jours des données d'origine pour les données d'entraînement"""
x = self.data
y = self.target
print(len(x))
# ElasticNetCV,LassoCV,Sélectionnez Elastic NetCV avec la plus petite erreur de RidgeCV
model = linear_model.ElasticNetCV(fit_intercept=True)
model.fit(x[0:self.training_data_count()], y[0:self.training_data_count()])
self.model = model
def predict(self):
u"""Prédisez la quantité de neige à l'aide d'un modèle d'apprentissage. Faites des prédictions pour les deux dernières années"""
x = self.data
y = self.target
model = self.model
yesterday_predict_val = None #Variable pour stocker la valeur prévue d'hier
for i, xi in enumerate(x):
real_val = y[i]
if i < self.training_data_count() + 1:
self.predicts.append(0)
self.reals.append(real_val)
self.day_counts.append(i)
continue
#Remplacez les chutes de neige d'hier par les prévisions d'hier
if yesterday_predict_val != None:
xi[2] = yesterday_predict_val
predict_val = int(model.predict([xi])[0])
#Si la prévision de neige est égale ou inférieure à 0, elle est définie sur 0.
if predict_val < 0:
predict_val = 0
self.predicts.append(predict_val)
self.reals.append(real_val)
self.day_counts.append(i)
yesterday_predict_val = predict_val
def show_graph(self):
u"""Comparez les valeurs prédites et mesurées avec un graphique"""
pyplot.plot(self.day_counts[self.predict_start_num():], self.reals[self.predict_start_num():], "b")
pyplot.plot(self.day_counts[self.predict_start_num():], self.predicts[self.predict_start_num():], "r")
pyplot.show()
def check(self):
u"""Mesurer l'erreur entre les données d'entraînement et les données de prédiction"""
x = np.array(self.data[self.predict_start_num():])
y = np.array(self.target[self.predict_start_num():])
model = self.model
p = np.array(self.predicts[self.predict_start_num():])
e = p - np.array(self.reals[self.predict_start_num():])
error = np.sum(e * e)
rmse_10cv = np.sqrt(error / len(self.data[self.predict_start_num():]))
print("RMSE(10-fold CV: {})".format(rmse_10cv))
def training_data_count(self):
u"""Laissez les deux dernières années et utilisez les données antérieures comme données d'entraînement. Renvoie le nombre de données d'entraînement"""
return self.record_count - 365 * 2
def predict_start_num(self):
u"""Les deux dernières années sont prévues et utilisées pour mesurer l'erreur à partir de la valeur mesurée. Renvoie la position de départ prévue"""
return self.training_data_count() + 1
if __name__ == "__main__":
forecaster = SnowForecast()
forecaster.load_csv()
forecaster.train()
forecaster.predict()
forecaster.check()
forecaster.show_graph()
Le résultat est le suivant (le bleu est la quantité réelle de neige, la ligne rouge est la quantité de neige prévue). "Résultat 2" affiché au début.
Hmm. Comme prévu, il est devenu plus imprécis que lorsque la quantité réelle de neige a été donnée hier. Cependant, il semble que la forme d'onde ne soit pas si perturbée.
Je me demandais si ce serait une prédiction plus foirée, mais je pensais que j'étais capable de la prédire comme ça. Cependant, bien qu'il ait été trompé avec succès par Gefun Gefun en cours de route, la température et la vitesse du vent données lors de la prédiction utilisent les valeurs mesurées du jour. Mais si vous souhaitez faire des prédictions pour une certaine période dans le futur, vous devez utiliser les valeurs prédites séparément ou arrêter d'utiliser ces valeurs en premier lieu, donc si vous utilisez les valeurs prédites, la précision sera plus élevée. Il descendra. De plus, le plus l'avenir. Donc, si vous voulez faire quelque chose comme ça, faites une prédiction en utilisant la valeur prédite, puis faites une prédiction en l'utilisant, et ainsi de suite, et plus tard, la légère erreur dans le processus précédent augmentera considérablement. pensée. Alors faites de votre mieux (Agence météorologique)