【机器学习】十大算法之一随机森林算法原理讲解
- 一·摘要
- 二·个人简介
- 三·什么是随机森林?
- 3.1 决策树
- 3.2 集成方法
- 3.2.1 Bagging方法
- 3.2.2 Boosting方法
- 3.3 随机森林算法
- 3.4 随机的含义
- 四·案例演示一
- 4.1 利用随机森林进行特征选择,然后使用SVR进行训练
- 4.2 利用SVR进行训练
- 五·案例演示二
- 5.1 预测隐形眼镜的类型
一·摘要
随机森林是一种集成学习方法,它通过构建多个决策树来进行分类或回归问题。这种方法的核心思想是利用多个决策树的预测结果,通过投票或平均的方式来提高整体模型的准确性和鲁棒性。随机森林中的“随机”体现在两个方面:首先,每棵树在训练时,从原始数据集中随机选择一部分数据点作为训练集;其次,在每棵树的每个分裂节点上,只考虑一部分特征,而不是所有特征。
这种方法的优点在于它能够处理高维数据,并且对特征的缺失值和异常值具有较好的容忍性。此外,随机森林还具有很好的抗过拟合能力,因为它通过集成多个模型来减少单一模型可能存在的过拟合问题。随机森林的另一个显著特点是它能够评估特征的重要性,这有助于理解数据中哪些特征对预测结果影响最大。
二·个人简介
🏘️🏘️个人主页:以山河作礼。
🎖️🎖️:Python领域新星创作者,CSDN实力新星认证,CSDN内容合伙人,阿里云社区专家博主,新星计划导师,在职数据分析师。
💕💕悲索之人烈焰加身,堕落者不可饶恕。永恒燃烧的羽翼,带我脱离凡间的沉沦。
类型 | 专栏 |
---|---|
Python基础 | Python基础入门—详解版 |
Python进阶 | Python基础入门—模块版 |
Python高级 | Python网络爬虫从入门到精通🔥🔥🔥 |
Web全栈开发 | Django基础入门 |
Web全栈开发 | HTML与CSS基础入门 |
Web全栈开发 | JavaScript基础入门 |
Python数据分析 | Python数据分析项目🔥🔥 |
机器学习 | 机器学习算法🔥🔥 |
人工智能 | 人工智能 |
三·什么是随机森林?
随机森林是一种强大的机器学习算法,属于集成学习方法的一种,由Leo Breiman在2001年提出。它通过构建大量决策树来进行分类或回归任务,并通过聚合这些树的预测结果来提高整体模型的准确性和鲁棒性。随机森林的"随机"体现在两个关键方面:一是在每棵树的训练过程中,从原始训练数据集中随机选择一部分数据点,即通过自助采样(bootstrap sampling)形成不同的数据子集;二是在每棵树的每个分裂节点上,并不是考虑所有可能的特征,而是随机选择一部分特征进行最佳分裂点的搜索。
3.1 决策树
决策树是一种直观且易于理解的监督学习算法,用于分类和回归任务。它通过一系列的问题将数据分割成不同的分支,最终达到预测结果。决策树的构建过程开始于选择一个特征,并基于该特征的值将数据集分割成两个子集。这个过程递归地在每个子集上重复,直到满足停止条件,如达到最大深度、所有数据点属于同一类别或没有更多的特征可以用于分割。每个分割点的选择都是基于某种标准,如信息增益、基尼不纯度或熵,以确保每次分割都能最大化类别的分离度。
决策树的一个关键优势是其模型的可解释性,因为树的结构清晰地展示了特征与目标变量之间的关系。用户可以很容易地追踪从根节点到叶节点的路径,理解每个决策点的逻辑。然而,决策树也有一些局限性,如容易过拟合,特别是当树变得非常深和复杂时。为了解决这个问题,常用的方法是剪枝,即通过移除一些分支来简化树的结构,从而减少模型的复杂度和过拟合的风险。
3.2 集成方法
集成方法是一种机器学习技术,它通过结合多个学习算法来解决单一模型难以解决的问题,从而提高整体模型的性能。这种方法的核心思想是"众人拾柴火焰高",即多个模型的预测结果通过某种方式结合起来,往往比单一模型的预测结果更加准确和稳定。
集成方法通常分为两大类:bagging(自举汇聚法)和boosting(提升法)。
3.2.1 Bagging方法
Bagging方法,全称为Bootstrap Aggregating,即自举汇聚法,是一种用于提高模型性能的集成学习技术。它由Leo Breiman在1996年提出,主要用于减少模型的方差,提高预测的准确性和稳定性。
Bagging的核心思想是通过自助采样(bootstrap sampling)从原始数据集中抽取多个小规模的训练数据集。每个小数据集的大小通常与原始数据集相同,但允许有重复的样本。然后,在每个小数据集上独立地训练一个基学习器,这些基学习器通常是相同的模型,例如决策树。由于每个基学习器都是在不同的数据子集上训练的,因此它们之间具有一定的独立性。
在训练完成后,Bagging方法通过聚合所有基学习器的预测结果来得到最终的预测。对于分类问题,通常采用投票机制,即选择得票最多的类别作为最终预测结果;对于回归问题,则通常采用平均值,即计算所有基学习器预测结果的平均值作为最终预测。
Bagging方法的优点在于它能够减少模型的方差,提高模型的泛化能力。由于每个基学习器都是在不同的数据子集上训练的,因此它们不太可能同时过拟合到训练数据中的噪声和异常值。此外,Bagging方法还能够提高模型的鲁棒性,即使某些基学习器表现不佳,其他基学习器仍然可以提供准确的预测。
3.2.2 Boosting方法
Boosting方法是一种迭代的集成学习技术,旨在通过逐步构建弱学习器并关注前一轮学习器的错误来提高整体模型的性能。这种方法的核心思想是,通过一系列简单的模型,如决策树桩,逐步纠正前一轮模型的不足,最终构建出一个强学习器。
Boosting的工作原理是从一个初始模型开始,然后对那些被初始模型错误分类的样本增加权重。在下一轮迭代中,新的模型将更加关注这些被错误分类的样本,尝试纠正这些错误。这个过程会重复进行,每一轮都会生成一个新的弱学习器,并且每个新模型都试图纠正前一个模型的不足。最终,所有模型的预测结果会通过某种方式(如加权平均)结合起来,形成一个最终的强学习器。
Boosting方法有几种不同的变体,其中最著名的包括AdaBoost、Gradient Boosting和XGBoost。AdaBoost(Adaptive Boosting)是一种经典的Boosting算法,它通过调整每个样本的权重来关注那些被前一轮模型错误分类的样本。Gradient Boosting是一种基于梯度下降的Boosting方法,它通过构建新的弱学习器来最小化损失函数的梯度。XGBoost(eXtreme Gradient Boosting)是一种高效的Gradient Boosting实现,它通过正则化项和优化的树构建算法来提高模型的性能和计算效率。
Boosting方法的优点包括:
- 提高准确性:通过逐步改进模型,Boosting能够显著提高预测的准确性。
- 减少偏差:Boosting通过关注被前一轮模型错误分类的样本来减少模型的偏差。
- 灵活性:Boosting可以应用于各种类型的弱学习器和损失函数。
3.3 随机森林算法
随机森林算法是一种集成学习方法,它通过构建大量的决策树并将它们的预测结果结合起来,以提高整体模型的准确性和鲁棒性。这种算法由Leo Breiman和Adele Cutler在2001年提出,它的核心在于"森林"中的"树木"——即多个决策树,每棵树都是独立构建的,并且在构建过程中引入随机性。
随机森林的工作流程通常包括以下几个步骤:
- 数据预处理:对原始数据进行清洗和标准化,以确保算法的有效运行。
- 自助采样:从原始数据集中通过自助采样的方式抽取多个不同的训练数据集。自助采样允许数据集中的样本重复出现,这意味着每个训练集的大小与原始数据集相同,但包含一些重复的样本。
- 特征随机选择:在每棵树的每个分裂节点上,随机选择一部分特征,而不是考虑所有可能的特征。这一步进一步增加了模型的多样性,并有助于减少过拟合。
- 决策树构建:使用每个训练数据集构建决策树,直到每个树达到其最大深度或达到其他停止条件。
- 预测和聚合:对于分类问题,每棵树给出一个预测,最终的预测结果是所有树预测结果的多数投票;对于回归问题,则是所有树预测结果的平均值。
随机森林算法的优点包括:
- 高准确性:由于集成了多个决策树,随机森林通常能够提供较高的预测准确性。
- 鲁棒性:随机森林对数据中的噪声和异常值具有较好的容忍性,因为它依赖于多个树的预测结果,而不是单个树。
- 特征重要性评估:随机森林能够评估各个特征对预测结果的重要性,这有助于特征选择和数据理解。
- 抗过拟合能力:通过集成多个树,随机森林减少了过拟合的风险。
3.4 随机的含义
随机的含义:
1, 对样本进行随机, 样本的个数是一样的.
2, 对特征进行随机,特征数是一样的.
1.数据的随机选取:
首先,从原始的数据集中采取有放回的抽样,构造子数据集,子数据集的数据是和原始数据集相同的。不同子数据集的元素可以重复,同一个子数据集中的元素也可以重复。第二,利用子数据集来构建子决策树,将这个数据放到每个子决策树中,每个子决策树输出一个结果。最后,如果有了新的数据需要通过随机森林得到分类结果,就可以通过对子决策树的判断结果的投票,得到随机森林的输出结果了。假设随机森林中有3棵子决策树,2棵子树的分类结果是A类,1棵子树的分类结果是B类,那么随机森林的分类结果就是A类。
2.待选特征的随机选取
与数据集的随机选取类似,随机森林中的子树的每一个分裂过程并未用到所有的待选特征,而是从所有的待选特征中随机选取一定的特征,之后再在随机选取的特征中选取最优的特征。这样能够使得随机森林中的决策树都能够彼此不同,提升系统的多样性,从而提升分类性能。
四·案例演示一
4.1 利用随机森林进行特征选择,然后使用SVR进行训练
1.导入相关库
import numpy as np
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
# url = 'http://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data'
url1 = pd.read_csv(r'wine.txt', header=None)
# url1 = pd.DataFrame(url1)
# df = pd.read_csv(url1,header=None)
url1.columns = ['Class label', 'Alcohol', 'Malic acid', 'Ash',
'Alcalinity of ash', 'Magnesium', 'Total phenols',
'Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins',
'Color intensity', 'Hue', 'OD280/OD315 of diluted wines', 'Proline']
# 重要性: [0.10658906 0.02539968 0.01391619 0.03203319 0.02207807 0.0607176
# 0.15094795 0.01464516 0.02235112 0.18248262 0.07824279 0.1319868
# 0.15860977]
# print(url1)
# 查看几个标签
# Class_label = np.unique(url1['Class label'])
# print(Class_label)
# 查看数据信息
# info_url = url1.info()
# print(info_url)
# 除去标签之外,共有13个特征,数据集的大小为178,
# 下面将数据集分为训练集和测试集
from sklearn.model_selection import train_test_split
print(type(url1))
# url1 = url1.values
# x = url1[:,0]
# y = url1[:,1:]
x, y = url1.iloc[:, 1:].values, url1.iloc[:, 0].values
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=0)
feat_labels = url1.columns[1:]
# n_estimators:森林中树的数量
# n_jobs 整数 可选(默认=1) 适合和预测并行运行的作业数,如果为-1,则将作业数设置为核心数
forest = RandomForestClassifier(n_estimators=10000, random_st`在这里插入代码片`ate=0, n_jobs=-1)
forest.fit(x_train, y_train)
# 下面对训练好的随机森林,完成重要性评估
# feature_importances_ 可以调取关于特征重要程度
importances = forest.feature_importances_
print("重要性:", importances)
x_columns = url1.columns[1:]
indices = np.argsort(importances)[::-1]
x_columns_indices = []
for f in range(x_train.shape[1]):
# 对于最后需要逆序排序,我认为是做了类似决策树回溯的取值,从叶子收敛
# 到根,根部重要程度高于叶子。
print("%2d) %-*s %f" % (f + 1, 30, feat_labels[indices[f]], importances[indices[f]]))
x_columns_indices.append(feat_labels[indices[f]])
print(x_columns_indices)
print(x_columns.shape[0])
print(x_columns)
print(np.arange(x_columns.shape[0]))
# 筛选变量(选择重要性比较高的变量)
threshold = 0.15
x_selected = x_train[:, importances > threshold]
# 可视化
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
plt.title("红酒的数据集中各个特征的重要程度", fontsize=18)
plt.ylabel("import level", fontsize=15, rotation=90)
plt.rcParams['font.sans-serif'] = ["SimHei"]
plt.rcParams['axes.unicode_minus'] = False
for i in range(x_columns.shape[0]):
plt.bar(i, importances[indices[i]], color='orange', align='center')
plt.xticks(np.arange(x_columns.shape[0]), x_columns_indices, rotation=90, fontsize=15)
plt.show()
结果:
RangeIndex: 178 entries, 0 to 177
Data columns (total 14 columns):
Class label 178 non-null int64
Alcohol 178 non-null float64
Malic acid 178 non-null float64
Ash 178 non-null float64
Alcalinity of ash 178 non-null float64
Magnesium 178 non-null int64
Total phenols 178 non-null float64
Flavanoids 178 non-null float64
Nonflavanoid phenols 178 non-null float64
Proanthocyanins 178 non-null float64
Color intensity 178 non-null float64
Hue 178 non-null float64
OD280/OD315 of diluted wines 178 non-null float64
Proline 178 non-null int64
dtypes: float64(11), int64(3)
memory usage: 19.5 KB
重要性: [0.10658906 0.02539968 0.01391619 0.03203319 0.02207807 0.0607176
0.15094795 0.01464516 0.02235112 0.18248262 0.07824279 0.1319868
0.15860977]
1) Color intensity 0.182483
2) Proline 0.158610
3) Flavanoids 0.150948
4) OD280/OD315 of diluted wines 0.131987
5) Alcohol 0.106589
6) Hue 0.078243
7) Total phenols 0.060718
8) Alcalinity of ash 0.032033
9) Malic acid 0.025400
10) Proanthocyanins 0.022351
11) Magnesium 0.022078
12) Nonflavanoid phenols 0.014645
13) Ash 0.013916
4.2 利用SVR进行训练
from sklearn.svm import SVR # SVM中的回归算法
import pandas as pd
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import numpy as np
# 数据预处理,使得数据更加有效的被模型或者评估器识别
from sklearn import preprocessing
from sklearn.externals import joblib
# 获取数据
origin_data = pd.read_csv('wine.txt',header=None)
X = origin_data.iloc[:,1:].values
Y = origin_data.iloc[:,0].values
print(type(Y))
# print(type(Y.values))
# 总特征 按照特征的重要性排序的所有特征
all_feature = [ 9, 12, 6, 11, 0, 10, 5, 3, 1, 8, 4, 7, 2]
# 这里我们选取前三个特征
topN_feature = all_feature[:3]
print(topN_feature)
# 获取重要特征的数据
data_X = X[:,topN_feature]
# 将每个特征值归一化到一个固定范围
# 原始数据标准化,为了加速收敛
# 最小最大规范化对原始数据进行线性变换,变换到[0,1]区间
data_X = preprocessing.MinMaxScaler().fit_transform(data_X)
# 利用train_test_split 进行训练集和测试集进行分开
X_train,X_test,y_train,y_test = train_test_split(data_X,Y,test_size=0.3)
# 通过多种模型预测
model_svr1 = SVR(kernel='rbf',C=50,max_iter=10000)
# 训练
# model_svr1.fit(data_X,Y)
model_svr1.fit(X_train,y_train)
# 得分
score = model_svr1.score(X_test,y_test)
print(score)
结果:
五·案例演示二
5.1 预测隐形眼镜的类型
分析lenses.txt文件, 最后一列为眼镜类型
使用随机森林模型训练, 并查看哪些特征最重要feature_importances_
import warnings
warnings.filterwarnings(action='ignore')
df = pd.read_table('../data/lenses.txt',header=None)
df.head()
df.columns
df[0] =df[0].factorize()[0]
df[1] =df[1].factorize()[0]
df[2] =df[2].factorize()[0]
df[3] =df[3].factorize()[0]
df[4] =df[4].factorize()[0]
data = df.iloc[:,0:4]
target = df.iloc[:,-1]
target = pd.DataFrame(target)
# ensemble 集成算法
from sklearn.ensemble import RandomForestClassifier
# n_estimators=100, 100个决策树
# bootstrap=True, 是否有放回抽样
# max_samples=None,最大样本数,行数
le = RandomForestClassifier(max_samples=100,max_features=3)
le
# 拆分数据集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(data,target,test_size=0.2)
le.fit(x_train,y_train)
le.feature_importances_
le.estimators_
le1 = RandomForestClassifier(n_estimators=10)
le1.fit(x_train,y_train)
le1.estimators_
# for 循环遍历所有的决策树
for tree in le1.estimators_:
y_pred = tree.predict(x_test)
print(y_pred)
le1.predict(x_test)