几种主要的分类预测模型的python代码实现-感知机,支持向量机,决策树和随机森林,人工神经网络

机器学习定义:假设用 P 来评估计算机程序在某任务类 T 上的性能,若一个程序利用经验 E 在任务 T 上获得了性能改善,则我们就说关于 T 和 P, 该程序对 E 进行了学习。
经验 E 指的是数据
任务T 可以有分类、回归、聚类、异常检测等其他任务
至于p,不同问题不同p
分类和回归属于监督学习问题。

分类预测模型

数据源-需下载解压

感知机

感知机的学习策略是通过极小化下面的损失函数来选取最终的直线:min∑𝑦(𝑤⋅𝑥+𝑏)
该损失函数表达的含义是误分类点到分离平面的总距离和。也就是说,误分类点越少越好,误分类点里分离平面的总距离和越小越好。
下面用案例举例说明如何用python使用感知机

from matplotlib import pyplot as plt
import pandas as pd
%matplotlib inline

# 读取数据
data = pd.read_csv("two_class_data.csv", header=0)
data.head()
# 读取数据列
x = data['x']
y = data['y']
c = data['class']
# 绘制散点图,c 参数用于分类着色
plt.scatter(x, y, c=c)

散点图显示这是一个明显二分类的数据集。下面使用 scikit-learn 提供的感知机方法来对上面的数据集进行分类效果测试。
首先定义特征变量和目标变量,并对数据集进行切分,70% 为训练集,30% 为测试集。

from sklearn.model_selection import train_test_split
from sklearn.linear_model import Perceptron

# 定义特征变量和目标变量
feature = data[['x', 'y']].values
target = data['class'].values
#用.values是以array形式返回指定column的所有取值

# 对数据集进行切分,70% 为训练集,30% 为测试集。
X_train, X_test, y_train, y_test = train_test_split(
    feature, target, test_size=0.3, random_state=50)
X_train.shape, X_test.shape, y_train.shape, y_test.shape

下面使用训练数据训练模型,并将模型运用到测试集上,得到预测结果。

# 构建模型
model = Perceptron(max_iter=1000, tol=1e-3)
# 训练模型
model.fit(X_train, y_train)
# 预测
results = model.predict(X_test)
results

模型结果估计

#将预测结果绘制到散点图中,表现出来
plt.figure(figsize=(9, 8))
# 以默认样式绘制训练数据
plt.scatter(X_train[:, 0], X_train[:, 1], alpha=0.3)
# 以方块样式绘制测试数据
plt.scatter(X_test[:, 0], X_test[:, 1], marker=',', c=y_test)
# 将预测结果用标签样式标注在测试数据左上方
for i, txt in enumerate(results):
    plt.annotate(txt, (X_test[:, 0][i], X_test[:, 1][i]))

#除了看图,可以直接导出我们的分类评估数据,得到测试集上的预测准确度
model.score(X_test, y_test)
#结果显示为0.96,精度如此高,很大程度是因为所用的数据是非常理想的二分类数据

支持向量机

支持向量机是一种常用,适用性广的分类方法。与感知机不同的是,支持向量机不仅可以用于线性分类,还可以用于非线性分类。
理论:最大间隔
对上面的数据用支持向量机方法

#导入支持向量机 SVC 和使用 SVC 构建模型。

from sklearn.svm import SVC
# 构建模型
model = SVC(gamma='scale')
# 训练模型
model.fit(X_train, y_train)
# 预测
results = model.predict(X_test)
results

测试模型效果

#作图
plt.figure(figsize=(9, 8))
# 以默认样式绘制训练数据
plt.scatter(X_train[:, 0], X_train[:, 1], alpha=0.3)
# 以方块样式绘制测试数据
plt.scatter(X_test[:, 0], X_test[:, 1], marker=',', c=y_test)
# 将预测结果用标签样式标注在测试数据左上方
for i, txt in enumerate(results):
    plt.annotate(txt, (X_test[:, 0][i], X_test[:, 1][i]))

#计算精确度
model.score(X_test, y_test)
#结果为1.0.说明对于该数据集而言,支持向量机的准确度应该会优于感知机。

除了线性分类,支持向量机还通过引入核函数来解决非线性分类的问题。
下面这三张图片演示了支持向量机处理非线性可分问题的过程。
图1 中,红色小球和蓝色小球无法使用一条直线完成分类,于是我们通过核技巧将其映射到三维空间中(图2),然后通过绿色的平面完成分类。最终再投影到二维空间中,平面投影下来就变成了一条曲线。
支持向量机处理非线性可分
将特征映射到高维空间的过程中,用到多种核函数包括:线性核函数、多项式核函数、高斯径向基核函数等。其中,最常用的就算是高斯径向基核函数了,也简称为 RBF 核。
下面举个非线性可分的例子。用到数据集中的zoo.csv

data = pd.read_csv('zoo.csv', header=0)
data.head()
# 定义特征变量和目标变量
feature = data.iloc[:, 1:17].values
target = data['type'].values

# 对数据集进行切分,70% 为训练集,30% 为测试集。
X_train, X_test, y_train, y_test = train_test_split(
    feature, target, test_size=0.3, random_state=50)
X_train.shape, X_test.shape, y_train.shape, y_test.shape
# 构建模型
model = SVC(gamma='scale')
# 训练模型
model.fit(X_train, y_train)
# 预测
results = model.predict(X_test)
results
#存在16个特征,无法可视化,直接求准确度
model.score(X_test, y_test)
#测试集的正确分类率为 0.867。准确率不太高的原因可能是数据集太少了,只有100行

下面采用 PCA 降维的方法,缩减特征的数量,从而更方便可视化呈现。

from sklearn.decomposition import PCA

# 使用 PCA 降维至 2
pca = PCA(n_components=2)
feature_pca = pca.fit_transform(feature)

# 对数据集进行切分,70% 为训练集,30% 为测试集。
X_train, X_test, y_train, y_test = train_test_split(
    feature_pca, target, test_size=0.3, random_state=50)
X_train.shape, X_test.shape, y_train.shape, y_test.shape

压缩成了两个特征量,重新构建模型

# 构建模型
model = SVC(gamma='scale')
# 训练模型
model.fit(X_train, y_train)
# 预测
results = model.predict(X_test)
results
model.score(X_test, y_test)
#准确度为0.833。比先前的 0.867 还要低。究其原因,是我们的特征数量减少了,这可能会影响到准确度。

#特征降为 2 维,可以作图了
# 以默认样式绘制训练数据
plt.scatter(X_train[:, 0], X_train[:, 1], alpha=0.3)
# 以方块样式绘制测试数据
plt.scatter(X_test[:, 0], X_test[:, 1], marker=',', c=y_test)
# 将预测结果用标签样式标注在测试数据左上方
for i, txt in enumerate(results):
    plt.annotate(txt, (X_test[:, 0][i], X_test[:, 1][i]))

K-近邻法(KNN)
用图说明原理:如下图所示的 A 类和 B 类。现在,我们新输入一个数据(五角星),要判断该数据属于哪一个类?
在这里插入图片描述
kNN 的方法是以该数据为圆心,画一个圆。圆的半径不确定,可大可小。当它为图示中的内圆时,B 类数据多余 A 类,所以五角星数据属于 B 类。当为大圆时,A 类数据多于 B 类,所以五角星属于 A 类。而圆的大小,取决于 𝑘 值。而 𝑘 指的是与新数据最近邻的 𝑘 个值。

  • 𝑘 值的大小。 𝑘 值一般通过测试数据交叉验证来选择。
  • 距离的度量。新数据与最近邻数据之间的距离计算方式,有欧式距离或者曼哈顿距离等。
  • 分类决策规则。kNN 的决策规则为多数表决,即新数据属于圆圈中占比最大的一类。

用数据源中的three_class_data.csv数据

from sklearn.neighbors import KNeighborsClassifier

# 导入数据
data = pd.read_csv('three_class_data.csv', header=0)
# 定义特征变量和目标变量
feature = data[['x', 'y']].values
target = data['class'].values
# 对数据集进行切分,70% 为训练集,30% 为测试集。
X_train, X_test, y_train, y_test = train_test_split(
    feature, target, test_size=0.3, random_state=50)
X_train.shape, X_test.shape, y_train.shape, y_test.shape
#数据中有三个类别
# 构建模型
model = KNeighborsClassifier()
# 训练模型
model.fit(X_train, y_train)
# 预测
results = model.predict(X_test)
results
model.score(X_test, y_test)
#准确率为1.0

#高线图绘制出分类决策边界
import numpy as np
from matplotlib.colors import ListedColormap

# 绘制决策边界等高线图
cm0 = plt.cm.Oranges
cm1 = plt.cm.Greens
cm2 = plt.cm.Reds
cm_color = ListedColormap(['red', 'yellow'])

x_min, x_max = data['x'].min() - .5, data['x'].max() + .5
y_min, y_max = data['y'].min() - .5, data['y'].max() + .5

xx, yy = np.meshgrid(np.arange(x_min, x_max, .1),
                     np.arange(y_min, y_max, .1))

Z0 = model.predict_proba(np.c_[xx.ravel(), yy.ravel()])[:, 0]
Z1 = model.predict_proba(np.c_[xx.ravel(), yy.ravel()])[:, 1]
Z2 = model.predict_proba(np.c_[xx.ravel(), yy.ravel()])[:, 2]

Z0 = Z0.reshape(xx.shape)
Z1 = Z1.reshape(xx.shape)
Z2 = Z2.reshape(xx.shape)

plt.contourf(xx, yy, Z0, cmap=cm0, alpha=.9)
plt.contourf(xx, yy, Z1, cmap=cm1, alpha=.5)
plt.contourf(xx, yy, Z2, cmap=cm2, alpha=.4)

# 绘制训练集和测试集
plt.scatter(X_train[:, 0], X_train[:, 1], c=y_train, cmap=cm_color)
plt.scatter(X_test[:, 0], X_test[:, 1], c=y_test,
            cmap=cm_color, edgecolors='black')

#图示结果清晰,主要是看一下 kNN 的决策边界:图中,颜色越深的地方代表属于某一类别的可能性越高。

决策树和随机森林

随机森林,可以认为是用决策树组成的森林
决策树步骤:

1.特征选项。特性选择及选择判断规则。一般情况下,我们依据 3 种指标来选择特征,分别是信息增益、信息增益比、以及基尼指数。

  • 信息增益:通过判断某一特征对决策树前后影响的信息差值,从而选出最关键的特征。这种依据信息增益来选择特征的算法,也被称作 ID3 算法。
  • 后来,我们发现信息增益在划分训练数据特征时,容易偏向取值较多的特征。于是,我们改进了 ID3 算法,通过信息增益比值来选择,发展出了 C4.5 算法。
  • 除此之外,还有一种叫 CART 的生成算法,它利用了基尼指数最小化的原则。

2.数的生成。选择完特征之后,我们就通过这些特征来生成一颗完整的决策树。生成的原则是,所有训练数据都能分配到相应的叶节点。
3.树的剪枝。
一颗完整的决策树,使得训练数据得到有效的划分。但是,你会发现完整的决策树往往对于测试数据的效果并不好。这就出现了过度拟合的问题。过度拟合,指模型对训练数据的效果很好,但是对测试数据的效果差,泛化能力较弱。
解决决策树过度拟合的方法是对决策树进行剪枝。剪枝,也就是去掉一些叶节点。剪枝并不是随意乱剪,它的依据是,剪枝前和剪枝后的决策树整体损失函数最小。

数据采用鸢尾花 IRIS 数据。无需下载,作为常用的基准数据集之一,scikit-learn 提供了相应的导入方法。数据总共包含 150 行数据。每一行数据由 4 个特征值及一个目标值组成。其中 4 个特征值分别为:萼片长度、萼片宽度、花瓣长度、花瓣宽度。

from sklearn import datasets

# 载入数据集
iris = datasets.load_iris()
iris.data, iris.target
#构建 IRIS 分类决策树。
from sklearn.tree import DecisionTreeClassifier

# 建立模型
model = DecisionTreeClassifier()
# 模型训练
model.fit(iris.data, iris.target)
#完成模型训练,其实就建立起一颗决策树了。然后,这里我们通过 graphviz 模块,将决策树绘制出来。
# 安装 graphviz 包
!pip install graphviz

from sklearn.tree import export_graphviz
import graphviz

img = export_graphviz(
    model, out_file=None,
    feature_names=iris.feature_names,  # 传入特征名称
    class_names=iris.target_names,  # 传入类别值
    filled=True, node_ids=True,
    rounded=True)

graphviz.Source(img)  # 展示决策树

随机森林与决策树不同的地方在于,它不只是建立一颗树,而是建立一堆树。与决策树不同,随机森林每次只从全部数据集中随机抽取一部分数据用于生成树。另外,随机森林在生成树的时候不会剪枝。
随机森林的优点多多,例如:它可以处理大量的数据;它可以在特征不均衡时,依然维持较高的准确度;随机森林学习速度快,一般情况下,结果比单纯应用决策树要好。

from sklearn.ensemble import RandomForestClassifier

X_train = iris.data[:120]
X_test = iris.data[120:]

y_train = iris.target[:120]
y_test = iris.target[120:]

# 建立模型
model_tree = DecisionTreeClassifier(random_state=10)
model_random = RandomForestClassifier(random_state=10, n_estimators=10)

# 训练模型并验证
model_tree.fit(X_train, y_train)
s1 = model_tree.score(X_test, y_test)

model_random.fit(X_train, y_train)
s2 = model_random.score(X_test, y_test)

print('DecisionTree:', s1)
print('RandomForest:', s2)
#结果显示,随机森林的正确分类率比决策树高 10 个百分点左右。

人工神经网络

from sklearn.neural_network import MLPClassifier

model = MLPClassifier(max_iter=1000)
model.fit(X_train, y_train)
model.score(X_test, y_test)
#结果为0.767
  • 9
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值