Auparavant, j'expliquais comment prédire le niveau d'eau à partir de la quantité de précipitations, mais après cela, j'ai découvert qu'il était devenu possible de prédire le niveau d'eau une heure plus tard avec une précision d'environ 95%, je vais donc le réorganiser. J'écrirai un article.
article | Contenu |
---|---|
Machine | MacBook Air (13-inch, Early 2015) |
Processeur | 2.2 GHz Intel Core i7 |
Mémoire | 8 GB 1600 MHz DDR3 |
Python | 3.6.0 :: Anaconda 4.3.1 (x86_64) |
Jupyter Notebook | 4.2.1 |
Veuillez vous référer à l'URL suivante pour le miso avant habituel.
Liste des données ouvertes | Site du portail Data City Sabae
Sur le site ci-dessus, si vous sélectionnez le groupe "Prévention des catastrophes", la notation suivante sera affichée. Cliquez sur le bouton "CSV" et téléchargez le CSV à partir du lien affiché.
En outre, les données météorologiques passées peuvent être téléchargées à partir de l'Agence météorologique, nous allons donc télécharger les données de précipitations horaires dans la ville de Fukui.
Agence météorologique | Téléchargement des données météorologiques passées
Utilisez le bloc-notes Jupyter pour charger les bibliothèques suivantes.
python
from ipywidgets import FloatProgress
from IPython.display import display
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import datetime
python
#Lire le fichier
filename = "sparql.csv"
df_level = pd.read_csv(filename, header=None, skiprows=1)
#Renommer la colonne
df_level.columns = ["url","datetime","level"]
#Convertir la date et l'heure en horodatage
df_level["datetime"] = df_level.datetime.map(lambda _: pd.to_datetime(_))
#Définir la date et l'heure comme index
df_level.index = df_level.pop("datetime")
#Trier par date et heure(...Je pense que ça fonctionnera sans ça, mais je vais le laisser)
df_level = df_level.sort_index()
#affichage graphique
df_level["level"].plot(figsize=(15,5))
Une fois exécuté, le graphique suivant sera affiché.
Lisez les données et affichez-les sur le graphique, en faisant attention au fait que le CSV contient des données qui ne sont pas comptées et que le code de caractère est shift JIS.
python
#Lire le fichier
filename = "data.csv"
df = pd.read_csv(filename,encoding="SHIFT-JIS",skiprows=4)
#Renommer la colonne
df_rain.columns = ["datetime", "rain", "Information sans phénomène","information de qualité","Nombre homogène"]
#Convertir la date et l'heure en horodatage
df_rain["datetime"] = df_rain.datetime.map(lambda _: pd.to_datetime(_))
#Définir la date et l'heure comme index
df_rain.index = df_rain.pop("datetime")
#affichage graphique
df_level.level.plot(figsize=(15,5))
df_rain.rain.plot(figsize=(15,5))
Une fois exécuté, le graphique suivant sera affiché. Au fait, l'orange est la quantité de précipitations.
Cette fois, puisque nous prévoyons le niveau d'eau une heure plus tard, j'aimerais prédire le niveau d'eau maximal une heure plus tard en utilisant le changement de niveau d'eau il y a une heure et la quantité de précipitations.
Pour cela, les données d'entraînement sont les suivantes.
contribution | production |
---|---|
Précipitations il y a une heure Niveau d'eau toutes les 5 minutes il y a 1 heure(10 points) |
Niveau d'eau maximum après 1 heure |
Étant donné que les données sur le niveau d'eau sont des données à des intervalles de 5 minutes, il devrait y avoir 12 points de données toutes les 60 minutes, mais il y a des données manquantes, et certaines d'entre elles ont 12 points ou moins selon le moment. Après essais et erreurs, le score est de 10 points.
De plus, comme les données de précipitations sont décrites comme "1 heure avant" sur le site Web de l'Agence météorologique, elles sont considérées comme étant les données 1 heure avant la date et l'heure fixées dans l'indice.
Sur cette base, la méthode de traitement des données est la suivante.
python
#Obtenir l'indice des précipitations
ixs = df_rain.index
#Création d'un tableau pour l'acquisition de données
df = []
y = []
for i in range(len(ixs)-2):
#Obtenir la date et l'heure à partir de l'index
dt1 = ixs[i]
dt2 = ixs[i + 1]
dt3 = ixs[i + 2]
#Obtenez des données de niveau d'eau à partir de données de date et d'heure
d1 = df_level[dt1:dt2].level.tolist()
d2 = df_level[dt2:dt3].level.tolist()
if len(d1) > 10 and len(d2) > 10:
#Obtenez le niveau d'eau maximum après 1 heure
y.append(max(d2))
#Trier les données de niveau d'eau il y a une heure par ordre décroissant
d1.sort()
d1.reverse()
#Obtenez 10 points de données
d1 = d1[:10]
#Obtenez des données sur les précipitations
d1.append(df_rain.ix[i].rain)
#Obtenez un tableau de données d'entrée
df.append(d1)
#Convertir en bloc de données
df = pd.DataFrame(df)
df["y"] = y
#Vérifiez le nombre de données
print(df.shape)
Quand je l'ai exécuté, (6863, 12) était affiché et j'ai pu obtenir 6863 lignes de données.
Nous allons apprendre la première moitié 90% des données par apprentissage automatique et vérifier le résultat de l'apprentissage dans la seconde moitié 10%.
python
#Divisez les données en entrée et en sortie
y = df.pop("y").as_matrix().astype("int").flatten()
X = df.as_matrix().astype("float")
#Divisé pour utiliser 90% pour l'apprentissage et 10% pour la vérification
num = int(len(X) * 0.9)
print(len(X), num, len(X)-num)
X_train = X[:num]
X_test = X[num:]
y_train = y[:num]
y_test = y[num:]
#Définir une forêt aléatoire comme modèle d'apprentissage
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor(random_state=42)
#Apprentissage et vérification
model.fit(X_train, y_train)
result = model.predict(X_test)
#But
print(model.score(X_test,y_test))
Quand je l'ai exécuté, la précision de la prédiction était "0,952915078747".
Je ne suis pas sûr des chiffres, alors dessinons un graphique.
python
pp = pd.DataFrame({'act': np.array(y_test), "pred": np.array(result), "rain": X_test[:,-1]})
pp.rain = pp.rain * 5
plt.figure(figsize=(15,5))
plt.ylim(0,250)
plt.plot(pp)
Le bleu est le niveau d'eau réel, l'orange est le niveau d'eau prévu, et il se chevauche tellement que la ligne bleue est à peine visible (^ - ^)
Hou la la!
Maintenant, changeons la quantité de précipitations du niveau de l'eau à un certain moment et prédisons le niveau de l'eau une heure plus tard.
python
import random
#Index de sélection aléatoire
i = random.randint(0,len(df))
d = df.ix[i].as_matrix().tolist()
print(d)
#Obtenir un tableau de test
df_test = []
#Créez des données de test en modifiant la quantité de précipitations de 0 à 20
for i in range(21):
temp = d[:10]
temp.append(i)
df_test.append(temp)
#Prévoir
test = model.predict(np.array(df_test).astype("float"))
#affichage graphique
plt.plot(test)
Les données utilisées étaient les valeurs suivantes.
python
[150.0, 149.0, 149.0, 148.0, 147.0, 147.0, 147.0, 146.0, 146.0, 146.0, 8.0, 147.0]
Le graphique du résultat de la prédiction est le suivant.
L'axe X représente les précipitations et l'axe Y le niveau d'eau. En regardant ce graphique, bien que le niveau d'eau augmente progressivement proportionnellement aux précipitations, il monte brusquement après 10 mm et tombe à 13 mm. ..
J'ai essayé quelques autres tests, mais tous avaient un graphique légèrement déformé. Même si la précision de prédiction des données de séries chronologiques est élevée, cela n'est pas utile ... (-_-;)
Je pensais que le niveau d'eau augmenterait à mesure que la quantité de précipitations augmenterait, mais la prédiction des données de test était un peu différente de ce à quoi je m'attendais, et elle n'a pas augmenté uniformément. Ceci est probablement dû au fait qu'il n'est pas possible de prédire correctement ce qui n'est pas inclus dans les données d'entraînement.
Très bien, considérons la méthode suivante dans cet esprit!
Essayons maintenant un algorithme récemment populaire. Le processus jusqu'au traitement des données est le même et la partie apprentissage automatique est modifiée comme suit.
À propos, le réseau de neurones est également connu sous le nom de perceptron multicouche. De plus, comme le réseau de neurones gère principalement les valeurs numériques de -1 à 1, il normalise les données d'apprentissage.
python
#Divisez les données en entrée et en sortie
y = df.pop("y").as_matrix().astype("int").flatten()
X = df.as_matrix().astype("float")
#Divisé pour utiliser 90% pour l'apprentissage et 10% pour la vérification
num = int(len(X) * 0.9)
print(len(X), num, len(X)-num)
X_train = X[:num]
X_test = X[num:]
y_train = y[:num]
y_test = y[num:]
#Normalisation des données
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
#Définir un réseau neuronal comme modèle d'entraînement
from sklearn.neural_network import MLPRegressor
model = MLPRegressor(random_state=42)
#Apprentissage et vérification
model.fit(X_train, y_train)
result = model.predict(X_test)
#But
print(model.score(X_test,y_test))
Lorsqu'elle est exécutée, la précision de la prédiction est "0,947163962045", ce qui est un peu pire que la forêt aléatoire (-_-;)
Mais pour le moment, j'essaierai jusqu'au bout.
python
import random
#Index de sélection aléatoire
i = random.randint(0,len(df))
d = df.ix[i].as_matrix().tolist()
print(d)
df_test = []
#Créez des données de test en modifiant la quantité de précipitations de 0 à 20
for i in range(21):
temp = d[:10]
temp.append(i)
df_test.append(temp)
#Normalisation des données d'entrée
d = scaler.transform(np.array(df_test).astype("float"))
#Prévoir
test = model.predict(d)
plt.plot(test)
Je vais essayer.
[54.0, 54.0, 54.0, 53.0, 53.0, 53.0, 53.0, 53.0, 53.0, 53.0, 0.0, 53.0]
Kita --------! !!
Le réseau neuronal est incroyable! !!
Merci à toutes les personnes impliquées dans l'open data à Sabae City pour leurs précieuses données. Nous sommes impatients de travailler avec vous à l'avenir.
Nous avons publié un document qui résume les données de Jupyter Notebook qui ont exécuté le contenu ci-dessus, veuillez donc vous y référer également.
Recommended Posts