L8:机器学习|随机森林学习记录

第L8周:机器学习|随机森林学习记录

随机森林(Random Forest)是一种集成学习方法,用于解决分类和回归问题。随机森林是一个包含多个决策树的分类器,并且其输出的类别是由个别树输出的类别的众数而定。

实例:利用一个人工合成的天气数据集,模拟了雨天、晴天、多云和雪天四种类型

异常值处理————描述性统计————构建随机森林模型进行预测————生成了模型的重要特征图

导入库

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report

数据读取

data = pd.read_csv(r"E:\文件\python学习\K同学啊 365\数据\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

数据检查与预处理

# 查看数据信息
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 13200 entries, 0 to 13199
Data columns (total 11 columns):
 #   Column                Non-Null Count  Dtype  
---  ------                --------------  -----  
 0   Temperature           13200 non-null  float64
 1   Humidity              13200 non-null  int64  
 2   Wind Speed            13200 non-null  float64
 3   Precipitation (%)     13200 non-null  float64
 4   Cloud Cover           13200 non-null  object 
 5   Atmospheric Pressure  13200 non-null  float64
 6   UV Index              13200 non-null  int64  
 7   Season                13200 non-null  object 
 8   Visibility (km)       13200 non-null  float64
 9   Location              13200 non-null  object 
 10  Weather Type          13200 non-null  object 
dtypes: float64(5), int64(2), object(4)
memory usage: 1.1+ MB
# 查看分类特征的唯一值
characteristic = ['Cloud Cover','Season','Location','Weather Type']
for i in characteristic:
    print(f'{i}:')
    print(data[i].unique())
    print('-'*50)
Cloud Cover:
['partly cloudy' 'clear' 'overcast' 'cloudy']
--------------------------------------------------
Season:
['Winter' 'Spring' 'Summer' 'Autumn']
--------------------------------------------------
Location:
['inland' 'mountain' 'coastal']
--------------------------------------------------
Weather Type:
['Rainy' 'Cloudy' 'Sunny' 'Snowy']
--------------------------------------------------
feature_map = {
    'Temperature': '温度',
    'Humidity': '湿度百分比',
    'Wind Speed': '风速',
    'Precipitation (%)': '降水量百分比',
    'Atmospheric Pressure': '大气压力',
    'UV Index': '紫外线指数',
    'Visibility (km)': '能见度'
}
plt.figure(figsize=(15, 10))

for i, (col, col_name) in enumerate(feature_map.items(), 1):
    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()

在这里插入图片描述

print(f"温度超过60°C的数据量:{data[data['Temperature'] > 60].shape[0]},占比{round(data[data['Temperature'] > 60].shape[0] / data.shape[0] * 100,2)}%。")
print(f"湿度百分比超过100%的数据量:{data[data['Humidity'] > 100].shape[0]},占比{round(data[data['Humidity'] > 100].shape[0] / data.shape[0] * 100,2)}%。")
print(f"降雨量百分比超过100%的数据量:{data[data['Precipitation (%)'] > 100].shape[0]},占比{round(data[data['Precipitation (%)'] > 100].shape[0] / data.shape[0] * 100,2)}%。")
温度超过60°C的数据量:207,占比1.57%。
湿度百分比超过100%的数据量:416,占比3.15%。
降雨量百分比超过100%的数据量:392,占比2.97%。
print("删前的数据shape:", data.shape)
data = data[(data['Temperature'] <= 60) & (data['Humidity'] <= 100) & (data['Precipitation (%)'] <= 100)]
print("删后的数据shape:", data.shape)
删前的数据shape: (13200, 11)
删后的数据shape: (12360, 11)

数据分析

data.describe(include='all')
TemperatureHumidityWind SpeedPrecipitation (%)Cloud CoverAtmospheric PressureUV IndexSeasonVisibility (km)LocationWeather Type
count12360.00000012360.00000012360.00000012360.0000001236012360.00000012360.0000001236012360.0000001236012360
uniqueNaNNaNNaNNaN4NaNNaN4NaN34
topNaNNaNNaNNaNovercastNaNNaNWinterNaNmountainSnowy
freqNaNNaNNaNNaN5726NaNNaN5288NaN45353130
mean18.07135966.9374609.35683750.864968NaN1005.7137433.791262NaN5.535801NaNNaN
std15.80436319.3903336.31833430.967846NaN38.3004713.720638NaN3.377554NaNNaN
min-24.00000020.0000000.0000000.000000NaN800.1200000.000000NaN0.000000NaNNaN
25%4.00000056.0000005.00000019.000000NaN994.5875001.000000NaN3.000000NaNNaN
50%21.00000069.0000008.50000054.000000NaN1007.4950002.000000NaN5.000000NaNNaN
75%30.00000081.00000013.00000079.000000NaN1016.7500006.000000NaN7.500000NaNNaN
max60.000000100.00000048.500000100.000000NaN1199.21000014.000000NaN20.000000NaNNaN
plt.figure(figsize=(20, 15))
plt.subplot(3, 4, 1)
sns.histplot(data['Temperature'], kde=True,bins=20)
plt.title('温度分布')
plt.xlabel('温度')
plt.ylabel('频数')

plt.subplot(3, 4, 2)
sns.boxplot(y=data['Humidity'])
plt.title('湿度百分比箱线图')
plt.ylabel('湿度百分比')

plt.subplot(3, 4, 3)
sns.histplot(data['Wind Speed'], kde=True,bins=20)
plt.title('风速分布')
plt.xlabel('风速(km/h)')
plt.ylabel('频数')

plt.subplot(3, 4, 4)
sns.boxplot(y=data['Precipitation (%)'])
plt.title('降雨量百分比箱线图')
plt.ylabel('降雨量百分比')

plt.subplot(3, 4, 5)
sns.countplot(x='Cloud Cover', data=data)
plt.title('云量 (描述)分布')
plt.xlabel('云量 (描述)')
plt.ylabel('频数')

plt.subplot(3, 4, 6)
sns.histplot(data['Atmospheric Pressure'], kde=True,bins=10)
plt.title('大气压分布')
plt.xlabel('气压 (hPa)')
plt.ylabel('频数')

plt.subplot(3, 4, 7)
sns.histplot(data['UV Index'], kde=True,bins=14)
plt.title('紫外线等级分布')
plt.xlabel('紫外线指数')
plt.ylabel('频数')

plt.subplot(3, 4, 8)
Season_counts = data['Season'].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['Visibility (km)'], kde=True,bins=10)
plt.title('能见度分布')
plt.xlabel('能见度(Km)')
plt.ylabel('频数')

plt.subplot(3, 4, 10)
sns.countplot(x='Location', data=data)
plt.title('地点分布')
plt.xlabel('地点')
plt.ylabel('频数')

plt.subplot(3, 4, (11,12))
sns.countplot(x='Weather Type', data=data)
plt.title('天气类型分布')
plt.xlabel('天气类型')
plt.ylabel('频数')

plt.tight_layout()
plt.show()

在这里插入图片描述

随机森林

new_data = data.copy()
label_encoders = {}
categorical_features = ['Cloud Cover', 'Season', 'Location', 'Weather Type']
for feature in categorical_features:
    le = LabelEncoder()
    new_data[feature] = le.fit_transform(data[feature])
    label_encoders[feature] = le

for feature in categorical_features:
    print(f"'{feature}'特征的对应关系:")
    for index, class_ in enumerate(label_encoders[feature].classes_):
        print(f"  {index}: {class_}")
'Cloud Cover'特征的对应关系:
  0: clear
  1: cloudy
  2: overcast
  3: partly cloudy
'Season'特征的对应关系:
  0: Autumn
  1: Spring
  2: Summer
  3: Winter
'Location'特征的对应关系:
  0: coastal
  1: inland
  2: mountain
'Weather Type'特征的对应关系:
  0: Cloudy
  1: Rainy
  2: Snowy
  3: Sunny
# 构建x,y
x = new_data.drop(['Weather Type'],axis=1)
y = new_data['Weather Type']

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

# 构建随机森林模型
rf_clf = RandomForestClassifier(random_state=15)
rf_clf.fit(x_train, y_train)
# 使用随机森林进行预测
y_pred_rf = rf_clf.predict(x_test)
class_report_rf = classification_report(y_test, y_pred_rf)
print(class_report_rf)
              precision    recall  f1-score   support

           0       0.88      0.91      0.89       871
           1       0.93      0.91      0.92       983
           2       0.92      0.93      0.92       929
           3       0.92      0.90      0.91       925

    accuracy                           0.91      3708
   macro avg       0.91      0.91      0.91      3708
weighted avg       0.91      0.91      0.91      3708

结果分析

feature_importances = rf_clf.feature_importances_
features_rf = pd.DataFrame({'特征': x.columns, '重要度': feature_importances})
features_rf.sort_values(by='重要度', ascending=False, inplace=True)
plt.figure(figsize=(10, 8))
sns.barplot(x='重要度', y='特征', data=features_rf)
plt.xlabel('重要度')
plt.ylabel('特征')
plt.title('随机森林特征图')
plt.show()

在这里插入图片描述

学习总结:

1.学会如何处理数据异常值,绘制并分析箱线图,可视化

2.如何用随机森林算法进行预测

随机森林原理总结:

  1. 随机抽样(Bootstrap Sampling):

随机森林使用Bootstrap采样从训练数据集中随机选择N个样本,其中N是训练数据集的大小。

  1. 特征随机选择:

在每次决策树节点的分裂过程中,随机森林引入了特征的随机性。

假设总共有M个特征,在每次分裂节点时,从这些特征中随机选择m个特征,其中m通常由用户指定。

  1. 决策树的构建:

决策树的构建过程涉及到选择最佳特征和分裂点,通常通过一些分裂标准(例如信息增益、基尼指数)来确定。

  1. 集成方法:

在随机森林中,多个决策树的结果被集成以进行分类或回归。对于分类问题,最终的分类结果是通过多数投票法来确定;对于回归问题,最终的回归结果是多个决策树的预测结果的平均值

  1. 特征重要性评估:

随机森林通常通过观察每个特征在多个决策树中的分裂情况以及其对模型性能的影响来估计特征的重要性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值