数据读取
气温预测的任务目标就是使用一份天气相关数据来预测某一天的最高温度,属于回归任务,首先观察一下数据集∶
# 数据读取
import pandas as pd
features = pd.read_csv('data/temps.csv')
features.head(5)
该项目实战主要完成以下 3 项任务。
- 使用随机森林算法完成基本建模任务∶包括数据预处理、特征展示、完成建模并进行可视化展示分析。
- 分析数据样本量与特征个数对结果的影响∶在保证算法一致的前提下,增加数据样本个数,观察结果变化。重新考虑特征工程,引入新特征后,观察结果走势。
- 对随机森林算法进行调参,找到最合适的参数∶掌握机器学习中两种经典调参方法,对当前模型选择最合适的参数。
数据可视化与预处理
输出结果显示该数据一共有348条记录,每个样本有9个特征。如果想进一步观察各个指标的统计特性,可以用 .describe()展示∶
# 统计指标
features.describe()
其中包括了各个列的数量,如果有缺失数据,数量就有所减少,这里因为并不存在缺失值,所以各个列的数量值就都是348了,均值,标准差,最大最小值等指标在这里就都显示出来了。 对于时间数据,我们也可以进行一些转换,目的就是有些工具包在绘图或者计算的过程中,需要标准的时间格式:
# 处理时间数据
import datetime
# 分别得到年,月,日
years = features['year']
months = features['month']
days = features['day']
# datetime格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]
为了更直观地观察数据,最简单有效的办法就是画图展示,首先导入Matplotlib 工具包,再选择一个合适的风格(其实风格差异并不是很大)∶
# 准备画图
import matplotlib.pyplot as plt
%matplotlib inline
# 指定默认风格
plt.style.use('fivethirtyeight')
接着我们设计画图的布局,这里我们需要展示4项指标,分别为最高气温的标签值,前天,昨天,朋友预测的气温最高值。既然是4个图,那不妨就2*2的规模来画吧,这样会更清晰一点,对每个图再指定好其名字和坐标轴含义就可以了:
# 设置布局
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, figsize = (10,10))
# 设置下方日期文字显示倾斜度
fig.autofmt_xdate(rotation = 45)
# 标签值
ax1.plot(dates,features['actual'])
ax1.set_xlabel(''); ax1.set_ylabel('Temperature'); ax1.set_title('Max Temp')
# 昨天
ax2.plot(dates, features['temp_1'])
ax2.set_xlabel(''); ax2.set_ylabel('Temperature'); ax2.set_title('Previous Max Temp')
# 前天
ax3.plot(dates, features['temp_2'])
ax3.set_xlabel('Date'); ax3.set_ylabel('Temperature'); ax3.set_title('Two Days Prior Max Temp')
# 我的逗逼朋友
ax4.plot(dates, features['friend'])
ax4.set_xlabel('Date'); ax4.set_ylabel('Temperature'); ax4.set_title('Friend Estimate')
# tight_layout会自动调整子图参数,使之填充整个图像区域。这是个实验特性,可能在一些情况下不工作。它仅仅检查坐标轴标签、刻度标签以及标题的部分。
plt.tight_layout(pad=1)
各项指标看起来都还算正常,由于是国外的天气数据所以跟咱们的统计标准有些区别。接下来就要考虑数据预处理问题了,原始数据中在week列中并不是一些数值特征,而是表示周几的字符串,这些计算机可不认识,需要我们来转换一下:
# 独热编码
features = pd.get_dummies(features)
features.head(5)
这样就完成了数据集中属性值的预处理工作,默认会把所有属性值都转换成独热编码的格式,并且还帮我们自动添加了后缀看起来更清晰了。
这里我们其实也可以按照自己的方式来设置编码特征的名字的,如果大家遇到了一个不太熟悉的函数,想看一下其中的细节,有一个更直接的方法就是在notebook当中直接调help工具来看一下它的API文档,下面返回的就是其细节介绍,不光有各个参数说明,还有一些小例子,建议大家在使用的过程中一定要养成多练多查的习惯,查找解决问题的方法也是一个很重要的技能:
print (help(pd.get_dummies))
Help on function get_dummies in module pandas.core.reshape.reshape:
get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False, dtype=None) -> 'DataFrame'
Convert categorical variable into dummy/indicator variables.
Parameters
----------
data : array-like, Series, or DataFrame
Data of which to get dummy indicators.
prefix : str, list of str, or dict of str, default None
String to append DataFrame column names.
Pass a list with length equal to the number of columns
when calling get_dummies on a DataFrame. Alternatively, `prefix`
can be a dictionary mapping column names to prefixes.
prefix_sep : str, default '_'
If appending prefix, separator/delimiter to use. Or pass a
list or dictionary as with `prefix`.
dummy_na : bool, default False
Add a column to indicate NaNs, if False NaNs are ignored.
columns : list-like, default None
Column names in the DataFrame to be encoded.
If `columns` is None then all the columns with
`object` or `category` dtype will be converted.
sparse : bool, default False
Whether the dummy-encoded columns should be backed by
a :class:`SparseArray` (True) or a regular NumPy array (False).
drop_first : bool, default False
Whether to get k-1 dummies out of k categorical levels by removing the
first level.
dtype : dtype, default np.uint8
Data type for new columns. Only a single dtype is allowed.
.. versionadded:: 0.23.0
Returns
-------
DataFrame
Dummy-coded data.
See Also
--------
Series.str.get_dummies : Convert Series to dummy codes.
Examples
--------
>>> s = pd.Series(list('abca'))
>>> pd.get_dummies(s)
a b c
0 1 0 0
1 0 1 0
2 0 0 1
3 1 0 0
>>> s1 = ['a', 'b', np.nan]
>>> pd.get_dummies(s1)
a b
0 1 0
1 0 1
2 0 0
>>> pd.get_dummies(s1, dummy_na=True)
a b NaN
0 1 0 0
1 0 1 0
2 0 0 1
>>> df = pd.DataFrame({'A': ['a', 'b', 'a'], 'B': ['b', 'a', 'c'],
... 'C': [1, 2, 3]})
>>> pd.get_dummies(df, prefix=['col1', 'col2'])
C col1_a col1_b col2_a col2_b col2_c
0 1 1 0 0 1 0
1 2 0 1 1 0 0
2 3 1 0 0 0 1
>>> pd.get_dummies(pd.Series(list('abcaa')))
a b c
0 1 0 0
1 0 1 0
2 0 0 1
3 1 0 0
4 1 0 0
>>> pd.get_dummies(pd.Series(list('abcaa')), drop_first=True)
b c
0 0 0
1 1 0
2 0 1
3 0 0
4 0 0
>>> pd.get_dummies(pd.Series(list('abc')), dtype=float)
a b c
0 1.0 0.0 0.0
1 0.0 1.0 0.0
2 0.0 0.0 1.0
标签与数据格式转换
# 数据与标签
import numpy as np
# 标签
labels = np.array(features['actual'])
# 在特征中去掉标签
features= features.drop('actual', axis = 1)
# 名字单独保存一下,以备后患
feature_list = list(features.columns)
# 转换成合适的格式
features = np.array(features)
训练集与测试集
# 数据集切分
from sklearn.model_selection import train_test_split
train_features, test_features, train_labels, test_labels = train_test_split(features, labels, test_size = 0.25,
random_state = 42)
print('训练集特征:', train_features.shape)
print('训练集标签:', train_labels.shape)
print('测试集特征:', test_features.shape)
print('测试集标签:', test_labels.shape)
训练集特征: (261, 14)
训练集标签: (261,)
测试集特征: (87, 14)
测试集标签: (87,)