概述
本章是使用机器学习预测天气系列教程的第一部分,使用Python和机器学习来构建模型,根据从Weather Underground收集的数据来预测天气温度。该教程将由三个不同的部分组成,涵盖的主题是:
- 数据收集和处理(本文)
- 线性回归模型(第2章)
- 神经网络模型(第3章)
本教程中使用的数据将从Weather Underground的免费层API服务中收集。我将使用python的requests库来调用API,得到从2015年起Lincoln, Nebraska的天气数据。 一旦收集完成,数据将需要进行处理并汇总转成合适的格式,然后进行清理。
第二篇文章将重点分析数据中的趋势,目标是选择合适的特性并使用python的statsmodels和scikit-learn库来构建线性回归模型。 我将讨论构建线性回归模型,必须进行必要的假设,并演示如何评估数据特征以构建一个健壮的模型。 并在最后完成模型的测试与验证。
最后的文章将着重于使用神经网络。 我将比较构建神经网络模型和构建线性回归模型的过程,结果,准确性。
Weather Underground介绍
Weather Underground是一家收集和分发全球各种天气测量数据的公司。 该公司提供了大量的API,可用于商业和非商业用途。 在本文中,我将介绍如何使用非商业API获取每日天气数据。所以,如果你跟随者本教程操作的话,您需要注册他们的免费开发者帐户。 此帐户提供了一个API密钥,这个密钥限制,每分钟10个,每天500个API请求。
获取历史数据的API如下:
http://api.wunderground.com/api/API_KEY/history_YYYYMMDD/q/STATE/CITY.json
- API_KEY: 注册账户获取
- YYYYMMDD: 你想要获取的天气数据的日期
- STATE: 州名缩写
- CITY: 你请求的城市名
调用API
本教程调用Weather Underground API获取历史数据时,用到如下的python库。
名称 | 描述 | 来源 |
---|---|---|
datetime | 处理日期 | 标准库 |
time | 处理时间 | 标准库 |
collections | 使用该库的namedtuples来结构化数据 | 标准库 |
pandas | 处理数据 | 第三方 |
requests | HTTP请求处理库 | 第三方 |
matplotlib | 制图库 | 第三方 |
好,我们先导入这些库:
from datetime import datetime, timedelta
import time
from collections import namedtuple
import pandas as pd
import requests
import matplotlib.pyplot as plt
接下里,定义常量来保存API_KEY和BASE_URL,注意,例子中的API_KEY不可用,你要自己注册获取。代码如下:
API_KEY = '7052ad35e3c73564'
# 第一个大括号是API_KEY,第二个是日期
BASE_URL = "http://api.wunderground.com/api/{}/history_{}/q/NE/Lincoln.json"
然后我们初始化一个变量,存储日期,然后定义一个list,指明要从API返回的内容里获取的数据。然后定义一个namedtuple类型的变量DailySummary来存储返回的数据。代码如下:
target_date = datetime(2016, 5, 16)
features = ["date", "meantempm", "meandewptm", "meanpressurem", "maxhumidity", "minhumidity", "maxtempm",
"mintempm", "maxdewptm", "mindewptm", "maxpressurem", "minpressurem", "precipm"]
DailySummary = namedtuple("DailySummary", features)
定义一个函数,调用API,获取指定target_date开始的days天的数据,代码如下:
def extract_weather_data(url, api_key, target_date, days):
records = []
for _ in range(days):
request = BASE_URL.format(API_KEY, target_date.strftime('%Y%m%d'))
response = requests.get(request)
if response.status_code == 200:
data = response.json()['history']['dailysummary'][0]
records.append(DailySummary(
date=target_date,
meantempm=data['meantempm'],
meandewptm=data['meandewptm'],
meanpressurem=data['meanpressurem'],
maxhumidity=data['maxhumidity'],
minhumidity=data['minhumidity'],
maxtempm=data['maxtempm'],
mintempm=data['mintempm'],
maxdewptm=data['maxdewptm'],
mindewptm=data['mindewptm'],
maxpressurem=data['maxpressurem'],
minpressurem=data['minpressurem'],