精华内容
下载资源
问答
  • 随机生存森林对心律失常患者一年死亡率的风险预测
  • 将基因相互作用信息整合到加权随机生存森林方法中,以进行准确的生存预测和生存生物标志物发现
  • 用R的randomForestSRC包做生存分析用randomForestSRC做生存分析导入randomForestSRC包准备生存分析的数据构建模型,进行生存分析绘图 用randomForestSRC做生存分析 导入randomForestSRC包 在R中的实现如如下图所示 ...

    用randomForestSRC做生存分析

    导入randomForestSRC包

    在R中的实现如如下图所示
    在这里插入图片描述

    准备生存分析的数据

    在R中的实现如下图所示
    在这里插入图片描述
    在上图中,data_express即是我们要进行生存分析的数据,数据共有411个样本。

    构建模型,进行生存分析

    在R中的实现如下图所示
    在这里插入图片描述

    绘图

    在R中的实现如下图所示
    在这里插入图片描述
    绘图结果如下
    在这里插入图片描述

    展开全文
  • 基于python使用随机森林算法进行生存分析和实验
  • 随机生存森林 随机生存森林通过训练大量生存树,以表决的形式,从个体树之中加权选举出最终的预测结果。 构建随机生存森林的一般流程为: Ⅰ. 模型通过“自助法”(Bootstrap)将原始数据以有放回的形式随机抽取样本...

    机器学习系列|基于随机森林的生存分析模型-R实战

    图片

    随机生存森林

    随机生存森林通过训练大量生存树,以表决的形式,从个体树之中加权选举出最终的预测结果。

    构建随机生存森林的一般流程为:

    Ⅰ. 模型通过“自助法”(Bootstrap)将原始数据以有放回的形式随机抽取样本,建立样本子集,并将每个样本中37%的数据作为袋外数据(Out-of-Bag Data)排除在外;

    Ⅱ. 对每一个样本随机选择特征构建其对应的生存树;

    Ⅲ. 利用Nelson-Aalen法估计随机生存森林模型的总累积风险;

    Ⅳ. 使用袋外数据计算模型准确度。

    案 例

    以美国梅奥诊所在1974—1984年间收集的原发性胆汁性胆管炎(primarybiliarycholangitis,PBC)数据为例,通过构建随机生存森林模型来探究D-青霉胺(DPCA)治疗对于原发性胆汁性胆管炎生存的影响。同时,也探讨其他主要临床指标是否也对PBC的生存有影响。原始数据共有总计418例患有PBC的研究对象,其中时间(time)的单位为生存天数,在此换算为生存年数。由于只考虑单次复发的情况,原始数据“status”变量中的事件重新分组为“0”(删失)和“1”(事件)。

    随机生存森林的构建:

    通过“randomForestSRC”包中的rfsrc函数构建随机生存森林模型。

    #建立随机生存森林模型rfsrc_pbcmy <- rfsrc(Surv(days, status) ~ .,                data = data_train, nsplit = 10,                na.action = "na.impute", tree.err = TRUE,                 importance = TRUE)
    

    结果如下,包括模型的一些默认参数设置等信息:

    变量输出值
    Sample size312
    Number of deaths121
    Was data imputedyes
    Numberoftrees1000
    Forest terminal node size15
    Average no. of terminal nodes15.779
    No. of variables tried at each split5
    Total no. of variables17
    Resampling used to grow treesswor
    Resample size used to grow trees197
    AnalysisRSF
    Familysurv
    Splitting rulelogrankrandom
    Number of random split points10
    Error rate19.85%

    随机生存森林使用了Harrell的一致性指数(concordance index)来计算其准确度。从上表可以看出模型的C-index约为1-Error rate = 1-19.85% = 0.8。模型默认生成了1000个二元生存树,从下图可以看出当生存树增加到一定数量后,错误率(Error rate)曲线趋于平稳(19.85%),说明树的棵数是合适的。

    #袋外数据错误率与生存树数量关系的可视化rfsrc_error <- gg_error(rfsrc_pbcmy)rfsrc_error <- na.omit(rfsrc_error)plot(rfsrc_error)
    

    图片

    变量筛选和结论

    随机生存森林可以对变量重要性进行排名,VIMP法和最小深度法是最常用的方法:变量VIMP值小于0说明该变量降低了预测的准确性,而当VIMP值大于0则说明该变量提高了预测的准确性;最小深度法通过计算运行到最终节点时的最小深度来给出各变量对于结局事件的重要性。

    下图为综合两种方法的散点图,其中,蓝色点代表VIMP值大于0,红色则代表VIMP值小于0;在红色对角虚线上的点代表两种方法对该变量的排名相同,高于对角虚线的点代表其VIMP排名更高,低于对角虚线的点则代表其最小深度排名更高。

    图片

    **相较于Cox比例风险回归模型等传统生存分析方法,随机生存森林模型的预测准确度至少等同或优于传统生存分析方法。**随机生存森林模型的优势体现在它不受比例风险假定、对数线性假定等条件的约束。同时,随机生存森林具备一般随机森林的优点,能够通过两个随机采样的过程来防止其算法的过度拟合问题。除此之外,随机生存森林还能够对高维数据进行生存分析和变量筛选,也能够应用于对竞争风险(competing risk)的分析。因而,随机生存森林模型有着更为广泛的研究空间。

    **但是随机生存森林也存在缺陷:易受离群值的影响。**分析中有离群值数据时,预测准确度会稍劣于传统生存分析方法。Cox比例风险回归模型对于生存数据的分析不仅仅用于预测,还可以较为便捷地给出各变量与生存结局的关系,所以随机生存森林模型应该和传统生存分析相结合应用,并不能完全替代传统生存分析模型。

    参考文献:

    [1]陈哲,许恒敏,李哲轩,等.随机生存森林:基于机器学习算法的生存分析模型[J].中华预防医学杂志,2021,55(01):104-109.

    [2]KayR.Goodnessoffitmethodsfortheproportionalhazardsregressionmodel:areview[J].RevEpidemiolSantePublique,1984,32(3-4):185-198.IshwaranH,KogalurUB,BlackstoneEH,etal.Randomsurvivalforests[J].AnnApplStat,2008,2(3):841-860.DOI:10.1214/08-aoas169.

    [3]ZhouY,McArdleJJ.RationaleandApplicationsofSurvivalTreeandSurvivalEnsembleMethods[J].Psychometrika,2015,80(3):811-833.DOI:10.1007/s11336-014-9413-1.

    [4]CuzickJ.Countingprocessesandsurvivalanalysis.ThomasR.FlemingandDavidP.Harrington,Wiley,NewYork,1991[J].StatisticsinMedicine,1992,11(13):1792-1793.DOI:10.1002/sim.478011131

    展开全文
  • 随机森林 kaggle 数据挖掘 categories: 数据挖掘 mathjax: true 文章目录前言:1 数据预处理1.1 读入数据1.2 训练集与数据集1.2.1 查看数据完整性1.2.2 查看训练数据描述信息1.3.1 年龄数据简化分组2 数据可视化2.1...

    tags:

    • 随机森林
    • kaggle
    • 数据挖掘
      categories: 数据挖掘
      mathjax: true

    前言:

    • Kaggle数据挖掘竞赛:使用随机森林预测泰坦尼克号生存情况

    数据来源kaggle

    1 数据预处理

    1.1 读入数据

    import pandas as pd
    data_train = pd.read_csv(r'train.csv')
    data_test = pd.read_csv(r'test.csv')
    data_train.head()
    
    PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
    0103Braund, Mr. Owen Harrismale22.010A/5 211717.2500NaNS
    1211Cumings, Mrs. John Bradley (Florence Briggs Th...female38.010PC 1759971.2833C85C
    2313Heikkinen, Miss. Lainafemale26.000STON/O2. 31012827.9250NaNS
    3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female35.01011380353.1000C123S
    4503Allen, Mr. William Henrymale35.0003734508.0500NaNS

    1.2 训练集与数据集

    data_test.head()
    
    PassengerIdPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
    08923Kelly, Mr. Jamesmale34.5003309117.8292NaNQ
    18933Wilkes, Mrs. James (Ellen Needs)female47.0103632727.0000NaNS
    28942Myles, Mr. Thomas Francismale62.0002402769.6875NaNQ
    38953Wirz, Mr. Albertmale27.0003151548.6625NaNS
    48963Hirvonen, Mrs. Alexander (Helga E Lindqvist)female22.011310129812.2875NaNS

    1.2.1 查看数据完整性

    data_train.info()
    
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 891 entries, 0 to 890
    Data columns (total 12 columns):
    PassengerId    891 non-null int64
    Survived       891 non-null int64
    Pclass         891 non-null int64
    Name           891 non-null object
    Sex            891 non-null object
    Age            714 non-null float64
    SibSp          891 non-null int64
    Parch          891 non-null int64
    Ticket         891 non-null object
    Fare           891 non-null float64
    Cabin          204 non-null object
    Embarked       889 non-null object
    dtypes: float64(2), int64(5), object(5)
    memory usage: 83.7+ KB
    

    总共有891组数据,其中age是714条,Cabin是204条,共计12个变量

    乘客ID,存活情况,船票级别,乘客姓名,性别,年龄,船上的兄弟姐妹以及配偶的人数,船上的父母以及子女的人数,船票编号,船票费用,所在船舱,登船的港口

    1.2.2 查看训练数据描述信息

    data_train.describe()
    
    PassengerIdSurvivedPclassAgeSibSpParchFare
    count891.000000891.000000891.000000714.000000891.000000891.000000891.000000
    mean446.0000000.3838382.30864229.6991180.5230080.38159432.204208
    std257.3538420.4865920.83607114.5264971.1027430.80605749.693429
    min1.0000000.0000001.0000000.4200000.0000000.0000000.000000
    25%223.5000000.0000002.00000020.1250000.0000000.0000007.910400
    50%446.0000000.0000003.00000028.0000000.0000000.00000014.454200
    75%668.5000001.0000003.00000038.0000001.0000000.00000031.000000
    max891.0000001.0000003.00000080.0000008.0000006.000000512.329200

    mean代表各项的均值,获救率为0.383838

    1.3.1 年龄数据简化分组

    def simplify_ages(df):
        #把缺失值补上,方便分组
        df.Age = df.Age.fillna(-0.5)
       
        #把Age分为不同区间,-1到0,1-5,6-12...,60以上,放到bins里,八个区间,对应的八个区间名称在group_names那
        bins = (-1, 0, 5, 12, 18, 25, 35, 60, 120)
        group_names = ['Unknown', 'Baby', 'Child', 'Teenager', 'Student', 'Young Adult', 'Adult', 'Senior']
        
        #开始对数据进行离散化,pandas.cut就是这个功能
        catagories = pd.cut(df.Age,bins,labels=group_names)
        df.Age = catagories
        return df
    
    

    简化Cabin,就是取字母

    def simplify_cabin(df):
        df.Cabin = df.Cabin.fillna('N')
        df.Cabin = df.Cabin.apply(lambda x:x[0])
        return df
    

    简化工资,也就是分组

    def simplify_fare(df):
        df.Fare = df.Fare.fillna(-0.5)
        bins = (-1, 0, 8, 15, 31, 1000)
        group_names = ['Unknown', '1_quartile', '2_quartile', '3_quartile', '4_quartile']
        catagories = pd.cut(df.Fare,bins,labels=group_names)
        df.Fare = catagories
        return df
    

    删除无用信息

    def simplify_drop(df):
        return df.drop(['Name','Ticket','Embarked'],axis=1)
    

    整合一遍,凑成新表

    def transform_features(df):
        df = simplify_ages(df)
        df = simplify_cabin(df)
        df = simplify_fare(df)
        df = simplify_drop(df)
        return df
    

    执行读取新表

    #必须要再读取一遍原来的表,不然会报错,不仅训练集要简化,测试集也要,两者的特征名称要一致
    data_train = pd.read_csv(r'train.csv')
    data_train = transform_features(data_train)
    data_test = transform_features(data_test)
    data_train.head()
    
    PassengerIdSurvivedPclassSexAgeSibSpParchFareCabin
    0103maleStudent101_quartileN
    1211femaleAdult104_quartileC
    2313femaleYoung Adult001_quartileN
    3411femaleYoung Adult104_quartileC
    4503maleYoung Adult002_quartileN
    #data_train=data_train.drop(["PassengerId","Cabin","Name"],axis=1)
    data_train.head(200)
    
    SurvivedPclassSexAgeSibSpParchTicketFareEmbarked
    003male22.010A/5 211717.2500S
    111female38.010PC 1759971.2833C
    213female26.000STON/O2. 31012827.9250S
    311female35.01011380353.1000S
    403male35.0003734508.0500S
    ..............................
    19511female58.000PC 17569146.5208C
    19603maleNaN003687037.7500Q
    19703male42.00145798.4042S
    19813femaleNaN003703707.7500Q
    19902female24.00024874713.0000S

    200 rows × 9 columns

    选取我们需要的那几个列作为输入, 对于票价和姓名我就舍弃了,姓名没什么用

    cols = ['PassengerId','Survived','Pclass','Sex','Age','SibSp','Parch','Fare','Embarked']
    data_tr=data_train[cols].copy()
    data_tr.head()
    
    PassengerIdSurvivedPclassSexAgeSibSpParchFareEmbarked
    0103male22.0107.2500S
    1211female38.01071.2833C
    2313female26.0007.9250S
    3411female35.01053.1000S
    4503male35.0008.0500S
    cols = ['PassengerId','Pclass','Sex','Age','SibSp','Parch','Fare','Embarked']
    data_te=data_test[cols].copy()
    data_te.head()
    
    PassengerIdPclassSexAgeSibSpParchFareEmbarked
    08923male34.5007.8292Q
    18933female47.0107.0000S
    28942male62.0009.6875Q
    38953male27.0008.6625S
    48963female22.01112.2875S
    data_tr.isnull().sum()
    data_te.isnull().sum()
    
    PassengerId     0
    Pclass          0
    Sex             0
    Age            86
    SibSp           0
    Parch           0
    Fare            1
    Embarked        0
    dtype: int64
    

    填充数据,,,,,,

    age_mean = data_tr['Age'].mean()
    data_tr['Age'] = data_tr['Age'].fillna(age_mean)
    data_tr['Embarked'] = data_tr['Embarked'].fillna('S')
    data_tr.isnull().sum()
    
    
    PassengerId    0
    Survived       0
    Pclass         0
    Sex            0
    Age            0
    SibSp          0
    Parch          0
    Fare           0
    Embarked       0
    dtype: int64
    
    data_tr.head()
    
    PassengerIdSurvivedPclassSexAgeSibSpParchFareEmbarked
    0103male22.0107.2500S
    1211female38.01071.2833C
    2313female26.0007.9250S
    3411female35.01053.1000S
    4503male35.0008.0500S

    用数组特征化编码年龄和S C Q等等,,因为随机森林的输入需要数值,字符不行

    #import numpy as np
    age_mean = data_te['Age'].mean()
    data_te['Age'] = data_te['Age'].fillna(age_mean)
    age_mean = data_te['Fare'].mean()
    data_te['Fare'] = data_te['Fare'].fillna(age_mean)
    #data_te.replace(np.na, 0, inplace=True)
    #data_te.replace(np.inf, 0, inplace=True)
    data_te['Sex']= data_te['Sex'].map({'female':0, 'male': 1}).astype(int)
    data_te['Embarked']= data_te['Embarked'].map({'S':0, 'C': 1,'Q':2}).astype(int)
    data_te.head()
    
    PassengerIdPclassSexAgeSibSpParchFareEmbarked
    08923134.5007.82922
    18933047.0107.00000
    28942162.0009.68752
    38953127.0008.66250
    48963022.01112.28750
    data_tr['Sex']= data_tr['Sex'].map({'female':0, 'male': 1}).astype(int)
    data_tr['Embarked']= data_tr['Embarked'].map({'S':0, 'C': 1,'Q':2}).astype(int)
    data_tr.head()
    #data_tr = pd.get_dummies(data_tr=data_tr,columns=['Embarked'])
    
    PassengerIdSurvivedPclassSexAgeSibSpParchFareEmbarked
    0103122.0107.25000
    1211038.01071.28331
    2313026.0007.92500
    3411035.01053.10000
    4503135.0008.05000

    2 数据可视化

    2.1 年龄和生存率之间的关系

    sns.barplot(x='Embarked',y='Survived',hue='Sex',data=data_train)
    
    <matplotlib.axes._subplots.AxesSubplot at 0x7fee5875e3c8>
    

    png

    • female的获救率大于 male,(应该是男士都比较绅士吧,即使面对死亡,也希望将最后的机会留给女生,,电影感悟)
    • 获救率 C 男性女性都是最高,Q时男性最低,S 时 女性最低
    • 男性的获救率低于女性的三分之一

    2.2 所做的位置和生存率之间的关系

    sns.pointplot(x='Pclass',y='Survived',hue='Sex',data=data_train,palette={'male':'blue','female':'pink'},
                 marker=['*',"o"],linestyle=['-','--'])
    
    <matplotlib.axes._subplots.AxesSubplot at 0x7fee586f70b8>
    

    png

    • 等级越高获救率越高
    • 女性大于男性

    2.3 生存率与年龄的关系

    sns.barplot(x = 'Age',y = 'Survived',hue='Sex',data = data_train)
    
    <matplotlib.axes._subplots.AxesSubplot at 0x7fee587238d0>
    

    png

    • 男性大于女性
    • student的生存率最低,bady的生存率最高
    sns.barplot(x = 'Cabin',y = 'Survived',hue='Sex',data = data_train)
    
    <matplotlib.axes._subplots.AxesSubplot at 0x7fee585b0748>
    

    png

    sns.barplot(x = 'Fare',y = 'Survived',hue='Sex',data = data_train)
    
    <matplotlib.axes._subplots.AxesSubplot at 0x7fee5852b390>
    

    png

    3 建立模型

    3.1 随机森林

    from sklearn.model_selection import train_test_split
    X_all = data_tr.drop(['PassengerId','Survived'],axis=1)#主要是乘客ID也没啥用,删就删了吧
    y_all = data_tr['Survived']
    p = 0.2 #用 百分之20作为测试集
    
    X_train,X_test, y_train, y_test = train_test_split(X_all,y_all,test_size=p, random_state=23)
    
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.metrics import make_scorer, accuracy_score
    from sklearn.model_selection import GridSearchCV
    
    #选择分类器的类型,我没试过其他的哦,因为在这个案例中,有人做过试验发现随机森林模型是最好的,所以选了它。呜呜,我下次试试其他的
    clf = RandomForestClassifier()
    
    #可以通过定义树的各种参数,限制树的大小,防止出现过拟合现象哦,也可以通过剪枝来限制,但sklearn中的决策树分类器目前不支持剪枝
    parameters = {'n_estimators': [4, 6, 9], 
                  'max_features': ['log2', 'sqrt','auto'], 
                  'criterion': ['entropy', 'gini'],        #分类标准用熵,基尼系数
                  'max_depth': [2, 3, 5, 10], 
                  'min_samples_split': [2, 3, 5],
                  'min_samples_leaf': [1,5,8]
                 }
    
    #以下是用于比较参数好坏的评分,使用'make_scorer'将'accuracy_score'转换为评分函数
    acc_scorer = make_scorer(accuracy_score)
    
    #自动调参,GridSearchCV,它存在的意义就是自动调参,只要把参数输进去,就能给出最优化的结果和参数
    #GridSearchCV用于系统地遍历多种参数组合,通过交叉验证确定最佳效果参数。
    grid_obj = GridSearchCV(clf,parameters,scoring=acc_scorer)
    grid_obj = grid_obj.fit(X_train,y_train)
    
    #将clf设置为参数的最佳组合
    clf = grid_obj.best_estimator_
    
    #将最佳算法运用于数据中
    clf.fit(X_train,y_train)
    
    /home/wvdon/anaconda3/envs/weidong/lib/python3.7/site-packages/sklearn/model_selection/_split.py:1978: FutureWarning: The default value of cv will change from 3 to 5 in version 0.22. Specify it explicitly to silence this warning.
      warnings.warn(CV_WARNING, FutureWarning)
    /home/wvdon/anaconda3/envs/weidong/lib/python3.7/site-packages/sklearn/model_selection/_search.py:814: DeprecationWarning: The default of the `iid` parameter will change from True to False in version 0.22 and will be removed in 0.24. This will change numeric results when test-set sizes are unequal.
      DeprecationWarning)
    
    
    
    
    
    RandomForestClassifier(bootstrap=True, class_weight=None, criterion='entropy',
                           max_depth=5, max_features='sqrt', max_leaf_nodes=None,
                           min_impurity_decrease=0.0, min_impurity_split=None,
                           min_samples_leaf=1, min_samples_split=3,
                           min_weight_fraction_leaf=0.0, n_estimators=4,
                           n_jobs=None, oob_score=False, random_state=None,
                           verbose=0, warm_start=False)
    

    3.2 预测

    predictions = clf.predict(X_test)
    print(accuracy_score(y_test,predictions))
    data_tr
    
    0.8268156424581006
    
    PassengerIdSurvivedPclassSexAgeSibSpParchFareEmbarked
    0103122.000000107.25000
    1211038.0000001071.28331
    2313026.000000007.92500
    3411035.0000001053.10000
    4503135.000000008.05000
    ..............................
    88688702127.0000000013.00000
    88788811019.0000000030.00000
    88888903029.6991181223.45000
    88989011126.0000000030.00001
    89089103132.000000007.75002

    891 rows × 9 columns

    3.3 预测test文件

    predictions = clf.predict(data_te.drop('PassengerId',axis=1))
    output = pd.DataFrame({'Passengers':data_te['PassengerId'],'Survived':predictions})
    output.to_csv(r'test1.csv')
    output.head()
    
    PassengersSurvived
    08920
    18930
    28940
    38950
    48960

    3.4 提交到kaggle官网

    结果是 0.77990
    hhhhhhhh还是比较满意的
    下次用深度学习试试

    
    
    展开全文
  • 随机森林:泰坦尼克号生存预测随机森林
  • 随机森林实现代码

    千次阅读 2020-10-12 21:09:51
    该代码使用python实现了,随机森林算法 使用数据库为Adult数据库,可以用来预测居民收入是否超过50K/year。该数据集类变量为年收入是否超过50k,属性变量包含年龄,工种,学历,职业,人种等重要信息,14个属性变量...

    该代码使用python实现了,随机森林算法

    使用数据库为Adult数据库,可以用来预测居民收入是否超过50K/year。该数据集类变量为年收入是否超过50k,属性变量包含年龄,工种,学历,职业,人种等重要信息,14个属性变量中有7个类别型变量。

    数据库操作

    引入数据库

    import pandas as pd
    import numpy as np
    import math
    import random
    
    
    df = pd.read_csv('Adult.csv')
    df
    
    ageworkclassfnlwgteducationeducation.nummarital.statusoccupationrelationshipracesexcapital.gaincapital.losshours.per.weeknative.countryincome
    090?77053HS-grad9Widowed?Not-in-familyWhiteFemale0435640United-States<=50K
    182Private132870HS-grad9WidowedExec-managerialNot-in-familyWhiteFemale0435618United-States<=50K
    266?186061Some-college10Widowed?UnmarriedBlackFemale0435640United-States<=50K
    354Private1403597th-8th4DivorcedMachine-op-inspctUnmarriedWhiteFemale0390040United-States<=50K
    441Private264663Some-college10SeparatedProf-specialtyOwn-childWhiteFemale0390040United-States<=50K
    ................................................
    3255622Private310152Some-college10Never-marriedProtective-servNot-in-familyWhiteMale0040United-States<=50K
    3255727Private257302Assoc-acdm12Married-civ-spouseTech-supportWifeWhiteFemale0038United-States<=50K
    3255840Private154374HS-grad9Married-civ-spouseMachine-op-inspctHusbandWhiteMale0040United-States>50K
    3255958Private151910HS-grad9WidowedAdm-clericalUnmarriedWhiteFemale0040United-States<=50K
    3256022Private201490HS-grad9Never-marriedAdm-clericalOwn-childWhiteMale0020United-States<=50K

    32561 rows × 15 columns

    处理缺失值

    df1 = df[(df['workclass']!='?')&(df['occupation']!='?')&(df['native.country']!='?')]
    df1
    
    ageworkclassfnlwgteducationeducation.nummarital.statusoccupationrelationshipracesexcapital.gaincapital.losshours.per.weeknative.countryincome
    182Private132870HS-grad9WidowedExec-managerialNot-in-familyWhiteFemale0435618United-States<=50K
    354Private1403597th-8th4DivorcedMachine-op-inspctUnmarriedWhiteFemale0390040United-States<=50K
    441Private264663Some-college10SeparatedProf-specialtyOwn-childWhiteFemale0390040United-States<=50K
    534Private216864HS-grad9DivorcedOther-serviceUnmarriedWhiteFemale0377045United-States<=50K
    638Private15060110th6SeparatedAdm-clericalUnmarriedWhiteMale0377040United-States<=50K
    ................................................
    3255622Private310152Some-college10Never-marriedProtective-servNot-in-familyWhiteMale0040United-States<=50K
    3255727Private257302Assoc-acdm12Married-civ-spouseTech-supportWifeWhiteFemale0038United-States<=50K
    3255840Private154374HS-grad9Married-civ-spouseMachine-op-inspctHusbandWhiteMale0040United-States>50K
    3255958Private151910HS-grad9WidowedAdm-clericalUnmarriedWhiteFemale0040United-States<=50K
    3256022Private201490HS-grad9Never-marriedAdm-clericalOwn-childWhiteMale0020United-States<=50K

    30162 rows × 15 columns

    获取数据集中一列的所有取值,例如sex中的male 和 female

    def get_all_category(line):
        line_class=list()
        for i in line:
            if i not in line_class:
                line_class.append(i)
        return line_class
    

    判断两个链表是否相同

    def equeal_list(list1,list2):
        if len(list1) != len(list2):
            return False
        for j in range(len(list1)):
            if list1[j] != list2[j]:
                return False
        return True
    
    def equeal_list_not_in_list(list1,list2):
        if len(list2) == 0:
            return True
        for i in range(len(list2)):
            if equeal_list(list1,list2[i]):
                return False
        return True
    

    计算信息增益

    计算信息熵

    E n t ( x ) = − ∑ k = 1 ∣ y ∣ p k l o g 2 ( p k ) Ent(x)=-\sum_{k=1}^{|y|}{p_klog2(p_k)} Ent(x)=k=1ypklog2(pk)

    def Ent(data):
        prob=pd.value_counts(data)/len(data)#计算某列不同值,并得出重复值
        return sum(np.log2(prob)*prob*-1)
    
    计算信息增益

    G a i n ( D , a ) = E n t ( D ) − ∑ v = 1 V ∣ D v ∣ ∣ D ∣ E n t ( D v ) Gain(D,a)=Ent(D)-\sum_{v=1}^V{\frac{|D^v|}{|D|}Ent(D^v)} Gain(D,a)=Ent(D)v=1VDDvEnt(Dv)

    def Gain(data,str1,str2): 
        e1=data.groupby(str1).apply(lambda x:Ent(x[str2]))
        p1=pd.value_counts(data[str1])/len(data[str2])
        e2=sum(e1*p1)
        return Ent(data[str2])-e2
    
    选取最优特征
    def get_best_spilt(data,str2):#data为该分支下的数据集,str2为二分类判断特征
        features=list()
        n_features=list()
        for k in data.columns:#所有特征
            n_features.append(k)
        n_features.remove(str2)#除去二分类特征
        k=math.ceil(math.log2(len(n_features)))
        features=random.sample(n_features,k)#取k个特征用来选取最优特征
        l=list()
        for s in features:
            g=Gain(data,s,str2)
            l.append(g)
        return n_features[l.index(max(l))]
        
        
    

    构造决策树类

    class Tree():
        def __init__(self,node,depth,is_leaf,spilt,node_df,label,tree_list,all_node):
            self.node=node#当前结点的标签名称----------String
            self.depth=depth#当前结点深度---------int
            self.is_leaf=is_leaf#当前结点是否为叶结点-------int 0 1
            self.spilt=spilt#当前结点的最佳特征--------String
            self.node_df=node_df#当前结点包含的数据集
            self.label=label#当前结点的二分类结果,需要判断是否为叶结点,如果不是叶结点则赋值为2
            self.tree_list=tree_list#当前结点下的所有子树
            self.all_node=all_node#当前已经用了的特征
    
    构造树
    决策树的3个中止条件
    1、子节点中的样本属于同一类
    2、子节点无样本
    3、特征已经用完
    
    判断是否为叶结点
    def is_leaf_now(data,str2):
        pol=pd.value_counts(data[str2])/len(data[str2])
        if len(data[data.columns[0]])==0:
            return False
        elif pol[0]==1:
            return False
        elif len(data.columns)==1:
            return False
        else:
            return True
    
    建树
    def built_tree(data,str2,Tnode,k,all_node):
        now_tree=Tree('',0,0,'',pd.DataFrame(),2,list(),list())#新建一棵树
        now_tree.node=Tnode#当前结点的标签,如male
        now_tree.node_df=data
        now_tree.depth=k+1
    #     print('is_leaf_now:',is_leaf_now(data,str2))
        if is_leaf_now(data,str2): 
            now_spilt=get_best_spilt(data,str2)#最佳特征
            now_tree.spilt=now_spilt
            now_tree.all_node=all_node
            #获取最佳特征下的所有取值可能
            all_category=get_all_category(now_tree.node_df[now_tree.spilt])
            for i in all_category:
                now_tree.all_node.append(now_tree.spilt)#为了判断树是否一样
                now_data=now_tree.node_df[now_tree.node_df[now_tree.spilt]==i]#取该属性的所有数据
                del now_data[now_tree.spilt]#删除该特征列的值,不在作为下一步计算
                new_tree=built_tree(now_data,str2,i,now_tree.depth,now_tree.all_node)
                now_tree.tree_list.append(new_tree)
           
        else:
            now_tree.is_leaf=1
            b=str(data[str2].head(1))
            la='<=50K'
            lb='>50K'
            la_result=la in b
            lb_result=lb in b
    #         print('la_result:',la_result)
    #         print('lb_result:',lb_result)
            if la_result:
                
                now_tree.label=-1
            elif lb_result:
                
                now_tree.label=1
        return now_tree
    

    创建随机森林

    def random_forest(train,str2):
        trees=list()
        already=list()
        #先new一颗tree
        Tnode='tree_root'
        depth=0
        all_node=list()
        tree=built_tree(train,str2,Tnode,depth,all_node)
        while len(trees)<=(6*5*4*3*2):
            if equeal_list_not_in_list(tree.all_node,already):#该tree和之前的树没有重复
                already.append(tree.all_node)
                trees.append(tree)
            all_node=list()
            tree=built_tree(train,str2,Tnode,depth,all_node)
        return trees
    

    预测函数

    该分支下没有该取值判断
    def is_no_var(now_spilt,data,thevar):
        all_catagory=get_all_category(data[now_spilt])
        if thevar not in all_catagory:
            return True
        return False
    

    返回对应值的树

    def get_tree_var(thevar,tree):
        for i in range(len(tree.tree_list)):
            if thevar == tree.tree_list[i].node:
                return tree.tree_list[i]
    
    数据进入到Tree得到的结果
    def Tree_result(tree,age,workclass,fnlwgt,education,education_num,marital_status,occupation,relationship,race,sex,hours_per_week,native_country):
        now_tree=tree
        label=0
        while now_tree.is_leaf==0:
    #         print(now_tree.node_df)
                  
            now_spilt=now_tree.spilt
            if now_spilt=='age':
                #如果该分类下没有这个取值返回0
                if is_no_var(now_spilt,now_tree.node_df,age):  
                    return 0
                #得到age值对应的树
                now_tree=get_tree_var(age,now_tree)
            elif now_spilt=='workclass':
                if is_no_var(now_spilt,now_tree.node_df,workclass):  
                    return 0
                now_tree=get_tree_var(workclass,now_tree)
            elif now_spilt=='fnlwgt':
                if is_no_var(now_spilt,now_tree.node_df,fnlwgt):  
                    return 0
                now_tree=get_tree_var(fnlwgt,now_tree)
            elif now_spilt=='education':
                if is_no_var(now_spilt,now_tree.node_df,education):  
                    return 0
                now_tree=get_tree_var(education,now_tree)
            elif now_spilt=='eduction.num':
                if is_no_var(now_spilt,now_tree.node_df,education_num):  
                    return 0
                now_tree=get_tree_var(education_num,now_tree)
            elif now_spilt=='marital.status':
                if is_no_var(now_spilt,now_tree.node_df,marital_status):  
                    return 0
                now_tree=get_tree_var(marital_status,now_tree)
            elif now_spilt=='occupation':
                if is_no_var(now_spilt,now_tree.node_df,occupation):  
                    return 0
                now_tree=get_tree_var(occupation,now_tree)
            elif now_spilt=='relationship':
                if is_no_var(now_spilt,now_tree.node_df,relationship):  
                    return 0
                now_tree=get_tree_var(relationship,now_tree)
            elif now_spilt=='race':
                if is_no_var(now_spilt,now_tree.node_df,race):  
                    return 0
                now_tree=get_tree_var(race,now_tree)
            elif now_spilt=='sex':
                if is_no_var(now_spilt,now_tree.node_df,sex):  
                    return 0
                now_tree=get_tree_var(sex,now_tree)
            elif now_spilt=='hours.per.week':
                if is_no_var(now_spilt,now_tree.node_df,hours_per_week):  
                    return 0
                now_tree=get_tree_var(hours_per_week,now_tree)
            elif now_spilt=='native.country':
                if is_no_var(now_spilt,now_tree.node_df,native_country):  
                    return 0
                now_tree=get_tree_var(native_country,now_tree)
            
    #     print(now_tree.label)   
        return now_tree.label
    
    数据进入到random forest 中得到的结果
    def random_forest_result(trees,age,workclass,fnlwgt,education,education_num,marital_status,occupation,relationship,race,sex,hours_per_week,native_country):
        k=0
        for i in range(len(trees)):
    #         print(Tree_result(trees[i],age,workclass,fnlwgt,education,education_num,marital_status,occupation,relationship,race,sex,hours_per_week,native_country))
            k=k+Tree_result(trees[i],age,workclass,fnlwgt,education,education_num,marital_status,occupation,relationship,race,sex,hours_per_week,native_country)
        
        return k
    
    暂时去掉一些特征,缩小数据集,用来测试程序
    del df1['capital.gain']
    del df1['capital.loss']
    del df1['education.num']
    del df1['native.country']
    del df1['race']
    del df1['hours.per.week']
    del df1['sex']
    del df1['fnlwgt']
    data=df1.head(100)
    data
    
    ageworkclasseducationmarital.statusoccupationrelationshipincome
    182PrivateHS-gradWidowedExec-managerialNot-in-family<=50K
    354Private7th-8thDivorcedMachine-op-inspctUnmarried<=50K
    441PrivateSome-collegeSeparatedProf-specialtyOwn-child<=50K
    534PrivateHS-gradDivorcedOther-serviceUnmarried<=50K
    638Private10thSeparatedAdm-clericalUnmarried<=50K
    ........................
    10850PrivateBachelorsMarried-civ-spouseExec-managerialWife>50K
    10947PrivateBachelorsMarried-civ-spouseExec-managerialHusband>50K
    11047Self-emp-incProf-schoolMarried-civ-spouseProf-specialtyHusband>50K
    11167PrivateBachelorsWidowedExec-managerialNot-in-family>50K
    11267Self-emp-incBachelorsMarried-civ-spouseExec-managerialHusband>50K

    100 rows × 7 columns

    训练模型

    trees=list()
    trees=random_forest(data,'income')
    print(len(trees))
    
    721
    

    预测

    k=random_forest_result(trees,82,'Self-emp-inc','fnlwgt','Some-college','education_num','Separated','Exec-managerial','Own-child','race','sex','hours_per_week','native_country')
    # print('OK!!!')
    print(k)
    
    74
    
    
    
    展开全文
  • 通俗易懂的随机森林模型讲解

    万次阅读 多人点赞 2018-04-17 22:42:09
    通俗易懂的随机森林模型讲解 大家好,我是你们的好朋友小木。对于随机森林的模型,网上已经有灰常灰常多的讲解,大家讲的也非常的不错。但绝大多数大神讲解都是注重于理论,把算数的地方都给忽略了,我这次要以举...
  • 3)随机森林因子(根据cox回归结果) 4)nomogram ( 根据cox回归结果,建立了中位生存时间,1年5年生存率的概率计算) -------------------????????‍♀️本文只有干货,非常干!????-----------------------------...
  • 随机森林实现泰坦尼克号数据集的分类预测,包含参数调试过程和分类结果评估,并绘制ROC曲线。
  • 随机森林 OOB理解

    千次阅读 2019-10-21 20:09:43
    1.有一个问题是, 对于随机森林的每一棵CART树是怎么训练的, 如何划分训练集测试集? Bootstrap, 对数据集随机有放回抽样N次作为一棵CART树的训练集. 根据概率论,可知数据集中有大约1/3的数据是没有被选取的(称为Out...
  • 文章目录1.决策树1.1 认识决策树1.2 信息论基础-银行贷款分析1.2.1 信息论基础-信息熵1.2.2 决策树的划分...集成学习方法-随机森林2.1 随机森林简述2.2 集成学习API2.3 泰坦尼克号乘客生存分类分析2.4 随机森林的优点 1
  • 随机森林模型预测和交叉验证

    千次阅读 2019-11-28 02:37:30
    使用随机森林模型来训练和交叉验证数据集。 数据矩阵:allmatrix 标签:target randomforest training preliminary trainning >>> from sklearn.ensemble import RandomForestClassifier >>> ...
  • 随机森林确定特征重要性排序

    千次阅读 2020-07-27 15:12:49
    from sklearn.datasets import load_boston from sklearn.ensemble import RandomForestRegressor from sklearn.model_selection import train_test_split import numpy as np #Load boston housing dataset as an ...
  • 使用手写数据集研究集成规模,树的最大深度以及特征数对随机森林分类结果的影响。代码在末尾。 使用交叉验证,返回accuracy,折数为10 1. 集成规模n_estimators 集成规模即树的数量。为了观察其影响,分别对数量1~...
  • Titanic生存预测-数据分析 数据分析学习之路 1.当我们拿到一个数据,首先要对数据进行观察,可以用Excel等工具,这里我 使用的是jupyter notebook 首先对数据进行观察,并进行简单的预处理 我们发现表中Age有177个...
  • 文章主要从以下几个方面进行介绍随机森林算法: 1.决策树算法。 2.集成学习思想。 3.随机森林算法的形成 一、决策树算法 1.决策树是什么? 决策树是一种基本的分类和回归方法。其主要优点是模型具有可读性。...
  • 同样的参数与随机种子 rf = RandomForestRegressor(n_estimators= 100, random_state=0) # 这里的训练集使用的是老数据集的 rf.fit(original_train_features, original_train_labels); # 为了测试效果能够公平,统一...
  • sklearn:随机森林的OOB错误

    千次阅读 2018-11-06 20:29:32
    使用引导程序聚合训练RandomForestClassifier,其中每个新树适合来自训练观察z_i =(x_i,y_i)的引导样本。 袋外(OOB)错误是使用来自各自引导样本中不包含z_i的树的预测计算的每个z_i的平均误差。...
  • print(dtr.score(data_test, target_test)) #导入随机森林模块 参数全部采用默认值 from sklearn.ensemble import RandomForestRegressor #创建随机森林对象 rfr = RandomForestRegressor(random_state = 42) #传入...
  • 在网上找到了一个博主的代码,进行了实现、修改,理解,初学者!我加了备注,直接就可以写,希望和大家一起学习!大家有好的学习文件可以私我共享!学渣在线等! ...博主原文大家一起学习!爱原博主么么扎!
  • 随机森林(RandomForest) 一、知识铺垫 1.1 决策树 决策树是机器学习最基本的模型,在不考虑其他复杂情况下,我们可以用一句话来描述决策树:如果得分大于等于60分,那么你及格了。(if-then语句) 这是一个最最...
  •  随机森林分类器中的树的个数,最小样本数及最小子叶数都是可以修改的。我们可以通过循环尝试找出最佳参数。这里以树的个数为例。 from sklearn.ensemble import RandomForestClassifier a = [] b = [] for i in ...
  • from sklearn.feature_extraction import DictVectorizer from sklearn.ensemble import RandomForestClassifier import pandas as pd 网址可以直接复制 data = pd.read_csv("...
  • sklearn的随机森林实现泰坦尼克号旅客生存预测介绍数据集介绍算法学习器分类器实现数据下载与导入预处理建立模型评估,预测结果代码 介绍 参考资料: ...
  • 随机森林也是一个集成学习方法,主要就是多个决策树模型来解决一个问题。比如,你训练了5个树,其中4个树的结果是true,1个树的结果是false, 那么最终结果就是少数服从多数 为True 。 建立多个树的过程 现在有N个...
  • 该内容共包含四部分代码,包含用python的sklearn包实现对kaggle上面泰坦尼克号的生存预测
  • 生存分析-随机森林实验与代码.pdf

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,343
精华内容 937
关键字:

随机生存森林