【火炉炼AI】机器学习014-用SVM构建非线性分类模型
(本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
支持向量机(Support Vector Machine,SVM)是一种常见的判别方法,其基本模型是在特征空间上找到最佳的分离超平面,使得数据集上的正负样本间隔最大。SVM用来解决二分类问题的有监督学习算法,其可以解决线性问题,也可以通过引入核函数的方法来解决非线性问题。
本项目旨在使用SVM构建非线性分类模型来判别数据集的不同类别。
1. 准备数据集
首先来加载和查看数据集的一些特性。如下代码加载数据集并查看其基本信息
# 准备数据集data_path='E:\PyProjects\DataSet\FireAI/data_multivar_2_class.txt'df=pd.read_csv(data_path,header=None)# print(df.head()) # 没有问题print(df.info()) # 查看数据信息,确保没有错误dataset_X,dataset_y=df.iloc[:,:-1],df.iloc[:,-1]# print(dataset_X.head())# print(dataset_X.info())# print(dataset_y.head()) # 检查没问题dataset_X=dataset_X.values dataset_y=dataset_y.values
-------------------------------------输---------出--------------------------------
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 300 entries, 0 to 299
Data columns (total 3 columns):
0 300 non-null float64
1 300 non-null float64
2 300 non-null int64
dtypes: float64(2), int64(1)
memory usage: 7.1 KB
None
--------------------------------------------完-------------------------------------
从上面的df.info()函数的结果可以看出,这个数据集有两个特征属性(0,1列,连续的float类型),一个标记(2列,离散的int型,只有两个类别),每一列都没有缺失值。然后来看看这个数据集中数据点的分布情况,如下图所示:
# 数据集可视化def visual_2D_dataset(dataset_X,dataset_y): '''将二维数据集dataset_X和对应的类别dataset_y显示在散点图中''' assert dataset_X.shape[1]==2,'only support dataset with 2 features' plt.figure() classes=list(set(dataset_y)) markers=['.',',','o','v','^','<','>','1','2','3','4','8' ,'s','p','*','h','H','+','x','D','d','|'] colors=['b','c','g','k','m','w','r','y'] for class_id in classes: one_class=np.array([feature for (feature,label) in zip(dataset_X,dataset_y) if label==class_id]) plt.scatter(one_class[:,0],one_class[:,1],marker=np.random.choice(markers,1)[0], c=np.random.choice(colors,1)[0],label='class_'+str(class_id)) plt.legend() visual_2D_dataset(dataset_X,dataset_y)
数据集中数据点的分布情况
我以前的很多文章都讲到了数据集的处理,拆分,准备等,此处的数据集比较简单,故而简单讲述一下。
2. 用SVM构建线性分类器
你没有看错,我就是想用SVM构建一个线性分类器来判别这个数据集。当然,即使是入门级的机器学习攻城狮们,也能看出,这个数据集是一个线性不可分类型,需要用非线性分类器来解决。所以,此处,我就用线性分类器来拟合一下,看看会有什么样的“不好”的结果。
# 从数据集的分布就可以看出,这个数据集不可能用直线分开# 为了验证我们的判断,下面还是使用SVM来构建线性分类器将其分类# 将整个数据集划分为train set和test setfrom sklearn.model_selection import train_test_split train_X, test_X, train_y, test_y=train_test_split( dataset_X,dataset_y,test_size=0.25,random_state=42)# print(train_X.shape) # (225, 2)# print(train_y.shape) # (225,)# print(test_X.shape) # (75, 2)# 使用线性核函数初始化一个SVM对象。from sklearn.svm import SVC classifier=SVC(kernel='linear') # 构建线性分类器classifier.fit(train_X,train_y)
-------------------------------------输---------出--------------------------------
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='auto', kernel='linear',
max_iter=-1, probability=False, random_state=None, shrinking=True,
tol=0.001, verbose=False)
--------------------------------------------完-------------------------------------
然后查看一下这个训练好的SVM线性分类器在训练集和测试集上的表现,如下为在训练集上的性能报告:
# 模型在训练集上的性能报告:from sklearn.metrics import classification_report plot_classifier(classifier,train_X,train_y) # 分类器在训练集上的分类效果target_names = ['Class-0', 'Class-1'] y_pred=classifier.predict(train_X) print(classification_report(train_y, y_pred, target_names=target_names))
SVM线性分类器在训练集上的分类效果
-------------------------------------输---------出--------------------------------
precision recall f1-score support
Class-0 0.60 0.96 0.74 114
Class-1 0.89 0.35 0.50 111
avg / total 0.74 0.66 0.62 225
--------------------------------------------完-------------------------------------
很明显,从分类效果图和性能报告中,都可以看出这个模型很差,差到姥姥家了。。。
所以,更不用说,在测试集上的表现了,当然是一个差字了得。。。
# 分类器在测试集上的分类效果plot_classifier(classifier,test_X,test_y) target_names = ['Class-0', 'Class-1'] y_pred=classifier.predict(test_X)print(classification_report(test_y, y_pred, target_names=target_names))
SVM线性分类器在测试集上的分类效果
-------------------------------------输---------出--------------------------------
precision recall f1-score support
Class-0 0.57 1.00 0.73 36
Class-1 1.00 0.31 0.47 39
avg / total 0.79 0.64 0.59 75
--------------------------------------------完-------------------------------------
3. 用SVM构建非线性分类器
很明显,用线性分类器解决不了这个数据集的判别问题,所以我们就上马非线性分类器吧。
使用SVM构建非线性分类器主要是考虑使用不同的核函数,此处指讲述两种核函数:多项式核函数和径向基函数。
# 从上面的性能报告中可以看出,分类效果并不好# 故而我们使用SVM建立非线性分类器,看看其分类效果# 使用SVM建立非线性分类器主要是使用不同的核函数# 第一种:使用多项式核函数:classifier_poly=SVC(kernel='poly',degree=3) # 三次多项式方程classifier_poly.fit(train_X,train_y)# 在训练集上的表现为:plot_classifier(classifier_poly,train_X,train_y) target_names = ['Class-0', 'Class-1'] y_pred=classifier_poly.predict(train_X)print(classification_report(train_y, y_pred, target_names=target_names))
SVM多项式核函数的非线性分类器的分类效果
-------------------------------------输---------出--------------------------------
precision recall f1-score support
Class-0 0.92 0.85 0.89 114
Class-1 0.86 0.93 0.89 111
avg / total 0.89 0.89 0.89 225
--------------------------------------------完-------------------------------------
# 第二种:使用径向基函数建立非线性分类器classifier_rbf=SVC(kernel='rbf') classifier_rbf.fit(train_X,train_y)# 在训练集上的表现为:plot_classifier(classifier_rbf,train_X,train_y) target_names = ['Class-0', 'Class-1'] y_pred=classifier_rbf.predict(train_X)print(classification_report(train_y, y_pred, target_names=target_names))
SVM径向基函数的非线性分类器的分类效果
-------------------------------------输---------出--------------------------------
precision recall f1-score support
Class-0 0.96 0.96 0.96 114
Class-1 0.96 0.95 0.96 111
avg / total 0.96 0.96 0.96 225
作者:炼丹老顽童
链接:https://www.jianshu.com/p/3ea7bb62ffe8
共同学习,写下你的评论
评论加载中...
作者其他优质文章