文章目录
- 算法简介
- 解决问题
- 获取数据集
- 探索性数据分析
- 查看数据集字段信息
- 查看数据集综合统计结果
- 查看特征值随时间变化趋势
- 数据预处理
- 处理缺失数据
- 字符列编码
- 数据集分割
- 训练集、验证集、测试集
- 数据集分割
- 构建模型并训练
- 结果分析与评估
- 进一步优化
- 实际使用
- 经验总结
算法简介
随机森林(RandomForest)算法是十大经典机器学习算法之一,用关于解决机器学习的回归和分类问题。
随机森林是一种应用广泛的集成学习方法,它建立了很多决策树并让这些树互相协作,得出最终的预测结果,使其具有很好的鲁棒性和泛化能力。
解决问题
使用数据集,训练随机森林温度预测模型,并用于实际温度预测。
获取数据集
数据集来源于https://www.kaggle.com/ 网站,点击datasets,搜索随机森林气温预测即可,这里挂上链接
https://www.kaggle.com/datasets/silveryzz/temperature-prediction-random-forest/code
具体下载方式参见其他文章
Kaggle网站使用问题记录
探索性数据分析
查看数据集字段信息
import pandas as pd
df = pd.read_csv('D:/xxx/人工智能/数据集/temps_extended.csv')
#由于数据集比较多,先只取2016年的数据来用,且不用ws_1、prcp_1、snwd_1三个特征值,后续优化对比会使用它们
df = df[df['year'] == 2016]
df = df.loc[:,~df.columns.isin(['ws_1','prcp_1','snwd_1'])]
#查看前5行字段
print(df.head())
year month day weekday temp_2 temp_1 average actual friend
1825 2016 1 1 Fri 42 42 45.6 46 53
1826 2016 1 2 Sat 42 46 45.7 42 33
1827 2016 1 3 Sun 46 42 45.8 40 52
1828 2016 1 4 Mon 42 40 45.9 38 53
1829 2016 1 5 Tues 40 38 46.0 46 60
需要预测的是actual 列(温度最大值),
特征列 temp_1(前一天温度),temp_2(前两天温度),friend(理解为一个系数),
除了actual,其余列都可以作为特征值,由于随机森林可以随机选择特征值去形成多棵决策树,所以暂不用人工去筛选使用哪些特征值。
查看数据集综合统计结果
print(df.describe())
year month day temp_2 temp_1 average \
count 365.0 365.000000 365.000000 365.000000 365.000000 365.000000
mean 2016.0 6.526027 15.720548 62.567123 62.591781 60.292603
std 0.0 3.452584 8.808321 12.656884 12.631960 10.742717
min 2016.0 1.000000 1.000000 33.000000 33.000000 45.100000
25% 2016.0 4.000000 8.000000 53.000000 53.000000 50.100000
50% 2016.0 7.000000 16.000000 62.000000 62.000000 58.800000
75% 2016.0 10.000000 23.000000 71.000000 71.000000 70.200000
max 2016.0 12.000000 31.000000 95.000000 95.000000 77.400000 actual friend
count 365.000000 365.000000
mean 62.572603 59.950685
std 12.658807 15.557154
min 33.000000 26.000000
25% 53.000000 48.000000
50% 62.000000 60.000000
75% 71.000000 71.000000
max 95.000000 95.000000
可以看到数据count(总条数),mean(均值),std(标准差),min(最小值),25%(25%处的值),50%(50%处的值),75%(75%处的值),max(最大值),其中,统计是只针对数值列的,非数值列会自动丢弃。
查看特征值随时间变化趋势
由于数据集是基于时间变化的,所以想看下列actual、temp_1,temp_2,friend随着时间变化趋势
# 由于日期是分散到多个列的,所以先转化成日期格式
import datetime
years = df['year']
months = df['month']
days = df['day']
#使用列表推导式拼接日期字符
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]
print(dates[:4])
#绘制趋势图
import matplotlib.pyplot as pltfig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2,ncols=2,figsize=(10,10))
ax1.plot(dates,df['actual'])
ax1.set_xlabel('Date')
ax1.set_ylabel('Actual')
ax1.set_title('最大温度')ax2.plot(dates,df['temp_1'])
ax2.set_xlabel('Date')
ax2.set_ylabel('temp_1')
ax2.set_title('前一天最大温度')ax3.plot(dates,df['temp_1'])
ax3.set_xlabel('Date')
ax3.set_ylabel('temp_2')
ax3.set_title('前两天最大温度')ax4.plot(dates,df['friend'])
ax4.set_xlabel('Date')
ax4.set_ylabel('friend')
ax4.set_title('friend')
plt.rcParams['font.sans-serif']=['FangSong']plt.show()
数据预处理
处理缺失数据
# 查看是否有缺失数据
print(df.isnull().any())
year False
month False
day False
weekday False
temp_2 False
temp_1 False
average False
actual False
friend False
dtype: bool
发现每列为false,并无缺失值。
字符列编码
# 数据预处理 机器学习算法只接受数值变量 ,对week列进行独热编码,将字符转成数字
df = pd.get_dummies(df)
print(df.head())
year month day temp_2 temp_1 average actual friend weekday_Fri \
1825 2016 1 1 42 42 45.6 46 53 True
1826 2016 1 2 42 46 45.7 42 33 False
1827 2016 1 3 46 42 45.8 40 52 False
1828 2016 1 4 42 40 45.9 38 53 False
1829 2016 1 5 40 38 46.0 46 60 False weekday_Mon weekday_Sat weekday_Sun weekday_Thurs weekday_Tues \
1825 False False False False False
1826 False True False False False
1827 False False True False False
1828 True False False False False
1829 False False False False True weekday_Wed
1825 False
1826 False
1827 False
1828 False
1829 False
数据集分割
训练集、验证集、测试集
先来记录下三个数据集的用途及分割经验:
训练集是用来训练模型的数据集
验证集用于验证模型性能的数据集,调整模型的超参数
测试集用于评估模型性能的数据集
也就是说训练集和验证集是用来训练生成模型的,测试集是用来评估模型性能好坏的
分割经验: 第一次分割(基于全量数据集) 训练集80% 测试集20%
第二次分割(基于第一次分割中的训练集)训练集80% 验证集20%
数据集分割
回到该项目,由于随机森林没有超参数需要优化(目前认知),所以只需要分割一次,训练集80% 测试集20%
#取出特征值和待预测标签值(纵向分割)
features = df.loc[:,df.columns != 'actual']
labels = df.loc[:,'actual']# 分割训练集与测试集
from sklearn.model_selection import train_test_split
train_features,test_features,train_labels,test_labels = train_test_split(features,labels,test_size=0.20,random_state=42)
其中 test_size=0.20表示训练集80%测试集20%
random_state=42 无特别含义,每次保持不变就行,由于分割是随机分割的,为了保证每次跑程序都能得到一样的结果,设置该字段,不然每次分割的训练数据和测试数据都不同,结果也会变化,不利于后续模型优化。
构建模型并训练
# 建立随机森林模型
from sklearn.ensemble import RandomForestRegressor
#建立模型
rf = RandomForestRegressor(n_estimators=1000,random_state=42)
# 训练模型
rf.fit(train_features,train_labels)
构建模型直接使用sklearn提供的随机森林模型库;
其中, n_estimators=1000 迭代次数,即随机森林中决策树的数量
random_state=42 同上
结果分析与评估
# 测试
pre = rf.predict(test_features)
import numpy as np
errors = abs(pre-test_labels)
print('误差是:', round(np.mean(errors), 2))
score = rf.score(test_features, test_labels)
print('score:', score)import sklearn.metrics as sm
print('MAE是:', sm.mean_absolute_error(pre, test_labels))
print('MSE是:', sm.mean_squared_error(pre, test_labels))
print('RMSE是:', np.sqrt(sm.mean_squared_error(pre, test_labels)))
误差是: 4.16
score: 0.843355562598595
MAE是: 4.16409589041096
MSE是: 26.98129152054795
RMSE是: 5.194351886477075
结果分析与评估:
score是得分,求得的是模型预测的精确度
MAE是 平均绝对误差,反映预测值的偏离程度。即平均误差
MSE是均方误差,
RMSE是均方根误差,值越小,模型预测能力越强,用于评估回归模型预测精度
进一步优化
优化思路有,增加特征值,增大训练数据量
下面试下增大数据量,使用所有年份数据量进行模型训练和结果评估,结果如下:
score是: 3.76
得分: 0.8561829315691637
MAE是: 3.764268792710706
MSE是: 23.038871845102502
RMSE是: 4.799882482426263
可以看到评估参数都得到有一定提升。
下面试下增加特征值,增加使用一开始去掉的三个特征值进行模型训练和结果评估,结果如下:
score是: 3.72
得分: 0.8591014577119477
MAE是: 3.719054669703872
MSE是: 22.571336589977218
RMSE是: 4.750930076308976
可以看到性能也有一定提升。
实际使用
把模型训练好,就可以使用其进行温度预测了
经验总结
1 数据集分割比例选取80%训练集 20%测试集 ,这个比例就是经过多次实践最终大家都认可这个比例训练的模型效果比较好,没有啥理论依据