Python手撸机器学习系列(十四):提升树算法实现

一、提升树

1.1 提升树概述

待更

1.2 提升树代码实现

为与李航《统计学习方法》第168页例8.2一致,回归树简化为只有一个根节点连接两个叶子结点的结构,因为只有一个特征。
当有多个特征的情况下应该递归生成回归树,但特征的划分方法与下面的代码一致。

import numpy as np

#单棵回归树,回归树本应递归生成,但这里为了与课本一致,简化成只有一个特征,即根节点带两个叶子结点的回归树
def Regression_Tree(Data):
    n = len(Data)
    points = [(Data[i][0]+Data[i+1][0])/2 for i in range(n-1)]
    min_error = float('inf')
    min_s = -1
    min_c1 = -1
    min_c2 = -1
    for s in points: #检查每个切分点
        R1 = [x[0] for x in Data if x[0] < s] #划分左区间
        label_1 = [x[1] for x in Data if x[0] < s]
        R2 = [x[0] for x in Data if x[0] > s] #划分右区间
        label_2 = [x[1] for x in Data if x[0] > s]
        c1 = np.mean(label_1) #左叶子结点取值
        c2 = np.mean(label_2) #右叶子结点取值
        ms = MSE(c1, label_1) + MSE(c2, label_2) #划分的均方误差
        if ms < min_error: #寻找最小均方误差的划分方式
            min_error = ms
            min_s = s
            min_c1 = c1
            min_c2 = c2
    tree = (min_s,(min_c1,min_c2))
    residual = [[x[0], x[1]-Tree_predict(x[0], tree)] for x in Data] #计算残差
    return  tree, residual #返回当前树以及残差数据

def Boosting_Tree(Data, m):
    final_model = []
    data = [x[0] for x in Data]
    label = [x[1] for x in Data]
    for i in range(m): #需要组合多少次回归树
        tree, Data = Regression_Tree(Data) #将残差作为下一次输入
        final_model.append(tree) #纳入新的回归树
        pred = [Boosting_predict(x, final_model) for x in data] 
        error = MSE(pred, label) #计算当前提升树的平方损失
        print('组合{}棵回归树后的提升树平方损失为:{}'.format(i+1,error))
    return final_model #返回回归树,这里也可以设置当损失达到多少时停止生成回归树

def MSE(pred,lable):
    return sum((np.array(pred)-np.array(lable))**2)

#单棵树预测值
def Tree_predict(x, Tree):
    return Tree[1][0] if x < Tree[0] else Tree[1][1]

#提升树预测值
def Boosting_predict(x, model):
    #遍历每棵树,增加或减少值
    pred = 0
    for i in range(len(model)):
        tree = model[i]
        pred += tree[1][0] if x < tree[0] else tree[1][1]
    return pred

if __name__ == '__main__':
    label = [5.56, 5.70, 5.91, 6.40, 6.80, 7.05, 8.90, 8.70, 9.00, 9.05]
    Data = [[i+1, label[i]] for i in range(10)] #两维[data,label]
    Final_boosting_tree = Boosting_Tree(Data,6)  #后面的数据设定为生成多少棵回归树

结果:

组合1棵回归树后的提升树平方损失为:1.9300083333333338
组合2棵回归树后的提升树平方损失为:0.8006750000000015
组合3棵回归树后的提升树平方损失为:0.47800833333333437
组合4棵回归树后的提升树平方损失为:0.30555925925926064
组合5棵回归树后的提升树平方损失为:0.2289152263374492
组合6棵回归树后的提升树平方损失为:0.17217806498628285

与李航《统计学习方法》第169-170页结果一致
也可以一直迭代下去,损失会越来越低:

组合12棵回归树后的提升树平方损失为:0.07710099633806546
组合13棵回归树后的提升树平方损失为:0.06961581825503288
组合14棵回归树后的提升树平方损失为:0.06035149269490475
组合15棵回归树后的提升树平方损失为:0.049114857588362024
组合16棵回归树后的提升树平方损失为:0.0459049073710459
组合17棵回归树后的提升树平方损失为:0.040459737736702577
组合18棵回归树后的提升树平方损失为:0.03836252259100614
组合19棵回归树后的提升树平方损失为:0.03221858035110763
组合20棵回归树后的提升树平方损失为:0.028268903196886488
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,对于这个问题,我可以给您提供一些思路和代码实现。 首先,我们需要导入相关的库和数据集,使用pandas库读取数据集: ```python import pandas as pd train_data = pd.read_csv('train.csv') test_data = pd.read_csv('test.csv') ``` 然后,我们需要对数据进行预处理,包括数据清洗、特征工程和特征选择等。在这里,我们可以先对数据进行简单的清洗: ```python train_data = train_data.drop(['Cabin'], axis=1) test_data = test_data.drop(['Cabin'], axis=1) train_data = train_data.dropna() test_data = test_data.dropna() ``` 接着,我们需要对数据进行特征工程,包括特征提取和特征转换等。在这里,我们可以对数据进行一些简单的特征提取,例如提取乘客的称呼(如Mr.、Mrs.、Miss等),并将其转换为数值型数据: ```python train_data['Title'] = train_data['Name'].map(lambda x: x.split(', ')[1].split('. ')[0]) test_data['Title'] = test_data['Name'].map(lambda x: x.split(', ')[1].split('. ')[0]) title_dict = {'Mr': 1, 'Miss': 2, 'Mrs': 3, 'Master': 4, 'Dr': 5, 'Rev': 6, 'Col': 7, 'Ms': 8, 'Mlle': 9, 'Major': 10, 'Lady': 11, 'Sir': 12, 'Mme': 13, 'Capt': 14, 'Jonkheer': 15, 'Don': 16, 'the Countess': 17} train_data['Title'] = train_data['Title'].map(title_dict) test_data['Title'] = test_data['Title'].map(title_dict) ``` 然后,我们可以对特征进行标准化处理: ```python from sklearn.preprocessing import StandardScaler scaler = StandardScaler() train_data[['Age', 'Fare']] = scaler.fit_transform(train_data[['Age', 'Fare']]) test_data[['Age', 'Fare']] = scaler.transform(test_data[['Age', 'Fare']]) ``` 接下来,我们需要将数据集分为训练集和验证集,然后使用决策算法进行模型训练和预测: ```python from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score from sklearn.model_selection import train_test_split features = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked', 'Title'] X = train_data[features] y = train_data['Survived'] X_train, X_valid, y_train, y_valid = train_test_split(X, y, test_size=0.2, random_state=42) clf = DecisionTreeClassifier() clf.fit(X_train, y_train) y_pred = clf.predict(X_valid) print('Accuracy:', accuracy_score(y_valid, y_pred)) ``` 最后,我们可以使用训练好的模型对测试集进行预测,并将结果保存为CSV文件: ```python X_test = test_data[features] y_test = clf.predict(X_test) submission = pd.DataFrame({'PassengerId': test_data['PassengerId'], 'Survived': y_test}) submission.to_csv('submission.csv', index=False) ``` 以上就是使用决策算法进行泰坦尼克号乘客生存预测的代码实现。需要注意的是,这只是一个简单的示例,实际的应用需要根据具体情况进行更加细致的数据处理和模型调优。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

锌a

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值