Python实战09:随机森林算法在天气分类的应用(入门)

📮 求内推

👩 个人简介:听障人,96年,计算机专业(本科),从事数据分析工作
🛠 语言与工具:包括但不限于Python、SQL、tableaubi、finebi、powerbi。
💻 期望岗位:数据分析、数据运营、报表开发等(hc偏技术方向)
📍 期望城市:杭州

背景说明

本数据集是人工合成的天气数据,旨在模拟用于分类任务的天气信息,并将其分为雨天、晴天、多云和雪天四种类型。
本数据集专为数据科学学习者、学生及初学者设计,用于实践数据预处理、特征工程、异常值检测方法、探索分类算法性能及模型评估。
本数据集为人工生成,不包含真实世界天气数据,其包含的异常值旨在提供实践异常检测和处理的机会。

数据说明

字段说明
Temperature(数值型)温度(单位:摄氏度),范围从极端寒冷到极端炎热
Humidity(数值型)湿度百分比,包括超过100%的异常值
Wind Speed(数值型)风速(单位:km/h),范围包括不切实际的高值
Precipitation(百分比)(数值型降水量百分比,包括异常值
Cloud Cover(类别型)云量描述
Atmospheric Pressure(数值型)大气压力(hPa),覆盖广泛范围
UV Index(数值型)紫外线指数,表示紫外线辐射的强度
Season(类别型)数据记录时的季节
Visibility(数值型)能见度(单位:km),包括非常低或非常高的值
Location(类别型)数据记录的地点
Weather Type(类别型)分类目标变量,表示天气类型;雨天(Rainy),晴天(Sunny),多云(Cloudy),雪天(Snowy)

问题描述

特征相关性分析
特征重要性分析
天气类型预测及模型评估

数据概览与清洗

import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np

from sklearn.model_selection import train_test_split,cross_val_score
from sklearn.feature_selection import SelectFromModel # 自动选择特征
from sklearn.ensemble import RandomForestClassifier # 随机森林算法
from sklearn.metrics import accuracy_score,recall_score, precision_score, roc_auc_score, classification_report # 评估模型性能
df = pd.read_csv(r'/home/mw/input/07292689/weather_classification_data.csv')

# 修改列名,加上该列名的单位
df.rename(columns=({'Temperature':'Temperature(℃)','Humidity':'Humidity(%)','Wind Speed':'Wind Speed(km/h)','Atmospheric Pressure':'Atmospheric Pressure(hPa)'}),inplace=True)
display(df.head())

print('-'*50)
print('数据集大小:',df.shape)
print('-'*50)
print('数据集存在重复值个数:',df.duplicated().sum())
print('-'*50)
print('数据集存在空值个数:',df.isna().sum())
print('-'*50)
print('数据集信息:',df.info())
print('-'*50)
display('数据集的统计描述:',df.describe(include='all'))
 

  • Temperature: 世界上有记录以来地球表面的最高气温被认为是56.7摄氏度,那么我们设超过60摄氏度的温度为异常。
  • Humidity(%): 湿度超过100%的为异常。
  • Precipitation (%): 和湿度同理。
  • Atmospheric Pressure: 最小值800 aPh通常在非常强烈的低气压系统例如在强烈的风暴中心中才会见到,而最大值1199 aPh在自然环境中几乎不可能出现,实际上气压很少超过1050 aPh。那么我们设超过1050 aPh的气压为异常。

以上四个异常情况需要处理。注:以上异常情况的判断源于AI。

# 剔除异常值以更新数据集
df = df[(df['Temperature(℃)']<=60) & (df['Humidity(%)']<=100) & (df['Precipitation (%)']<=100) & (df['Atmospheric Pressure(hPa)']<=1050)]
df.describe(include='all')

ok,数据应该处理得干净了。接下来看看分类变量的唯一值及其计数。

# print([df[f].unique() for f in ['Cloud Cover','Season','Weather Type']])

for f in ['Cloud Cover','Season','Weather Type','Location']:
    display(df[f].value_counts().reset_index(name='count'))

特征相关性分析

corr_df = df.select_dtypes(include=[np.number]).corr().round(2)
# display(corr_df)

fig = px.imshow(corr_df,text_auto=True,aspect='auto') # 显示数据标签,自动调整图像的比例
fig.update_xaxes(side='top') # 将x轴标签放在顶部
fig.update_layout(width=1000,height=500)
fig.show()

  • Temperature与Precipitation之间存在显著的负相关性。这意味着温度较高时,降水量通常较少。
  • Temperature与UV Index之间存在显著的正相关性。这意味着温度较高时,紫外线强度也较强。
  • Humidity与Precipitation之间存在显著的正相关性。这意味着湿度较大时,降水量通常较多。
  • Humidity与UV Index之间存在显著的负相关性。这意味着湿度较高时,紫外线指数较低。
  • Humidity与Visibility之间存在显著的负相关性。这意味着湿度较高时,能见度通常较低。
  • Wind Speed与Precipitation之间存在显著的正相关性。这意味着风速较大时,降水量通常较多。但是需要注意的是,这种相关性并不一定意味着因果关系,因为风速和降水量可能受到其他因素的共同影响。
  • Precipitation与UV Index之间存在显著的负相关性。这意味着降水量较大时,紫外线指数较低。
  • Precipitation与Visibility之间存在显著的负相关性。这意味着降水量较大时,能见度通常较低。
  • Atmospheric Pressure与Temperature之间存在微弱的正相关性。着意味着温度较高时,大气压力略微升高。不过需要注意的是,这种相关性较弱,而且实际情况下这两者的关系可能更加复杂。
  • UV Index与Visibility之间存在显著的正相关性。这意味着紫外线指数较高时,能见度通常较好。

天气类型预测及模型评估

前期准备工作

ndf = df.copy() 

# 对分类变量进行独热编码处理
cat_list = ['Cloud Cover','Season','Location']
ndf = pd.get_dummies(ndf,columns=cat_list)
# display(ndf.head())

# 准备数据集
x = ndf.drop('Weather Type',axis=1) 
y = ndf['Weather Type']

# 划分数据集
x_train,x_test,y_train,y_test = train_test_split(x,y,test_size=0.2,random_state=42)

使用随机森林算法进行天气类型预测

# 选择模型并训练
rf_model = RandomForestClassifier()
rf_model.fit(x_train,y_train)

# 预测及预测效果
pre = rf_model.predict(x_test)
print(f'Model prediction accuracy:{accuracy_score(y_test,pre)*100:.2f}%')

# 使用训练好的模型输出特征重要性
feature_importances = rf_model.feature_importances_*100
f_importance_df = pd.DataFrame({'Feature':x.columns,'Importance':feature_importances})
f_importance_df = f_importance_df.sort_values(by='Importance',ascending=False,ignore_index=True)
display(f_importance_df)
Model prediction accuracy:94.50%

使用 SelectFromModel 选择特征并进行天气类型预测

# 使用SelecFromModel选择特征
# 创建SelectFromModel创建对象,并使用随机森林分类器作为基础估计器。threshold={'median'|'mean'}表示选择特征重要性高于中位数/平均数的特征。
selector = SelectFromModel(RandomForestClassifier(),threshold='median') 
selector.fit(x_train,y_train) # 训练

# 选择特征
# 使用transform方法从训练集中选择特征
x_train_selector = selector.transform(x_train)
x_test_selector = selector.transform(x_test)

# 重新训练模型
# 使用选择的特征重新训练随机森林分类器
rf_model_selected = RandomForestClassifier()
rf_model_selected.fit(x_train_selector,y_train)

# 预测
pre_sel = rf_model_selected.predict(x_test_selector)

# 使用训练好的模型输出特征重要性
feature_importances_sel = rf_model_selected.feature_importances_*100
# selector.get_support()表示返回一个布尔数组,表示哪些特征被留下来,传递给x.columns来筛选那些被标记为True的特征名。
selected_feature_names = x.columns[selector.get_support()] 
f_sel_df = pd.DataFrame({'Feature':selected_feature_names,'Importance':feature_importances_sel})
f_sel_df = f_sel_df.sort_values(by='Importance',ascending=False,ignore_index=True)
display(f_sel_df)

# 评估模型
# 预测准确率
print(f'Model prediction accuracy:{accuracy_score(y_test,pre_sel)*100:.2f}%')
# score是模型的一个方法,大多数模型都有该方法。而上面的accuracy_score是sklearn的一个函数,适用于所有模型。
# print(f'score:{rf_model_selected.score(x_test_selector,y_test)}')

# 交叉验证
# N折交叉验证(5-fold cross-validation)的意思是将数据集分成N个相等的部分(称为“折”),然后进行N次迭代,在每次迭代中,选择其中一个部分作为测试集,其余N-1个部分组成训练集。这样,每个部分都会被用作一次测试集,而其余部分则作为训练集。
# 使用cross_val_score函数进行5折交叉验证,scoring='accuracy'表示使用准确率作为评估指标。
cv_scores = cross_val_score(rf_model_selected,x_train_selector,y_train,cv=5,scoring='accuracy')
# 计算五次交叉验证的平均准确率
mean_av_scores = cv_scores.mean()*100
print(f'Mean cross-validation accuracy:{mean_av_scores:.2f}%')

# 精确率
# precision_score函数默认是为二分类问题设计的。
# 当目标变量是多分类时,需要指定一个合适的average参数来计算精度
# average='weighted'计算每个类别的精确度,然后按每个类别的支持度(即每个类别的实际出现次数)加权平均
precision = precision_score(y_test,pre_sel,average='weighted')*100
print(f'Model prediction precision:{precision:.2f}%')

# 召回率
recall = recall_score(y_test,pre_sel,average='weighted')*100
print(f'Model recall score:{recall:.2f}%')

# 分类报告
print()
report = classification_report(y_test,pre_sel)
print(report)

Model prediction accuracy:93.87%
Mean cross-validation accuracy:94.25%
Model prediction precision:93.95%
Model recall score:93.87%

小结

  • 第一个模型的预测准确率为94.41%,第二个模型的预测准确率约为94%左右。这两个准确率非常接近,表示特征选择并没有显著降低模型的性能。
  • 第二个模型的预测准确率约为94%左右,表明该模型在测试集上的预测表现很好。
  • 第二个模型的交叉验证准确率约为94%,表示该模型在不同数据子集上具有一致的表现。
  • 第二个模型的精确率和召回率均为94%,表示该模型不仅能够很好的预测正类(正确的天气类型),而且很少将非正类误判为正类。

接下来看看分类报告

Cloudy:

  • Precision (精确率): 0.94,意味着模型预测为多云的样本中有94%实际上是多云。
  • Recall (召回率): 0.92,意味着实际多云的样本中有92%被模型正确识别为多云。
  • F1-Score (F1分数): 0.93,是精确率和召回率的加权平均值。
  • Support (支持度): 635,即测试集中实际多云的样本总数。

其他类别,这里就不赘述了。本563,即测试集中实际晴天的样本总数。

总结

  • 从报告中可以看出,模型在四个天气类别上的性能非常好,精确率和召回率都很高,且接近一致。
  • 模型在预测多云和晴天时略显保守,召回率相对低一些,而在预测下雨和下雪时,则更加准确,具有较高的召回率。
  • 加权平均和宏平均的指标也都接近94%,意味着模型的整体性能良好,并且在不同类别间的性能差异不大。
  • 支持度的分布显示了每个类别的样本数量,这对理解性能指标的加权方式是有帮助的。
  • 18
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值