当前位置:   article > 正文

随机森林分类模型(python案例代码)

随机森林分类模型

随机森林模型概述

        随机森林(Random Forest)是一种集成学习方法,常用于分类和回归问题。它通过构建多个决策树来进行预测,然后通过取这些树的输出的平均值(回归问题)或投票(分类问题)来提高模型的准确性和鲁棒性。随机森林具有很强的泛化能力,对于复杂的数据集和高维特征空间也表现良好。

6a9d5e2e48ff44c1b3f5e6b76955e630.png

特点和工作原理

决策树的集成

        随机森林是由多个决策树组成的集成模型。每个决策树都是基学习器,用于对数据进行分类或回归。每个树的输出被整合起来以提高整体模型的性能。

随机性

        随机森林引入了随机性,这使得每个决策树都是在不同的数据子集上训练的。具体来说,每个决策树的训练样本是通过有放回抽样(bootstrap抽样)得到的,这意味着某些样本可能在同一个树中出现多次,而其他一些样本可能根本没有出现。

特征的随机选择

        在每个决策树的节点上,随机森林只考虑一部分特征进行分裂。这样可以确保每个树都不是完全相同的,增加了整体模型的多样性。

投票或平均

        对于分类问题,随机森林采用多数投票的方式,即每个树投票选择的类别最终成为整体模型的输出。对于回归问题,取所有树的输出的平均值作为最终的预测结果。

防止过拟合

        随机森林的随机性有助于防止过拟合,使得模型对训练数据的过度拟合的风险降低。

高性能

        由于每个树都可以独立训练,随机森林可以通过并行处理快速构建,适用于大规模数据集。

        随机森林通过整合多个决策树的意见,减小了单个决策树的过拟合风险,提高了模型的鲁棒性和泛化能力。

什么时候用随机森林分类

51de324fbd6a40c2a596130e8fc55038.png

复杂的分类问题

        随机森林在处理复杂的分类问题时表现出色,能够捕捉数据中复杂的非线性关系和交互作用。

高维度的特征空间

        当数据集具有大量特征时,随机森林通常能够有效地处理高维度的特征空间,而不容易受到维度灾难的影响。

大规模数据集

        由于随机森林的训练可以并行化,因此它在处理大规模数据集时具有较好的性能,能够提供相对较快的训练速度。

不平衡的数据集

        随机森林对于类别不平衡的问题相对鲁棒,因为在每个决策树的训练中采用了有放回的抽样,使得每个类别都有机会被充分考虑。

不需要过多的特征工程

        随机森林对于原始数据的处理相对鲁棒,不太需要进行复杂的特征工程。它能够处理不同类型的特征,包括连续型和离散型特征。

模型解释性要求不高

        虽然随机森林能够提供相对好的预测性能,但其模型结构相对复杂,解释性不如一些简单的线性模型。如果对于模型的解释性要求很高,可能需要考虑其他模型。

处理缺失值

         随机森林能够有效地处理包含缺失值的数据,无需对缺失值进行额外的处理。

构建和训练的基本步骤

        下面是使用Python中的Scikit-Learn库来构建和训练随机森林分类模型的基本步骤:

  1. # 导入必要的库
  2. from sklearn.model_selection import train_test_split
  3. from sklearn.ensemble import RandomForestClassifier
  4. from sklearn.metrics import accuracy_score, classification_report
  5. # 假设你有一个包含特征的X和相应标签的y的数据集
  6. # X是特征矩阵,y是目标变量
  7. # 划分数据集为训练集和测试集
  8. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
  9. # 创建随机森林分类器
  10. rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)
  11. # 训练模型
  12. rf_classifier.fit(X_train, y_train)
  13. # 在测试集上进行预测
  14. y_pred = rf_classifier.predict(X_test)
  15. # 评估模型性能
  16. accuracy = accuracy_score(y_test, y_pred)
  17. print(f'Accuracy: {accuracy:.2f}')
  18. # 输出更详细的分类报告
  19. print('Classification Report:\n', classification_report(y_test, y_pred))

上述代码中的关键步骤包括:

        1、导入所需的库。

        2、使用train_test_split函数将数据集划分为训练集和测试集。

        3、创建RandomForestClassifier对象,设置参数如n_estimators(决策树的数量)等。

        4、使用训练集来拟合(训练)模型。

        5、使用训练后的模型对测试集进行预测。

        6、使用accuracy_score和classification_report等指标来评估模型性能。

        注意,随机森林有许多超参数,如n_estimators、max_depth等,你可以根据具体问题进行调整以优化模型性能。

案例代码1

        在这个案例中,使用一个流行的数据集,即Iris(鸢尾花)数据集。这个数据集包含了三个不同种类的鸢尾花(Setosa、Versicolor和Virginica),每个种类有四个特征(花瓣长度、花瓣宽度、花萼长度和花萼宽度)。

        首先,确保你已经安装了Scikit-Learn库。你可以使用以下命令安装:

pip install scikit-learn

然后,你可以使用以下Python代码来创建和训练随机森林分类模型:

  1. # 导入必要的库
  2. from sklearn.datasets import load_iris
  3. from sklearn.model_selection import train_test_split
  4. from sklearn.ensemble import RandomForestClassifier
  5. from sklearn.metrics import accuracy_score, classification_report
  6. # 加载鸢尾花数据集
  7. iris = load_iris()
  8. X = iris.data
  9. y = iris.target
  10. # 划分数据集为训练集和测试集
  11. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
  12. # 创建随机森林分类器
  13. rf_classifier = RandomForestClassifier(n_estimators=100, random_state=42)
  14. # 训练模型
  15. rf_classifier.fit(X_train, y_train)
  16. # 在测试集上进行预测
  17. y_pred = rf_classifier.predict(X_test)
  18. # 评估模型性能
  19. accuracy = accuracy_score(y_test, y_pred)
  20. print(f'Accuracy: {accuracy:.2f}')
  21. # 输出更详细的分类报告
  22. print('Classification Report:\n', classification_report(y_test, y_pred))

        在这个案例中,使用了鸢尾花数据集,将数据集划分为训练集和测试集,创建了一个包含100个决策树的随机森林分类器,并输出了模型的准确度和分类报告。你可以根据你的实际需求和数据集进行调整和修改。

案例代码2

  1. 随机森林需要调整的参数有:
  2. 1) 决策树的个数
  3. 2) 特征属性的个数
  4. 3) 递归次数(即决策树的深度)
  5. from numpy import inf
  6. from numpy import zeros
  7. import numpy as np
  8. from sklearn.model_selection import train_test_split
  9. #生成数据集。数据集包括标签,全包含在返回值的dataset上
  10. def get_Datasets():
  11. from sklearn.datasets import make_classification
  12. dataSet,classLabels=make_classification(n_samples=200,n_features=100,n_classes=2)
  13. #print(dataSet.shape,classLabels.shape)
  14. return np.concatenate((dataSet,classLabels.reshape((-1,1))),axis=1)
  15. #切分数据集,实现交叉验证。可以利用它来选择决策树个数。但本例没有实现其代码。
  16. #原理如下:
  17. #第一步,将训练集划分为大小相同的K份;
  18. #第二步,我们选择其中的K-1分训练模型,将用余下的那一份计算模型的预测值,
  19. #这一份通常被称为交叉验证集;第三步,我们对所有考虑使用的参数建立模型
  20. #并做出预测,然后使用不同的K值重复这一过程。
  21. #然后是关键,我们利用在不同的K下平均准确率最高所对应的决策树个数
  22. #作为算法决策树个数
  23. def splitDataSet(dataSet,n_folds): #将训练集划分为大小相同的n_folds份;
  24. fold_size=len(dataSet)/n_folds
  25. data_split=[]
  26. begin=0
  27. end=fold_size
  28. for i in range(n_folds):
  29. data_split.append(dataSet[begin:end,:])
  30. begin=end
  31. end+=fold_size
  32. return data_split
  33. #构建n个子集
  34. def get_subsamples(dataSet,n):
  35. subDataSet=[]
  36. for i in range(n):
  37. index=[] #每次都重新选择k个 索引
  38. for k in range(len(dataSet)): #长度是k
  39. index.append(np.random.randint(len(dataSet))) #(0,len(dataSet)) 内的一个整数
  40. subDataSet.append(dataSet[index,:])
  41. return subDataSet
  42. # subDataSet=get_subsamples(dataSet,10)
  43. #############################################################################
  44. #根据某个特征及值对数据进行分类
  45. def binSplitDataSet(dataSet,feature,value):
  46. mat0=dataSet[np.nonzero(dataSet[:,feature]>value)[0],:]
  47. mat1=dataSet[np.nonzero(dataSet[:,feature]<value)[0],:]
  48. return mat0,mat1
  49. '''
  50. feature=2
  51. value=1
  52. dataSet=get_Datasets()
  53. mat0,mat1= binSplitDataSet(dataSet,2,1)
  54. '''
  55. #计算方差,回归时使用
  56. def regErr(dataSet):
  57. return np.var(dataSet[:,-1])*np.shape(dataSet)[0]
  58. #计算平均值,回归时使用
  59. def regLeaf(dataSet):
  60. return np.mean(dataSet[:,-1])
  61. def MostNumber(dataSet): #返回多类
  62. #number=set(dataSet[:,-1])
  63. len0=len(np.nonzero(dataSet[:,-1]==0)[0])
  64. len1=len(np.nonzero(dataSet[:,-1]==1)[0])
  65. if len0>len1:
  66. return 0
  67. else:
  68. return 1
  69. #计算基尼指数 一个随机选中的样本在子集中被分错的可能性 是被选中的概率乘以被分错的概率
  70. def gini(dataSet):
  71. corr=0.0
  72. for i in set(dataSet[:,-1]): #i 是这个特征下的 某个特征值
  73. corr+=(len(np.nonzero(dataSet[:,-1]==i)[0])/len(dataSet))**2
  74. return 1-corr
  75. def select_best_feature(dataSet,m,alpha="huigui"):
  76. f=dataSet.shape[1] #拿过这个数据集,看这个数据集有多少个特征,即f个
  77. index=[]
  78. bestS=inf;
  79. bestfeature=0;bestValue=0;
  80. if alpha=="huigui":
  81. S=regErr(dataSet)
  82. else:
  83. S=gini(dataSet)
  84. for i in range(m):
  85. index.append(np.random.randint(f)) #在f个特征里随机,注意是随机!选择m个特征,然后在这m个特征里选择一个合适的分类特征。
  86. for feature in index:
  87. for splitVal in set(dataSet[:,feature]): #set() 函数创建一个无序不重复元素集,用于遍历这个特征下所有的值
  88. mat0,mat1=binSplitDataSet(dataSet,feature,splitVal)
  89. if alpha=="huigui": newS=regErr(mat0)+regErr(mat1) #计算每个分支的回归方差
  90. else:
  91. newS=gini(mat0)+gini(mat1) #计算被分错率
  92. if bestS>newS:
  93. bestfeature=feature
  94. bestValue=splitVal
  95. bestS=newS
  96. if (S-bestS)<0.001 and alpha=="huigui": # 对于回归来说,方差足够了,那就取这个分支的均值
  97. return None,regLeaf(dataSet)
  98. elif (S-bestS)<0.001:
  99. #print(S,bestS)
  100. return None,MostNumber(dataSet) #对于分类来说,被分错率足够下了,那这个分支的分类就是大多数所在的类。
  101. #mat0,mat1=binSplitDataSet(dataSet,feature,splitVal)
  102. return bestfeature,bestValue
  103. def createTree(dataSet,alpha="huigui",m=20,max_level=10): #实现决策树,使用20个特征,深度为10,
  104. bestfeature,bestValue=select_best_feature(dataSet,m,alpha=alpha)
  105. if bestfeature==None:
  106. return bestValue
  107. retTree={}
  108. max_level-=1
  109. if max_level<0: #控制深度
  110. return regLeaf(dataSet)
  111. retTree['bestFeature']=bestfeature
  112. retTree['bestVal']=bestValue
  113. lSet,rSet=binSplitDataSet(dataSet,bestfeature,bestValue) #lSet是根据特征bestfeature分到左边的向量,rSet是根据特征bestfeature分到右边的向量
  114. retTree['right']=createTree(rSet,alpha,m,max_level)
  115. retTree['left']=createTree(lSet,alpha,m,max_level) #每棵树都是二叉树,往下分类都是一分为二。
  116. #print('retTree:',retTree)
  117. return retTree
  118. def RondomForest(dataSet,n,alpha="huigui"): #树的个数
  119. #dataSet=get_Datasets()
  120. Trees=[] # 设置一个空树集合
  121. for i in range(n):
  122. X_train, X_test, y_train, y_test = train_test_split(dataSet[:,:-1], dataSet[:,-1], test_size=0.33, random_state=42)
  123. X_train=np.concatenate((X_train,y_train.reshape((-1,1))),axis=1)
  124. Trees.append(createTree(X_train,alpha=alpha))
  125. return Trees # 生成好多树
  126. ###################################################################
  127. #预测单个数据样本,重头!!如何利用已经训练好的随机森林对单个样本进行 回归或分类!
  128. def treeForecast(trees,data,alpha="huigui"):
  129. if alpha=="huigui":
  130. if not isinstance(trees,dict): #isinstance() 函数来判断一个对象是否是一个已知的类型
  131. return float(trees)
  132. if data[trees['bestFeature']]>trees['bestVal']: # 如果数据的这个特征大于阈值,那就调用左支
  133. if type(trees['left'])=='float': #如果左支已经是节点了,就返回数值。如果左支还是字典结构,那就继续调用, 用此支的特征和特征值进行选支。
  134. return trees['left']
  135. else:
  136. return treeForecast(trees['left'],data,alpha)
  137. else:
  138. if type(trees['right'])=='float':
  139. return trees['right']
  140. else:
  141. return treeForecast(trees['right'],data,alpha)
  142. else:
  143. if not isinstance(trees,dict): #分类和回归是同一道理
  144. return int(trees)
  145. if data[trees['bestFeature']]>trees['bestVal']:
  146. if type(trees['left'])=='int':
  147. return trees['left']
  148. else:
  149. return treeForecast(trees['left'],data,alpha)
  150. else:
  151. if type(trees['right'])=='int':
  152. return trees['right']
  153. else:
  154. return treeForecast(trees['right'],data,alpha)
  155. #随机森林 对 数据集打上标签 0、1 或者是 回归值
  156. def createForeCast(trees,test_dataSet,alpha="huigui"):
  157. cm=len(test_dataSet)
  158. yhat=np.mat(zeros((cm,1)))
  159. for i in range(cm): #
  160. yhat[i,0]=treeForecast(trees,test_dataSet[i,:],alpha) #
  161. return yhat
  162. #随机森林预测
  163. def predictTree(Trees,test_dataSet,alpha="huigui"): #trees 是已经训练好的随机森林 调用它!
  164. cm=len(test_dataSet)
  165. yhat=np.mat(zeros((cm,1)))
  166. for trees in Trees:
  167. yhat+=createForeCast(trees,test_dataSet,alpha) #把每次的预测结果相加
  168. if alpha=="huigui": yhat/=len(Trees) #如果是回归的话,每棵树的结果应该是回归值,相加后取平均
  169. else:
  170. for i in range(len(yhat)): #如果是分类的话,每棵树的结果是一个投票向量,相加后,
  171. #看每类的投票是否超过半数,超过半数就确定为1
  172. if yhat[i,0]>len(Trees)/2:
  173. yhat[i,0]=1
  174. else:
  175. yhat[i,0]=0
  176. return yhat
  177. if __name__ == '__main__' :
  178. dataSet=get_Datasets()
  179. print(dataSet[:,-1].T) #打印标签,与后面预测值对比 .T其实就是对一个矩阵的转置
  180. RomdomTrees=RondomForest(dataSet,4,alpha="fenlei") #这里我训练好了 很多树的集合,就组成了随机森林。一会一棵一棵的调用。
  181. print("---------------------RomdomTrees------------------------")
  182. #print(RomdomTrees[0])
  183. test_dataSet=dataSet #得到数据集和标签
  184. yhat=predictTree(RomdomTrees,test_dataSet,alpha="fenlei") # 调用训练好的那些树。综合结果,得到预测值。
  185. print(yhat.T)
  186. #get_Datasets()
  187. print(dataSet[:,-1].T-yhat.T)

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/844716
推荐阅读
相关标签
  

闽ICP备14008679号