Python-Level5-day04:线性回归的集成学习模型之bosting与随机森林算法,线性回归总结,分类问题的逻辑回归模型及其实现,分类问题的损失函数,多分类实现方法,决策树分类原理与汽车案例

线性回归的集成学习模型之boosting算法与随机森林算法,线性回归总结,分类问题的逻辑回归模型及其实现,分类问题的损失函数,多分类实现方法,决策树分类原理与案例(小汽车质量)

二、集成学习

1. 集成学习

决策树是中庸的模型,集成学习通过构建并合并多个模型来完成学习任务,从而获得比单一学习模型更显著优越的泛化性能,简言之,集成学习就是利用模型的“集体智慧”,提升预测的准确率. 根据单个模型方式,集成学习可以分为两大类:

  • 个体模型间存在强依赖关系,必须串行生成的序列化(前面模型结果作为后面模型的输入)方法,其代表为Boosting算法;

  • 个体模型之间不存在强依赖关系,可同时生成的并行化方法,代表是Bagging和随机森林算法.

2. Boosting

1)什么是Boosting

Boosting(直译为推进、提升)是一族可以将弱学习器提升为强学习器的算法,其工作原理是:

  • 先训练出第一个初始模型;

  • 根据第一个模型的表现进行调整参数与权重,使得模型预测错误的数据获得更多的关注,争取再重新训练下一个模型将其预测正确;类似于考试错题集。

  • 不断重复第二步,直到模型数量达到预先设定的数目T,最终将这T个模型加权结合.

AdaBoosting是Boosting算法族中最著名的算法,它根据每次训练集之中每个样本的分类是否正确,以及上次的总体分类的准确率,来确定每个样本的权值。将修改过权值的新数据集送给下层分类器进行训练,最后将每次训练得到的分类器最后融合起来,作为最后的决策分类器。

2)实现Boosting

sklearn中,AdaBoosting(正向激励)相关API:

import sklearn.tree as st
import sklearn.ensemble as se
​
# model: 决策树模型(单个模型,基学习器)
model = st.DecisionTreeRegressor(max_depth=4)
​
# n_estimators:构建400棵不同权重的决策树,训练模型(这个模型里面有很多子模型即400个决策树,每个深度4,前后树串起来的)
model = se.AdaBoostRegressor(model, # 单模型
                             n_estimators=400, # 决策树数量
                             random_state=7)# 随机种子
​
# 训练模型
model.fit(train_x, train_y)
​
# 测试模型
pred_test_y = model.predict(test_x)

代码:

# AdaBoosting示例
# 使用AdaBoosting预测波士顿房价
import sklearn.datasets as sd
import sklearn.utils as su
import sklearn.tree as st
import sklearn.ensemble as se
import sklearn.metrics as sm
​
boston = sd.load_boston()  # 加载boston地区房价数据
print(boston.feature_names)
print(boston.data.shape)
print(boston.target.shape)
​
random_seed = 7  # 随机种子,计算随机值,相同的随机种子得到的随机值一样
x, y = su.shuffle(boston.data, boston.target, random_state = random_seed)
# 计算训练数据的数量
train_size = int(len(x) * 0.8) # 以boston.data中80%的数据作为训练数据
# 构建训练数据、测试数据
train_x = x[:train_size]  # 训练输入, x前面80%的数据
test_x = x[train_size:]   # 测试输入, x后面20%的数据
train_y = y[:train_size]  # 训练输出
test_y = y[train_size:]   # 测试输出
​
model2 = se.AdaBoostRegressor(st.DecisionTreeRegressor(max_depth=4),
                              n_estimators=400,   # 决策树数量
                              random_state=random_seed) # 随机种子
# 训练
model2.fit(train_x, train_y)
# 预测
pre_test_y2 = model2.predict(test_x)
# 打印预测输出和实际输出的R2值
print(sm.r2_score(test_y, pre_test_y2))

执行结果:

['CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO'
 'B' 'LSTAT']
(506, 13)
(506,)
0.9068598725149652

可以看到,通过AdaBoosting算法,回归模型获得了更高的R2值.

3. 随机森林

1)什么是随机森林

随机森林(Random Forest,简称RF)是专门为决策树设计的一种集成学习方法,是Bagging法的一种拓展,它是指每次构建决策树模型时,不仅随机选择部分样本,而且还随机选择部分特征来构建多棵决策树. 这样不仅规避了强势样本对预测结果的影响,而且也削弱了强势特征的影响,使模型具有更强的泛化能力.

随机森林简单、容易实现、计算开销小,在很多现实任务中展现出强大的性能,被誉为“代表集成学习技术水平的方法”.

2)如何实现随机森林

sklearn中,随机森林相关API:

import sklearn.ensemble as se
​
model = se.RandomForestRegressor(
    max_depth, # 决策树最大深度
    n_estimators, # 决策树数量
    min_samples_split)# 子表中最小样本数 若小于这个数字,则不再继续向下拆分

以下是利用随机森林实现波士顿房价预测的代码:

# 使用随机森林预测波士顿房价
import sklearn.datasets as sd
import sklearn.utils as su
import sklearn.tree as st
import sklearn.ensemble as se
import sklearn.metrics as sm
​
boston = sd.load_boston()  # 加载boston地区房价数据
print(boston.feature_names)
print(boston.data.shape)
print(boston.target.shape)
​
random_seed = 7  # 随机种子,计算随机值,相同的随机种子得到的随机值一样
x, y = su.shuffle(boston.data, boston.target, random_state=random_seed)
# 计算训练数据的数量
train_size = int(len(x) * 0.8)  # 以boston.data中80%的数据作为训练数据
# 构建训练数据、测试数据
train_x = x[:train_size]  # 训练输入, x前面80%的数据
test_x = x[train_size:]  # 测试输入, x后面20%的数据
train_y = y[:train_size]  # 训练输出
test_y = y[train_size:]  # 测试输出
​
# 创建随机森林回归器,并进行训练
model = se.RandomForestRegressor(max_depth=10,  # 最大深度
                                 n_estimators=1000,  # 树数量
                                 min_samples_split=2)  # 最小样本数量,小于该数就不再划分子节点
model.fit(train_x, train_y)  # 训练
​
# 基于天统计数据的特征重要性
fi_dy = model.feature_importances_
# print(fi_dy)
pre_test_y = model.predict(test_x)
print(sm.r2_score(test_y, pre_test_y))  # 打印r2得分

打印输出:

['CRIM' 'ZN' 'INDUS' 'CHAS' 'NOX' 'RM' 'AGE' 'DIS' 'RAD' 'TAX' 'PTRATIO'
 'B' 'LSTAT']
(506, 13)
(506,)
0.9271955403309159

三、总结

1)什么是决策树:利用样本特征进行决策归类,将具有相同属性的样本划入一个子节点,投票产生分类,平均值产生回归

2)决策树的用途:用作分类器、回归器

3)如何构建决策树:根据信息增益、增益率、基尼系数构建子节点。对应3种不同决策树。

4)什么情况下使用决策树:实用性较广,课用于一般回归、分类问题

5)决策树优化:集成学习、随机森林。 即多个决策树模型共同预测结果

回归问题内容:线性回归,多项式回归,线性回归变种,决策树回归,神经网络回归

一般用于回归的模型都可以用于分类

分类问题:逻辑回归,决策树分类,支持向量机,朴素贝叶斯

四、练习

(1)有一批水果(如下图所示),按照形状进行分类,将长条形、椭圆形各划分到不同子节点中,计算划分后的信息增益.

原始按照颜色信息熵1.522 划分后0,8 * 1+0.2* * 0 = 0.8 信息增益0.722 因此按照形状划分的信息增益比较大,颜色特征更加强烈img

(2)一批样本包含A和B两个类别,计算:当A类别比率依次占0%, 10%, 20%, ..., 100%时,这批样本信息熵值,并以占比作为x轴数值、信息熵作为y轴数值绘制图像.

import math
import numpy as np
import matplotlib.pyplot as mp
​
arr = np.array([[0.0000001, 1.0],
                [0.1, 0.9],
                [0.2, 0.8],
                [0.3, 0.7],
                [0.4, 0.6],
                [0.5, 0.5],
                [0.6, 0.4],
                [0.7, 0.3],
                [0.8, 0.2],
                [0.9, 0.1],
                [1.0, 0.0000001]])
result = []
for a in arr: # 遍历每种组合,进行计算
    v1 = -(a[0] * math.log(a[0])) # p * log(p)
    v2 = -(a[1] * math.log(a[1]))
    result.append(v1 + v2)
print(result)
​
# 可视化
mp.figure("Entropy")
mp.title("Entropy")
mp.xlabel("A%")
mp.ylabel("entropy")
mp.grid(linestyle=":")
# 0~1.1(不包含)以0.1为间隔产生均匀数组
x = np.arange(0, 1.1, 0.1)
mp.plot(x, result, c="red", label="entropy")
mp.legend()
mp.show()
​
#结论:对半开熵值最大,系统最混乱,好人与坏人一样多。一九开系统较为纯净,好人比坏人多。

延伸阅读

  • VMware公司使用定制的决策树进行定价优化

VMware(VMW)是一家提供虚拟化技术、终端服务和云处理的公司,它将产品销售给B2B客户。长期以来,VMW公司的产品价格罕有变动。当接收到大订单的时候,销售代表会通过销售人员特别折扣(Sales Person Specific discount,SPF)标识来给出特定折扣。而VMW的定价部门则希望找到一种方法来优化其产品定价。在各个商业领域,市场上都有着对应的解决定价问题的数据挖掘解决方案。解决方案的目标不仅是优化定价,同时还要让客户的利益最大化。
​
VMW公司的分析和数据科学小组通过分析历史价格和相应的销量变化,来理解折扣百分比与SPF标识的关联性,并以此为依据归纳出所有产品的推荐定价。传统的定价优化会根据数量变化来进行价格变动,但是VMW公司并不会改变价格,而是使用折扣作为替代方法,但是使用折扣需要额外的步骤来确定是否需要给出折扣以及折扣率。
小组使用决策树的方法,基于折扣率和SPF标识的使用情况来对所有订单进行分类。根据业务的需求,以一种特定顺序构建出多分支(非二元)决策树。各种可能订单定价的属性都在决策树构建中被考虑进来。决策树构建过程中,基于均方误差、熵、log-loss、Gini指标等确定了决策树构建过程中分支属性的顺序。相比于使用标准分裂标准,使用的是根据业务需求定制的分裂标准。分裂停止标准是最小化观测对象数目。针对完成的分块,基于分块的属性特性观察其折扣百分比与SPF使用情况的关联性,并完成产品平台级的定价推荐。

一、逻辑回归(分类)

1. 概述

1)什么是逻辑回归

逻辑回归(Logistic Regression) 虽然被称为回归,但其实际上是分类模型,常用于二分类。逻辑回归因其简单、可并行化(多程序同时运行)、可解释强(中间过程清楚)而受到广泛应用。二分类(也称为逻辑分类)是常见的分类方法,是将一批样本或数据划分到两个类别,例如一次考试,根据成绩可以分为及格、不及格两个类别,如下表所示:

姓名成绩分类
Jerry861
Tom981
Lily580
………………

这就是逻辑分类,将连续值映射到两个类别中。

2)逻辑函数

逻辑回归是一种广义的线性回归,其原理是利用线性模型根据输入计算输出(线性模型输出值为连续),并在逻辑函数作用下,将连续值转换为两个离散值(0或1),其表达式如下:

$$
y = h(w_1x_1 + w_2x_2 + w_3x_3 + ... + w_nx_n + b)
$$

其中,括号中的部分为线性模型,计算结果在函数h()的作用下,做二值化转换,函数h()的定义为:

$$
h= \frac{1}{1+e^{-t}}
$$

该函数称为Sigmoid函数(又称逻辑函数),能将(-\infty, +\infty)的值映射到(0, 1)之间,其图像为:img

可以设定一个阈值(例如0.5),当函数的值大于阈值时,分类结果为1;当函数值小于阈值时,分类结果为0. 也可以根据实际情况调整这个阈值.

3)分类问题的损失函数

对于回归问题,可以使用均方差作为损失函数,对于分类问题,如何度量预测值与真实值之间的差异?分类问题采用交叉熵作为损失函数,当只有两个类别时,交叉熵表达式为:

$$
E(y, \hat{y}) = -[y \ log(\hat{y}) + (1-y)log(1-\hat{y})]
$$

其中,y为真实值,\hat{y}为预测值.

  • 当y=1时,预测值\hat{y}越接近于1,log(\hat{y})越接近于0,损失函数值越小,表示误差越小,预测的越准确;当预测时\hat{y}接近于0时,log(\hat{y})接近于负无穷大,加上符号后误差越大,表示越不准确;

  • 当y=0时,预测值\hat{y}越接近于0,log(1-\hat{y})越接近于0,损失函数值越小,表示误差越小,预测越准确;当预测值\hat{y}接近于1时,log(1-\hat{y})接近于负无穷大,加上符号后误差越大,表示越不准确.

2. 逻辑回归实现

sklearn中,逻辑回归相关API如下:

# 创建模型
# solver参数:逻辑函数中指数的函数关系(liblinear表示线性关系)
# C参数:正则强度,越大拟合效果越小,通过调整该参数防止过拟合
model = lm.LogisticRegression(solver='liblinear', C=1)
​
# 训练
model.fit(x, y) 
​
# 预测
pred_y = model.predict(x)

以下是使用sklearn库提供的逻辑分类器(LogisticRegression)实现的代码:

# 逻辑分类器示例
import numpy as np
import sklearn.linear_model as lm
import matplotlib.pyplot as mp
​
x = np.array([[3, 1], [2, 5], [1, 8], [6, 4],#每个样本两个特征值
              [5, 2], [3, 5], [4, 7], [4, -1]])
y = np.array([0, 1, 1, 0, 0, 1, 1, 0])
​
# 创建逻辑分类器对象
model = lm.LogisticRegression()
model.fit(x, y)  # 训练
​
# 预测
test_x = np.array([[3, 9], [6, 1]])
test_y = model.predict(test_x)  # 预测
print(test_y)
​
# 计算显示坐标的边界
left = x[:, 0].min() - 1
right = x[:, 0].max() + 1
buttom = x[:, 1].min() - 1
top = x[:, 1].max() + 1
​
# 产生网格化矩阵
grid_x, grid_y = np.meshgrid(np.arange(left, right, 0.01),
                             np.arange(buttom, top, 0.01))
​
print("grid_x.shape:", grid_x.shape)
print("grid_y.shape:", grid_y.shape)
​
# 将x,y坐标合并成两列
mesh_x = np.column_stack((grid_x.ravel(), grid_y.ravel()))
print("mesh_x.shape:", mesh_x.shape)
​
# 根据每个点的xy坐标进行预测,并还原成二维形状
mesh_z = model.predict(mesh_x)
mesh_z = mesh_z.reshape(grid_x.shape)
​
mp.figure('Logistic Regression', facecolor='lightgray')
mp.title('Logistic Regression', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x, grid_y, mesh_z, cmap='gray')
mp.scatter(x[:, 0],  # 样本x坐标
           x[:, 1],  # 样本y坐标
           c=y, cmap='brg', s=80)
mp.scatter(test_x[:, 0], test_x[:, 1], c="red", marker='s', s=80)
mp.show()

执行结果:img

3. 多分类实现

逻辑回归产生两个分类结果,可以通过多个二元分类器实现多元分类(一个多元分类问题转换为多个二元分类问题). 如有以下样本数据:

特征1特征2特征3实际类别
x_1x_2x_3A
x_1x_2x_3B
x_1x_2x_3C

进行以下多次分类,得到结果:

第一次:分为A类(值为1)和非A类(值为0)

第二次:分为B类(值为1)和非B类(值为0)

第三次:分为C类(值为1)和非C类(值为0)

……

以此类推.

利用逻辑分类器实现多元分类示例代码如下:

# 多元分类器示例
import numpy as np
import sklearn.linear_model as lm
import matplotlib.pyplot as mp
​
# 输入
x = np.array([[4, 7],
              [3.5, 8],
              [3.1, 6.2],
              [0.5, 1],
              [1, 2],
              [1.2, 1.9],
              [6, 2],
              [5.7, 1.5],
              [5.4, 2.2]])
# 输出(多个类别)
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2])
​
# 创建逻辑分类器对象
model = lm.LogisticRegression(C=200) # 调整该值为1看效果
model.fit(x, y)  # 训练
​
# 坐标轴范围
left = x[:, 0].min() - 1
right = x[:, 0].max() + 1
h = 0.005
​
buttom = x[:, 1].min() - 1
top = x[:, 1].max() + 1
v = 0.005
​
grid_x, grid_y = np.meshgrid(np.arange(left, right, h),
                             np.arange(buttom, top, v))
​
mesh_x = np.column_stack((grid_x.ravel(), grid_y.ravel()))
mesh_z = model.predict(mesh_x)
mesh_z = mesh_z.reshape(grid_x.shape)
​
# 可视化
mp.figure('Logistic Classification', facecolor='lightgray')
mp.title('Logistic Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x, grid_y, mesh_z, cmap='gray')
mp.scatter(x[:, 0], x[:, 1], c=y, cmap='brg', s=80)
mp.show()

执行结果:img

4. 总结

1)逻辑回归是分类问题,用于实现二分类问题

2)实现方式:利用线性模型计算,在逻辑函数作用下产生分类

3)多分类实现:可以将多分类问题转化为二分类问题实现(多个二分类模型对象多分类)

4)用途:广泛用于各种分类问题

一、决策树分类

1. 决策树分类原理

决策树可以作为分类器使用,从而实现分类问题。使用决策树实现分类时,先根据不同特征将样本划分到不同叶子节点,再根据投票法(少数服从多数)决定预测结果属于哪个类别,预测类别即同一个子节点下数量最多的样本的类别。例如,预测一部电视剧是好剧还是烂剧,可以用以下决策树来实现:img

根据以上决策树模型,可以做这样的分类预测:

  • 如果是都市题材,导演为张三,好剧的数量较多,预测结果为好剧;

  • 如果是古装题材,导演为张三,烂剧的数据量较多,预测结果为烂剧.

2. 决策树分类案例

sklearn中, 提供了以下API实现决策树分类器或随机森林分类器:

sklearn.tree.DecisionTreeClassifier() # 决策树分类器---单个模型
sklearn.ensemble.RandomForestClassifier() # 随机森林分类器 案例采用它---集成模型

该示例中,用离散特征去预测离散值。根据一组小汽车样本数据,该组样本数据统计了小汽车常见特征信息及其分类,特征包括:汽车价格、维修费用、车门数量、载客数、后备箱、安全性,标签为汽车质量。各属性取值如下表所示:

索引-名称取值范围含义说明
1-buyingvhigh, high, med, low购买价格
2-maintvhigh, high, med, low维护费用
3-doors2, 3, 4, 5more车门数量
4-persons2, 4, more载客数
5-lug_bootsmall, med, big后备箱大小
6-safetylow, med, high安全性
标签unacc, acc, good, vgood汽车质量

以下是使用决策树进行分类的示例代码。需要对数据集用标签编码成数字。字符串不好处理。

# 决策树分类示例
import numpy as np
import sklearn.preprocessing as sp
import sklearn.ensemble as se
import sklearn.model_selection as ms
​
raw_samples = []  # 保存一行样本数据
with open("../data/car.txt", "r") as f:
    for line in f.readlines():
        raw_samples.append(line.replace("\n", "").split(","))
​
data = np.array(raw_samples).T  # 转置
encoders = []  # 记录标签编码器
train_x = []  # 编码后的x
​
# 对样本数据进行标签编码
for row in range(len(data)):
    encoder = sp.LabelEncoder()  # 创建标签编码器
    encoders.append(encoder)
    if row < len(data) - 1:  # 不是最后一行,为样本特征
        lbl_code = encoder.fit_transform(data[row])  # 编码
        train_x.append(lbl_code)
    else:  # 最后一行,为样本输出
        train_y = encoder.fit_transform(data[row])
​
train_x = np.array(train_x).T  # 转置回来,变为编码后的数组
print(train_x)
​
# 创建随机森林分类器
model = se.RandomForestClassifier(max_depth=8,  # 最大树高
                                  n_estimators=150,  # 评估系数
                                  random_state=7)  # 随机种子
# 训练
model.fit(train_x, train_y)
print("accuracy:", model.score(train_x, train_y)) # 打印平均精度,看测试准确度如何
​
# 预测
## 待预测数据
data = [['high', 'med', '5more', '4', 'big', 'low'],
        ['high', 'high', '4', '4', 'med', 'med'],
        ['low', 'low', '2', '2', 'small', 'high'],
        ['low', 'med', '3', '4', 'med', 'high']]
data = np.array(data).T
test_x = []
for row in range(len(data)):
    encoder = encoders[row]  # 取得每列对应的标签编码器
    test_x.append(encoder.transform(data[row]))  # 待预测数据编码
​
test_x = np.array(test_x).T  # 转置回来
​
pred_test_y = model.predict(test_x)  # 执行预测
​
pred_test_y = encoders[-1].inverse_transform(pred_test_y)  # 预测结果反向编码
print("pred_test_y:", pred_test_y)  # 预测结果

执行结果:

accuracy: 0.9704861111111112
pred_test_y: ['unacc' 'acc' 'unacc' 'vgood']
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

dpq666dpq666

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

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

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

打赏作者

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

抵扣说明:

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

余额充值