极客时间已完结课程限时免费阅读

35丨AdaBoost(下):如何使用AdaBoost对房价进行预测?

35丨AdaBoost(下):如何使用AdaBoost对房价进行预测?-极客时间

35丨AdaBoost(下):如何使用AdaBoost对房价进行预测?

讲述:陈旸

时长08:37大小7.90M

今天我带你用 AdaBoost 算法做一个实战项目。AdaBoost 不仅可以用于分类问题,还可以用于回归分析。
我们先做个简单回忆,什么是分类,什么是回归呢?实际上分类和回归的本质是一样的,都是对未知事物做预测。不同之处在于输出结果的类型,分类输出的是一个离散值,因为物体的分类数有限的,而回归输出的是连续值,也就是在一个区间范围内任何取值都有可能。
这次我们的主要目标是使用 AdaBoost 预测房价,这是一个回归问题。除了对项目进行编码实战外,我希望你能掌握:
AdaBoost 工具的使用,包括使用 AdaBoost 进行分类,以及回归分析。
使用其他的回归工具,比如决策树回归,对比 AdaBoost 回归和决策树回归的结果。

如何使用 AdaBoost 工具

我们可以直接在 sklearn 中使用 AdaBoost。如果我们要用 AdaBoost 进行分类,需要在使用前引用代码:
from sklearn.ensemble import AdaBoostClassifier
我们之前讲到过,如果你看到了 Classifier 这个类,一般都会对应着 Regressor 类。AdaBoost 也不例外,回归工具包的引用代码如下:
from sklearn.ensemble import AdaBoostRegressor
我们先看下如何在 sklearn 中创建 AdaBoost 分类器。
我们需要使用 AdaBoostClassifier(base_estimator=None, n_estimators=50, learning_rate=1.0, algorithm=’SAMME.R’, random_state=None) 这个函数,其中有几个比较主要的参数,我分别来讲解下:
base_estimator:代表的是弱分类器。在 AdaBoost 的分类器和回归器中都有这个参数,在 AdaBoost 中默认使用的是决策树,一般我们不需要修改这个参数,当然你也可以指定具体的分类器。
n_estimators:算法的最大迭代次数,也是分类器的个数,每一次迭代都会引入一个新的弱分类器来增加原有的分类器的组合能力。默认是 50。
learning_rate:代表学习率,取值在 0-1 之间,默认是 1.0。如果学习率较小,就需要比较多的迭代次数才能收敛,也就是说学习率和迭代次数是有相关性的。当你调整 learning_rate 的时候,往往也需要调整 n_estimators 这个参数。
algorithm:代表我们要采用哪种 boosting 算法,一共有两种选择:SAMME 和 SAMME.R。默认是 SAMME.R。这两者之间的区别在于对弱分类权重的计算方式不同。
random_state:代表随机数种子的设置,默认是 None。随机种子是用来控制随机模式的,当随机种子取了一个值,也就确定了一种随机规则,其他人取这个值可以得到同样的结果。如果不设置随机种子,每次得到的随机数也就不同。
那么如何创建 AdaBoost 回归呢?
我们可以使用 AdaBoostRegressor(base_estimator=None, n_estimators=50, learning_rate=1.0, loss=‘linear’, random_state=None) 这个函数。
你能看出来回归和分类的参数基本是一致的,不同点在于回归算法里没有 algorithm 这个参数,但多了一个 loss 参数。
loss 代表损失函数的设置,一共有 3 种选择,分别为 linear、square 和 exponential,它们的含义分别是线性、平方和指数。默认是线性。一般采用线性就可以得到不错的效果。
创建好 AdaBoost 分类器或回归器之后,我们就可以输入训练集对它进行训练。我们使用 fit 函数,传入训练集中的样本特征值 train_X 和结果 train_y,模型会自动拟合。使用 predict 函数进行预测,传入测试集中的样本特征值 test_X,然后就可以得到预测结果。

如何用 AdaBoost 对房价进行预测

了解了 AdaBoost 工具包之后,我们看下 sklearn 中自带的波士顿房价数据集。
这个数据集一共包括了 506 条房屋信息数据,每一条数据都包括了 13 个指标,以及一个房屋价位。
13 个指标的含义,可以参考下面的表格:
这些指标分析得还是挺细的,但实际上,我们不用关心具体的含义,要做的就是如何通过这 13 个指标推导出最终的房价结果。
如果你学习了之前的算法实战,这个数据集的预测并不复杂。
首先加载数据,将数据分割成训练集和测试集,然后创建 AdaBoost 回归模型,传入训练集数据进行拟合,再传入测试集数据进行预测,就可以得到预测结果。最后将预测的结果与实际结果进行对比,得到两者之间的误差。具体代码如下:
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.datasets import load_boston
from sklearn.ensemble import AdaBoostRegressor
# 加载数据
data=load_boston()
# 分割数据
train_x, test_x, train_y, test_y = train_test_split(data.data, data.target, test_size=0.25, random_state=33)
# 使用AdaBoost回归模型
regressor=AdaBoostRegressor()
regressor.fit(train_x,train_y)
pred_y = regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print("房价预测结果 ", pred_y)
print("均方误差 = ",round(mse,2))
运行结果:
房价预测结果 [20.2 10.4137931 14.63820225 17.80322581 24.58931298 21.25076923
27.52222222 17.8372093 31.79642857 20.86428571 27.87431694 31.09142857
12.81666667 24.13131313 12.81666667 24.58931298 17.80322581 17.66333333
27.83 24.58931298 17.66333333 20.90823529 20.10555556 20.90823529
28.20877193 20.10555556 21.16882129 24.58931298 13.27619048 31.09142857
17.08095238 26.19217391 9.975 21.03404255 26.74583333 31.09142857
25.83960396 11.859375 13.38235294 24.58931298 14.97931034 14.46699029
30.12777778 17.66333333 26.19217391 20.10206186 17.70540541 18.45909091
26.19217391 20.10555556 17.66333333 33.31025641 14.97931034 17.70540541
24.64421053 20.90823529 25.83960396 17.08095238 24.58931298 21.43571429
19.31617647 16.33733333 46.04888889 21.25076923 17.08095238 25.83960396
24.64421053 11.81470588 17.80322581 27.63636364 23.59731183 17.94444444
17.66333333 27.7253886 20.21465517 46.04888889 14.97931034 9.975
17.08095238 24.13131313 21.03404255 13.4 11.859375 26.19214286
21.25076923 21.03404255 47.11395349 16.33733333 43.21111111 31.65730337
30.12777778 20.10555556 17.8372093 18.40833333 14.97931034 33.31025641
24.58931298 22.88813559 18.27179487 17.80322581 14.63820225 21.16882129
26.91538462 24.64421053 13.05 14.97931034 9.975 26.19217391
12.81666667 26.19214286 49.46511628 13.27619048 17.70540541 25.83960396
31.09142857 24.13131313 21.25076923 21.03404255 26.91538462 21.03404255
21.16882129 17.8372093 12.81666667 21.03404255 21.03404255 17.08095238
45.16666667]
均方误差 = 18.05
这个数据集是比较规范的,我们并不需要在数据清洗,数据规范化上花太多精力,代码编写起来比较简单。
同样,我们可以使用不同的回归分析模型分析这个数据集,比如使用决策树回归和 KNN 回归。
编写代码如下:
# 使用决策树回归模型
dec_regressor=DecisionTreeRegressor()
dec_regressor.fit(train_x,train_y)
pred_y = dec_regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print("决策树均方误差 = ",round(mse,2))
# 使用KNN回归模型
knn_regressor=KNeighborsRegressor()
knn_regressor.fit(train_x,train_y)
pred_y = knn_regressor.predict(test_x)
mse = mean_squared_error(test_y, pred_y)
print("KNN均方误差 = ",round(mse,2))
运行结果:
决策树均方误差 = 23.84
KNN均方误差 = 27.87
你能看到相比之下,AdaBoost 的均方误差更小,也就是结果更优。虽然 AdaBoost 使用了弱分类器,但是通过 50 个甚至更多的弱分类器组合起来而形成的强分类器,在很多情况下结果都优于其他算法。因此 AdaBoost 也是常用的分类和回归算法之一。

AdaBoost 与决策树模型的比较

在 sklearn 中 AdaBoost 默认采用的是决策树模型,我们可以随机生成一些数据,然后对比下 AdaBoost 中的弱分类器(也就是决策树弱分类器)、决策树分类器和 AdaBoost 模型在分类准确率上的表现。
如果想要随机生成数据,我们可以使用 sklearn 中的 make_hastie_10_2 函数生成二分类数据。假设我们生成 12000 个数据,取前 2000 个作为测试集,其余作为训练集。
有了数据和训练模型后,我们就可以编写代码。我设置了 AdaBoost 的迭代次数为 200,代表 AdaBoost 由 200 个弱分类器组成。针对训练集,我们用三种模型分别进行训练,然后用测试集进行预测,并将三个分类器的错误率进行可视化对比,可以看到这三者之间的区别:
import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from sklearn.metrics import zero_one_loss
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import AdaBoostClassifier
# 设置AdaBoost迭代次数
n_estimators=200
# 使用
X,y=datasets.make_hastie_10_2(n_samples=12000,random_state=1)
# 从12000个数据中取前2000行作为测试集,其余作为训练集
train_x, train_y = X[2000:],y[2000:]
test_x, test_y = X[:2000],y[:2000]
# 弱分类器
dt_stump = DecisionTreeClassifier(max_depth=1,min_samples_leaf=1)
dt_stump.fit(train_x, train_y)
dt_stump_err = 1.0-dt_stump.score(test_x, test_y)
# 决策树分类器
dt = DecisionTreeClassifier()
dt.fit(train_x, train_y)
dt_err = 1.0-dt.score(test_x, test_y)
# AdaBoost分类器
ada = AdaBoostClassifier(base_estimator=dt_stump,n_estimators=n_estimators)
ada.fit(train_x, train_y)
# 三个分类器的错误率可视化
fig = plt.figure()
# 设置plt正确显示中文
plt.rcParams['font.sans-serif'] = ['SimHei']
ax = fig.add_subplot(111)
ax.plot([1,n_estimators],[dt_stump_err]*2, 'k-', label=u'决策树弱分类器 错误率')
ax.plot([1,n_estimators],[dt_err]*2,'k--', label=u'决策树模型 错误率')
ada_err = np.zeros((n_estimators,))
# 遍历每次迭代的结果 i为迭代次数, pred_y为预测结果
for i,pred_y in enumerate(ada.staged_predict(test_x)):
# 统计错误率
ada_err[i]=zero_one_loss(pred_y, test_y)
# 绘制每次迭代的AdaBoost错误率
ax.plot(np.arange(n_estimators)+1, ada_err, label='AdaBoost Test 错误率', color='orange')
ax.set_xlabel('迭代次数')
ax.set_ylabel('错误率')
leg=ax.legend(loc='upper right',fancybox=True)
plt.show()
运行结果:
从图中你能看出来,弱分类器的错误率最高,只比随机分类结果略好,准确率稍微大于 50%。决策树模型的错误率明显要低很多。而 AdaBoost 模型在迭代次数超过 25 次之后,错误率有了明显下降,经过 125 次迭代之后错误率的变化形势趋于平缓。
因此我们能看出,虽然单独的一个决策树弱分类器效果不好,但是多个决策树弱分类器组合起来形成的 AdaBoost 分类器,分类效果要好于决策树模型。

总结

今天我带你用 AdaBoost 回归分析对波士顿房价进行了预测。因为这是个回归分析的问题,我们直接使用 sklearn 中的 AdaBoostRegressor 即可。如果是分类,我们使用 AdaBoostClassifier。
另外我们将 AdaBoost 分类器、弱分类器和决策树分类器做了对比,可以看出经过多个弱分类器组合形成的 AdaBoost 强分类器,准确率要明显高于决策树算法。所以 AdaBoost 的优势在于框架本身,它通过一种迭代机制让原本性能不强的分类器组合起来,形成一个强分类器。
其实在现实工作中,我们也能找到类似的案例。IBM 服务器追求的是单个服务器性能的强大,比如打造超级服务器。而 Google 在创建集群的时候,利用了很多 PC 级的服务器,将它们组成集群,整体性能远比一个超级服务器的性能强大。
再比如我们讲的“三个臭皮匠,顶个诸葛亮”,也就是 AdaBoost 的价值所在。
今天我们用 AdaBoost 分类器与决策树分类做对比的时候,使用到了 sklearn 中的 make_hastie_10_2 函数生成数据。实际上在第 19 篇,我们对泰坦尼克号的乘客做生存预测的时候,也讲到了决策树工具的使用。你能不能编写代码,使用 AdaBoost 算法对泰坦尼克号乘客的生存做预测,看看它和决策树模型,谁的准确率更高?
你也可以把这篇文章分享给你的朋友或者同事,一起切磋一下。
分享给需要的人,Ta购买本课程,你将得18
生成海报并分享

赞 14

提建议

上一篇
34丨AdaBoost(上):如何使用AdaBoost提升分类器性能?
下一篇
36丨数据分析算法篇答疑
unpreview
 写留言

精选留言(23)

  • TKbook
    2019-03-05
    源代码中: # 从 12000 个数据中取前 2000 行作为测试集,其余作为训练集 test_x, test_y = X[2000:],y[2000:] train_x, train_y = X[:2000],y[:2000] 这个部分的代码写错了吧 应该是: test_x, test_y = x[: 2000], y[: 2000] train_x, train_y = x[2000:], y[2000:]
    展开

    编辑回复: 您好,文章已进行更正,谢谢您的反馈。

    17
  • third
    2019-03-04
    结果仍然为AdaBoost算法最优。 个人发现,前两个分类器出结果很快 分析最优: 1.AdaBoost算法经过了更多运算,特别是在迭代弱分类器和组合上 2.良好组合起来的个体,能够创造更大的价值。 决策树弱分类器准确率为 0.7867 决策树分类器准确率为 0.7891 AdaBoost 分类器准确率为 0.8138 import numpy as np import pandas as pd from sklearn.model_selection import cross_val_score from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import AdaBoostClassifier from sklearn.feature_extraction import DictVectorizer # 1.数据加载 train_data=pd.read_csv('./Titanic_Data/train.csv') test_data=pd.read_csv('./Titanic_Data/test.csv') # 2.数据清洗 # 使用平均年龄来填充年龄中的 NaN 值 train_data['Age'].fillna(train_data['Age'].mean(),inplace=True) test_data['Age'].fillna(test_data['Age'].mean(),inplace=True) # 均价填充 train_data['Fare'].fillna(train_data['Fare'].mean(),inplace=True) test_data['Fare'].fillna(test_data['Fare'].mean(),inplace=True) # 使用登陆最多的港口来填充 train_data['Embarked'].fillna('S',inplace=True) test_data['Embarked'].fillna('S',inplace=True) # 特征选择 features=['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked'] train_features=train_data[features] train_labels=train_data['Survived'] test_features=test_data[features] # 将符号化的Embarked对象抽象处理成0/1进行表示 dvec=DictVectorizer(sparse=False) train_features=dvec.fit_transform(train_features.to_dict(orient='record')) test_features=dvec.transform(test_features.to_dict(orient='record')) # 决策树弱分类器 dt_stump = DecisionTreeClassifier(max_depth=1,min_samples_leaf=1) dt_stump.fit(train_features, train_labels) print(u'决策树弱分类器准确率为 %.4lf' % np.mean(cross_val_score(dt_stump, train_features, train_labels, cv=10))) # 决策树分类器 dt = DecisionTreeClassifier() dt.fit(train_features, train_labels) print(u'决策树分类器准确率为 %.4lf' % np.mean(cross_val_score(dt, train_features, train_labels, cv=10))) # AdaBoost 分类器 ada = AdaBoostClassifier(base_estimator=dt_stump,n_estimators=200) ada.fit(train_features, train_labels) print(u'AdaBoost 分类器准确率为 %.4lf' % np.mean(cross_val_score(ada, train_features, train_labels, cv=10)))
    展开

    编辑回复: 结果正确,一般来说AdaBoost的结果会比决策树分类器略好一些。

    7
  • 王彬成
    2019-03-04
    由于乘客测试集缺失真实值,采用 K 折交叉验证准确率 -------------------- 运行结果: 决策树弱分类器准确率为 0.7867 决策树分类器准确率为 0.7813 AdaBoost 分类器准确率为 0.8138 ------------------------- 代码: import numpy as np from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import AdaBoostClassifier import pandas as pd from sklearn.feature_extraction import DictVectorizer from sklearn.model_selection import cross_val_score # 设置 AdaBoost 迭代次数 n_estimators=200 # 数据加载 train_data=pd.read_csv('./Titanic_Data/train.csv') test_data=pd.read_csv('./Titanic_Data/test.csv') # 模块 2:数据清洗 # 使用平均年龄来填充年龄中的 NaN 值 train_data['Age'].fillna(train_data['Age'].mean(),inplace=True) test_data['Age'].fillna(test_data['Age'].mean(),inplace=True) # 使用票价的均值填充票价中的 nan 值 train_data['Fare'].fillna(train_data['Fare'].mean(),inplace=True) test_data['Fare'].fillna(test_data['Fare'].mean(),inplace=True) # 使用登录最多的港口来填充登录港口Embarked的 nan 值 train_data['Embarked'].fillna('S',inplace=True) test_data['Embarked'].fillna('S',inplace=True) # 特征选择 features=['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked'] train_features=train_data[features] train_labels=train_data['Survived'] test_features=test_data[features] # 将符号化的Embarked对象处理成0/1进行表示 dvec=DictVectorizer(sparse=False) train_features=dvec.fit_transform(train_features.to_dict(orient='record')) test_features=dvec.transform(test_features.to_dict(orient='record')) # 决策树弱分类器 dt_stump = DecisionTreeClassifier(max_depth=1,min_samples_leaf=1) dt_stump.fit(train_features, train_labels) print(u'决策树弱分类器准确率为 %.4lf' % np.mean(cross_val_score(dt_stump, train_features, train_labels, cv=10))) # 决策树分类器 dt = DecisionTreeClassifier() dt.fit(train_features, train_labels) print(u'决策树分类器准确率为 %.4lf' % np.mean(cross_val_score(dt, train_features, train_labels, cv=10))) # AdaBoost 分类器 ada = AdaBoostClassifier(base_estimator=dt_stump,n_estimators=n_estimators) ada.fit(train_features, train_labels) print(u'AdaBoost 分类器准确率为 %.4lf' % np.mean(cross_val_score(ada, train_features, train_labels, cv=10)))
    展开

    作者回复: Good Job

    6
  • 梁林松
    2019-03-04
    跑第二块代码是需要引入两个模块 from sklearn.tree import DecisionTreeRegressor from sklearn.neighbors import KNeighborsRegressor

    编辑回复: 对的 需要引入相应的回归类库。

    3
  • 2019-04-21
    得到结果: CART决策树K折交叉验证准确率: 0.39480897860892333 AdaBoostK折交叉验证准确率: 0.4376641797318339 from sklearn.tree import DecisionTreeRegressor from sklearn.ensemble import AdaBoostRegressor from sklearn.feature_extraction import DictVectorizer from sklearn.model_selection import cross_val_predict import pandas as pd import numpy as np #读取数据 path = '/Users/apple/Desktop/GitHubProject/Read mark/数据分析/geekTime/data/' train_data = pd.read_csv(path + 'Titannic_Data_train.csv') test_data = pd.read_csv(path + 'Titannic_Data_test.csv') #数据清洗 train_data['Age'].fillna(train_data['Age'].mean(),inplace=True) test_data['Age'].fillna(test_data['Age'].mean(), inplace=True) train_data['Embarked'].fillna('S', inplace=True) test_data['Embarked'].fillna('S', inplace=True) #特征选择 features = ['Pclass','Sex','Age','SibSp','Parch','Embarked'] train_features = train_data[features] train_result = train_data['Survived'] test_features = test_data[features] devc = DictVectorizer(sparse=False) train_features = devc.fit_transform(train_features.to_dict(orient='record')) test_features = devc.fit_transform(test_features.to_dict(orient='record')) #构造决策树,进行预测 tree_regressor = DecisionTreeRegressor() tree_regressor.fit(train_features,train_result) predict_tree = tree_regressor.predict(test_features) #交叉验证准确率 print('CART决策树K折交叉验证准确率:', np.mean(cross_val_predict(tree_regressor,train_features,train_result,cv=10))) #构造AdaBoost ada_regressor = AdaBoostRegressor() ada_regressor.fit(train_features,train_result) predict_ada = ada_regressor.predict(test_features) #交叉验证准确率 print('AdaBoostK折交叉验证准确率:',np.mean(cross_val_predict(ada_regressor,train_features,train_result,cv=10)))
    展开

    编辑回复: 准确率一般不会这么低,所以你可以查下代码中是否有错误。 这里需要注意的是,应该是用DecisionTreeClassifier和AdaBoostClassifier,因为泰坦尼克生存预测是个分类问题(离散值),不是回归问题(连续值)。 另外在我们在做K折交叉验证的时候,应该使用:cross_val_score cross_val_score 用来返回评测的准确率 cross_val_predict 用来返回预测的分类结果 这两处地方你调整下,再跑跑代码

    1
  • KokutoDa
    2021-05-22
    准确率: adaboost 交叉验证:0.81147315855181 决策树交叉验证:0.7812484394506866 adaboost(accuracy_score):0.8484848484848485 决策树(accuracy_score)0.9820426487093153 老师,为什么交叉验证的准确率和accuracy_score的准确率计算结果相反? import pandas as pd from sklearn.ensemble import AdaBoostClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.feature_extraction import DictVectorizer from sklearn.model_selection import cross_val_score from sklearn.metrics import accuracy_score import numpy as np # adaboost 预测泰坦尼克号生存 # 数据加载 train_data = pd.read_csv('../Titanic_Data/train.csv') test_data = pd.read_csv('../Titanic_Data/test.csv') # 数据清洗 train_data['Age'].fillna(train_data['Age'].mean(), inplace=True) test_data['Age'].fillna(test_data['Age'].mean(),inplace=True) train_data['Fare'].fillna(train_data['Fare'].mean(), inplace=True) test_data['Fare'].fillna(test_data['Fare'].mean(),inplace=True) # 使用登录最多的港口来填充登录港口的 nan 值 train_data['Embarked'].fillna('S', inplace=True) test_data['Embarked'].fillna('S',inplace=True) # 特征选择 features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked'] X_train = train_data[features] y_train = train_data['Survived'] X_test = test_data[features] # 替换成计算机能理解的 dvec=DictVectorizer(sparse=False) X_train = dvec.fit_transform(X_train.to_dict(orient='record')) # Adaboost ada = AdaBoostClassifier(n_estimators=200) ada.fit(X_train, y_train) ada_pred = ada.predict(X_train) # 决策树 clf = DecisionTreeClassifier(criterion='entropy') clf.fit(X_train, y_train) clf_pred = clf.predict(X_train) print(np.mean(cross_val_score(ada, X_train, y_train, cv=10))) print(np.mean(cross_val_score(clf, X_train, y_train, cv=10))) print(accuracy_score(y_train, ada_pred)) print(accuracy_score(y_train, clf_pred))
    展开
  • Liam
    2021-03-26
    ax = fig.add_subplot(111)ax.plot([1,n_estimators],[dt_stump_err]*2, 'k-', label=u'决策树弱分类器 错误率')ax.plot([1,n_estimators],[dt_err]*2,'k--', label=u'决策树模型 错误率')ada_err = np.zeros((n_estimators,)). 疑问:这里*2是什么意思,能解析下代码吗?

    作者回复: print([0.8] * 2) 你会看到打印结果为:[0.8, 0.8] 列表 * n 代表列表被复制扩展n倍长。 乘号*常被用于快速初始化list,但有一个隐患:被乘号复制的对象都指向同一个空间,所以如果你的列表中的元素要用来存储不同值时,建议用for循环。 老师这里只是为了可视化,所以才使用这种方式。

    1
  • 小晨
    2021-03-10
    弱分类器准确率为 0.7868 决策树分类器准确率为 0.7823 AdaBoost分类器准确率为:0.8115 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Peter import numpy as np import pandas as pd from sklearn.ensemble import AdaBoostClassifier from sklearn.feature_extraction import DictVectorizer from sklearn.model_selection import cross_val_score from sklearn.tree import DecisionTreeClassifier # 迭代次数 n_estimators = 200 train_data = pd.read_csv(r'data/Titanic_Data_train.csv') test_data = pd.read_csv(r'data/Titanic_Data_Test.csv') # 用平均年龄将缺失的年龄补齐 train_data['Age'].fillna(train_data['Age'].mean(), inplace=True) test_data['Age'].fillna(test_data['Age'].mean(), inplace=True) # 用平均票价将缺失的票价补齐 train_data['Fare'].fillna(train_data['Fare'].mean(), inplace=True) test_data['Fare'].fillna(test_data['Fare'].mean(), inplace=True) # 用登船港口最多的S补齐缺失 train_data['Embarked'].fillna('S', inplace=True) test_data['Embarked'].fillna('S', inplace=True) # 将可用来分类的数据放到训练集中 features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked'] train_features = train_data[features] train_labels = train_data['Survived'] test_features = test_data[features] # 字符串数据规范化,转为int型 dvec = DictVectorizer(sparse=False) train_features = dvec.fit_transform(train_features.to_dict(orient='record')) test_features = dvec.transform(test_features.to_dict(orient='record')) # 弱分类器 dt_stump = DecisionTreeClassifier(max_depth=1, min_samples_leaf=1) dt_stump.fit(train_features, train_labels) print(u'弱分类器准确率为 %.4lf' % dt_stump.score(train_features, train_labels)) # 决策树分类器 dt = DecisionTreeClassifier() dt.fit(train_features, train_labels) print(u'决策树分类器准确率为 %.4lf' % np.mean(cross_val_score(dt, train_features, train_labels, cv=10))) # AdaBoost分类器 ada = AdaBoostClassifier(base_estimator=dt_stump, n_estimators=n_estimators) ada.fit(train_features, train_labels) ada_score = np.mean(cross_val_score(ada, train_features, train_labels, cv=10)) print("AdaBoost分类器准确率为:%.4lf" % ada_score)
    展开

    作者回复: 结果正确,一般来说AdaBoost的结果会比决策树分类器略好一些

  • 非同凡想
    2020-11-26
    交作业: import numpy as np import pandas as pd from sklearn import tree from sklearn import feature_extraction from sklearn.model_selection import cross_val_score from sklearn.ensemble import AdaBoostClassifier # load dataset train_data = pd.DataFrame(pd.read_csv('~/Documents/titanic_data/train.csv')) test_data = pd.DataFrame(pd.read_csv('~/Documents/titanic_data/test.csv')) # data cleaning train_data['Age'].fillna(train_data['Age'].mean(), inplace=True) test_data['Age'].fillna(test_data['Age'].mean(), inplace=True) test_data['Fare'].fillna(test_data['Fare'].mean(), inplace=True) train_data['Embarked'].fillna('S', inplace=True) test_data['Embarked'].fillna('S', inplace=True) # select features features = ['Pclass', 'Sex', "Age", 'SibSp', 'Parch', 'Fare', 'Embarked'] train_x = train_data[features] train_y = train_data['Survived'] test_x = test_data[features] # one-hot dict_vec = feature_extraction.DictVectorizer(sparse=False) train_x = dict_vec.fit_transform(train_x.to_dict(orient='record')) test_x = dict_vec.transform(test_x.to_dict(orient='record')) print(dict_vec.feature_names_) # decision tree dtc = tree.DecisionTreeClassifier() dtc.fit(train_x, train_y) print("决策树准确率", dtc.score(train_x, train_y)) print("决策树:k折交叉验证准确率:", np.mean(cross_val_score(dtc, train_x, train_y, cv= 10))) # adaboost ada = AdaBoostClassifier(n_estimators=50) ada.fit(train_x, train_y) print("AdaBoost准确率", ada.score(train_x, train_y)) print("AdaBoost k折交叉验证准确率:", np.mean(cross_val_score(ada, train_x, train_y, cv= 10))) 决策树准确率 0.9820426487093153 决策树:k折交叉验证准确率: 0.7744943820224719 AdaBoost准确率 0.8338945005611672 AdaBoost k折交叉验证准确率: 0.8070037453183521
    展开
  • 萌辰
    2020-07-05
    在AdaBoost、决策树回归、KNN房价预测对比中发现,随机种子对决策树的预测结果有影响。 分别测试了三种不同的随机种子: dec_regressor=DecisionTreeRegressor(random_state=1) dec_regressor=DecisionTreeRegressor(random_state=20) dec_regressor=DecisionTreeRegressor(random_state=30) 测试结果为: 决策树均方误差1 = 36.65 决策树均方误差20 = 25.54 决策树均方误差30 = 37.19 思考: 此处考虑这里没有限制种子的随机性,对比的结果可能过于随机了,无法真实反映算法效果,两种算法原理中随机种子的应用情况不同。思考是不是采用多次随机MSE结果求平均的方法作为【比较项】更为合适 KNN算法无随机种子影响。
    展开

    作者回复: DecisionTreeRegressor的参数random_state随机数种子,用来控制估算器的随机性。 即使分割器设置为“best”,每个分割中的特征也始终是随机排列的。 当max_features <n_features时,算法将在每个分割处随机选择max_features,然后再在其中找到最佳分割。 但是,即使max_features = n_features,找到的最佳分割也可能因不同的运行而有所不同。 就是这种情况,如果对于几个分割而言标准的改进是相同的,并且必须随机选择一个分割。 为了在拟合过程中获得确定性的行为,random_state必须固定为整数。 使用相同random_state,则每次使用相同的分割策略。所以不同随机数种子参数,得到的结果不同。

  • even
    2020-06-30
    不同的算法有不同的特点,老师是否可以做个总结和对比。比如在实际的工作或者项目中,根据经验和不同的算法特点,如何选择算法,为什么选择这种算法。希望老师能分享这一块实际应用场景的经验。
  • §mc²ompleXWr
    2020-06-09
    使用自带的数据集就不用做数据规范化么?

    作者回复: 是否需要进行数据规范化,取决于所使用的模型和特征的数据范围。比如:树模型和朴素贝叶斯模型不需要进行规范化;如果数据集特征的数据已经都在0-1之间,或者已经符合标准化,则无需规范化。

  • 鲨鱼鲸鱼鳄鱼
    2020-05-25
    老师,请问AdaBoost模型在预测前需不需要对数据进行标准化或者归一化,做有什么好处,不做有什么好处呢

    作者回复: AdaBoost模型默认使用的弱分类器是决策树模型,树模型只看点之间的相对位置,不计算二者之间的距离,因此不需要进行数据规范化(包括标准化或归一化等)

  • 张贺
    2020-03-27
    老师讲的很清晰

    作者回复: 谢谢张贺同学

  • 热水泡面不会做
    2020-03-10
    可不可以解释一下这里的学习率体现在哪里呢?之前的原理讲解里好像没有用到学习率?
  • Untitled
    2020-03-08
    结果: ada train precision = 0.8338945005611672 ada 10k precison = 0.8070037453183521 clf train precision = 0.9820426487093153 clf 10k precision = 0.7767041198501872 #代码 import pandas as pd import numpy as np from sklearn.feature_extraction import DictVectorizer from sklearn.ensemble import AdaBoostClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.model_selection import cross_val_score train_data = pd.read_csv('train.csv') test_data = pd.read_csv('test.csv') train_data['Age'].fillna(train_data['Age'].mean(),inplace=True) test_data['Age'].fillna(train_data['Age'].mean(),inplace=True) train_data['Fare'].fillna(train_data['Age'].mean(),inplace=True) test_data['Fare'].fillna(train_data['Age'].mean(),inplace=True) train_data['Embarked'].fillna('S',inplace=True) test_data['Embarked'].fillna('S',inplace=True) features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked'] train_features = train_data[features] train_labels = train_data['Survived'] test_features = test_data[features] dvec=DictVectorizer(sparse=False) train_features=dvec.fit_transform(train_features.to_dict(orient='record')) test_features=dvec.transform(test_features.to_dict(orient='record')) ada = AdaBoostClassifier() ada.fit(train_features, train_labels) print("ada train precision = ",ada.score(train_features, train_labels)) print("ada 10k precison = ", np.mean(cross_val_score(ada,train_features,train_labels,cv=10))) clf=DecisionTreeClassifier(criterion='entropy') clf.fit(train_features,train_labels) print("clf train precision = ", clf.score(train_features, train_labels)) print("clf 10k precision = ", np.mean(cross_val_score(clf,train_features,train_labels,cv=10)))
    展开
  • 骑行的掌柜J
    2019-08-14
    打错了 陈老师是对的 是回归算法😂里没有分类算法的algorithm 参数。
  • 滨滨
    2019-04-21
    分类和回归都是做预测,分类是离散值,回归是连续值

    作者回复: 对的

  • hlz-123
    2019-03-27
    老师,在AdaBoost 与决策树模型的比较的例子中,弱分类器 dt_stump = DecisionTreeClassfier(max_depth=1,min_samples_leaf=1) 为什么两个参数都设置为1,相当于只有1个根节点,2个叶节点? 而普通的决策树分类器,没有设置参数,这是什么原因?
  • 叮当猫
    2019-03-19
    fit_transform数据统一处理,求问什么时候需要? 在我同时没有进行fit_transform的情况下,准确率: 决策树弱分类器的准确率是0.7867 决策树分类器的准确率是0.7734 AdaBoost分类器的准确率是0.8161 在我对数据同时进行fit_transform的情况下,准确率: 决策树弱分类器的准确率是0.7867 决策树分类器的准确率是0.7745 AdaBoost分类器的准确率是0.8138 以下是第一种情况: train_data['Embarked'] = train_data['Embarked'].map({'S':0, 'C':1, 'Q':2}) test_data['Embarked'] = test_data['Embarked'].map({'S':0, 'C':1, 'Q':2}) train_data['Sex'] = train_data['Sex'].map({'male':0, 'female':1}) test_data['Sex'] = test_data['Sex'].map({'male':0, 'female':1}) train_data['Age'].fillna(train_data['Age'].mean(), inplace=True) test_data['Age'].fillna(test_data['Age'].mean(), inplace=True) train_data['Fare'].fillna(train_data['Fare'].mean(), inplace=True) test_data['Fare'].fillna(test_data['Fare'].mean(), inplace=True) features = ['Pclass', 'Sex','Age','SibSp', 'Parch', 'Fare', 'Embarked'] train_features = train_data[features] train_labels = train_data['Survived'] test_features = test_data[features] #train_features = dvec.fit_transform(train_features.to_dict(orient='record')) #test_features = dvec.transform(test_features.to_dict(orient='record')) 以下是第二种情况: #train_data['Embarked'] = train_data['Embarked'].map({'S':0, 'C':1, 'Q':2}) #test_data['Embarked'] = test_data['Embarked'].map({'S':0, 'C':1, 'Q':2}) #train_data['Sex'] = train_data['Sex'].map({'male':0, 'female':1}) #test_data['Sex'] = test_data['Sex'].map({'male':0, 'female':1}) train_data['Age'].fillna(train_data['Age'].mean(), inplace=True) test_data['Age'].fillna(test_data['Age'].mean(), inplace=True) train_data['Fare'].fillna(train_data['Fare'].mean(), inplace=True) test_data['Fare'].fillna(test_data['Fare'].mean(), inplace=True) features = ['Pclass', 'Sex','Age','SibSp', 'Parch', 'Fare', 'Embarked'] train_features = train_data[features] train_labels = train_data['Survived'] test_features = test_data[features] train_features = dvec.fit_transform(train_features.to_dict(orient='record')) test_features = dvec.transform(test_features.to_dict(orient='record'))
    展开