当前位置:   article > 正文

Python 机器学习 随机森林 天气最高温度预测任务(一)_python+sklearn温度预测

python+sklearn温度预测

我们要完成三项任务:

  • 使用随机森林算法完成基本建模任务

基本任务需要我们处理数据,观察特征,完成建模并进行可视化展示分析

  • 观察数据量与特征个数对结果影响

在保证算法一致的前提下,加大数据个数,观察结果变换。重新考虑特征工程,引入新特征后观察结果走势。

  • 对随机森林算法进行调参,找到最合适的参数

掌握机器学习中两种经典调参方法,对当前模型进行调节

  1. # 数据读取
  2. import pandas as pd
  3. features = pd.read_csv('data/temps.csv')
  4. features.head(5)

 

数据表中

  • year,moth,day,week分别表示的具体的时间
  • temp_2:前天的最高温度值
  • temp_1:昨天的最高温度值
  • average:在历史中,每年这一天的平均最高温度值
  • actual:这就是我们的标签值了,当天的真实最高温度
  • friend:这一列可能是凑热闹的,你的朋友猜测的可能值,咱们不管它就好了

 数据大小

  1. print('The shape of our features is:', features.shape)
  2. # 统计指标
  3. features.describe()

  1. # 处理时间数据
  2. import datetime
  3. # 分别得到年,月,日
  4. years = features['year']
  5. months = features['month']
  6. days = features['day']
  7. # datetime格式
  8. dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
  9. dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]

数据展示 

  1. # 准备画图
  2. import matplotlib.pyplot as plt
  3. %matplotlib inline
  4. # 指定默认风格
  5. plt.style.use('fivethirtyeight')
  6. # 设置布局
  7. fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, figsize = (10,10))
  8. fig.autofmt_xdate(rotation = 45)
  9. # 标签值
  10. ax1.plot(dates, features['actual'])
  11. ax1.set_xlabel(''); ax1.set_ylabel('Temperature'); ax1.set_title('Max Temp')
  12. # 昨天
  13. ax2.plot(dates, features['temp_1'])
  14. ax2.set_xlabel(''); ax2.set_ylabel('Temperature'); ax2.set_title('Previous Max Temp')
  15. # 前天
  16. ax3.plot(dates, features['temp_2'])
  17. ax3.set_xlabel('Date'); ax3.set_ylabel('Temperature'); ax3.set_title('Two Days Prior Max Temp')
  18. # 我的逗逼朋友
  19. ax4.plot(dates, features['friend'])
  20. ax4.set_xlabel('Date'); ax4.set_ylabel('Temperature'); ax4.set_title('Friend Estimate')
  21. plt.tight_layout(pad=2)

各项指标看起来都还算正常,由于是国外的天气数据所以跟咱们的统计标准有些区别。接下来就要考虑数据预处理问题了,原始数据中在week列中并不是一些数值特征,而是表示周几的字符串,这些计算机可不认识,需要我们来转换一下:

数据预处理

  1. # 独热编码
  2. features = pd.get_dummies(features)
  3. features.head(5)

这样就完成了数据集中属性值的预处理工作,默认会把所有属性值都转换成独热编码的格式,并且还帮我们自动添加了后缀看起来更清晰了,这里我们其实也可以按照自己的方式来设置编码特征的名字的,如果大家遇到了一个不太熟悉的函数,想看一下其中的细节,有一个更直接的方法就是在notebook当中直接调help工具来看一下它的API文档,下面返回的就是其细节介绍,不光有各个参数说明,还有一些小例子,建议大家在使用的过程中一定要养成多练多查的习惯,查找解决问题的方法也是一个很重要的技能:

标签与数据格式转换

  1. # 数据与标签
  2. import numpy as np
  3. # 标签
  4. labels = np.array(features['actual'])
  5. # 在特征中去掉标签
  6. features= features.drop('actual', axis = 1)
  7. # 名字单独保存一下,以备后患
  8. feature_list = list(features.columns)
  9. # 转换成合适的格式
  10. features = np.array(features)

 训练集与测试集

  1. # 数据集切分
  2. from sklearn.model_selection import train_test_split
  3. train_features, test_features, train_labels, test_labels = train_test_split(features, labels, test_size = 0.25,
  4. random_state = 42)

建立一个基础的随机森林模型 

  1. # 导入算法
  2. from sklearn.ensemble import RandomForestRegressor
  3. # 建模
  4. rf = RandomForestRegressor(n_estimators= 1000, random_state=42)
  5. # 训练
  6. rf.fit(train_features, train_labels)

由于数据样本量还是非常小的,所以很快就可以得到结果了,这里我们先用MAPE指标来进行评估,也就是平均绝对百分误差,其实对于回归任务,评估方法还是比较多,给大家列出来几种,很简单就可以实现出来,也可以选择其他指标来进行评估: 

  1. # 预测结果
  2. predictions = rf.predict(test_features)
  3. # 计算误差
  4. errors = abs(predictions - test_labels)
  5. # mean absolute percentage error (MAPE)
  6. mape = 100 * (errors / test_labels)
  7. print ('MAPE:',np.mean(mape))

MAPE指标

可视化展示树

  1. # 导入所需工具包
  2. from sklearn.tree import export_graphviz
  3. import pydot #pip install pydot
  4. # 拿到其中的一棵树
  5. tree = rf.estimators_[5]
  6. # 导出成dot文件
  7. export_graphviz(tree, out_file = 'tree.dot', feature_names = feature_list, rounded = True, precision = 1)
  8. # 绘图
  9. (graph, ) = pydot.graph_from_dot_file('tree.dot')
  10. # 展示
  11. graph.write_png('tree.png');
  12. print('The depth of this tree is:', tree.tree_.max_depth)
  13. # 限制一下树模型
  14. rf_small = RandomForestRegressor(n_estimators=10, max_depth = 3, random_state=42)
  15. rf_small.fit(train_features, train_labels)
  16. # 提取一颗树
  17. tree_small = rf_small.estimators_[5]
  18. # 保存
  19. export_graphviz(tree_small, out_file = 'small_tree.dot', feature_names = feature_list, rounded = True, precision = 1)
  20. (graph, ) = pydot.graph_from_dot_file('small_tree.dot')
  21. graph.write_png('small_tree.png');

 

 

特征重要性

  1. # 得到特征重要性
  2. importances = list(rf.feature_importances_)
  3. # 转换格式
  4. feature_importances = [(feature, round(importance, 2)) for feature, importance in zip(feature_list, importances)]
  5. # 排序
  6. feature_importances = sorted(feature_importances, key = lambda x: x[1], reverse = True)
  7. # 对应进行打印
  8. [print('Variable: {:20} Importance: {}'.format(*pair)) for pair in feature_importances]

用最重要的特征再来试试 

  1. # 选择最重要的那两个特征来试一试
  2. rf_most_important = RandomForestRegressor(n_estimators= 1000, random_state=42)
  3. # 拿到这俩特征
  4. important_indices = [feature_list.index('temp_1'), feature_list.index('average')]
  5. train_important = train_features[:, important_indices]
  6. test_important = test_features[:, important_indices]
  7. # 重新训练模型
  8. rf_most_important.fit(train_important, train_labels)
  9. # 预测结果
  10. predictions = rf_most_important.predict(test_important)
  11. errors = abs(predictions - test_labels)
  12. # 评估结果
  13. mape = np.mean(100 * (errors / test_labels))
  14. print('mape:', mape)
  15. # 转换成list格式
  16. x_values = list(range(len(importances)))
  17. # 绘图
  18. plt.bar(x_values, importances, orientation = 'vertical')
  19. # x轴名字
  20. plt.xticks(x_values, feature_list, rotation='vertical')
  21. # 图名
  22. plt.ylabel('Importance'); plt.xlabel('Variable'); plt.title('Variable Importances');

 预测值与真实值之间的差异

  1. # 日期数据
  2. months = features[:, feature_list.index('month')]
  3. days = features[:, feature_list.index('day')]
  4. years = features[:, feature_list.index('year')]
  5. # 转换日期格式
  6. dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
  7. dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]
  8. # 创建一个表格来存日期和其对应的标签数值
  9. true_data = pd.DataFrame(data = {'date': dates, 'actual': labels})
  10. # 同理,再创建一个来存日期和其对应的模型预测值
  11. months = test_features[:, feature_list.index('month')]
  12. days = test_features[:, feature_list.index('day')]
  13. years = test_features[:, feature_list.index('year')]
  14. test_dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
  15. test_dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in test_dates]
  16. predictions_data = pd.DataFrame(data = {'date': test_dates, 'prediction': predictions})
  17. # 真实值
  18. plt.plot(true_data['date'], true_data['actual'], 'b-', label = 'actual')
  19. # 预测值
  20. plt.plot(predictions_data['date'], predictions_data['prediction'], 'ro', label = 'prediction')
  21. plt.xticks(rotation = '60');
  22. plt.legend()
  23. # 图名
  24. plt.xlabel('Date'); plt.ylabel('Maximum Temperature (F)'); plt.title('Actual and Predicted Values');

看起来还可以,这个走势我们的模型已经基本能够掌握了,接下来我们要再深入到数据中了,考虑几个问题: 1.如果可以利用的数据量增大,会对结果产生什么影响呢? 2.加入新的特征会改进模型效果吗?此时的时间效率又会怎样?

数据集:https://aistudio.baidu.com/aistudio/datasetdetail/124549icon-default.png?t=LBL2https://aistudio.baidu.com/aistudio/datasetdetail/124549评论区的HXD发布在了paddle上面供大家取用,感谢@王多头发

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/600494
推荐阅读
相关标签
  

闽ICP备14008679号