机器学习(六)—— 分类

分类

分类(classification)即找一个函数判断输入数据所属的类别,可以是二类别问题(是/不是),也可以是多类别问题(在多个类别中判断输入数据具体属于哪一个类别)。与回归问题(regression)相比,分类问题的输出不再是连续值,而是离散值,用来指定其属于哪个类别
——

https://blog.csdn.net/hohaizx/article/details/81835381

1. 逻辑分类

api: sklearn.linear_model.LogisticRegression(solver=‘liblinear’, C=)

solver 表示逻辑函数中指数的函数关系 liblinear 表示线性函数关系  C 表示正则强度,防止过拟合, 数值越大,拟合度越小
  1. api的内在逻辑
    首先理解逻辑函数sigmoid: y=1/(1+e^(-x))
    在这里插入图片描述
    由图可知,sigmoid是一个值域为(0, 1),定义域为(-∞, +∞)的函数的函数,且当x=0时,y=0.5
    根据样本的输入与输出构建线性回归模型,以回归模型的的预测输出作为sigmoid的输入,得到0-1之间的一个数值,此数值即可作为对应样本时1类的概率或者可信度;x<0 y<0.5划分为1类别的概率比较小,x>0 y>0.5划分为1类别的概率比较大,这是线性函数非线性化的一种方式。
  2. api的使用
    代码示例:
import numpy as np
import matplotlib.pyplot as plt

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])

# 绘制分类边界
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
n = 500
grid_x, grid_y = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
# 人为划分界限
# grid_z = np.piecewise(grid_x, [grid_x > grid_y, grid_x < grid_y], [0, 1])
# 自我识别 划分边界
mesh_x = np.column_stack((grid_x.ravel(), grid_y.ravel()))
mesh_z = model.predict(mesh_x)
grid_z = mesh_z.reshape(grid_x.shape)

plt.figure('classification', facecolor='lightgray')
plt.title('classification', fontsize=16)
plt.scatter(x[:, 0], x[:, 1], c=y, cmap='jet', label='points', s=70, zorder=3)
# 调用plt.pcolormesh绘制费雷比那界限  把可是去检查分为坐标网格,不同类填充不同颜色
plt.pcolormesh(grid_x, grid_y, grid_z, cmap='gray')
plt.legend()
plt.show()

在这里插入图片描述
该方式是将显示的区域划分为500*500的小方格,根据划分依据填充颜色。这里有一点不明白,就是为什么不用函数线区划分,是因为在边界的点类别本来就很难界定么
3. 多元分类
上面的描述只适用于二元分类,对于多元分类则需要对属于每一种类别的概率分别进行训练,得到多个模型,最终选择概率最高的类别作为样本的分类结果,这个过程逻辑分类会自动进行分析类别个数,代码无需改动。
代码示例:

x2 = 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]])
y2 = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2])

# 构建逻辑分类模型
model2 = lm.LogisticRegression(solver='liblinear', C=100)  # C 调节拟合度
# 训练
model2.fit(x2, y2)

# 绘制分类边界
l2, r2 = x2[:, 0].min() - 1, x2[:, 0].max() + 1
b2, t2 = x2[:, 1].min() - 1, x2[:, 1].max() + 1
n = 500
grid_x2, grid_y2 = np.meshgrid(np.linspace(l2, r2, n), np.linspace(b2, t2, n))
mesh_x2 = np.column_stack((grid_x2.ravel(), grid_y2.ravel()))
mesh_z2 = model2.predict(mesh_x2)
grid_z2 = mesh_z2.reshape(grid_x2.shape)

plt.figure('logistic classification', facecolor='lightgray')
plt.title('logistic classification', fontsize=16)
plt.scatter(x2[:, 0], x2[:, 1], c=y2, cmap='jet', label='points', s=70, zorder=3)
# 调用plt.pcolormesh绘制费雷比那界限  把可是去检查分为坐标网格,不同类填充不同颜色
plt.pcolormesh(grid_x2, grid_y2, grid_z2, cmap='gray')
plt.legend()
plt.show()

在这里插入图片描述

2. 朴素贝叶斯分类

朴素贝叶斯分类器是一系列以假设特征之间强(朴素)独立下运用贝叶斯定理为基础的简单概率分类器。该分类器模型会给问题实例分配用特征值表示的类标签,类标签取自有限集合。它不是训练这种分类器的单一算法,而是一系列基于相同原理的算法:所有朴素贝叶斯分类器都假定样本每个特征与其他特征都不相关 —— 百度百科
1. 贝叶斯定理

	所有统计样本中
		P(A) 事件概率 发生事件A的概率
        P(B|A) 条件概率 在发生事件B的情况下,发生时间A的概率 P(A|B)=P(A)/P(B)
        P(A,B) 联合概率 同时放生事件B和事件A的概率
    贝叶斯定理:
        P(A|B)=P(B|A)P(A)/P(B)  <===    P(A,B)=P(A)P(B|A)=P(B)P(A|B)
    朴素:条件独立,特征值之间没有因果关系
    如:
       P(A,B,C,D,E)
      =P(A|B,C,D,E)P(B,C,D,E)
      =P(A|B,C,D,E)P(B|C,D,E)P(C,D,E)
      =P(A|B,C,D,E)P(B|C,D,E)P(C|D,E)P(D,E)
      =P(A|B,C,D,E)P(B|C,D,E)P(C|D,E)P(D|E)P(E)
      =P(A|E)P(B|E)P(C|E)P(D|E)P(E)
    对应的P(A)、P(B)、P(C)、P(D)、P(E)可以根据概率分布函数计算得到

2. api的使用
api:sklearn.naive_bayes
代码示例:

import sklearn.naive_bayes as nb
import numpy as np
import matplotlib.pyplot as plt
import sklearn.model_selection as ms

x = np.array(
    [[8.73, 0.31], [4.71, -0.42], [4.58, 6.18], [9.38, 2.18], [4.78, 5.28], [1.22, 2.25], [9.22, 1.14], [5.61, -0.34],
     [7.8, 0.51], [1.98, 1.69], [7.51, 1.76], [0.95, 2.09], [3.43, 0.24],
     [8.72, 0.31], [4.74, -0.42], [4.55, 6.18], [9.39, 2.18], [4.77, 5.28], [1.24, 2.25], [9.21, 1.14], [5.63, -0.34],
     [7.82, 0.51], [1.99, 1.69], [7.53, 1.76], [0.96, 2.09], [3.44, 0.24]
     ])
y = np.array([2, 3, 1, 2, 1, 0, 2, 3, 2, 0, 2, 0, 3, 2, 3, 1, 2, 1, 0, 2, 3, 2, 0, 2, 0, 3])

# 构建基于高斯分布的朴素贝叶斯分类模型
model = nb.GaussianNB()
model.fit(x, y)

# 绘制分类边界
l, r = x[:, 0].min() - 1, x[:, 0].max() + 1
b, t = x[:, 1].min() - 1, x[:, 1].max() + 1
n = 500
grid_x, grid_y = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
mesh_x = np.column_stack((grid_x.ravel(), grid_y.ravel()))
mesh_z = model.predict(mesh_x)
grid_z = mesh_z.reshape(grid_x.shape)

# 画图
plt.figure('NB Classification', facecolor='lightgray')
plt.title('NB Classification', fontsize=20)
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
plt.pcolormesh(grid_x, grid_y, grid_z, cmap='gray')
plt.scatter(x[:, 0], x[:, 1], c=y, cmap='brg', s=80)
plt.show()

在这里插入图片描述
3. 分类的优化
api:sklearn.model_selection
a、数据集的划分
对于分类问题,对所有数据样本进行训练集和测试集的划分,但是不应该使用整个样本空间的百分比划分,而是在每个类别样本中按照特定比例进行比例划分,以提高模型分类的可信度
代码示例:

# 训练集和测试集的划分
train_x, test_x, train_y, test_y = ms.train_test_split(x, y, test_size=0.2, random_state=7)
# 绘制分类边界
l, r = train_x[:, 0].min() - 1, train_x[:, 0].max() + 1
b, t = train_x[:, 1].min() - 1, train_x[:, 1].max() + 1
n = 500
grid_x, grid_y = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
mesh_x = np.column_stack((grid_x.ravel(), grid_y.ravel()))
mesh_z = model.predict(mesh_x)
grid_z = mesh_z.reshape(grid_x.shape)

# 画图
plt.figure('NB Classification', facecolor='lightgray')
plt.title('NB Classification', fontsize=20)
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
plt.pcolormesh(grid_x, grid_y, grid_z, cmap='gray')
plt.scatter(test_x[:, 0], test_x[:, 1], c=test_y, cmap='brg', s=80)
plt.show()

b、交叉验证
由于数据集对特殊样本的划分具有不确定性,所以需要进行多次交叉验证
交叉验证:把样本空间的所有样本均分为n份,使用不同的训练集训练模型,不同的测试集测试模型

交叉验证指标
	精确度(accuracy):分类正确的样本数/总的测试样本数
	查准率(precision_weighted):针对每个类别预测正确的样本数/预测出来的样本数
	召回率(recall_weighted):针对每个类别,预测正确的样本数/实际存在的样本数
	f1得分(f1_weighted):2*查找率*召回率/(查准率+召回率)
每次交叉验证,都会对指标进行计算,交叉验证结束后取各自类别的指标取平均值,作为该次交叉验证的操作结果,最终以数组的形式返回指标

代码示例:

import sklearn.naive_bayes as nb
import numpy as np
import matplotlib.pyplot as plt
import sklearn.model_selection as ms

x = np.array(
    [[8.73, 0.31], [4.71, -0.42], [4.58, 6.18], [9.38, 2.18], [4.78, 5.28], [1.22, 2.25], [9.22, 1.14], [5.61, -0.34],
     [7.8, 0.51], [1.98, 1.69], [7.51, 1.76], [0.95, 2.09], [3.43, 0.24],
     [8.72, 0.31], [4.74, -0.42], [4.55, 6.18], [9.39, 2.18], [4.77, 5.28], [1.24, 2.25], [9.21, 1.14], [5.63, -0.34],
     [7.82, 0.51], [1.99, 1.69], [7.53, 1.76], [0.96, 2.09], [3.44, 0.24]
     ])
y = np.array([2, 3, 1, 2, 1, 0, 2, 3, 2, 0, 2, 0, 3, 2, 3, 1, 2, 1, 0, 2, 3, 2, 0, 2, 0, 3])
# 训练集和测试集的划分
train_x, test_x, train_y, test_y = ms.train_test_split(x, y, test_size=0.2, random_state=7)

# 构建基于高斯分布的朴素贝叶斯分类模型
model = nb.GaussianNB()
# 交叉验证
ac_score = ms.cross_val_score(model, train_x, train_y, cv=5, scoring='accuracy')
print(ac_score, '\n', ac_score.mean())
pw_score = ms.cross_val_score(model, train_x, train_y, cv=5, scoring='precision_weighted')
print(pw_score, '\n', pw_score.mean())
rw_score = ms.cross_val_score(model, train_x, train_y, cv=5, scoring='recall_weighted')
print(rw_score, '\n', rw_score.mean())
f1_score = ms.cross_val_score(model, train_x, train_y, cv=5, scoring='f1_weighted')
print(f1_score, '\n', f1_score.mean())

model.fit(x, y)


# 绘制分类边界
l, r = train_x[:, 0].min() - 1, train_x[:, 0].max() + 1
b, t = train_x[:, 1].min() - 1, train_x[:, 1].max() + 1
n = 500
grid_x, grid_y = np.meshgrid(np.linspace(l, r, n), np.linspace(b, t, n))
mesh_x = np.column_stack((grid_x.ravel(), grid_y.ravel()))
mesh_z = model.predict(mesh_x)
grid_z = mesh_z.reshape(grid_x.shape)

# 画图
plt.figure('NB Classification', facecolor='lightgray')
plt.title('NB Classification', fontsize=20)
plt.xlabel('x', fontsize=14)
plt.ylabel('y', fontsize=14)
plt.tick_params(labelsize=10)
plt.pcolormesh(grid_x, grid_y, grid_z, cmap='gray')
plt.scatter(test_x[:, 0], test_x[:, 1], c=test_y, cmap='brg', s=80)
plt.show()

由于数据量太少,模型预测不太准确,这里就不展示结果了。交叉验证存在一个疑问就是:交叉验证是在底层将返回值传递给了模型训练,还是只是一个验证?如果只是一个验证感觉对模型的优化没有任何意义。

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值