sklearn的系统学习——决策树回归(含有python完整代码及案例)

目录

结果随机性?

交叉验证

如何调参?

网格搜索


上一篇我们了解了决策树,以及决策树分类器,这一篇来一起了解决策树解决回归问题。

其实,决策树回归和决策树分类器的参数、属性以及接口几乎一样。只是criterion参数不同

criterion

mse:  均方误差,使用叶节点的中值来最小化L2损失

mae:  绝对平方误差,使用叶节点的中值来最小化L1损失

friedman_mse: 费尔德曼均方误差

 关键代码

regressor = DecisionTreeRegressor(random_state=42)  #实例化
regressor.fit(xtrain,ytrain)  #训练
score = regressor.score(xtest,ytest)  #评估

加个波士顿房价小案例

from sklearn.datasets import load_boston
from sklearn.tree import DecisionTreeRegressor
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_score
import numpy as np
import matplotlib.pyplot as plt

boston = load_boston()
# print(boston.data.shape)
regressor = DecisionTreeRegressor(random_state=42)  #实例化
xtrain,xtest,ytrain,ytest = train_test_split(boston.data,boston.target,test_size=0.3)
regressor.fit(xtrain,ytrain)
score = regressor.score(xtest,ytest)
print(score)
# 交叉验证
cross = cross_val_score(regressor,boston.data,boston.target,cv=10,scoring='neg_mean_squared_error')  #负均方误差
cross1 = cross_val_score(regressor,boston.data,boston.target,cv=10)  #  以R的平方进行评估,越接近1越好
print(cross)
print(cross1)

 再来一个拟合正弦曲线的小案例吧

rng = np.random.RandomState(1)  #numpy生成一个随机数种子
# rng.rand(10)  生成10个0-1的数字
# rng.rand(10,5)  生成10行5列的数组
x = np.sort(5 * rng.rand(80,1),axis=0)   #生成0-5的数字,排序后的数组
# print(x)
y = np.sin(x).ravel()   #np.sin(x)生成的是二维的,但做的是单标签问题,用ravel进行降维
plt.scatter(x,y)
# plt.show()  #此时可以看到一条正弦曲线的散点图
# print(y)
#加入噪音  为某些y加上或减去随机数字
# y[::5] 所有的行,所有的列,每五个取一个
y[::5] += 3 * (0.5 - rng.rand(16))
plt.scatter(x,y)
# plt.show()

regr_1 = DecisionTreeRegressor(max_depth=2)
regr_2 = DecisionTreeRegressor(max_depth=5)
regr_1.fit(x,y)
regr_2.fit(x,y)
#numpy生成的随机的数列,0为开始,5为结束,0.01为步长,np.newaxis增维度
xtest = np.arange(0.0,5.0,0.01)[:,np.newaxis]

y_1 = regr_1.predict(xtest)
y_2 = regr_2.predict(xtest)

plt.scatter(x,y,s=20,edgecolors='black',c='darkorange',label='data')
plt.plot(xtest,y_1,color='orange',label='max_depth_=2',linewidth=2)
plt.plot(xtest,y_2,color='red',label='max_depth_=5',linewidth=2)  #更容易受到噪声影响
plt.xlabel('data')
plt.ylabel('target')
plt.title('DecisionTreeRegressor')
plt.legend()
plt.show()

 

其实,到这里决策树回归已经完全说完了,嘿嘿嘿,是不是很简单呐。

那下面我们来接着上一次的问题接着讨论,主要是两个方面:1、结果随机性;2、如何调参。

结果随机性?

不难发现,每次运行的结果会不太一样,其原因有二,一是训练集和测试集可能划分不一致,二是决策树random_state未固定。第二个问题其实我们已经解决,就是设定固定值。但是第一个怎么避免怎么解决呢?

交叉验证

那我们何不反其道而行,既然每次必然不一样,而且不想将一次划分的数据集存储(当然仅看一次的划分结果并不可靠,可能这一次恰好划分的数据非常好,得分非常高),所以干脆借助交叉验证来计算均值喽,避免随机性和偶然性(具体交叉验证是什么可以进我主页或者直接点击“交叉验证”四个字即可跳转查看哦)。

关键代码

from sklearn.model_selection import cross_val_score
cross1 = cross_val_score(regressor,boston.data,boston.target,cv=10)  #  以R的平方进行评估,越接近1越好

如何调参?

我们上一篇主要介绍的还是对于决策树的每个参数怎么一个一个调参,但是有没有一种简单粗暴的方法让它自己去遍历然后确定最优组合呢?有呀,网格搜索!

网格搜索

网格搜索:能够帮助我们同时调整多个参数的技术,枚举技术

所以引来的缺点自然不用多说,耗时,计算量大,而且可能算了好久发现结果没有自己随便调的高(这是因为凡是我们自己设定的,它都不会舍弃,而我们不是上帝视角,可能有些参数设定并不合适),但总之还是个不错的方法。

关键代码

from sklearn.model_selection import GridSearchCV
import numpy as np

gini_threholds = np.linspace(0,0.5,10)  #随机的有顺序的50个数
# np.arange(0,0.5,0.01)                 #随机的步长为0.01的数
#一连串的参数和参数对应的我们希望网格搜索的参数的取值范围
parameters = {'criterion':('gini','entropy')
              ,'splitter':('best','random')
              ,'max_depth':[*range(1,10)]
              ,'min_samples_leaf':[*range(1,50,5)]
              ,'min_impurity_decrease':gini_threholds
              }
#实例化模型
clf = DecisionTreeClassifier(random_state=42)
GS = GridSearchCV(clf,parameters,cv=5)
GS = GS.fit(xtrain,ytrain)
# s = GS.score(xtest,ytest)

print('最优组合',GS.best_params_)
print('最优分数',GS.best_score_)

最后,加个泰坦尼克号的案例,附上详细代码。

数据集下载  https://www.kaggle.com/competitions/titanic

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeRegressor
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import cross_val_score
##数据集下载  https://www.kaggle.com/competitions/titanic
data = pd.read_csv('train.csv')
# print(data.head(5))
# print(data.info())
# print(data.columns)

##########数据预处理###############
#删除特征
data.drop(['Name','Ticket','Cabin'],inplace=True,axis=1)  #axis=1  对列进行操作
# print(data1.shape())
#c处理缺失值
data['Age'] = data['Age'].fillna(data['Age'].mean())
data = data.dropna(axis=0)  #axis=0行 axis=1 列
#Embarked列转换为012
labels = data['Embarked'].unique().tolist()
data['Embarked'] = data['Embarked'].apply(lambda x: labels.index(x))
#性别转化为01,有两种方式
#法一
# labels1 = data['Sex'].unique().tolist()
# data['Sex'] = data['Sex'].apply(lambda x: labels1.index(x))
#法二
data['Sex'] = (data['Sex'] == 'male').astype('int')
data.loc[:,'Sex'] = (data['Sex'] == 'male').astype('int') #更推荐使用 loc里面必须写的是列名,而不能写数字,如果要写数字就用iloc
# print(data.head(5))


x = data.loc[:,data.columns != 'Survived']
y = data.loc[:,data.columns == 'Survived']
print(x.shape)
print(y.shape)
xtrain,xtest,ytrain,ytest = train_test_split(x,y,test_size=0.3)
#重整理索引 按从0开始
for i in [xtrain,xtest,ytrain,ytest]:
    i.index = range(i.shape[0])
# print(xtrain.index)

######模型#########
clf = DecisionTreeClassifier(random_state=25)
clf = clf.fit(xtrain,ytrain)
result = clf.score(xtest,ytest)
print(result)

clf1 = DecisionTreeClassifier(random_state=25)
score = cross_val_score(clf1,x,y,cv=5).mean()
print(score)
tr=[]
te=[]
for i in range(10):
    clf = DecisionTreeClassifier(random_state=25
                                 ,max_depth=i+1
                                 ,criterion='entropy')
    clf = clf.fit(xtrain,ytrain)
    score_tr = clf.score(xtrain,ytrain)
    score_te = cross_val_score(clf,x,y,cv=5).mean()
    tr.append(score_tr)
    te.append(score_te)
print('最高分数',max(te))

plt.plot(range(1,11),tr,color='red',label='train')
plt.plot(range(1,11),te,color='green',label='test')
plt.legend()
plt.show()

###########网格搜索###########################
'''
能够帮助我们同时调整多个参数的技术,枚举技术
缺点:因为是枚举,一个一个试,所以计算量非常大,耗时,并且其实网格搜索可能没有自己设置的高,因为设置的都不能舍弃
'''
from sklearn.model_selection import GridSearchCV
import numpy as np

gini_threholds = np.linspace(0,0.5,10)#随机的有顺序的五十个数
# entropy_threholds = np.linspace(0,1,50)#随机的有顺序的五十个数
# np.arange(0,0.5,0.01)#随机的步长为0.01的数
#一连串的参数和参数对应的我们希望网格搜索的参数的取值范围
parameters = {'criterion':('gini','entropy')
              ,'splitter':('best','random')
              ,'max_depth':[*range(1,10)]
              ,'min_samples_leaf':[*range(1,50,5)]
              ,'min_impurity_decrease':gini_threholds
              }
#实例化模型
clf = DecisionTreeClassifier(random_state=42)
GS = GridSearchCV(clf,parameters,cv=5)
GS = GS.fit(xtrain,ytrain)
# s = GS.score(xtest,ytest)

print('最优组合',GS.best_params_)
print('最优分数',GS.best_score_)

到此,决策树的内容就结束了,下一步随机森林。

  • 3
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
决策树算法是一种广泛应用于分类和回归的机器学习算法,它基于树形结构对样本进行分类或预测。决策树算法的主要思想是通过一系列的判断来对样本进行分类或预测。在决策树中,每个节点表示一个属性或特征,每个分支代表该属性或特征的一个取值,而每个叶子节点代表一个分类或预测结果。 决策树算法的训练过程主要包括以下步骤: 1. 特征选择:根据某种指标(如信息增益或基尼系数)选择最优的特征作为当前节点的分裂属性。 2. 决策树生成:根据选择的特征将数据集分成若干个子集,并递归地生成决策树。 3. 剪枝:通过剪枝操作来提高决策树的泛化性能。 决策树算法的优点包括易于理解和解释、计算复杂度较低、对缺失值不敏感等。但是,决策树算法也存在一些缺点,如容易出现过拟合、对离散数据敏感等。 下面是一个决策树算法的案例:假设我们要根据一个人的年龄、性别、教育程度和职业预测其收入水平(高于或低于50K)。首先,我们需要将这些特征进行编码,将其转换为数值型数据。然后,我们可以使用决策树算法对这些数据进行训练,并生成一个决策树模型。最后,我们可以使用该模型对新的数据进行分类或预测。例如,根据一个人的年龄、性别、教育程度和职业,我们可以使用决策树模型预测该人的收入水平。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值