机器学习经典应用--鸢尾花分类+3D成果可视化


ddf945049f922b905daaa388c79e4cd

任务描述

构建一个模型,根据鸢尾花的花萼和花瓣大小将其分为三种不同的品种

数据集

数据集下载

总共包含150行数据

每一行数据由 4 个特征值及一个目标值组成。

4 个特征值分别为:萼片长度、萼片宽度、花瓣长度、花瓣宽度

目标值为三种不同类别的鸢尾花,分别为: Iris setosa、Iris versicolour、Iris virginica

请添加图片描述

首先导入必要的包:

numpy : python第三方库,用于科学计算

matplotlib : python第三方库,主要用于进行可视化

sklearn: python的重要机器学习库,其中封装了大量的机器学习算法,如:分类、回归、降维以及聚类

import numpy as np                
from matplotlib import colors     
from sklearn import svm            
from sklearn.svm import SVC
from sklearn import model_selection
import matplotlib.pyplot as plt
import matplotlib as mpl

Step1. 数据准备

  1. 从指定路径下加载数据
  2. 对加载的数据进行数据分割,x_train,y_train,x_test,y_test分别表示训练集特征、训练集标签、测试集特征、测试集标签
#将字符串转为整型,便于数据加载
#这是一个字典
def iris_type(s):
    it = {b'Iris-setosa':0, b'Iris-versicolor':1, b'Iris-virginica':2}
    return it[s]

b' ' 表示这是一个 bytes 对象,用在Python3中,Python3里默认的str是unicode类。Python2的str本身就是bytes类。

#加载数据
data_path='/home/aistudio/data/data2301/iris.data'  #数据文件的路径
data = np.loadtxt(data_path,                       #数据文件路径
                  dtype=float,                    #数据类型
                  delimiter=',',                 #数据分隔符
                  converters={4:iris_type})    #将第5列使用函数iris_type进行转换,预处理
#print(data)                                 #data为二维数组,data.shape=(150, 5)
#print(data.shape)
#数据分割
x, y = np.split(data,                           #要切分的数组
                (4,),                           #沿轴切分的位置,第5列开始往后为y
                axis=1)                         #代表纵向分割,按列分割
x = x[:, 0:2]      
#在X中我们取前两列作为特征,为了后面的可视化。x[:,0:2]代表第一维(行)全取,第二维(列)取0~2
#如果想取0,2,3列,x = np.stack((x[:, 0], x[:, 2], x[:, 3]), axis=1)
#print(x)
x_train, x_test, y_train, y_test = model_selection.train_test_split(x,  
                                                                    y, 
                                                                    random_state=1,
                                                                    test_size=0.3)
#x为所要划分的样本特征集
#y为所要划分的样本结果,0,1,2
#random_state随机数种子,就是把数据打乱
#test_size测试样本占比

numpy.loadtxt() 用法

numpy.split() 用法

train_test_split()用法

Step2. 模型搭建

  • C : float,可选(默认值= 1.0)
    错误术语的惩罚参数CC越大,相当于惩罚松弛变量,希望松弛变量接近0,即对误分类的惩罚增大,趋向于对训练集全分对的情况,这样对训练集测试时准确率很高,但泛化能力弱。C值小,对误分类的惩罚减小,允许容错,将他们当成噪声点,泛化能力较强。

  • kernel : string,optional(default =‘rbf’)
    核函数类型,str类型,默认为’rbf’。可选参数为:

    • ’linear’:线性核函数

    • ‘poly’:多项式核函数

    • ‘rbf’:径像核函数/高斯核

    • ‘sigmod’:sigmod核函数

    • ‘precomputed’:核矩阵

      precomputed表示自己提前计算好核函数矩阵,这时候算法内部就不再用核函数去计算核矩阵,而是直接用你给的核矩阵,核矩阵需要为n*n的。

  • decision_function_shape : ‘ovo’,‘ovr’,默认= ‘ovr’
    决策函数类型,可选参数 ’ovo’ 和 ’ovr’ ,默认为 ’ovr’ 。

decision_function_shape= 'ovr’时,为one v rest,即一个类别与其他类别进行划分,

decision_function_shape= 'ovo’时,为one v one,即将类别两两之间进行划分,用二分类的方法模拟多分 类的结果。

sklearn.svm.SVC()函数

# SVM分类器构建
def classifier():
    #clf = svm.SVC(C=0.8,kernel='rbf', gamma=50,decision_function_shape='ovr')
    clf = svm.SVC(C=0.5,                         #误差项惩罚系数,默认值是1
                  kernel='linear',               #线性核 kenrel="rbf":高斯核
                  decision_function_shape='ovr') #决策函数
    return clf
# 定义模型:SVM模型定义
clf = classifier()

Step3. 模型训练

#训练模型
def train(clf,x_train,y_train):
    clf.fit(x_train,         #训练集特征向量
            y_train.ravel()) #训练集目标值
# 训练SVM模型
train(clf,x_train,y_train)

fit()方法用于训练svm,具体参数已经在定义svc对象时给出,这时候只需要给出数据集x和x对应的标签y。

ravel()方法将数组维度拉成一维数组

Step4. 模型评估

#判断a b是否相等,计算acc的均值
def show_accuracy(a, b, tip):
    acc = a.ravel() == b.ravel()  #acc是一个包含很多1,0的数组
    print('%s Accuracy:%.3f' %(tip, np.mean(acc)))  #np.mean()用来求均值
def print_accuracy(clf,x_train,y_train,x_test,y_test):
    #打印训练集和测试集的准确率score(x_train,y_train):表示输出x_train,y_train在模型上的准确率
    print('trianing prediction:%.3f' %(clf.score(x_train, y_train)))
    print('test data prediction:%.3f' %(clf.score(x_test, y_test)))
    #原始结果与预测结果进行对比 predict()表示对x_train样本进行预测,返回样本类别
    show_accuracy(clf.predict(x_train), y_train, 'traing data')
    show_accuracy(clf.predict(x_test), y_test, 'testing data')
    #计算决策函数的值,表示x到各分割平面的距离
    print('decision_function:\n', clf.decision_function(x_train))
print_accuracy(clf, x_train, y_train, x_test, y_test)

d1b1b2c46987571fa64aec4827f48e4

np.mean()函数

scikit-learn工具包中分类模型predict_proba、predict、decision_function用法详解_ 原理介绍很赞

Step5. 模型使用

np.stack

np.mgrid

numpy.flat

plt.pcolormesh

np.squeeze()

def draw(clf, x):
    iris_feature = 'sepal length', 'sepal width', 'petal lenght', 'petal width'
    # 开始画图
    x1_min, x1_max = x[:, 0].min(), x[:, 0].max()               #第0列的范围
    x2_min, x2_max = x[:, 1].min(), x[:, 1].max()               #第1列的范围
    x1, x2 = np.mgrid[x1_min:x1_max:200j, x2_min:x2_max:200j]   #生成网格采样点,2D
    grid_test = np.stack((x1.flat, x2.flat), axis=1)            #stack():沿着新的轴加入一系列数组, flat的作用是将数组分解成可连续访问的元素,目的就是把他拉直后合并,并且不改变数组
    print('grid_test:\n', grid_test)
    # 输出样本到决策面的距离
    z = clf.decision_function(grid_test)
    print('the distance to decision plane:\n', z)
    
    grid_hat = clf.predict(grid_test)                           # 预测分类值 得到【0,0.。。。2,2,2】
    print('grid_hat:\n', grid_hat)  
    grid_hat = grid_hat.reshape(x1.shape)                       # reshape grid_hat和x1形状一致
    #若3*3矩阵e,则e.shape()为3*3,表示3行3列   
 
    cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
    cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])
 
    plt.pcolormesh(x1, x2, grid_hat, cmap=cm_light)  # pcolormesh(x,y,z,cmap)这里参数代入x1,x2,grid_hat,cmap=cm_light绘制的是背景。
    plt.scatter(x[:, 0], x[:, 1], c=np.squeeze(y), edgecolor='k', s=50, cmap=cm_dark) # 样本点
    plt.scatter(x_test[:, 0], x_test[:, 1], s=120, facecolor='none', zorder=10)       # 测试点
    plt.xlabel(iris_feature[0], fontsize=20)  #x轴名称
    plt.ylabel(iris_feature[1], fontsize=20)
    plt.xlim(x1_min, x1_max)  #x轴作图范围
    plt.ylim(x2_min, x2_max)
    plt.title('svm in iris data classification', fontsize=30)
    plt.grid()
    plt.show()

# 模型使用
draw(clf,x)
#输出
grid_test:
 [[4.3       2.       ]
 [4.3       2.0120603]
 [4.3       2.0241206]
 ...
 [7.9       4.3758794]
 [7.9       4.3879397]
 [7.9       4.4      ]]
the distance to decision plane:
 [[ 2.17689921  1.23467171 -0.25941323]
 [ 2.17943684  1.23363096 -0.25941107]
 [ 2.18189345  1.23256802 -0.25940892]
 ...
 [-0.27958977  0.83621535  2.28683228]
 [-0.27928358  0.8332275   2.28683314]
 [-0.27897389  0.83034313  2.28683399]]
grid_hat:
 [0. 0. 0. ... 2. 2. 2.]
d03a87323ffb159216548aea356b9e1

若训练的不是0,1列,而是2,3列,则模型准确率会提高

3190616859f4ea1ccc55b9181e586f2

7f788cfde8d97f4e37859fdaca2beec

若训练所有列,准确率达到最高

664a4fbfee0e52b350b6c1947953004

3D可视化模型

现在挑选0,2,3列进行3维的建模

#用如下代码代替之前的分割数据的代码 原:x = x[:, 0:2] 
x = np.stack((x[:, 0], x[:, 2], x[:, 3]), axis=1)
def draw(clf, x):
    iris_feature = 'sepal length', 'sepal width', 'petal lenght', 'petal width'
    # 开始画图
    x0_min, x0_max = x[:, 0].min(), x[:, 0].max()
    x1_min, x1_max = x[:, 1].min(), x[:, 1].max()  # 第0列的范围
    x2_min, x2_max = x[:, 2].min(), x[:, 2].max()  # 第1列的范围
    x0, x1, x2 = np.mgrid[x0_min:x0_max:50j, x1_min:x1_max:50j, x2_min:x2_max:50j]  # 生成网格采样点,3D
    grid_test = np.stack((x0.flat, x1.flat, x2.flat), axis=1)  # stack():沿着新的轴加入一系列数组, flat的作用是将数组分解成可连续访问的元素,目的就是把他拉直后合并,并且不改变数组
    print('grid_test:\n', grid_test)

    grid_hat = clf.predict(grid_test)  # 预测分类值 得到【0,0.。。。2,2,2】
    print('grid_hat:\n', grid_hat)
    grid_hat = grid_hat.reshape(x1.shape)  # reshape grid_hat和x1形状一致
    # 若3*3矩阵e,则e.shape()为3*3,表示3行3列

    cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
    cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])

    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')

    # s:marker标记的大小
    # c: 颜色  可为单个,可为序列
    # depthshade: 是否为散点标记着色以呈现深度外观。对 scatter() 的每次调用都将独立执行其深度着色。
    # marker:样式
    # alpha为点的透明度,在0~1之间
    ax.scatter(xs=x1, ys=x2, zs=x0, zdir='z', s=10, c=grid_hat, depthshade=True, cmap=cm_light,alpha=0.01)
    ax.scatter(xs=x[:,1], ys=x[:,2], zs=x[:,0], zdir='z', s=30, c=np.squeeze(y), depthshade=True, cmap=cm_dark, marker="^")
    plt.show()

draw(clf, x)

结果如下

ddf945049f922b905daaa388c79e4cd

  • 19
    点赞
  • 154
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
非常感谢您的提问。以下是用Python编写SVM分类问题并可视化的步骤: 1. 导入所需的Python库,包括numpy、pandas、matplotlib和sklearn等。 2. 准备数据: 在这里我们可以使用sklearn的内置数据集Iris,这是一种经典的多类别分类问题数据集。我们通过加载Iris数据集来实现我们的SVM分类模型。 3. 数据预处理:划分数据集为训练数据集和测试数据集。 4. 特征缩放:进行数据标准化以确保归一性。 5. 定义模型并训练:使用sklearn提供的SVM实现,定义一个支持向量机分类器,并在训练数据集上进行训练。 6. 预测结果:对测试集进行预测并计算准确率。 7. 数据可视化:使用matplotlib库绘制分类结果的决策边界,以显示我们的分类器。 下面是示例代码: ```python import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler from sklearn.svm import SVC from sklearn.metrics import accuracy_score # Load Iris dataset iris = datasets.load_iris() X = iris.data y = iris.target # Split dataset into training and test data sets X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0) # Scaling features to have mean 0 and variance 1 sc = StandardScaler() sc.fit(X_train) X_train_std = sc.transform(X_train) X_test_std = sc.transform(X_test) # Train SVM classifier on training data svm = SVC(kernel='linear', C=1.0, random_state=0) svm.fit(X_train_std, y_train) # Make predictions using trained classifier y_pred = svm.predict(X_test_std) # Calculate model accuracy accuracy = accuracy_score(y_test, y_pred) print('Model accuracy:', accuracy) # Plot decision regions from matplotlib.colors import ListedColormap X_combined_std = np.vstack((X_train_std, X_test_std)) y_combined = np.hstack((y_train, y_test)) markers = ('s', 'x', 'o') colors = ('red', 'blue', 'green') cmap = ListedColormap(colors[:len(np.unique(y_combined))]) x1_min, x1_max = X_combined_std[:, 0].min() - 1, X_combined_std[:, 0].max() + 1 x2_min, x2_max = X_combined_std[:, 1].min() - 1, X_combined_std[:, 1].max() + 1 xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, 0.1), np.arange(x2_min, x2_max, 0.1)) Z = svm.predict(np.array([xx1.ravel(), xx2.ravel()]).T) Z = Z.reshape(xx1.shape) plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap) plt.xlim(xx1.min(), xx1.max()) plt.ylim(xx2.min(), xx2.max()) for idx, cl in enumerate(np.unique(y_combined)): plt.scatter(x=X_combined_std[y_combined == cl, 0], y=X_combined_std[y_combined == cl, 1], alpha=0.8, c=cmap(idx), marker=markers[idx], label=cl) plt.xlabel('Sepal length [standardized]') plt.ylabel('Petal length [standardized]') plt.legend(loc='upper left') plt.show() ``` 希望这个回答对你有所帮助,如果你还有其他问题,请随时问我。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

赵鸣漩

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

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

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

打赏作者

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

抵扣说明:

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

余额充值