机器学习算法系列(3)随机森林

本文介绍了随机森林的算法原理,包括森林的概念和随机性的双重特点。在气温预测的案例中,阐述了数据预处理、模型构建和调参的具体流程,强调了特征选择的重要性。随机森林具备解决分类和回归问题、抗过拟合等优点,但也存在过拟合风险、计算成本高和训练时间长等缺点。

一、算法原理

随机森林: 森林:多个决策树并行运行;随机:两重随机性,每个决策树特征个数和样本个数按一定比例随机选择,最后投票选出最终结果。
在这里插入图片描述
二、案例:气温预测

#导入库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

plt.style.use("fivethirtyeight")
%matplotlib inline

import warnings
warnings.filterwarnings("ignore")#忽略警告
#读取数据
df = pd.read_csv('temps_extended.csv')
df.head()

在这里插入图片描述

print('数据维度',df.shape)

在这里插入图片描述

df.describe()

在这里插入图片描述
1.数据预处理

(1)标准时间格式

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]
dates[0:5]

在这里插入图片描述
(2)变量时序图

fig,((ax1,ax2),(ax3,ax4),(ax5,ax6),(ax7,ax8)) = plt.subplots(4,2,figsize = (15,20))
fig.autofmt_xdate(rotation = 45 )

ax1.plot(dates,df["actual"])
ax1.set_xlabel("");ax1.set_ylabel("Temperature");ax1.set_title("Max Temp")

ax2.plot(dates,df["ws_1"])
ax2.set_xlabel("");ax2.set_ylabel("Temperature");ax2.set_title("Previous Wind Speed")

ax3.plot(dates,df["prcp_1"])
ax3.set_xlabel("");ax3.set_ylabel("Temperature");ax3.set_title("Previous Precipitation")

ax4.plot(dates,df["snwd_1"])
ax4.set_xlabel("");ax4.set_ylabel("Temperature");ax4.set_title("Previous Snow")

ax5.plot(dates,df["temp_2"])
ax5.set_xlabel("");ax5.set_ylabel("Temperature");ax5.set_title("Prior Max Temp")

ax6.plot(dates,df["temp_1"])
ax6.set_xlabel("");ax6.set_ylabel("Temperature");ax6.set_title("Previous Max Temp")

ax7.plot(dates,df["average"])
ax7.set_xlabel("Date");ax7.set_ylabel("Temperature");ax7.set_title("Previous Average Temp")

ax8.plot(dates,df["friend"])
ax8.set_xlabel("Date");ax8.set_ylabel("Temperature");ax8.set_title("Friend Estimate")

plt.tight_layout(pad = 2)

在这里插入图片描述
(3)独热编码

#one hot encoder
df2 = pd.get_dummies(df)
df2.head()

在这里插入图片描述
2.构建模型

#导入库
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
#构建特征和标签
y = df2["actual"]
X = df2.drop("actual",axis = 1)

X_list = list(X.columns)

y = np.array(y)
X = np.array(X)
#数据集切分
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.25,random_state = 42)

(1)评估标准函数

def evaluate(model,X_test,y_test):
    predictions = model.predict(X_test)
    errors = abs(predictions - y_test)
    mape = errors / y_test
    accuracy = 1 - mape

    print('平均气温误差:',np.mean(errors))
    print('Accuracy = {:0.2%}'.format(np.mean(accuracy)))

(2)基准模型

%%time

rf = RandomForestRegressor(random_state = 42)
rf.fit(X_train,y_train)
evaluate(rf,X_test,y_test)

在这里插入图片描述
(3)树模型可视化

#导入库
from sklearn.tree import export_graphviz
import pydot
#限制一下树模型
rf_small = RandomForestRegressor(n_estimators = 10,max_depth = 3,random_state = 42)
rf_small.fit(X_train,y_train)
#提取一棵树
tree_small = rf_small.estimators_[5]
#保存
export_graphviz(tree_small,out_file = "small_tree.dot",feature_names = X_list,rounded = True,precision = 1)
(graph,) = pydot.graph_from_dot_file("small_tree.dot")
graph.write_png("small_tree.png")
#画出树模型
from IPython.display import Image
Image(graph.create_png())

在这里插入图片描述
(4)特征重要性衡量

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

在这里插入图片描述

importances = list(rf.feature_importances_)
x_values = list(range(len(importances)))
plt.bar(x_values,importances,orientation = "vertical")
plt.xticks(x_values,X_list,rotation = "vertical")
plt.ylabel("Importances");plt.xlabel("Variable");plt.title("Variable Importances")

在这里插入图片描述

# 对特征进行排序
sorted_importances = [importance[1] for importance in feature_importances]
sorted_features = [importance[0] for importance in feature_importances]

# 累计重要性
cumulative_importances = np.cumsum(sorted_importances)

# 绘制折线图
plt.plot(x_values, cumulative_importances, 'g-')

# 画一条红色虚线,0.95那
plt.hlines(y = 0.95, xmin=0, xmax=len(sorted_importances), color = 'r', linestyles = 'dashed')

# X轴
plt.xticks(x_values, sorted_features, rotation = 'vertical')

# Y轴和名字
plt.xlabel('Variable'); plt.ylabel('Cumulative Importance'); plt.title('Cumulative Importances');

在这里插入图片描述
分析:选择95%重要的特征。

(5)真实值与预测值之间的差异
在这里插入图片描述
3.调参具体流程

X_train = pd.DataFrame(X_train,columns = X_list)
X_test = pd.DataFrame(X_test,columns = X_list)
important_features = ['temp_1', 'average', 'ws_1', 'temp_2', 'friend']
X_train = X_train[important_features]
X_test = X_test[important_features]

(1)调参

rf = RandomForestRegressor(random_state = 42)

from pprint import pprint
pprint(rf.get_params())#打印模型所有参数

在这里插入图片描述
(2)随机搜索

from sklearn.model_selection import RandomizedSearchCV

n_estimators = [int(x) for x in np.linspace(start = 200,stop = 2000,num = 10)]
max_features = ['auto','sqrt']
max_depth = [int(x) for x in np.linspace(start = 10,stop = 20,num = 2)]
max_depth.append(None)
min_samples_split = [2,5,10]
min_samples_leaf = [1,2,4]
bootstrap = [True,False]

random_grid = {'n_estimators':n_estimators,
               'max_features':max_features,
               'max_depth':max_depth,
               'min_samples_split':min_samples_split,
               'min_samples_leaf':min_samples_leaf,
               'bootstrap':bootstrap}
%%time

rf = RandomForestRegressor()

rf_random = RandomizedSearchCV(estimator = rf,
                               param_distributions = random_grid,
                               n_iter = 100,
                               scoring = 'neg_mean_absolute_error',
                               cv = 3,
                               verbose = 2,
                               random_state = 42,
                               n_jobs = -1)
rf_random.fit(X_train,y_train)
rf_random.best_params_

在这里插入图片描述

#最优参数
best_random = rf_random.best_estimator_
evaluate(best_random,X_test,y_test)

在这里插入图片描述
(3)详细搜索

from sklearn.model_selection import GridSearchCV

param_grid = {'n_estimators':[1000,1200,1400,1600],
              'max_features':['auto'],
              'max_depth':[8,10,12],
              'min_samples_split':[3,5,7],
              'min_samples_leaf':[2,3,4,5,6],
              'bootstrap':[True]}
%%time

rf = RandomForestRegressor()

grid_search = GridSearchCV(estimator = rf,
                           param_grid = param_grid,
                           scoring = 'neg_mean_absolute_error',
                           cv = 3,
                           verbose = 2,
                           n_jobs = -1)

grid_search.fit(X_train,y_train)
grid_search.best_params_

在这里插入图片描述

best_grid = grid_search.best_estimator_
evaluate(best_grid,X_test,y_test)

在这里插入图片描述

print('最终模型参数:\n')
pprint(best_grid.get_params())

在这里插入图片描述
分析:

(1)基准模型:
在这里插入图片描述
(2)随机搜索:
在这里插入图片描述
(3)详细搜索:
在这里插入图片描述
基准模型使用所有特征,随机搜索和详细搜索使用5个重要特征,减少特征,降低准确度,但提高了运算速度,数据量小的时候,可以使用所有特征;数据量比较大的时候,需要做质量和效率的平衡,选择贡献度占95%的重要特征。

三、总结

优点:

(1)可以用来解决分类和回归问题:随机森林可以同时处理分类和数值特征。

(2)抗过拟合能力:通过平均决策树,降低过拟合的风险性。

(3)只有在半数以上的基分类器出现差错时才会做出错误的预测:随机森林非常稳定,即使数据集中出现了一个新的数据点,整个算法也不会受到过多影响,它只会影响到一颗决策树,很难对所有决策树产生影响。

缺点:

(1)据观测,如果一些分类/回归问题的训练数据中存在噪音,随机森林中的数据集会出现过拟合的现象。
(2)比决策树算法更复杂,计算成本更高。
(3)由于其本身的复杂性,它们比其他类似的算法需要更多的时间来训练。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值