2 随机森林模型
2.1基本概念
2001年Breiman把分类树组合成随机森林(Breiman 2001a),即在变量(列)的使用和数据(行)的使用上进行随机化,生成很多分类树,再汇总分类树的结果。随机森林在运算量没有显著提高的前提下提高了预测精度。
算法流程:
构建决策树的个数t,单颗决策树的特征个数f,m个样本,n个特征数据集
1 单颗决策树训练
1.1 采用有放回抽样,从原数据集经过m次抽样,获得有m个样本的数据集(可能有重复样本)
1.2 从n个特征里,采用无放回抽样原则,去除f个特征作为输入特征
1.3 在新的数据集(m个样本, f个特征数据集上)构建决策树
1.4 重复上述过程t次,构建t棵决策树
2 随机森林的预测结果
生成t棵决策树,对于每个新的测试样例,综合多棵决策树预测的结果作为随机森林的预测结果。
回归问题:取t棵决策树预测值的平均值作为随机森林预测结果
分类问题:少数服从多数的原则,取单棵的分类结果作为类别随机森林预测结果
在Sklearn中RandomForestClassifier和RandomForestRegressor分类和回归树算法。
2.2 Sklearn中的构建随机森林
from sklearn.ensemble import RandomForestClassifier def base_of_decision_tree_forest(n_estimator,random_state): wine = datasets.load_wine() # 仅选前两个特征 X = wine.data[:,:2] y = wine.target X_train, X_test, y_train, y_test = train_test_split(X, y) forest = RandomForestClassifier(n_estimators=n_estimator, random_state=random_state, n_jobs=2) #n_jobs:设置为CPU个数 # 在训练数据集上进行学习 forest.fit(X_train, y_train) cmap_light = ListedColormap(['#FFAAAA','#AAFFAA','#AAAAFF’]) cmap_bold = ListedColormap(['#FF0000','#00FF00','#0000FF’]) #分别将样本的两个特征值创建图像的横轴和纵轴 x_min,x_max = X_train[:,0].min()-1,X_train[:,0].max()+1 y_min,y_max = X_train[:,1].min()-1,X_train[:,1].max()+1 xx, yy = np.meshgrid(np.arange(x_min, x_max, .02),np.arange(y_min, y_max, .02)) #给每个样本分配不同的颜色 Z = forest.predict(np.c_[xx.ravel(),yy.ravel()]) Z = Z.reshape(xx.shape) plt.pcolormesh(xx,yy,Z,cmap=cmap_light,shading='auto’) #用散点把样本表示出来 plt.scatter(X[:,0],X[:,1],c=y,cmap=cmap_bold,s=20,edgecolors='k’) plt.xlim(xx.min(),xx.max()) plt.ylim(yy.min(),yy.max()) print("红酒数据随机森林训练集得分(n_estimators:"+str(n_estimator)+",random_state:"+str(random_state)+"):{:.2f}".format(forest.score(X_train,y_train))) print("红酒数据随机森林测试集得分(n_estimators:"+str(n_estimator)+",random_state:"+str(random_state)+"):{:.2f}".format(forest.score(X_test,y_test))) def tree_forest(): #定义图像中分区的颜色和散点的颜色 figure,axes = plt.subplots(4,4,figsize =(100,10)) plt.subplots_adjust(hspace=0.95) i = 0 for n_estimator in range(4,8): for random_state in range(2,6): plt.subplot(4,4,i+1) plt.title("n_estimator:"+str(n_estimator)+"random_state:"+str(random_state)) plt.suptitle("Classifier:RandomForest") base_of_decision_tree_forest(n_estimator,random_state) i = i + 1 plt.show()
得到的结果总结如下表。
2.3 随机森林避免过拟合
我们以2个月亮数据进行分析。
import mglearn def my_RandomForet(): # 生成一个用于模拟的二维数据集 X, y = datasets.make_moons(n_samples=100, noise=0.25, random_state=3) # 训练集和测试集的划分 X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y,random_state=42) # 初始化一个包含 5 棵决策树的随机森林分类器 forest = RandomForestClassifier(n_estimators=5, random_state=2) # 在训练数据集上进行学习 forest.fit(X_train, y_train) # 可视化每棵决策树的决策边界 fig, axes = plt.subplots(2, 3, figsize=(20, 10)) for i, (ax, tree) in enumerate(zip(axes.ravel(), forest.estimators_)): ax.set_title('Tree {}'.format(i)) mglearn.plots.plot_tree_partition(X_train, y_train, tree, ax=ax) print("决策树"+str(i)+"训练集得分:{:.2%}".format(tree.score(X_train,y_train))) print("决策树"+str(i)+"测试集得分:{:.2%}".format(tree.score(X_test,y_test))) # 可视化集成分类器的决策边界 print("随机森林训练集得分:{:.2%}".format(forest.score(X_train,y_train))) print("随机森林测试集得分:{:.2%}".format(forest.score(X_test,y_test))) mglearn.plots.plot_2d_separator(forest, X_train, fill=True, ax=axes[-1, -1],alpha=0.4) axes[-1, -1].set_title('Random Forest') mglearn.discrete_scatter(X_train[:, 0], X_train[:, 1], y_train) plt.show()
输出
虽然决策树3不存在过拟合,决策树4的差值与随机森林得分一致,但是随机森林得分比他们都要高。
2.4案例
下面我们通过一个案例来介绍一下随机森林的使用,案例的内容是预测某人的收入是否可以>50K。我们到http://archive.ics.uci.edu/ml/machine-learning-databases/adult/网上下载adult.dat文件,它的格式是csv文件的形式,把它改为adult.csv,可用Excel文件打开。
import pandas as pd def income_forecast(): data=pd.read_csv('adult.csv', header=None,index_col=False, names=['年龄','单位性质','权重','学历','受教育时长', '婚姻状况','职业','家庭情况','种族','性别', '资产所得','资产损失','周工作时长','原籍', '收入']) #为了方便展示,我们选取其中一部分数据 data_title = data[['年龄','单位性质','学历','性别','周工作时长','职业','收入']] print(data_title.head())
输出
正如我们前面所述,通过pd.read_csv()函数可以把csv文件给出来。
#利用shape方法获取数据集的大小 data_title.shape
输出
data_title.shape: (32561, 7)
说明里面有32561个样本,7个属性。
print("data_title.shape:\n",data_title.shape) data_title.info()
输出
Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 年龄 32561 non-null int64 1 单位性质 32561 non-null object 2 学历 32561 non-null object 3 性别 32561 non-null object 4 周工作时长 32561 non-null int64 5 职业 32561 non-null object 6 收入 32561 non-null object dtypes: int64(2), object(5) memory usage: 1.7+ MB
可以看出,单位性质、学历、性别、职业、收入均不是数值类型,于是使用pd.get_dummies()函数对数据进行处理。
##1-数据准备 #1.2 数据预处理 #用get_dummies将文本数据转化为数值 data_dummies=pd.get_dummies(data_title) print("data_dummies.shape:\n",data_dummies.shape) #对比样本原始特征和虚拟变量特征---df.columns获取表头 print('样本原始特征:\n',list(data_title.columns),'\n') print('虚拟变量特征:\n',list(data_dummies.columns))
输出
样本原始特征:
['年龄', '单位性质', '学历', '性别', '周工作时长', '职业', '收入']
虚拟变量特征:
['年龄', '周工作时长', '单位性质_ ?', '单位性质_ Federal-gov', '单位性质_ Local-gov', '单位性质_ Never-worked', '单位性质_ Private', '单位性质_ Self-emp-inc', '单位性质_ Self-emp-not-inc', '单位性质_ State-gov', '单位性质_ Without-pay', '学历_ 10th', '学历_ 11th', '学历_ 12th', '学历_ 1st-4th', '学历_ 5th-6th', '学历_ 7th-8th', '学历_ 9th', '学历_ Assoc-acdm', '学历_ Assoc-voc', '学历_ Bachelors', '学历_ Doctorate', '学历_ HS-grad', '学历_ Masters', '学历_ Preschool', '学历_ Prof-school', '学历_ Some-college', '性别_ Female', '性别_ Male', '职业_ ?', '职业_ Adm-clerical', '职业_ Armed-Forces', '职业_ Craft-repair', '职业_ Exec-managerial', '职业_ Farming-fishing', '职业_ Handlers-cleaners', '职业_ Machine-op-inspct', '职业_ Other-service', '职业_ Priv-house-serv', '职业_ Prof-specialty', '职业_ Protective-serv', '职业_ Sales', '职业_ Tech-support', '职业_ Transport-moving', '收入_ <=50K', '收入_ >50K']
这样把特性与值进行合并,比如'单位性质'分成了'单位性质_ ?', '单位性质_ Federal-gov', '单位性质_ Local-gov', '单位性质_ Never-worked', '单位性质_ Private', '单位性质_ Self-emp-inc', '单位性质_ Self-emp-not-inc', '单位性质_ State-gov', '单位性质_ Without-pay'几部分。
print(data_dummies.head())
输出
这里0表示符合这个条件,1表示不符合,比如:单位性质_ Local-gov=1表示地方政府。
#1.3 选择特征 #按位置选择---位置索引---df.iloc[[行1,行2],[列1,列2]]---行列位置从0开始,多行多列用逗号隔开,用:表示全部(不需要[]) #选择除了收入外的字段作为数值特征并赋值给x---df[].values x=data_dummies.loc[:,'年龄':'职业_ Transport-moving'].values #将'收入_ >50K'‘作为预测目标y y = data_dummies['收入_ >50K'].values #查看x,y数据集大小情况 print('特征形态:{} 标签形态:{}'.format(x.shape, y.shape))
输出
特征形态:(32561, 44) 标签形态:(32561,)
32561条数据,44个属性。
##2-数据建模---拆分数据集/模型训练/测试 #2.1将数据拆分为训练集和测试集---要用train_test_split模块中的train_test_split()函数,随机将75%数据化为训练集,25%数据为测试集 #导入数据集拆分工具 #拆分数据集---x,y都要拆分,rain_test_split(x,y,random_state=0),random_state=0使得每次生成的伪随机数不同 x_train,x_test,y_train,y_test=train_test_split(x,y,random_state=0) #查看拆分后的数据集大小情况 print('x_train_shape:{}'.format(x_train.shape)) print('x_test_shape:{}'.format(x_test.shape)) print('y_train_shape:{}'.format(y_train.shape)) print('y_test_shape:{}'.format(y_test.shape))
输出
x_train_shape:(24420, 44) x_test_shape:(8141, 44) y_train_shape:(24420,) y_test_shape:(8141,)
24420条训练数据,8141条测试数据。
##2、数据建模---模型训练/测试---决策树算法 #2.2 模型训练---算法.fit(x_train,y_train) #使用算法 tree = DecisionTreeClassifier(max_depth=5)#这里参数max_depth最大深度设置为5 #算法.fit(x,y)对训练数据进行拟合 tree.fit(x_train, y_train) ##2、数据建模---拆分数据集/模型训练/测试---决策树算法 #2.3 模型测试---算法.score(x_test,y_test) score_test=tree.score(x_test,y_test) score_train=tree.score(x_train,y_train) print('test_score:{:.2%}'.format(score_test)) print('train_score:{:.2%}'.format(score_train))
输出
test_score:79.62% train_score:80.34%
测试数据得分为79.62%,我们就用这个模型进行预测,假设小王为37岁,机关工作,硕士,男,每周工作40小时,文员,它对应的数据为=[[37,40,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0]],预测代码如下。
#3、模型应用---算法.predict(x_new)---决策树算法 #导入要预测数据--可以输入新的数据点,也可以随便取原数据集中某一数据点,但是注意要与原数据结构相同x_new=[[37,40,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0]] #37岁,机关工作,硕士,男,每周工作40小时,文员 prediction=tree.predict(x_new) print('预测数据:{}'.format(x_new)) print('预测结果:{}'.format(prediction))
输出
预测数据:[[37, 40, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 预测结果:[0]
所以小王的薪水>50K。(本数据由1994年美国人口普查数据库抽取出来,仅供学习使用。)
3.用sklearn数据测试所有决策树和随机森林模型
修改文件machinelearn_data_model.py。
… def machine_learn(data,model): #支持的模型 modeltype = "LinearRegression,LogisticRegression,Ridge,Lasso,SVM,sm,KNeighborsClassifier,LinearSVR,SVC_linear,SVC_sigmoid,SVC_poly,SVR_linear,SVR_sigmoid,SVR_poly," modeltype += "DecisionTreeClassifie,DecisionTreeRegressor,RandomForestClassifie,RandomForestRegressor" #决策树的深度 max_depth = 5 #随机森林的n_estimators和random_state n_estimators = 5 random_state = 2 #n_jobs为CPU的核数 n_jobs=2 … elif model == "DecisionTreeClassifie": if data == "boston": y_train = y_train.astype('int') y_test = y_test.astype('int') md = DecisionTreeClassifier(max_depth=max_depth).fit(X_train, y_train) elif model == "DecisionTreeRegressor": md = DecisionTreeRegressor(max_depth=max_depth).fit(X_train, y_train) elif model == "RandomForestClassifier": if data == "boston": y_train = y_train.astype('int') y_test = y_test.astype('int') md = RandomForestClassifier(n_estimators=n_estimators, random_state=random_state, n_jobs=n_jobs).fit(X_train, y_train) elif model == "RandomForestRegressor": md = RandomForestRegressor(n_estimators=n_estimators, random_state=random_state, n_jobs=n_jobs).fit(X_train, y_train) else: return "提供的模型错误,包括:"+modeltype … 在这里考虑: DecisionTreeClassifie算法在波士顿房价下要求目标y必须为int类型,所以做了判断; 决策树的深度:max_depth = 5; 随机森林的n_estimators= 5和random_state= 2; n_jobs为CPU的核数,设置为变量。 这样,我们就可以对指定模型指定数据进行定量分析 from machinelearn_data_model import data_for_model def Tree_and_forest_for_all_data_and_model(): datas = ["iris","wine","breast_cancer","diabetes","boston","two_moon"] models = ["DecisionTreeClassifie","DecisionTreeRegressor","RandomForestClassifie","RandomForestRegressor"] for data in datas: for model in models: data_for_model.machine_learn(data,model)
我们对测试结果进行比较:
—————————————————————————————————
软件安全测试
https://study.163.com/course/courseMain.htm?courseId=1209779852&share=2&shareId=480000002205486
接口自动化测试
https://study.163.com/course/courseMain.htm?courseId=1209794815&share=2&shareId=480000002205486
DevOps 和Jenkins之DevOps
https://study.163.com/course/courseMain.htm?courseId=1209817844&share=2&shareId=480000002205486
DevOps与Jenkins 2.0之Jenkins
https://study.163.com/course/courseMain.htm?courseId=1209819843&share=2&shareId=480000002205486
Selenium自动化测试
https://study.163.com/course/courseMain.htm?courseId=1209835807&share=2&shareId=480000002205486
性能测试第1季:性能测试基础知识
https://study.163.com/course/courseMain.htm?courseId=1209852815&share=2&shareId=480000002205486
性能测试第2季:LoadRunner12使用
https://study.163.com/course/courseMain.htm?courseId=1209980013&share=2&shareId=480000002205486
性能测试第3季:JMeter工具使用
https://study.163.com/course/courseMain.htm?courseId=1209903814&share=2&shareId=480000002205486
性能测试第4季:监控与调优
https://study.163.com/course/courseMain.htm?courseId=1209959801&share=2&shareId=480000002205486
Django入门
https://study.163.com/course/courseMain.htm?courseId=1210020806&share=2&shareId=480000002205486
啄木鸟顾老师漫谈软件测试
https://study.163.com/course/courseMain.htm?
courseId=1209958326&share=2&shareId=480000002205486