ML_寒假实践

1. IRIS数据集分类


介绍

Iris数据集是常用的分类实验数据集,由Fisher, 1936收集整理。Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。数据集包含150个数据样本,分为3类,每类50个数据,每个数据包含4个属性。可通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。

要求:至少使用2种机器学习方法完成分类,如KNN、SVM、决策树、神经网络等,掌握所用方法的原理以及代码细节,需要利用画图进行必要的数据分析,如有能力可考虑对分类方法进行结合、优化或自行编写实现等。完成1份实践报告,格式不限,要求至少包含基本实验原理、源代码、运行截图以及过程分析等。


实验原理

svm

支持向量机(Support Vector Machine, SVM)的基本模型是在特征空间上找到最佳的分离超平面使得训练集上正负样本间隔最大。SVM是用来解决二分类问题的有监督学习算法,多元分类问题可以通过构造多个SVM分类器的方法来解决。

在使用非线性SVM算法时,很最重要的是核函数的选择。
常用核函数如下:
1.多项式核函数:poly,通过多项式函数增加原始样本特征的高次方程幂,作为新特征。
2.径向基核函数:rbf,通过高斯分布函数增加原始样本特征的分布概率作为新的特征。
3.线性核函数:linear. 该参数不会通过核函数进行维度的提升,仅在原始维度空间中寻求线性分类边界。

我使用了sklearn库的svm.SVC算法进行实现
关于svm.svc的参数,我对使用到重点参数加粗

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

在大多数情况下,数据并不是完美的线性可分数据,可能会存在少量的点出现在分类超平面的另外一侧。我们希望尽量保证将这些点进行正确分类,同时又保证分类面与两类样本点有足够大的几何间隔。在这种情况下,我们为每一个样本点加上一个松弛变量,允许有小的误差存在。在加入松弛变量后,我们还要在目标函数中加入相应的惩罚参数C,对这个松弛变量起到一个监督克制的作用。两者的关系,有点类似道家的阴阳制衡的关系,此消彼长。

kernel :核函数,默认是rbf,可以是‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’
关于核函数的选取,kernel='linear’时,为线性核,C越大分类效果越好,但有可能会过拟合(defaul C=1)。而当kernel='rbf’时(default),为高斯核,gamma值越小,分类界面越连续;gamma值越大,分类界面越“散”,分类效果越好,但有可能会过拟合

degree :多项式poly函数的维度,默认是3,选择其他核函数时会被忽略。
gamma : ‘rbf’,‘poly’ 和‘sigmoid’的核函数参数。默认是’auto’。 如果gamma是’auto’,那么实际系数是1 / n_features。
coef0 :核函数中的独立项。 它只在’poly’和’sigmoid’中很重要。probability :是否启用概率估计。 必须在调用fit之前启用它,并且会减慢该方法的速度。默认为False
shrinking :是否采用shrinking heuristic方法(收缩启发式),默认为true
tol :停止训练的误差值大小,默认为1e-3
cache_size :核函数cache缓存大小,默认为200
class_weight :类别的权重,字典形式传递。设置第几类的参数C为weight*C(C-SVC中的C)
verbose :允许冗余输出
max_iter :最大迭代次数。-1为无限制。
decision_function_shape :‘ovo’, ‘ovr’ or None, default=ovr

扫描二维码关注公众号,回复: 12715110 查看本文章

关于‘ovo’, ‘ovr’的解释:
一对多法(one-versus-rest,简称OVR SVMs)
训练时依次把某个类别的样本归为一类,其他剩余的样本归为另一类,这样k个类别的样本就构造出了k个SVM。分类时将未知样本分类为具有最大分类函数值的那类。
decision_function(X)[source]
样品X与分离超平面的距离。
参数:
X:数组式,形式(n_samples,n_features)
返回值:
X:array-like,shape(n_samples,n_classes *(n_classes-1)/ 2)
返回模型中每个类的样本的决策函数。 如果decision_function_shape =‘ovr’,则形式为(n_samples,n_classes)

重要sklearn函数:
fit(X,y,sample_weight = None)[来源]
根据给定的训练数据拟合SVM模型。
参数:
X:{array-like,sparse matrix},shape(n_samples,n_features)训练向量,其中n_samples是样本数,n_feature是特征数。 对于kernel =“预计算”,X的预期形状为(n_samples,n_samples)。
y:array-like,shape(n_samples,)目标值(分类中的类标签,回归中的实数)
sample_weight:array-like,shape(n_samples,)每样品权重 每个样品重新调整C。 较高的权重会使分类器更加强调这些要点。
返回值:
self:对象返回自我。

predict(X)[source]对X中的样本进行分类。对于一个类的模型,返回+1或-1。
参数:
X:{array-like,sparse matrix},shape(n_samples,n_features)
对于kernel =“precomputed”,X的预期形式为[n_samples_test,n_samples_train]
返回:
y_pred:array,shape(n_samples,)X中样本的类标签

名词解释:
间隔:一个点到分割面的距离,称为点相对于分割面的距离。

数据集中所有的点到分割面的最小间隔的2倍,称为分类器或数据集的间隔。

最大间隔:SVM分类器是要找最大的数据集间隔。

支持向量:坐落在数据边际的两边超平面上的点被称为支持向量

朴素贝叶斯

贝叶斯分类算法是统计学是一种概率分类方法,朴素贝叶斯分类时贝叶斯分类中最简单的一种。利用贝叶斯公式根据某特征的先验概率计算出其后延概率,然后选择具有最大后延概率的类作为该特征所属的类。朴素贝叶斯,称之为“朴素”,是因为整个形式化过程只做了最原始、最简单的假设,具体假设如下:

  • 特征之间相互独立
  • 每个特征同等重要

高斯朴素贝叶斯

我在代码中实现的是GaussianNB
GaussianNB是先验为高斯分布(正态分布)的朴素贝叶斯,假设每个标签的数据都服从高斯分布(正态分布)。
算法流程:

  1. 处理数据,得到m个具有n个特征的样本,这些样本分别属于{Y1,Y2,Y3}{Y1,Y2,Y3}类别(类别数量增多,这里说明朴素贝叶斯处理多分类问题的流程)。
  2. 通过数据分析可以得到每个特征的类条件概率P(xi|Y)P(xi|Y),再通过全概率公式求得P(X)P(X)。
    P(X)=P(X|Y1)P(Y1)+P(X|Y2)P(Y2)+P(X|Y3)P(Y3)
    P(X)=P(X|Y1)P(Y1)+P(X|Y2)P(Y2)+P(X|Y3)P(Y3)
    其中 P(X|Yk)P(X|Yk)可根据特征独立性展开。
  3. 将求得的先验概率和类条件概率带入朴素贝叶斯公式,求得每个类别的后验概率。我们可以选择概率最大的类别为最后确定的类别。

KMeans聚类

算法描述:

  1. 随机选择k个中心
  2. 遍历所有样本,把样本划分到距离最近的一个中心
  3. 划分之后就有K个簇,计算每个簇的平均值作为新的质心
  4. 重复步骤2,直到达到停止条件
    停止条件:聚类中心不再发生变化;所有的距离最小;迭代次数达到设定值,

源代码及过程分析

数据预处理

将字符串转为整形,整形转化为字符串

def iris_type(s):
    it ={
    
    b'Iris-setosa':0,b'Iris-versicolor':1,b'Iris-virginica':2}
    return it[s]
def iris_type2(s):
    it ={
    
    0:'Iris-setosa',1:'Iris-versicolor',2:'Iris-virginica'}
    return it[s]

对数据集进行读取,将数据进行分割,处理标签为整形,分别存储到x,y集

data = np.loadtxt('D:/Download/QQ/8240722/Document/8240722/FileRecv/机器学习小组/假期实践/1. IRIS数据集分类/iris.data', #数据文件路径
                  dtype=float,                 #数据类型
                  delimiter=',',               #数据分隔符
                  converters={
    
    4:iris_type})    #将第五列使用iris_type进行转换
#1.2数据分割
x,y=np.split(data,                             #数组数据
             (4,),                             #第5列开始往后为y
             axis=1)                           #代表纵向分割,按列分割

划分样本特征集和标签集,设置0.3的的测试样本比,并对模型进行定义

x = x[:,:4]                          #前四列特征集
x_train,x_test,y_train,y_test=model_selection.train_test_split(x,              #被划分得样本特征集
                                                               y,              #被划分得样本标签
                                                               random_state=1, #随机数种子,混洗数据时用于概率估计
                                                               test_size=0.3)  #测试样本占比

这里定义了三种算法:1svm模型 2高斯贝叶斯分类器 3KMeans聚类器

def classifier():
    clf = svm.SVC(C=0.5,                             #误差惩罚系数  对偏离点的重视程度
                  kernel ='linear',                  #线性核 kernel=‘rbf’:高斯核
                  decision_function_shape='ovr')     #决策函数 因为3种,一对多的问题,所以决策函数设置为ovr
    return clf
def classifier2():
    clf = GaussianNB()
    return clf
def classifier3():
    clf = KMeans(n_clusters=3)
    return clf

对模型进行训练和评估

#3.训练模型
train(clf,x_train,y_train)
#4模型评估
#*svm
print_accuracy(clf,x_train,y_train,x_test,y_test)
#draw(clf,x)

#*k-means
#dram_km(clf,x_train)

对模型评估的具体操作,并把分类可视化,输出训练集和测试集的准确率

def print_accuracy(clf,x_train,y_train,x_test,y_test):
    # 分别打印出训练集和测试集的准确率score(x_train,y_train);表示输出x_train,y_train在模型上的准确率
    print('training 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))

def draw(clf,x):
    iris_feature='sepal length','sepal width','petal length','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]     # 生成的网格采样点
    grid_test=np.stack((x1.flat,x2.flat),axis=1)                # 测试点
    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,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','b','r'])
    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)
    plt.ylabel(iris_feature[1], fontsize=20)
    plt.xlim(x1_min,x1_max)
    plt.ylim(x2_min,x2_max)
    plt.title('SVM in iris data classification',fontsize=30)
    plt.grid()
    plt.show()

def dram_km(clf,x):
    label_pred = clf.labels_ #获取聚类标签
    # 绘制k-means结果
    x0 = x[label_pred == 0]
    x1 = x[label_pred == 1]
    x2 = x[label_pred == 2]
    plt.scatter(x0[:, 0], x0[:, 1], c="red", marker='o', label='label0')
    plt.scatter(x1[:, 0], x1[:, 1], c="green", marker='*', label='label1')
    plt.scatter(x2[:, 0], x2[:, 1], c="blue", marker='+', label='label2')
    plt.xlabel('sepal length')
    plt.ylabel('sepal width')
    plt.legend(loc=2)
    plt.show() 
#5模型使用
arr = input()
arr = [float(n) for n in arr.split()]
print(iris_type2(clf.predict([arr])[0]))

运行截图与总结

在这里插入图片描述
在这里插入图片描述
训练集准确率0.981,测试集准确率0.978 输出属性矩阵测试分类器正确率较高
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/DreamStark20/article/details/114190472
ML