逻辑分类
y = w0+w1x1 + w2x2 + ... + wnxn
z = f(y)
y >= 0, z = 1
y < 0, z = 0 1
z = sigmoid(y) = ----------
1 + e^-y
y = 0, z = 0.5
y->oo, z->1
y->-oo, z->0
-----------------
预测函数:
y = 1 / (1 + e^-(w0+w1x1 + w2x2 + ... + wnxn))
y > 0.5, y = 1
y < 0.5, y = 0
y = 0.8:(x1x2..xn)隶属于1类别的概率是0.8,因此分类为1。
y = 0.2:(x1x2..xn)隶属于1类别的概率是0.2,因此分类为0。
根据预测函数得到损失函数,通过梯度下降算法,找到使损失函数取得极小值的模型参数:w0...wn,将未知类别的输入样本,代入模型,得出其隶属于1类别的概率,据此判定其预测类别。
model = lm.LogisticRegression(
solver='liblinear', C=正则强度)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
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(
solver='liblinear', C=1)
model.fit(x, y)
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
grid_x = np.meshgrid(np.arange(l, r, h),
np.arange(b, t, v))
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()]
flat_y = model.predict(flat_x)
grid_y = flat_y.reshape(grid_x[0].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[0], grid_x[1], grid_y,
cmap='gray')
mp.scatter(x[:, 0], x[:, 1], c=y, cmap='brg',
s=60)
mp.show()
多元分类
利用分类器模型本身的算法实现多元分类,如决策树。
通过组合多个二元分类的预测结果实现多元分类,如逻辑分类器。
... A 1 0 0
... B 0 1 0
... A 1 0 0
... B 0 1 0
... C 0 0 1
... C 0 0 1
| | |
| | v
| v 训练二元分类器Z,其输出值,就是属于C类的概率
v 训练二元分类器Y,其输出值就是属于B类的概率
训练二元分类器X,其输出值就是属于A类的概率
X Y Z
... 0.7 0.4 0.8 -> C
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
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(
solver='liblinear', C=100)
model.fit(x, y)
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
grid_x = np.meshgrid(np.arange(l, r, h),
np.arange(b, t, v))
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()]
flat_y = model.predict(flat_x)
grid_y = flat_y.reshape(grid_x[0].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[0], grid_x[1], grid_y,
cmap='gray')
mp.scatter(x[:, 0], x[:, 1], c=y, cmap='brg',
s=60)
mp.show()
朴素贝叶斯分类
1.算法原理
P(美女,爱你)=P(美女)P(爱你|美女) // 贝叶斯定理
1% 1%
10000个人
100美女
1爱你
X样本被划分为C类别的概率:
P(X,C)=
P(x1,x2,x3,C)=P(x1|x2,x3,C)P(x2,x3,C)
| \_____/ | \___/
v v v v
爱你 美女 爱你美女
=P(x1|x2,x3,C)P(x2|x3,C)P(x3,C)
=P(x1|x2,x3,C)P(x2|x3,C)P(x3|C)P(C)
| 朴素:条件独立,特征值之间没有因果关系
v
=P(x1|C)P(x2|C)P(x3|C)P(C)
根据上面的公式,由训练数据集中统计得到,某个特定类别(C)的概率,和该类别条件下各个特征值(x1,x2,x3)出现的概率,彼此相乘,就得到有这组特征值构成的样本(X)被划分为该类别(C)的概率。通过比较不同类别的划分概率,取其最大值作为预测结果。在样本数不足的时候,如果已知样本的特征值服从某种概率分布规则,可以用其概率密度函数或概率质量函数直接求得针对特定特征值计算所需要的概率值。
import sklearn.naive_bayes as nb
# 基于正态分布的朴素贝叶斯分类器
model = nb.GaussianNB()
高斯分布 = 正态分布
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
import sklearn.naive_bayes as nb
import matplotlib.pyplot as mp
x, y = [], []
with open('../../data/multiple1.txt', 'r') as f:
for line in f.readlines():
data = [float(substr) for substr
in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x = np.array(x)
y = np.array(y, dtype=int)
# 创建朴素贝叶斯分类器模型
model = nb.GaussianNB()
# 训练朴素贝叶斯分类器模型
model.fit(x, y)
# 点阵水平边界和步长
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
# 点阵垂直边界和步长
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
# 生成二维点阵
# _ grid_x
# ^ |h| /
# t | * * * *
# | * * * *-- v
# b | * * * *--
# +-------->
# l r
grid_x = np.meshgrid(np.arange(l, r, h),
np.arange(b, t, v))
# 将点阵中每个点的水平坐标和垂直坐标作为
# 样本的两个特征合并成一个两列的二维数组
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()]
# 利用朴素贝叶斯分类器模型预测点阵的类别
flat_y = model.predict(flat_x)
# 将一维形式的类别变成点阵形式的二维数组
grid_y = flat_y.reshape(grid_x[0].shape)
# 将训练集中的输入代入模型预测其类别输出
pred_y = model.predict(x)
# 计算预测正确的比例
print((pred_y == y).sum() / pred_y.size)
# 绘制训练样本和分类边界
mp.figure('Naive Bayes Classification',
facecolor='lightgray')
mp.title('Naive Bayes Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y,
cmap='gray')
mp.scatter(x[:, 0], x[:, 1], c=y, cmap='brg',
s=60)
mp.show()
2.划分训练集和测试集
0 80% 20%
1 80% 20%
2 80% 20%
| |
v v
训练 测试
import sklearn.model_selection as ms
ms.train_test_split(输入集, 输出集, test_size=测试集比例,
random_state=随机种子)
->训练输入,测试输入,训练输出,测试输出
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
import sklearn.model_selection as ms
import sklearn.naive_bayes as nb
import matplotlib.pyplot as mp
x, y = [], []
with open('../../data/multiple1.txt', 'r') as f:
for line in f.readlines():
data = [float(substr) for substr
in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x = np.array(x)
y = np.array(y, dtype=int)
# 按照3:1的比例划分训练集和测试集
train_x, test_x, train_y, test_y = ms.train_test_split(
x, y, test_size=0.25, random_state=7)
# 创建朴素贝叶斯分类器模型
model = nb.GaussianNB()
# 用训练集训练朴素贝叶斯分类器模型
model.fit(train_x, train_y)
# 点阵水平边界和步长
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
# 点阵垂直边界和步长
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
# 生成二维点阵
# _ grid_x
# ^ |h| /
# t | * * * *
# | * * * *-- v
# b | * * * *--
# +-------->
# l r
grid_x = np.meshgrid(np.arange(l, r, h),
np.arange(b, t, v))
# 将点阵中每个点的水平坐标和垂直坐标作为
# 样本的两个特征合并成一个两列的二维数组
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()]
# 利用朴素贝叶斯分类器模型预测点阵的类别
flat_y = model.predict(flat_x)
# 将一维形式的类别变成点阵形式的二维数组
grid_y = flat_y.reshape(grid_x[0].shape)
# 用测试集验证模型预测结果的正确率
pred_test_y = model.predict(test_x)
print((pred_test_y == test_y).sum() / pred_test_y.size)
# 绘制训练样本和分类边界
mp.figure('Naive Bayes Classification',
facecolor='lightgray')
mp.title('Naive Bayes Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y,
cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1], c=test_y,
cmap='brg', s=60)
mp.show()
3.交叉验证
在正式训练模型之前,通过交叉验证评估所选择的模型算法和超参数是否合适,如果指标可以接受那么继续训练,否则更换或调整模型的算法和超参数。
ms.cross_val_score(模型对象,输入,输出,cv=验证次数,
scoring=指标)->每次验证的指标分值数组
指标:
对于A类别
模型判定属于A类别的样本数为C+D,其中C真的属于A类别,而D其实是属于其它类别的。
C/(C+D) - 针对A类别的查准率,对不对
在整个样本空间中A类别的样本共为C+B个,其中C被模型正确识别出来,而B个被模型误判为其它类别。
C/(C+B) - 针对A类别的召回率,全不全
F1得分 = 2x查准率x召回率/(查准率+召回率)
precision_weighted - 查准率 \
recall_weighted - 召回率 > 取各类别指标的平均值
f1_weighted - F1得分 _______/
accuracy - 正确率
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
import sklearn.model_selection as ms
import sklearn.naive_bayes as nb
import matplotlib.pyplot as mp
x, y = [], []
with open('../../data/multiple1.txt', 'r') as f:
for line in f.readlines():
data = [float(substr) for substr
in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x = np.array(x)
y = np.array(y, dtype=int)
# 按照3:1的比例划分训练集和测试集
train_x, test_x, train_y, test_y = ms.train_test_split(
x, y, test_size=0.25, random_state=7)
# 创建朴素贝叶斯分类器模型
model = nb.GaussianNB()
# 通过交叉验证评估模型的可用性
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='precision_weighted').mean()) # 查准率
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='recall_weighted').mean()) # 召回率
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='f1_weighted').mean()) # F1得分
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='accuracy').mean()) # 正确率
# 用训练集训练朴素贝叶斯分类器模型
model.fit(train_x, train_y)
# 点阵水平边界和步长
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
# 点阵垂直边界和步长
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
# 生成二维点阵
# _ grid_x
# ^ |h| /
# t | * * * *
# | * * * *-- v
# b | * * * *--
# +-------->
# l r
grid_x = np.meshgrid(np.arange(l, r, h),
np.arange(b, t, v))
# 将点阵中每个点的水平坐标和垂直坐标作为
# 样本的两个特征合并成一个两列的二维数组
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()]
# 利用朴素贝叶斯分类器模型预测点阵的类别
flat_y = model.predict(flat_x)
# 将一维形式的类别变成点阵形式的二维数组
grid_y = flat_y.reshape(grid_x[0].shape)
# 用测试集验证模型预测结果的正确率
pred_test_y = model.predict(test_x)
print((pred_test_y == test_y).sum() / pred_test_y.size)
# 绘制训练样本和分类边界
mp.figure('Naive Bayes Classification',
facecolor='lightgray')
mp.title('Naive Bayes Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y,
cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1], c=test_y,
cmap='brg', s=60)
mp.show()
4.混淆矩阵
sm.confusion_matrix(实际输出, 预测输出)->混淆矩阵
混淆矩阵中的每一行表示实际类别样本数,每一列表示预测类别样本数,主对角线上的元素表示预测正确的样本数。理想混淆矩阵,非主对角线上的元素应该都为0。非主对角线上的元素越多,其值越大,表示模型的精度越差,反之越好。用主对角线上的元素除以其所在列元素之和就是相应类别的查准率。用主对角线上的元素除以其所在行元素之和就是相应类别的召回率。
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
import sklearn.model_selection as ms
import sklearn.naive_bayes as nb
import sklearn.metrics as sm
import matplotlib.pyplot as mp
x, y = [], []
with open('../../data/multiple1.txt', 'r') as f:
for line in f.readlines():
data = [float(substr) for substr
in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x = np.array(x)
y = np.array(y, dtype=int)
# 按照3:1的比例划分训练集和测试集
train_x, test_x, train_y, test_y = ms.train_test_split(
x, y, test_size=0.25, random_state=7)
# 创建朴素贝叶斯分类器模型
model = nb.GaussianNB()
# 通过交叉验证评估模型的可用性
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='precision_weighted').mean()) # 查准率
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='recall_weighted').mean()) # 召回率
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='f1_weighted').mean()) # F1得分
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='accuracy').mean()) # 正确率
# 用训练集训练朴素贝叶斯分类器模型
model.fit(train_x, train_y)
# 点阵水平边界和步长
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
# 点阵垂直边界和步长
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
# 生成二维点阵
# _ grid_x
# ^ |h| /
# t | * * * *
# | * * * *-- v
# b | * * * *--
# +-------->
# l r
grid_x = np.meshgrid(np.arange(l, r, h),
np.arange(b, t, v))
# 将点阵中每个点的水平坐标和垂直坐标作为
# 样本的两个特征合并成一个两列的二维数组
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()]
# 利用朴素贝叶斯分类器模型预测点阵的类别
flat_y = model.predict(flat_x)
# 将一维形式的类别变成点阵形式的二维数组
grid_y = flat_y.reshape(grid_x[0].shape)
# 用测试集验证模型预测结果的正确率
pred_test_y = model.predict(test_x)
print((pred_test_y == test_y).sum() / pred_test_y.size)
# 通过混淆矩阵检验模型的预测结果
cm = sm.confusion_matrix(test_y, pred_test_y)
print(cm)
# 绘制训练样本和分类边界
mp.figure('Naive Bayes Classification',
facecolor='lightgray')
mp.title('Naive Bayes Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y,
cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1], c=test_y,
cmap='brg', s=60)
mp.figure('Confusion Matrix', facecolor='lightgray')
mp.title('Confusion Matrix', fontsize=20)
mp.xlabel('Predicted Class', fontsize=14)
mp.ylabel('True Class', fontsize=14)
mp.xticks(np.unique(pred_test_y))
mp.yticks(np.unique(test_y))
mp.tick_params(labelsize=10)
mp.imshow(cm, interpolation='nearest', cmap='jet')
mp.show()
5.分类报告
sm.classification_report(实际输出, 预测输出)->分类报告
计算每个类别的查准率、召回率和F1得分,极其平均值。
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import numpy as np
import sklearn.model_selection as ms
import sklearn.naive_bayes as nb
import sklearn.metrics as sm
import matplotlib.pyplot as mp
x, y = [], []
with open('../../data/multiple1.txt', 'r') as f:
for line in f.readlines():
data = [float(substr) for substr
in line.split(',')]
x.append(data[:-1])
y.append(data[-1])
x = np.array(x)
y = np.array(y, dtype=int)
# 按照3:1的比例划分训练集和测试集
train_x, test_x, train_y, test_y = ms.train_test_split(
x, y, test_size=0.25, random_state=7)
# 创建朴素贝叶斯分类器模型
model = nb.GaussianNB()
# 通过交叉验证评估模型的可用性
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='precision_weighted').mean()) # 查准率
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='recall_weighted').mean()) # 召回率
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='f1_weighted').mean()) # F1得分
print(ms.cross_val_score(
model, x, y, cv=5,
scoring='accuracy').mean()) # 正确率
# 用训练集训练朴素贝叶斯分类器模型
model.fit(train_x, train_y)
# 点阵水平边界和步长
l, r, h = x[:, 0].min() - 1, x[:, 0].max() + 1, 0.005
# 点阵垂直边界和步长
b, t, v = x[:, 1].min() - 1, x[:, 1].max() + 1, 0.005
# 生成二维点阵
# _ grid_x
# ^ |h| /
# t | * * * *
# | * * * *-- v
# b | * * * *--
# +-------->
# l r
grid_x = np.meshgrid(np.arange(l, r, h),
np.arange(b, t, v))
# 将点阵中每个点的水平坐标和垂直坐标作为
# 样本的两个特征合并成一个两列的二维数组
flat_x = np.c_[grid_x[0].ravel(), grid_x[1].ravel()]
# 利用朴素贝叶斯分类器模型预测点阵的类别
flat_y = model.predict(flat_x)
# 将一维形式的类别变成点阵形式的二维数组
grid_y = flat_y.reshape(grid_x[0].shape)
# 用测试集验证模型预测结果的正确率
pred_test_y = model.predict(test_x)
print((pred_test_y == test_y).sum() / pred_test_y.size)
# 通过混淆矩阵检验模型的预测结果
cm = sm.confusion_matrix(test_y, pred_test_y)
print(cm)
# 通过分类报告展示模型的预测结果
cr = sm.classification_report(test_y, pred_test_y)
print(cr)
# 绘制训练样本和分类边界
mp.figure('Naive Bayes Classification',
facecolor='lightgray')
mp.title('Naive Bayes Classification', fontsize=20)
mp.xlabel('x', fontsize=14)
mp.ylabel('y', fontsize=14)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0], grid_x[1], grid_y,
cmap='gray')
mp.scatter(test_x[:, 0], test_x[:, 1], c=test_y,
cmap='brg', s=60)
mp.figure('Confusion Matrix', facecolor='lightgray')
mp.title('Confusion Matrix', fontsize=20)
mp.xlabel('Predicted Class', fontsize=14)
mp.ylabel('True Class', fontsize=14)
mp.xticks(np.unique(pred_test_y))
mp.yticks(np.unique(test_y))
mp.tick_params(labelsize=10)
mp.imshow(cm, interpolation='nearest', cmap='jet')
mp.show()
想要看更多的课程请微信关注SkrEric的编程课堂