国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python實現的隨機森林算法與簡單總結

2020-01-04 16:01:17
字體:
來源:轉載
供稿:網友

本文實例講述了Python實現的隨機森林算法。分享給大家供大家參考,具體如下:

隨機森林是數據挖掘中非常常用的分類預測算法,以分類或回歸的決策樹為基分類器。算法的一些基本要點:

*對大小為m的數據集進行樣本量同樣為m的有放回抽樣;
*對K個特征進行隨機抽樣,形成特征的子集,樣本量的確定方法可以有平方根、自然對數等;
*每棵樹完全生成,不進行剪枝;
*每個樣本的預測結果由每棵樹的預測投票生成(回歸的時候,即各棵樹的葉節點的平均)

著名的python機器學習包scikit learn的文檔對此算法有比較詳盡的介紹: http://scikit-learn.org/stable/modules/ensemble.html#random-forests

出于個人研究和測試的目的,基于經典的Kaggle 101泰坦尼克號乘客的數據集,建立模型并進行評估。比賽頁面及相關數據集的下載:https://www.kaggle.com/c/titanic

泰坦尼克號的沉沒,是歷史上非常著名的海難。突然感到,自己面對的不再是冷冰冰的數據,而是用數據挖掘的方法,去研究具體的歷史問題,也是饒有興趣。言歸正傳,模型的主要的目標,是希望根據每個乘客的一系列特征,如性別、年齡、艙位、上船地點等,對其是否能生還進行預測,是非常典型的二分類預測問題。數據集的字段名及實例如下:

 

PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
1 0 3 Braund, Mr. Owen Harris male 22 1 0 A/5 21171 7.25   S
2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female 38 1 0 PC 17599 71.2833 C85 C
3 1 3 Heikkinen, Miss. Laina female 26 0 0 STON/O2. 3101282 7.925   S
4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35 1 0 113803 53.1 C123 S
5 0 3 Allen, Mr. William Henry male 35 0 0 373450 8.05   S

 

值得說明的是,SibSp是指sister brother spouse,即某個乘客隨行的兄弟姐妹、丈夫、妻子的人數,Parch指parents,children

下面給出整個數據處理及建模過程,基于ubuntu+python 3.4( anaconda科學計算環境已經集成一系列常用包,pandas numpy sklearn等,這里強烈推薦)

懶得切換輸入法,寫的時候主要的注釋都是英文,中文的注釋是后來補充的:-)

# -*- coding: utf-8 -*-"""@author: kim"""from model import *#載入基分類器的代碼#ETL:same procedure to training set and test settraining=pd.read_csv('train.csv',index_col=0)test=pd.read_csv('test.csv',index_col=0)SexCode=pd.DataFrame([1,0],index=['female','male'],columns=['Sexcode']) #將性別轉化為01training=training.join(SexCode,how='left',on=training.Sex)training=training.drop(['Name','Ticket','Embarked','Cabin','Sex'],axis=1)#刪去幾個不參與建模的變量,包括姓名、船票號,船艙號test=test.join(SexCode,how='left',on=test.Sex)test=test.drop(['Name','Ticket','Embarked','Cabin','Sex'],axis=1)print('ETL IS DONE!')#MODEL FITTING#===============PARAMETER AJUSTMENT============min_leaf=1min_dec_gini=0.0001n_trees=5n_fea=int(math.sqrt(len(training.columns)-1))#=============================================='''''BEST SCORE:0.83min_leaf=30min_dec_gini=0.001n_trees=20'''#ESSEMBLE BY RANDOM FORESTFOREST={}tmp=list(training.columns)tmp.pop(tmp.index('Survived'))feaList=pd.Series(tmp)for t in range(n_trees):#  fea=[]  feasample=feaList.sample(n=n_fea,replace=False)#select feature  fea=feasample.tolist()  fea.append('Survived')#    feaNew=fea.append(target)  subset=training.sample(n=len(training),replace=True)#generate the dataset with replacement  subset=subset[fea]#  print(str(t)+' Classifier built on feature:')#  print(list(fea))  FOREST[t]=tree_grow(subset,'Survived',min_leaf,min_dec_gini) #save the tree#MODEL PREDICTION#======================currentdata=trainingoutput='submission_rf_20151116_30_0.001_20'#======================prediction={}for r in currentdata.index:#a row  prediction_vote={1:0,0:0}  row=currentdata.get(currentdata.index==r)  for n in range(n_trees):    tree_dict=FOREST[n] #a tree    p=model_prediction(tree_dict,row)    prediction_vote[p]+=1  vote=pd.Series(prediction_vote)  prediction[r]=list(vote.order(ascending=False).index)[0]#the vote resultresult=pd.Series(prediction,name='Survived_p')#del prediction_vote#del prediction#result.to_csv(output)t=training.join(result,how='left')accuracy=round(len(t[t['Survived']==t['Survived_p']])/len(t),5)print(accuracy)

上述是隨機森林的代碼,如上所述,隨機森林是一系列決策樹的組合,決策樹每次分裂,用Gini系數衡量當前節點的“不純凈度”,如果按照某個特征的某個分裂點對數據集劃分后,能夠讓數據集的Gini下降最多(顯著地減少了數據集輸出變量的不純度),則選為當前最佳的分割特征及分割點。代碼如下:

# -*- coding: utf-8 -*-"""@author: kim"""import pandas as pdimport numpy as np#import sklearn as skimport mathdef tree_grow(dataframe,target,min_leaf,min_dec_gini):  tree={} #renew a tree  is_not_leaf=(len(dataframe)>min_leaf)  if is_not_leaf:    fea,sp,gd=best_split_col(dataframe,target)    if gd>min_dec_gini:      tree['fea']=fea      tree['val']=sp#      dataframe.drop(fea,axis=1) #1116 modified      l,r=dataSplit(dataframe,fea,sp)      l.drop(fea,axis=1)      r.drop(fea,axis=1)      tree['left']=tree_grow(l,target,min_leaf,min_dec_gini)      tree['right']=tree_grow(r,target,min_leaf,min_dec_gini)    else:#return a leaf      return leaf(dataframe[target])  else:    return leaf(dataframe[target])  return treedef leaf(class_lable):  tmp={}  for i in class_lable:    if i in tmp:      tmp[i]+=1    else:      tmp[i]=1  s=pd.Series(tmp)  s.sort(ascending=False)  return s.index[0]def gini_cal(class_lable):  p_1=sum(class_lable)/len(class_lable)  p_0=1-p_1  gini=1-(pow(p_0,2)+pow(p_1,2))  return ginidef dataSplit(dataframe,split_fea,split_val):  left_node=dataframe[dataframe[split_fea]<=split_val]  right_node=dataframe[dataframe[split_fea]>split_val]  return left_node,right_nodedef best_split_col(dataframe,target_name):  best_fea=''#modified 1116  best_split_point=0  col_list=list(dataframe.columns)  col_list.remove(target_name)  gini_0=gini_cal(dataframe[target_name])  n=len(dataframe)  gini_dec=-99999999  for col in col_list:    node=dataframe[[col,target_name]]    unique=node.groupby(col).count().index    for split_point in unique: #unique value      left_node,right_node=dataSplit(node,col,split_point)      if len(left_node)>0 and len(right_node)>0:        gini_col=gini_cal(left_node[target_name])*(len(left_node)/n)+gini_cal(right_node[target_name])*(len(right_node)/n)        if (gini_0-gini_col)>gini_dec:          gini_dec=gini_0-gini_col#decrease of impurity          best_fea=col          best_split_point=split_point    #print(col,split_point,gini_0-gini_col)  return best_fea,best_split_point,gini_decdef model_prediction(model,row): #row is a df  fea=model['fea']  val=model['val']  left=model['left']  right=model['right']  if row[fea].tolist()[0]<=val:#get the value    branch=left  else:    branch=right  if ('dict' in str( type(branch) )):    prediction=model_prediction(branch,row)  else:    prediction=branch  return prediction

實際上,上面的代碼還有很大的效率提升的空間,數據集不是很大的情況下,如果選擇一個較大的輸入參數,例如生成100棵樹,就會顯著地變慢;同時,將預測結果提交至kaggle進行評測,發現在測試集上的正確率不是很高,比使用sklearn里面相應的包進行預測的正確率(0.77512)要稍低一點 :-(  如果要提升準確率,兩個大方向: 構造新的特征;調整現有模型的參數。

這里是拋磚引玉,歡迎大家對我的建模思路和算法的實現方法提出修改意見。

 

希望本文所述對大家Python程序設計有所幫助。


注:相關教程知識閱讀請移步到python教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 铜鼓县| 乳山市| 大城县| 大新县| 寻甸| 泽普县| 申扎县| 内丘县| 襄樊市| 太保市| 余干县| 繁昌县| 高台县| 临西县| 宁乡县| 乐昌市| 文化| 呼伦贝尔市| 安西县| 东港市| 海城市| 睢宁县| 兰考县| 孟津县| 绍兴县| 保康县| 河西区| 襄樊市| 信宜市| 阿合奇县| 德阳市| 开封县| 金堂县| 嘉鱼县| 尉犁县| 江口县| 泰宁县| 龙川县| 太仆寺旗| 田阳县| 博客|