您的位置:首页 > 科技 > IT业 > 机器学习/数据分析--通俗语言带你入门随机森林,并用随机森林进行天气分类预测(Accuracy为0.92)

机器学习/数据分析--通俗语言带你入门随机森林,并用随机森林进行天气分类预测(Accuracy为0.92)

2024/12/23 11:31:04 来源:https://blog.csdn.net/weixin_74085818/article/details/141680044  浏览:    关键词:机器学习/数据分析--通俗语言带你入门随机森林,并用随机森林进行天气分类预测(Accuracy为0.92)
  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

前言

  • 机器学习是深度学习和数据分析的基础,接下来将更新常见的机器学习算法及其案例
  • 注意:在打数学建模比赛中,机器学习用的也很多,可以一起学习
  • 欢迎收藏 + 点赞 + 关注

文章目录

  • 1、简介
    • 1、集成学习Bagging
    • 2、随机森林简介
  • 2、案例:不同天气分类
    • 1、导入数据
    • 2、数据检查和数据预处理
    • 3、数据分析
    • 4、模型创建
      • 1、标签编码
      • 2、模型创建
    • 5、模型预测于评估
    • 6、特征重要特征展示

1、简介

1、集成学习Bagging

Bagging集成核心思想:将数据集集随机分为N份,每一份用一个模型求解,最后将所有模型结果进行投票得出结果

转化为图像如下:

在这里插入图片描述

自动采样法

自动采样法,可以有放回的采样,假设m个样本的数据集,每一次随机拿去一个样本,然后放回,这样就有概率下一次再被选中,经过m次采样,一次大概有百分之63.2%(数学公式推导而出)的数据被选中。

数学公式推导:

假设每一个样本被选择的概率为 1/m,这样进行m次选择,没有选择的概率为:

( 1 − 1 m ) m (1-\frac1m)^m (1m1)m

当m-> ∞ \infty 的时候,结果趋于: 1 e ≈ 0.368 。 \frac1e\approx0.368\text{ 。} e10.368  然后用1减去,得到的。

2、随机森林简介

随机森林是一种集成学习算法,将多个决策树按照Bagging思想进行集成,然后对每个决策树的结果进行投票,非常适合复杂分类的情况下处理数据,下图为随机森林大体结构:

在这里插入图片描述

2、案例:不同天气分类

简介:本项目使用了一个人工合成的天气数据集,模拟了雨天、晴天、多云和雪天四种类型

任务:对数进行数据分析,建立随机森林模型对天气类别进行分类预测

1、导入数据

import numpy as np 
import pandas as pd 
import matplotlib.pyplot as plt data = pd.read_csv('weather_classification_data.csv')
data
TemperatureHumidityWind SpeedPrecipitation (%)Cloud CoverAtmospheric PressureUV IndexSeasonVisibility (km)LocationWeather Type
014.0739.582.0partly cloudy1010.822Winter3.5inlandRainy
139.0968.571.0partly cloudy1011.437Spring10.0inlandCloudy
230.0647.016.0clear1018.725Spring5.5mountainSunny
338.0831.582.0clear1026.257Spring1.0coastalSunny
427.07417.066.0overcast990.671Winter2.5mountainRainy
....................................
1319510.07414.571.0overcast1003.151Summer1.0mountainRainy
13196-1.0763.523.0cloudy1067.231Winter6.0coastalSnowy
1319730.0775.528.0overcast1012.693Autumn9.0coastalCloudy
131983.07610.094.0overcast984.270Winter2.0inlandSnowy
13199-5.0380.092.0overcast1015.375Autumn10.0mountainRainy

13200 rows × 11 columns

names = ['温度', '湿度', '风速', '降水量(%)', '云量', '气压', '紫外线指数', '季节' ,'能见度(km)', '地点', '天气类型']
data.columns = names
data
温度湿度风速降水量(%)云量气压紫外线指数季节能见度(km)地点天气类型
014.0739.582.0partly cloudy1010.822Winter3.5inlandRainy
139.0968.571.0partly cloudy1011.437Spring10.0inlandCloudy
230.0647.016.0clear1018.725Spring5.5mountainSunny
338.0831.582.0clear1026.257Spring1.0coastalSunny
427.07417.066.0overcast990.671Winter2.5mountainRainy
....................................
1319510.07414.571.0overcast1003.151Summer1.0mountainRainy
13196-1.0763.523.0cloudy1067.231Winter6.0coastalSnowy
1319730.0775.528.0overcast1012.693Autumn9.0coastalCloudy
131983.07610.094.0overcast984.270Winter2.0inlandSnowy
13199-5.0380.092.0overcast1015.375Autumn10.0mountainRainy

13200 rows × 11 columns

2、数据检查和数据预处理

# 查看是否有缺失值
data.isnull().sum()
温度         0
湿度         0
风速         0
降水量(%)     0
云量         0
气压         0
紫外线指数      0
季节         0
能见度(km)    0
地点         0
天气类型       0
dtype: int64
# 查看数据信息
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 13200 entries, 0 to 13199
Data columns (total 11 columns):#   Column   Non-Null Count  Dtype
---  ------   --------------  -----
0   温度       13200 non-null  float641   湿度       13200 non-null  int64
2   风速       13200 non-null  float643   降水量(%)   13200 non-null  float644   云量       13200 non-null  object5   气压       13200 non-null  float646   紫外线指数    13200 non-null  int64
7   季节       13200 non-null  object8   能见度(km)  13200 non-null  float649   地点       13200 non-null  object10  天气类型     13200 non-null  object
dtypes: float64(5), int64(2), object(4)
memory usage: 1.1+ MB
# 分别对云量、季节、地点、天气类型进行分类
columns = ['云量', '季节', '地点', '天气类型']
for i in columns:print(f'{i}')print(data[i].unique())print('*' * 50)
云量
['partly cloudy' 'clear' 'overcast' 'cloudy']
**************************************************
季节
['Winter' 'Spring' 'Summer' 'Autumn']
**************************************************
地点
['inland' 'mountain' 'coastal']
**************************************************
天气类型
['Rainy' 'Cloudy' 'Sunny' 'Snowy']
**************************************************

分析

  • 云量:四类
  • 季节:四类
  • 地点:四类
  • 天气类型:四类
# 纸箱图分析,对数据进行异常值分析
import seaborn as sns #设置字体
from pylab import mpl
mpl.rcParams["font.sans-serif"] = ["SimHei"]  # 显示中文
plt.rcParams['axes.unicode_minus'] = False		# 显示负号feature_map = {'温度': '温度','湿度': '湿度百分比','风速': '风速','降水量(%)': '降水量百分比','气压': '大气压力','紫外线指数': '紫外线指数','能见度(km)': '能见度'
}plt.figure(figsize=(15, 10))for i, (col, col_name) in enumerate(feature_map.items(), 1):     # 1 是索引从1开始,1、2、3、4……plt.subplot(2, 4, i)sns.boxplot(y=data[col])plt.title(f'{col_name}的纸箱图', fontsize=14)plt.ylabel('数值', fontsize=12)plt.grid(axis='y', linestyle='--', alpha=0.7)plt.tight_layout()   # 自动调整宽距
plt.show()

在这里插入图片描述

异常值分析

  • 温度:高于60,违背常理,删去
  • 湿度:存在超过100的值,删除
  • 风速:风速影响因素很多,这里不做处理
  • 降雨量:存在超过100的值,删除
  • 大气压力:大气压力受到很多因素影响,如:高海拔引起,不处理
  • 能见度:可能受到雾霾、雨季的影响,不处理
# 统计异常值占比
print('温度: ', data[data['温度'] > 60.0]['温度'].count() / data['温度'].count())
print('湿度: ', data[data['湿度'] > 100.0]['湿度'].count() / data['湿度'].count())
print('降水量(%): ', data[data['降水量(%)'] > 100.0]['降水量(%)'].count() / data['降水量(%)'].count())
温度:  0.015681818181818182
湿度:  0.03151515151515152
降水量(%):  0.029696969696969697

分析

  • 发现异常值占比极低,故删除
# 删除异常值
print(f'删除前数据维度{data.shape}')
data = data[(data['温度'] <= 60.0) & (data['湿度'] <= 100.0) & (data['降水量(%)'] <= 100.0)]
print(f'删除后数据维度{data.shape}')
删除前数据维度(13200, 11)
删除后数据维度(12360, 11)

3、数据分析

# 统计分析
data.describe()
温度湿度风速降水量(%)气压紫外线指数能见度(km)
count12360.00000012360.00000012360.00000012360.00000012360.00000012360.00000012360.000000
mean18.07135966.9374609.35683750.8649681005.7137433.7912625.535801
std15.80436319.3903336.31833430.96784638.3004713.7206383.377554
min-24.00000020.0000000.0000000.000000800.1200000.0000000.000000
25%4.00000056.0000005.00000019.000000994.5875001.0000003.000000
50%21.00000069.0000008.50000054.0000001007.4950002.0000005.000000
75%30.00000081.00000013.00000079.0000001016.7500006.0000007.500000
max60.000000100.00000048.500000100.0000001199.21000014.00000020.000000
# 对每个数据进行图示化展示,看** 处理后的数据 ** 是否正常
plt.figure(figsize=(20, 15))
plt.subplot(3, 4, 1)
sns.histplot(data['温度'], kde=True, bins=20)   # kde:直方图上绘制核密度曲线,bins:分为几个柱子
plt.title('温度分布')
plt.xlabel('温度')
plt.ylabel('频率')plt.subplot(3, 4, 2)
sns.boxplot(y=data['湿度'])
plt.title('湿度百分比图')
plt.ylabel('湿度占比')plt.subplot(3, 4, 3)
sns.histplot(data['风速'], kde=True, bins=20)
plt.title('风速分布')
plt.xlabel('风速(km/h)')
plt.ylabel('频率')plt.subplot(3, 4, 4)
sns.boxplot(y=data['降水量(%)'])
plt.title('降水量百分比纸箱图')
plt.ylabel('降水量占比')plt.subplot(3, 4, 5)
sns.countplot(x='云量', data=data)
plt.title('云量分布')
plt.xlabel('云量描述')
plt.ylabel('频率')plt.subplot(3, 4, 6)
sns.histplot(data['气压'], kde=True, bins=20)
plt.title('气压分布')
plt.xlabel('气压')
plt.ylabel('频率')plt.subplot(3, 4, 7)
sns.histplot(data['紫外线指数'], kde=True, bins=20)
plt.title('紫外线等级分布')
plt.xlabel('紫外线')
plt.ylabel('频率')plt.subplot(3, 4, 8)
season_counts = data['季节'].value_counts()
plt.pie(season_counts, labels=season_counts.index, autopct='%1.1f%%', startangle=140)
plt.title('季节分布')plt.subplot(3, 4, 9)
sns.histplot(data['能见度(km)'], kde=True, bins=20)
plt.title('能见度分布')
plt.xlabel('能见度km/h')
plt.ylabel('频率')plt.subplot(3, 4, 10)
sns.countplot(x='地点', data=data)
plt.title('地点分布')
plt.xlabel('地点')
plt.ylabel('频速')plt.subplot(3, 4, (11,12))
sns.countplot(x='天气类型', data=data)
plt.title('天气类型分布')
plt.xlabel('天气类型')
plt.ylabel('频数')plt.tight_layout()
plt.show()

在这里插入图片描述

数据分析

  • 温度:>60度已经去除,主要集中在(-10, 5),(10, 40)之间,符合常理
  • 湿度:分布在百分之二十到百分之百之间,且数据集中在 中位数附件,符合常理
  • 风速:集中在0-20之间,且集中分布,风速较低,极端风速极少,符合常理
  • 降雨量:分布在0-100之间,主要集中在20-80,中位数大概在50左右,对称,能够反映大多数天气情况下的降雨量
  • 云量:主要为 局部多云阴天比较多,多云最少
  • 气压分布:极端情况少,主要集中在1000附件,符合常理
  • 紫外线:大多数较低,高的占比较少,缝合常理
  • 季节分布:冬天气温占比做多
  • 能见度:能见度大多数集中在5KM附件,能见度正常
  • 地点分布:反映了数据中不同地点天气的数量
  • 天气类型:四种天气类型数量差不多,比较平均和对称

总的来说,数据处理后,数据没有问题,可以进行下一步处理

4、模型创建

1、标签编码

from sklearn.preprocessing import LabelEncoder
new_data = data.copy()
columns = ['云量', '季节', '地点', '天气类型']feture_name = {}for i in columns:le = LabelEncoder()new_data[i] = le.fit_transform(data[i])  feture_name[i] = le   # 每一个编码器,都是返回的是编码结果
# 展示对应的标签编码
for i in columns:print(i, ': ')for index, class_ in enumerate(feture_name[i].classes_):print(f'index: {index}: {class_}')
云量 :
index: 0: clear
index: 1: cloudy
index: 2: overcast
index: 3: partly cloudy
季节 :
index: 0: Autumn
index: 1: Spring
index: 2: Summer
index: 3: Winter
地点 :
index: 0: coastal
index: 1: inland
index: 2: mountain
天气类型 :
index: 0: Cloudy
index: 1: Rainy
index: 2: Snowy
index: 3: Sunny

2、模型创建

from sklearn.model_selection import train_test_split
# 数据集划分
X = new_data.drop('天气类型', axis=1)
y = new_data['天气类型']X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
from sklearn.ensemble import RandomForestClassifier
# 创建随机森林模型
model = RandomForestClassifier()
# 模型的训练
model.fit(X_train, y_train)

5、模型预测于评估

from sklearn.metrics import classification_reporty_pred = model.predict(X_test)
model_evaluation = classification_report(y_test, y_pred)
print(model_evaluation)
precision    recall  f1-score   support0       0.89      0.93      0.91       6361       0.92      0.90      0.91       6222       0.94      0.93      0.93       6143       0.92      0.92      0.92       600accuracy                           0.92      2472macro avg       0.92      0.92      0.92      2472
weighted avg       0.92      0.92      0.92      2472

分析
平均准确率、平均召回率、平均f1得分均在0.92,效果极好

6、特征重要特征展示

feature_importances = model.feature_importances_
feture_rf = pd.DataFrame({'特征': X.columns, '重要度': feature_importances})
feture_rf.sort_values(by='重要度', inplace=True, ascending=False)  # ascending=False:说明降序
plt.figure(figsize=(10, 8))
sns.barplot(x='重要度', y='特征', data=feture_rf)
plt.title('特征影响程度')
plt.xlabel('特征重要占比')
plt.ylabel('特征名字')
plt.show()

在这里插入图片描述

从图中可以看出,温度、降水量、紫外线指数、能见度、气压影响因素最大。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com