前言
随机森林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 那样的算法。
- 随机森林算法在训练和预测时都比较慢。
- 如果需要区分的类别十分多,随机森林的表现并不会很好。
最后,感谢下面两个博客文章,也是从别人的内容上学。这是简单的实战文章,之后我会去了解一些量化分析、算法优化方面的内容, -
参考博客