写点什么

决策树 - 用回归树拟合正弦曲线

  • 2022-11-03
    山东
  • 本文字数:1857 字

    阅读完需:约 6 分钟

import numpy as npfrom sklearn.tree import DecisionTreeClassifierimport matplotlib.pyplot as plt
复制代码


rng = np.random.RandomState(1)X = np.sort(5 * rng.rand(80,1), axis=0)# axis=0,沿列的方向排序数据,如果有多列,每一列数据之间自己进行排序,是独立的# axis=1,沿行的方向排序数据;axis=None,将高维数组转化为一维并升序排序
复制代码


rng = np.random.RandomState(1):一个伪随机数生成器,返回 RandomState 对象。随机数是用确定性的算法计算出来自均匀分布的随机数序列。并不真正的随机,但具有类似于随机数的统计特征,如均匀性、独立性等。rand(80),指的是一个 80 个元素的一维数组,不是 80 行 1 列,或者 1 行 80 列,因为这二者都是二维数组的描述方式由于fit接收 X 不接收一维特征,因此我们需要生成二维数组(数据矩阵),也就是rng.rand(80,1)


这里要注意 np.random.RandomState(1).rand()和 np.random.rand(),是不同的,前者是在一个固定的伪随机数生成器下生成的的随机数,即使我们在前面写了前者,但不经过固定的伪随机数生成器来调用 rand,那么我们生成的随机数依旧无法被固定。例如现在我们固定了一个伪随机数生成器

for i in range(3):
 rng = np.random.RandomState(1)
 print(rng.rand(3))
 print(np.random.rand(3))
---
[4.17022005e-01 7.20324493e-01 1.14374817e-04]
[0.24854201 0.50811133 0.49999858]
[4.17022005e-01 7.20324493e-01 1.14374817e-04]
[0.5478054  0.59739849 0.22514079]
[4.17022005e-01 7.20324493e-01 1.14374817e-04]
[0.17886054 0.60591715 0.64348522]

显然前者是固定的,对后者并无影响

这里有一些个人理解。可能 np.random.RandomState(1).rand()调用后再调用 np.random.rand(),会影响已经生成的 RandomState 对象,因此如果调用了 np.random.rand(),我们再想使用 np.random.RandomState(1).rand()生成固定随机数,需要再次得到之前的 RandomState 对象。即下述情况

rng = np.random.RandomState(1)
for i in range(2):
 print(rng.rand(3))
 print(np.random.rand(3))
---
[4.17022005e-01 7.20324493e-01 1.14374817e-04]
[0.16401897 0.4949546  0.87024651]
[0.30233257 0.14675589 0.09233859]
[0.80481614 0.63129344 0.67668002]


y = np.sin(X).ravel()# ravel()返回的是视图,修改时会影响原始矩阵# flatten()返回一份拷贝,对拷贝所做修改不会影响原始矩阵
复制代码


np.sin(X)结果是二维数组(80,1),但 y 必须是一维数组,因此使用ravel()降维


plt.figure()plt.scatter(X, y, edgecolor='black')
复制代码



增加一个的噪声


y[::5] += 3 * (0.5 - rng.rand(16))# y[::5],意为每5行、每5列
复制代码


plt.figure()plt.scatter(X, y, edgecolor='black')
复制代码



训练决策树


regr_1 = DecisionTreeRegressor(max_depth=2)regr_2 = DecisionTreeRegressor(max_depth=5)regr_1.fit(X,y)regr_2.fit(X,y)
复制代码


X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]# np.arange(开始点, 结束点, 步长),从开始点每次增加步长的大小,直到结束点(不包括结束点)
复制代码


[:, np.newaxis]类似于reshape(-1,1),把一维变成二维


np.random.rand(5).reshape(-1,1)
---
array([[0.04267956],
    [0.78550248],
    [0.26686091]])

a = np.array([1, 2, 3, 4])
print(a[:])# 切片
# 几维数组,就最多能有几个切片,但低维数组可以用newaxis填充空的部分来升维
print(a[:, np.newaxis]) # 行数是a里的元素个数,列上的数据顺序是a里元素的顺序
# 可以认为是加列的方式变为二维数组,np.newaxis写在列索引位置
print(a[np.newaxis, :]) # 列数是a里的元素个数,行上的数据顺序是a里元素的顺序
# 可以认为是加行的方式变为二维数组,np.newaxis写在行索引位置
---
[1 2 3 4]
[[1]
[2]
[3]
[4]]
[[1 2 3 4]]

np.newaxis可以只会结论,不需要知道为什么


根据训练的决策树预测结果


y_1 = regr_1.predict(X_test)y_2 = regr_2.predict(X_test)
复制代码


plt.figure() # 新建画布plt.scatter(X, y, s=20, edgecolor='black', c='darkorange', label='data')plt.plot(X_test, y_1, color='cornflowerblue', label='max_depth=2', linewidth=2) # 画线plt.plot(X_test, y_2, color='yellowgreen', label='max_depth=5', linewidth=2)plt.xlabel('data')plt.ylabel('target')plt.title('Decision Tree Regression')plt.legend()plt.show()
复制代码



显然最大深度等于 5 的受噪声影响大,有过拟合的趋势


视频作者:菜菜TsaiTsai 链接:【技术干货】菜菜的机器学习sklearn【全85集】Python进阶_哔哩哔哩_bilibili


发布于: 刚刚阅读数: 5
用户头像

还未添加个人签名 2022-09-14 加入

还未添加个人简介

评论

发布
暂无评论
决策树-用回归树拟合正弦曲线_机器学习_烧灯续昼2002_InfoQ写作社区