机器学习项目实践——鸢尾花分类
基于SVM算法实现鸢尾花分类
摘要:支持向量机,因其英文名为support vector machine,故一般简称SVM,通俗来讲,它是一种二类分类模型,其基本模型定义为特征空间上的间隔最大的线性分类器,其学习策略便是间隔最大化,最终可转化为一个凸二次规划问题的求解。最基础的便是二分类问题,给定一个数据集,含有多个属性,通过这些属性,建立超平面,使得这些点分为2类,定义标签1与-1,然后对其他的点进行预测。本实验实现svm分类程序对鸢尾花数据集进行分类,并分析结果与得出相关的结论。
一、问题介绍:
构建一个模型,根据鸢尾花的花萼和花瓣大小将其分为三种不同的品种。
iris数据集总共包含150行数据
每一行数据由 4 个特征值及一个目标值组成。
4 个特征值分别为:萼片长度、萼片宽度、花瓣长度、花瓣宽度
目标值为三种不同类别的鸢尾花,分别为: Iris Setosa、Iris Versicolour、Iris Virginica
通过数据完成模型建立和评估
二、解题步骤:
1.数据准备
(1)从指定路径下加载数据,将字符型转化为整型
(2)对加载的数据进行分割,x_train,x_test,y_train,y_test分别表示训练集特征、训练集标签、测试集特征、测试集标签
(3)一部分数据用于构建模型,称为训练数据,另一部分用于评估模型性能,称为测试数据。可以利用scikit-learn中train_test_split函数可以实现这个功能。
导入项目所需要的包:
import numpy as np from sklearn import model_selection import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib import colors from sklearn import svm, datasets from sklearn.model_selection import train_test_split from sklearn.metrics import roc_curve, auc from sklearn.preprocessing import label_binarize #标签二值化LabelBinarizer,可以把yes和no转化为0和1,或是把incident和normal转化为0和1。 from sklearn.multiclass import OneVsRestClassifier 12345678910
将字符型转为整形,便于数据加载:
def iris_type(s): class_label={b'setosa':0,b'versicolor':1,b'virginica':2} return class_label[s] 123'
2.加载数据:
使用numpy中的loadtxt读入数据文件
注意数据的读取,delimiter参数是根据txt文件中的分隔符来设置的!
#使用numpy中的loadtxt读入数据文件 filepath='iris.txt' # 数据文件路径 #注意数据的读取,delimiter参数是根据txt文件中的分隔符来设置的! data=np.loadtxt(filepath,dtype=float,delimiter=None,converters={4:iris_type}) 1234
3.数据分割:
np.split 按照列(axis=1)进行分割,从第四列开始往后的作为y 数据,之前的作为X 数据。函数 split(数据,分割位置,轴=1(水平分割) or 0(垂直分割))。
x = X[:,0:2]
在 X中取前两列作为特征(为了后期的可视化画图更加直观,故只取前两列特征值向量进行训练)
用train_test_split将数据随机分为训练集和测试集,测试集占总数据的30%(test_size=0.3),random_state是随机数种子
参数解释:
x:train_data:所要划分的样本特征集。
y:train_target:所要划分的样本结果。
test_size:样本占比,如果是整数的话就是样本的数量。
random_state:是随机数的种子。(随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:种子不同,产生不同的随机数;种子相同,即使实例不同也产生相同的随机数。)
X, y = np.split(data, (4,),axis=1) # np.split 按照列(axis=1)进行分割,从第四列开始往后的作为y 数据,之前的作为X 数据。函数 split(数据,分割位置,轴=1(水平分割) or 0(垂直分割))。 x = X[:,0:2] # 在 X中取前两列作为特征(为了后期的可视化画图更加直观,故只取前两列特征值向量进行训练) x_train,x_test,y_train,y_test=model_selection.train_test_split(x,y,random_state=1,test_size=0.3) 1234
4.定义模型:
搭建模型,训练SVM分类器
classifier=svm.SVC(kernel='rbf',gamma=0.1,decision_function_shape='ovo',C=0.8) train(classifier, x_train, y_train) 12
kernel='linear’时,为线性核函数,C越大分类效果越好,但有可能会过拟合(defaul C=1)。
kernel=‘rbf’(default)时,为高斯核函数,gamma值越小,分类界面越连续;gamma值越大,分类界面越“散”,分类效果越好,但有可能会过拟合。
decision_function_shape='ovo’时,为one v one分类问题,即将类别两两之间进行划分,用二分类的方法模拟多分类的结果。
decision_function_shape='ovr’时,为one v rest分类问题,即一个类别与其他类别进行划分。
5.模型评估:
计算决策函数的值,可以通过decision_function()实现decision_function中每一列的值代表距离各类别的距离。只需要调用该函数即可。
def print_accuracy(model, x_train, y_train,x_test, y_test ): print('SVM-输出训练集的准确率为:', model.score(x_train, y_train)) print("SVM-输出测试集的准确率为:", model.score(x_test, y_test)) #原始结果与预测结果进行对比 show_accuracy(model.predict(x_train), y_train, 'traing data') show_accuracy(model.predict(x_test), y_test, 'testing data') #计算决策函数的值,可以通过decision_function()实现。decision_function中每一列的值代表距离各类别的距离。 print('decision_function:n', model.decision_function(x_train)) 12345678'
6.模型可视化:
通过matplotlib函数可直接引用画出测试集的散点图
def draw(model, x): x1_min, x1_max = x[:, 0].min(), x[:, 0].max() # 第0列的范围 x[:, 0] ":"表示所有行,0表示第1列 x2_min, x2_max = x[:, 1].min(), x[:, 1].max() # 第1列的范围 x[:, 0] ":"表示所有行,1表示第2列 x1, x2 = np.mgrid[x1_min:x1_max:200j, x2_min:x2_max:200j] # 生成网格采样点(用meshgrid函数生成两个网格矩阵X1和X2) grid_test = np.stack((x1.flat, x2.flat), axis=1) # 测试点,再通过stack()函数,axis=1,生成测试点 # .flat 将矩阵转变成一维数组 (与ravel()的区别:flatten:返回的是拷贝 grid_hat = model.predict(grid_test) # 预测分类值 grid_hat = grid_hat.reshape(x1.shape) # 使之与输入的形状相同 123456789'
7.绘制ROC曲线
ROC的全称是Receiver Operating Characteristic Curve,中文名字叫“受试者工作特征曲线”首先是由二战中的电子工程师和雷达工程师发明的,用来侦测战场上的敌军载具(飞机、船舰),也就是信号检测理论。之后很快就被引入了心理学来进行信号的知觉检测。此后被引入机器学习领域,用来评判分类、检测结果的好坏。
ROC曲线的横坐标为FPR(假正率),纵坐标为TPR(真正率)。有了ROC曲线需要对模型有一个定量的分析,这里就需要引入AUC(Area under ROC Curve)面积,AUC指的就是ROC曲线下方的面积,计算AUC只需要沿着ROC的横轴做积分即可,真实场景下ROC曲线一般在y=x直线的上方,所以AUC的取值一般在0.5~1之间,AUC值越大说明模型的性能越好。
iris = datasets.load_iris() # 鸢尾花数据导入 X = iris.data # 每一列代表了萼片或花瓣的长宽,一共4列,每一列代表某个被测量的鸢尾植物,iris.shape=(150,4) y = iris.target # target是一个数组,存储了data中每条记录属于哪一类鸢尾植物,所以数组的长度是150,所有不同值只有三个 random_state = np.random.RandomState(0) # 给定状态为0的随机数组 y = label_binarize(y, classes=[0, 1, 2]) n_classes = y.shape[1] n_samples, n_features = X.shape X = np.c_[X, random_state.randn(n_samples, 200 * n_features)] # 添加合并生成特征测试数据集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0)
1234567891011121314151617三、结果分析:
1.采用SVM模型得到训练集和测试集的准确率如下:
2.计算得到决策函数的值:
3.可视化展示散点图:
4.ROC曲线的绘制:
总结:
通过散点图及ROC曲线图和准确率的表现来看,该实验基于SVM模型实现鸢尾花的分类识别中,模型的训练效果比较满意,识别率可以达到80%。但有些地方还可以继续完善,完善后的效果应该可以达到90%。
四、源代码:
import numpy as np from sklearn import model_selection import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib import colors from sklearn import svm, datasets from sklearn.model_selection import train_test_split from sklearn.metrics import roc_curve, auc from sklearn.preprocessing import label_binarize #标签二值化LabelBinarizer,可以把yes和no转化为0和1,或是把incident和normal转化为0和1。 from sklearn.multiclass import OneVsRestClassifier # # 当使用numpy中的loadtxt函数导入该数据集时,假设数据类型dtype为浮点型,但是很明显数据集的第五列的数据类型是字符串并不是浮点型。 # # 因此需要额外做一个工作,即通过loadtxt()函数中的converters参数将第五列通过转换函数映射成浮点类型的数据。 # # 首先,我们要写出一个转换函数: # # 定义一个函数,将不同类别标签与数字相对应 def iris_type(s): class_label={b'setosa':0,b'versicolor':1,b'virginica':2} return class_label[s] def train(model, x_train, y_train): model.fit(x_train,y_train.ravel()) def show_accuracy(a, b, tip): acc = (a.ravel() == b.ravel()) print("%s Accuracy:%.3f"%(tip, np.mean(acc))) def print_accuracy(model, x_train, y_train,x_test, y_test ): print('SVM-输出训练集的准确率为:', model.score(x_train, y_train)) print("SVM-输出测试集的准确率为:", model.score(x_test, y_test)) #原始结果与预测结果进行对比 show_accuracy(model.predict(x_train), y_train, 'traing data') show_accuracy(model.predict(x_test), y_test, 'testing data') #计算决策函数的值,可以通过decision_function()实现。decision_function中每一列的值代表距离各类别的距离。 print('decision_function:n', model.decision_function(x_train)) def draw(model, x): x1_min, x1_max = x[:, 0].min(), x[:, 0].max() # 第0列的范围 x[:, 0] ":"表示所有行,0表示第1列 x2_min, x2_max = x[:, 1].min(), x[:, 1].max() # 第1列的范围 x[:, 0] ":"表示所有行,1表示第2列 x1, x2 = np.mgrid[x1_min:x1_max:200j, x2_min:x2_max:200j] # 生成网格采样点(用meshgrid函数生成两个网格矩阵X1和X2) grid_test = np.stack((x1.flat, x2.flat), axis=1) # 测试点,再通过stack()函数,axis=1,生成测试点 # .flat 将矩阵转变成一维数组 (与ravel()的区别:flatten:返回的是拷贝 grid_hat = model.predict(grid_test) # 预测分类值 grid_hat = grid_hat.reshape(x1.shape) # 使之与输入的形状相同 # # 2.指定默认字体 # mpl.rcParams['font.sans-serif'] = [u'SimHei'] # mpl.rcParams['axes.unicode_minus'] = False # 3.绘制 cm_light = mpl.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF']) cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b']) # alpha = 0.5 plt.pcolormesh(x1, x2, grid_hat, cmap=cm_light) # 预测值的显示 # plt.plot(x[:, 0], x[:, 1], 'o', alpha=alpha, color='blue', markeredgecolor='k') 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, facecolors='none', zorder=10) # 圈中测试集样本 plt.xlabel('sepal length', fontsize=13) plt.ylabel('sepal width', fontsize=13) plt.xlim(x1_min, x1_max) plt.ylim(x2_min, x2_max) plt.title('SVM feature', fontsize=15) #plt.grid() plt.show() #1.数据准备 #1.1加载数据 #使用numpy中的loadtxt读入数据文件 filepath='iris.txt' # 数据文件路径 #注意数据的读取,delimiter参数是根据txt文件中的分隔符来设置的! data=np.loadtxt(filepath,dtype=float,delimiter=None,converters={4:iris_type}) #1.2数据分割 X, y = np.split(data, (4,),axis=1) # np.split 按照列(axis=1)进行分割,从第四列开始往后的作为y 数据,之前的作为X 数据。函数 split(数据,分割位置,轴=1(水平分割) or 0(垂直分割))。 x = X[:,0:2] # 在 X中取前两列作为特征(为了后期的可视化画图更加直观,故只取前两列特征值向量进行训练) x_train,x_test,y_train,y_test=model_selection.train_test_split(x,y,random_state=1,test_size=0.3) # #用train_test_split将数据随机分为训练集和测试集,测试集占总数据的30%(test_size=0.3),random_state是随机数种子 # 参数解释: # x:train_data:所要划分的样本特征集。 # y:train_target:所要划分的样本结果。 # test_size:样本占比,如果是整数的话就是样本的数量。 # random_state:是随机数的种子。 # (随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。 # 随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:种子不同,产生不同的随机数;种子相同,即使实例不同也产生相同的随机数。) #2.定义模型:SVM模型定义 #搭建模型,训练SVM分类器 # classifier=svm.SVC(kernel='linear',gamma=0.1,decision_function_shape='ovo',C=0.1) # kernel='linear'时,为线性核函数,C越大分类效果越好,但有可能会过拟合(defaul C=1)。 classifier=svm.SVC(kernel='rbf',gamma=0.1,decision_function_shape='ovo',C=0.8) # kernel='rbf'(default)时,为高斯核函数,gamma值越小,分类界面越连续;gamma值越大,分类界面越“散”,分类效果越好,但有可能会过拟合。 # decision_function_shape='ovo'时,为one v one分类问题,即将类别两两之间进行划分,用二分类的方法模拟多分类的结果。 # decision_function_shape='ovr'时,为one v rest分类问题,即一个类别与其他类别进行划分。 train(classifier, x_train, y_train) #调用ravel()函数将矩阵转变成一维数组 #4.模型评估 print_accuracy(classifier, x_train, y_train, x_test, y_test) # SVM-输出训练集的准确率为: 0.838095238095 # SVM-输出测试集的准确率为: 0.777777777778 #5.模型可视化 draw(classifier, x) #6.绘制ROC曲线 iris = datasets.load_iris() # 鸢尾花数据导入 X = iris.data # 每一列代表了萼片或花瓣的长宽,一共4列,每一列代表某个被测量的鸢尾植物,iris.shape=(150,4) y = iris.target # target是一个数组,存储了data中每条记录属于哪一类鸢尾植物,所以数组的长度是150,所有不同值只有三个 random_state = np.random.RandomState(0) # 给定状态为0的随机数组 y = label_binarize(y, classes=[0, 1, 2]) n_classes = y.shape[1] n_samples, n_features = X.shape X = np.c_[X, random_state.randn(n_samples, 200 * n_features)] # 添加合并生成特征测试数据集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0) # 根据此模型训练简单数据分类器 classifier = OneVsRestClassifier(svm.SVC(kernel='linear', probability=True, random_state=random_state)) # 线性分类支持向量机 y_score = classifier.fit(X_train, y_train).decision_function(X_test) # 用一个分类器对应一个类别, 每个分类器都把其他全部的类别作为相反类别看待。 fpr = dict() tpr = dict() roc_auc = dict() for i in range(n_classes): fpr[i], tpr[i], _ = roc_curve(y_test[:, i], y_score[:, i]) # 计算ROC曲线面积 roc_auc[i] = auc(fpr[i], tpr[i]) fpr["micro"], tpr["micro"], _ = roc_curve(y_test.ravel(), y_score.ravel()) roc_auc["micro"] = auc(fpr["micro"], tpr["micro"]) plt.figure() lw = 2 plt.plot(fpr[2], tpr[2], color='darkorange', lw=lw, label='ROC curve (area = %0.4f)' % roc_auc[2]) plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--') plt.xlabel('FPR') plt.ylabel('TPR') plt.ylim([0.0, 1.0]) plt.xlim([0.0, 1.0]) plt.legend(loc="lower right") plt.title("Precision-Recall") plt.show()
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153相关知识
【机器学习】鸢尾花分类:机器学习领域经典入门项目实战
【机器学习】鸢尾花分类
第一个机器学习项目(鸢尾花分类问题)
[Python机器学习]鸢尾花分类 机器学习应用
机器学习(三):感知器算法实现鸢尾花分类项目实战
[机器学习基础][笔记] 一、鸢尾花分类
【机器学习】KNN算法实现鸢尾花分类
机器学习案例:鸢尾花分类——基于Scikit
机器学习入门——鸢尾花问题
Python机器学习基础教程——1.7第一个应用:鸢尾花分类——学习笔记
网址: 机器学习项目实践——鸢尾花分类 https://www.huajiangbk.com/newsview546227.html
上一篇: 【sklearn练习】KMean |
下一篇: 鸢尾花 Excel数据分析 |
推荐分享

- 1君子兰什么品种最名贵 十大名 4012
- 2世界上最名贵的10种兰花图片 3364
- 3花圈挽联怎么写? 3286
- 4迷信说家里不能放假花 家里摆 1878
- 5香山红叶什么时候红 1493
- 6花的意思,花的解释,花的拼音 1210
- 7教师节送什么花最合适 1167
- 8勿忘我花图片 1103
- 9橄榄枝的象征意义 1093
- 10洛阳的市花 1039