随机森林实战教程-Python-Demo

前言

随机森林Python版本有很可以调用的库,使用随机森林非常方便,主要用到以下的库:

  • sklearn
  • pandas
  • numpy
  • 随机森林入门

    我们先通过一段代码来了解Python中如何使用随机森林。

    from sklearn.datasets import load_iris
    from sklearn.ensemble import RandomForestClassifier
    import pandas as pd
    import numpy as np
    
    iris = load_iris()   # 这里是sklearn中自带的一部分数据
    df = pd.DataFrame(iris.data, columns=iris.feature_names) # 格式化数据
    print (df)          # 
    df['is_train'] = np.random.uniform(0, 1, len(df)) <= .75
    df['species'] = pd.Categorical.from_codes(iris.target, iris.target_names)  ## 新接口 数据
    df.head()
    
    train, test = df[df['is_train']==True], df[df['is_train']==False]
    
    features = df.columns[:4]
    clf = RandomForestClassifier(n_jobs=2)
    y, _ = pd.factorize(train['species'])
    clf.fit(train[features], y)  # 用train来训练样本
    
    test_pred=clf.predict(test[features])   #用测试数据来做预测
    preds = iris.target_names[test_pred]
    pd.crosstab(test['species'], preds, rownames=['actual'], colnames=['preds'])

    上述是一个利用sklearn的数据做的

    kaggle-美国人口普查年收入比赛

    现在我们在kaggle上的数据集上做一次实验,这个数据集有训练集和测试集,训练集便于我们训练模型,测试集用来校验我们模型的正确性,这是最简单的。

  • 需要导入的库
  • import pandas as pd  # load csv's (pd.read_csv)
    import numpy as np   # math (lin. algebra)
    
    import sklearn as skl   # machine learning
    from sklearn.ensemble import RandomForestClassifier
    #from plotnine import *
    import matplotlib.pyplot as plt
    from sklearn.preprocessing import LabelEncoder
    from sklearn_pandas import DataFrameMapper
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.metrics import classification_report
    

  • 数据读取
  • def get_train_data():
    #下面两个文件路径替换为你电脑上该文件的路径
        train_path = "D:/workspace/Data/kggal/AmericaIncome/adult.data"
        test_path = 'D:/workspace/Data/kggal/AmericaIncome/adult.test'
        columns = ['Age','Workclass','fnlgwt','Education','EdNum','MaritalStatus','Occupation','Relationship','Race','Sex','CapitalGain','CapitalLoss','HoursPerWeek','Country','Income']
        df_train_set = pd.read_csv(train_path, names=columns)
        #print(df_train_set.head())
        return df_train_set
    
    def get_test_data():
        test_path = 'D:/workspace/Data/kggal/AmericaIncome/adult.test'
        columns = ['Age','Workclass','fnlgwt','Education','EdNum','MaritalStatus','Occupation','Relationship','Race','Sex','CapitalGain','CapitalLoss','HoursPerWeek','Country','Income']
        df_test_set = pd.read_csv(test_path, names=columns)
        #print(df_test_set.head())
        return df_test_set

  • 数据预处理
  • df_train_set=get_train_data()
    df_test_set=get_test_data()
    
    df_train_set.drop('fnlgwt', axis=1, inplace=True)
    df_test_set.drop('fnlgwt', axis=1, inplace=True)
    
    print(df_train_set.replace(' ?', np.nan).shape)
    #(32561, 14)
    print(df_train_set.replace(' ?', np.nan).dropna().shape)
    # (30162, 15)
    print(df_test_set.replace(' ?', np.nan).shape)
    #(16282, 14)
    print(df_test_set.replace(' ?', np.nan).dropna().shape)
    # (15060, 15)
    
    # 删除含有?(缺失行)
    train_set = df_train_set.replace(' ?', np.nan).dropna()
    
    test_set = df_test_set.replace(' ?', np.nan).dropna()
    
    # 把测试语料集中的 Income 归一化
    test_set['Income'] = test_set.Income.replace({' <=50K.': ' <=50K', ' >50K.': ' >50K'})
    print(test_set.Income.unique())
    # [' <=50K' ' >50K']
    print(df_train_set.Income.unique())
    # [' <=50K' ' >50K']
    
    # 因为有 受教育的年数,所以这里不需要教育这一列
    train_set.drop(["Education"], axis=1, inplace=True)
    test_set.drop(["Education"], axis=1, inplace=True)

  • 将数据中的特征向量化以及得到特征值、预测值分开
  • combined_set = pd.concat([train_set, test_set], axis=0)
    for feature in combined_set.columns:
        if combined_set[feature].dtype == 'object':
            combined_set[feature] = pd.Categorical(combined_set[feature]).codes
    
    train_set = combined_set[:train_set.shape[0]]
    test_set = combined_set[test_set.shape[0]:]
    print(train_set.Workclass.unique())
    print(test_set.Income.unique())
    
    cols = list(train_set.columns)
    cols.remove("Income")
    
    x_train, y_train = train_set[cols].values, train_set["Income"].values
    #测试集的输入和输出结果分开,用来校验模型的准确率
    x_test, y_test = test_set[cols].values, test_set["Income"].values

  • 预测模型
  • treeClassifier = DecisionTreeClassifier()
    treeClassifier.fit(x_train, y_train) # 训练模型
    treeClassifier.score(x_test, y_test)
    print(treeClassifier.score(x_test, y_test))
    # 输出为:0.8700351435581195
    y_pred = treeClassifier.predict(x_test)  # 用测试集做预测
    print(classification_report(y_test, y_pred)) # 查看模型的预测值与真实值
    #输出为
                 precision    recall  f1-score   support
    
              0       0.90      0.93      0.92     22674
              1       0.77      0.67      0.72      7488
    
    avg / total       0.87      0.87      0.87     30162
    

    从上面的输出结果可以看到,最简单的随机森林模型,没有加任何参数优化、交叉验证等等,可以达到的准确率为87%左右,而且这个数据集规模较大,训练集3万多条,测试集1万多条,其结果也较为合理,之后的文章会讲解一下优化方面的内容。

    总结

    随机森林算法模型的形式化描述如下:

  • 训练入参
    n个特征加一个分类结果
  • 特征1 特征2 特征3 特征4 ... 特征n 分类结果

  • 预测入参
    预测的入参就是n个特征
  • 特征1 特征2 特征3 特征4 ... 特征n 

    本文中不同特征中的数据并没有进行归一化处理,很多特征的量化数值很大,其实都可以归一化处理一下,这样就不会被某一个特征影响掉,后期可以考虑优化一下,然后整个算法的训练模型部分的代码量其实没多少,前期很多代码都是数据集的预处理,将不符合规范的数据集去掉,以及将数据中的字符特征转换为数值特征,这样便于模型训练。其实很多数据都是这样的,必须知道所有的数据情况,这里数据集的唯一好处是告诉你了特征有那些,如果没有告诉你特征,你就必须自己提取特征,在很多比赛中都是要自己思考需要那些特征,建议参考天池大数据的技术圈中,往届比赛大家的分享–>天池新人实战赛o2o优惠券使用预测。
    随机森林有以下缺陷:

  • 当我们需要推断超出范围的独立变量或非独立变量,随机森林做得并不好,我们最好使用如 MARS 那样的算法。
  • 随机森林算法在训练和预测时都比较慢。
  • 如果需要区分的类别十分多,随机森林的表现并不会很好。
    最后,感谢下面两个博客文章,也是从别人的内容上学。这是简单的实战文章,之后我会去了解一些量化分析、算法优化方面的内容,
  • 参考博客

    从决策树到随机森林:树型算法的原理与实现
    kaggle-2美国人口普查年收入50K分类
    数据集下载地址

    你可能感兴趣的:(学术)