数学建模_随机森林分类模型详解Python代码
生活随笔
收集整理的這篇文章主要介紹了
数学建模_随机森林分类模型详解Python代码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數學建模_隨機森林分類模型詳解Python代碼
隨機森林需要調整的參數有: (1) 決策樹的個數 (2) 特征屬性的個數 (3) 遞歸次數(即決策樹的深度)''' from numpy import inf from numpy import zeros import numpy as np from sklearn.model_selection import train_test_split#生成數據集。數據集包括標簽,全包含在返回值的dataset上 def get_Datasets():from sklearn.datasets import make_classificationdataSet,classLabels=make_classification(n_samples=200,n_features=100,n_classes=2)#print(dataSet.shape,classLabels.shape)return np.concatenate((dataSet,classLabels.reshape((-1,1))),axis=1)#切分數據集,實現交叉驗證。可以利用它來選擇決策樹個數。但本例沒有實現其代碼。 #原理如下: #第一步,將訓練集劃分為大小相同的K份; #第二步,我們選擇其中的K-1分訓練模型,將用余下的那一份計算模型的預測值, #這一份通常被稱為交叉驗證集;第三步,我們對所有考慮使用的參數建立模型 #并做出預測,然后使用不同的K值重復這一過程。 #然后是關鍵,我們利用在不同的K下平均準確率最高所對應的決策樹個數 #作為算法決策樹個數def splitDataSet(dataSet,n_folds): #將訓練集劃分為大小相同的n_folds份;fold_size=len(dataSet)/n_foldsdata_split=[]begin=0end=fold_sizefor i in range(n_folds):data_split.append(dataSet[begin:end,:])begin=endend+=fold_sizereturn data_split #構建n個子集 def get_subsamples(dataSet,n):subDataSet=[]for i in range(n):index=[] #每次都重新選擇k個 索引for k in range(len(dataSet)): #長度是kindex.append(np.random.randint(len(dataSet))) #(0,len(dataSet)) 內的一個整數subDataSet.append(dataSet[index,:])return subDataSet# subDataSet=get_subsamples(dataSet,10) ##############################################################################根據某個特征及值對數據進行分類 def binSplitDataSet(dataSet,feature,value):mat0=dataSet[np.nonzero(dataSet[:,feature]>value)[0],:]mat1=dataSet[np.nonzero(dataSet[:,feature]<value)[0],:]return mat0,mat1'''feature=2 value=1dataSet=get_Datasets()mat0,mat1= binSplitDataSet(dataSet,2,1) '''#計算方差,回歸時使用 def regErr(dataSet):return np.var(dataSet[:,-1])*np.shape(dataSet)[0]#計算平均值,回歸時使用 def regLeaf(dataSet):return np.mean(dataSet[:,-1])def MostNumber(dataSet): #返回多類#number=set(dataSet[:,-1])len0=len(np.nonzero(dataSet[:,-1]==0)[0])len1=len(np.nonzero(dataSet[:,-1]==1)[0])if len0>len1:return 0else:return 1#計算基尼指數 一個隨機選中的樣本在子集中被分錯的可能性 是被選中的概率乘以被分錯的概率 def gini(dataSet):corr=0.0for i in set(dataSet[:,-1]): #i 是這個特征下的 某個特征值corr+=(len(np.nonzero(dataSet[:,-1]==i)[0])/len(dataSet))**2return 1-corrdef select_best_feature(dataSet,m,alpha="huigui"):f=dataSet.shape[1] #拿過這個數據集,看這個數據集有多少個特征,即f個index=[]bestS=inf;bestfeature=0;bestValue=0;if alpha=="huigui":S=regErr(dataSet)else:S=gini(dataSet)for i in range(m):index.append(np.random.randint(f)) #在f個特征里隨機,注意是隨機!選擇m個特征,然后在這m個特征里選擇一個合適的分類特征。 for feature in index:for splitVal in set(dataSet[:,feature]): #set() 函數創建一個無序不重復元素集,用于遍歷這個特征下所有的值mat0,mat1=binSplitDataSet(dataSet,feature,splitVal) if alpha=="huigui": newS=regErr(mat0)+regErr(mat1) #計算每個分支的回歸方差else:newS=gini(mat0)+gini(mat1) #計算被分錯率if bestS>newS:bestfeature=featurebestValue=splitValbestS=newS if (S-bestS)<0.001 and alpha=="huigui": # 對于回歸來說,方差足夠了,那就取這個分支的均值return None,regLeaf(dataSet)elif (S-bestS)<0.001:#print(S,bestS)return None,MostNumber(dataSet) #對于分類來說,被分錯率足夠下了,那這個分支的分類就是大多數所在的類。#mat0,mat1=binSplitDataSet(dataSet,feature,splitVal)return bestfeature,bestValuedef createTree(dataSet,alpha="huigui",m=20,max_level=10): #實現決策樹,使用20個特征,深度為10,bestfeature,bestValue=select_best_feature(dataSet,m,alpha=alpha)if bestfeature==None:return bestValueretTree={}max_level-=1if max_level<0: #控制深度return regLeaf(dataSet)retTree['bestFeature']=bestfeatureretTree['bestVal']=bestValuelSet,rSet=binSplitDataSet(dataSet,bestfeature,bestValue) #lSet是根據特征bestfeature分到左邊的向量,rSet是根據特征bestfeature分到右邊的向量retTree['right']=createTree(rSet,alpha,m,max_level)retTree['left']=createTree(lSet,alpha,m,max_level) #每棵樹都是二叉樹,往下分類都是一分為二。#print('retTree:',retTree)return retTreedef RondomForest(dataSet,n,alpha="huigui"): #樹的個數#dataSet=get_Datasets()Trees=[] # 設置一個空樹集合for i in range(n):X_train, X_test, y_train, y_test = train_test_split(dataSet[:,:-1], dataSet[:,-1], test_size=0.33, random_state=42)X_train=np.concatenate((X_train,y_train.reshape((-1,1))),axis=1)Trees.append(createTree(X_train,alpha=alpha))return Trees # 生成好多樹 ####################################################################預測單個數據樣本,重頭!!如何利用已經訓練好的隨機森林對單個樣本進行 回歸或分類! def treeForecast(trees,data,alpha="huigui"): if alpha=="huigui":if not isinstance(trees,dict): #isinstance() 函數來判斷一個對象是否是一個已知的類型return float(trees)if data[trees['bestFeature']]>trees['bestVal']: # 如果數據的這個特征大于閾值,那就調用左支if type(trees['left'])=='float': #如果左支已經是節點了,就返回數值。如果左支還是字典結構,那就繼續調用, 用此支的特征和特征值進行選支。 return trees['left']else:return treeForecast(trees['left'],data,alpha)else:if type(trees['right'])=='float':return trees['right']else:return treeForecast(trees['right'],data,alpha) else:if not isinstance(trees,dict): #分類和回歸是同一道理return int(trees)if data[trees['bestFeature']]>trees['bestVal']:if type(trees['left'])=='int':return trees['left']else:return treeForecast(trees['left'],data,alpha)else:if type(trees['right'])=='int':return trees['right']else:return treeForecast(trees['right'],data,alpha) #隨機森林 對 數據集打上標簽 0、1 或者是 回歸值 def createForeCast(trees,test_dataSet,alpha="huigui"):cm=len(test_dataSet) yhat=np.mat(zeros((cm,1)))for i in range(cm): #yhat[i,0]=treeForecast(trees,test_dataSet[i,:],alpha) #return yhat#隨機森林預測 def predictTree(Trees,test_dataSet,alpha="huigui"): #trees 是已經訓練好的隨機森林 調用它!cm=len(test_dataSet) yhat=np.mat(zeros((cm,1))) for trees in Trees:yhat+=createForeCast(trees,test_dataSet,alpha) #把每次的預測結果相加if alpha=="huigui": yhat/=len(Trees) #如果是回歸的話,每棵樹的結果應該是回歸值,相加后取平均else:for i in range(len(yhat)): #如果是分類的話,每棵樹的結果是一個投票向量,相加后,#看每類的投票是否超過半數,超過半數就確定為1if yhat[i,0]>len(Trees)/2: yhat[i,0]=1else:yhat[i,0]=0return yhatif __name__ == '__main__' :dataSet=get_Datasets() print(dataSet[:,-1].T) #打印標簽,與后面預測值對比 .T其實就是對一個矩陣的轉置RomdomTrees=RondomForest(dataSet,4,alpha="fenlei") #這里我訓練好了 很多樹的集合,就組成了隨機森林。一會一棵一棵的調用。print("---------------------RomdomTrees------------------------")#print(RomdomTrees[0])test_dataSet=dataSet #得到數據集和標簽yhat=predictTree(RomdomTrees,test_dataSet,alpha="fenlei") # 調用訓練好的那些樹。綜合結果,得到預測值。print(yhat.T) #get_Datasets()print(dataSet[:,-1].T-yhat.T) 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的数学建模_随机森林分类模型详解Python代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数学建模——逻辑回归模型Python代码
- 下一篇: 数学建模——线性规划模型详解Python