用Python开始机器学习(8:SVM支持向量机)

SVM支持向量机是建立于统计学习理论上的一种分类算法,适合与处理具备高维特征的数据集。

SVM算法的数学原理相对比较复杂,好在由于SVM算法的研究与应用如此火爆,优快云博客里也有大量的好文章对此进行分析,下面给出几个本人认为讲解的相当不错的:

支持向量机通俗导论(理解SVM的3层境界):http://blog.youkuaiyun.com/v_july_v/article/details/7624837

JULY大牛讲的是如此详细,由浅入深层层推进,以至于关于SVM的原理,我一个字都不想写了。。强烈推荐。

还有一个比较通俗的简单版本的:手把手教你实现SVM算法:手把手教你实现SVM算法(一)_自在逍遥的博客-优快云博客_svm算法

SVN原理比较复杂,但是思想很简单,一句话概括,就是通过某种核函数,将数据在高维空间里寻找一个最优超平面,能够将两类数据分开。

针对不同数据集,不同的核函数的分类效果可能完全不一样。可选的核函数有这么几种:

线性函数:形如K(x,y)=x*y这样的线性函数;

多项式函数:形如K(x,y)=[(x·y)+1]^d这样的多项式函数;

径向基函数:形如K(x,y)=exp(-|x-y|^2/d^2)这样的指数函数;

Sigmoid函数:就是上一篇文章中讲到的Sigmoid函数。

我们就利用之前的几个数据集,直接给出Python代码,看看运行效果:

测试1:身高体重数据

# -*- coding: utf-8 -*-
import numpy as np
import scipy as sp
from sklearn import svm
from sklearn.model_selection import train_test_split
import sklearn.model_selection
import matplotlib.pyplot as plt


data = []
labels = []
with open("data\\1.txt") as ifile:
    for line in ifile:
        tokens = line.strip().split(' ')
        data.append([float(tk) for tk in tokens[:-1]])
        labels.append(tokens[-1])
x = np.array(data)
labels = np.array(labels)
y = np.zeros(labels.shape)
y[labels == 'fat'] = 1
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.1)

hx = 0.01
hy = 0.1
# create a mesh to plot in
x_min, x_max = x_train[:, 0].min() - 0.1, x_train[:, 0].max() + 0.1
y_min, y_max = x_train[:, 1].min() - 1, x_train[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, hx),
                     np.arange(y_min, y_max, hy))

# '''圆形边界数据生成。测试BRF函数 '''
# h = 0.1
# x_min, x_max = -1, 1
# y_min, y_max = -1, 1
# xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
#                      np.arange(y_min, y_max, h))
# n = xx.shape[0] * xx.shape[1]
# x = np.array([xx.T.reshape(n).T, xx.reshape(n)]).T
# y = (x[:, 0] * x[:, 0] + x[:, 1] * x[:, 1] < 0.8)
# y.reshape(xx.shape)
#
# x_train, x_test, y_train, y_test \
#     = train_test_split(x, y, test_size=0.2)

''' SVM '''
# title for the plots
titles = ['LinearSVC (linear kernel)',
          'SVC with polynomial (degree 3) kernel',
          'SVC with RBF kernel',
          'SVC with Sigmoid kernel']
clf_linear = svm.SVC(kernel='linear').fit(x_train, y_train)
# clf_linear  = svm.LinearSVC().fit(x, y)
clf_poly = svm.SVC(kernel='poly', degree=3).fit(x_train, y_train)
clf_rbf = svm.SVC().fit(x_train, y_train)
clf_sigmoid = svm.SVC(kernel='sigmoid').fit(x_train, y_train)

for i, clf in enumerate((clf_linear, clf_poly, clf_rbf, clf_sigmoid)):
    answer = clf.predict(x_train)
    print(clf)
    print(np.mean(answer == y_train))
    print(answer)
    print(y_train)

    plt.subplot(2, 2, i + 1)
    plt.subplots_adjust(wspace=0.4, hspace=0.4)

    # Put the result into a color plot
    x_train_ = np.c_[xx.ravel(), yy.ravel()]
    answer = clf.predict(x_train_)
    z = answer.reshape(xx.shape)
    plt.contourf(xx, yy, z, cmap=plt.cm.hot, alpha=0.8)

    # Plot also the training points
    plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=plt.cm.Paired)
    plt.xlabel(u'身高')
    plt.ylabel(u'体重')
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.xticks(())
    plt.yticks(())
    plt.title(titles[i])

plt.show()

运行结果如下:

可以看到,针对这个数据集,使用3次多项式核函数的SVM,得到的效果最好。(注意:由于数据太少,你跑出来的效果可能跟我的有差别。)

测试2:影评态度

下面看看SVM在康奈尔影评数据集上的表现:(代码略)

SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='linear', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.814285714286


SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='poly', max_iter=-1, probability=False, random_state=None,  shrinking=True, tol=0.001, verbose=False)
0.492857142857


SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='rbf', max_iter=-1, probability=False, random_state=None,  shrinking=True, tol=0.001, verbose=False)
0.492857142857


SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='sigmoid', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.492857142857
可见在该数据集上,线性分类器效果最好。

测试3:圆形边界

最后我们测试一个数据分类边界为圆形的情况:圆形内为一类,原型外为一类。看这类非线性的数据SVM表现如何:

测试数据生成代码如下所示:(把上面代码中的注释取消即可。)

''' 数据生成 '''
h = 0.1
x_min, x_max = -1, 1
y_min, y_max = -1, 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                     np.arange(y_min, y_max, h))
n = xx.shape[0]*xx.shape[1]
x = np.array([xx.T.reshape(n).T, xx.reshape(n)]).T
y = (x[:,0]*x[:,0] + x[:,1]*x[:,1] < 0.8)
y.reshape(xx.shape)

x_train, x_test, y_train, y_test\
    = train_test_split(x, y, test_size = 0.2)

测试结果如下:

SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='linear', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.65
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='poly', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.675
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='rbf', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.9625
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, degree=3, gamma=0.0,  kernel='sigmoid', max_iter=-1, probability=False, random_state=None,
  shrinking=True, tol=0.001, verbose=False)
0.65


可以看到,对于这种边界,径向基函数的SVM得到了近似完美的分类结果。而其他的分类器显然束手无策。

### 回答1: 雷达信号综合分选算法是一种用于处理雷达接收到的信号并对其进行分析和分类的算法。下面我将为你提供一个在优快云上找到的一种高效的雷达信号综合分选算法代码示例。 ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIGNALS 100 typedef struct { int frequency; int amplitude; int duration; } RadarSignal; int compare(const void *a, const void *b) { RadarSignal *signal1 = (RadarSignal *)a; RadarSignal *signal2 = (RadarSignal *)b; // 比较频率,按升序排列 if (signal1->frequency < signal2->frequency) return -1; else if (signal1->frequency > signal2->frequency) return 1; else { // 如果频率相同,比较振幅,按降序排列 if (signal1->amplitude > signal2->amplitude) return -1; else if (signal1->amplitude < signal2->amplitude) return 1; else return 0; } } void sortSignals(RadarSignal signals[], int numSignals) { qsort(signals, numSignals, sizeof(RadarSignal), compare); } int main() { RadarSignal signals[MAX_SIGNALS]; int numSignals; // 从输入中获取雷达信号数量 printf("请输入雷达信号的数量:"); scanf("%d", &numSignals); // 从输入中获取雷达信号的频率、振幅和持续时间 printf("请输入每个雷达信号的频率、振幅和持续时间:\n"); for (int i = 0; i < numSignals; i++) { printf("信号%d: ", i + 1); scanf("%d %d %d", &signals[i].frequency, &signals[i].amplitude, &signals[i].duration); } sortSignals(signals, numSignals); // 输出排序后的雷达信号 printf("\n排序后的雷达信号:\n"); for (int i = 0; i < numSignals; i++) { printf("信号%d: 频率=%d 振幅=%d 持续时间=%d\n", i + 1, signals[i].frequency, signals[i].amplitude, signals[i].duration); } return 0; } ``` 以上是一个基于C语言的雷达信号综合分选算法的代码示例。这个算法的实现通过定义一个雷达信号的类型和一个比较函数来实现信号的排序。使用`qsort`函数对信号进行排序后,输出排序后的雷达信号信息。这个例子可能还需要根据具体需求进行修改和完善,但它可以帮助你了解一种高效的雷达信号综合分选算法的实现方式。 ### 回答2: 雷达信号综合分选是一种用于从复杂的雷达信号中提取有用信息的算法。在这个问题中,我建议您在优快云上搜索相关的算法代码。 在搜索之前,您可以根据以下几个步骤来实施该算法。 1. 首先,您需要将雷达信号输入到算法中。您可以使用任何编程语言处理输入信号,如C++或Python。 2. 然后,您可以使用数字信号处理(DSP)技术来对雷达信号进行增强和处理。您可以使用优快云上的相关教程和代码来学习这些技术。 3. 接下来,您可以使用特征提取算法来从雷达信号中提取有用的信息。这些特征可以包括目标的位置、速度、距离、角度等。您可以查找优快云上提供的基于功率谱密度、相关性或其他方法的算法代码。 4. 最后,您可以使用分类算法将提取的特征与预定义的目标进行匹配。这可以帮助您确定目标的类型和属性。常见的分类算法包括最小二乘法、支持向量机SVM)等。您可以在优快云上找到这些算法的示例代码和实现。 总之,要找到一个高效的雷达信号综合分选算法代码,请在优快云上搜索相关的教程和代码示例。这将帮助您理解并实施该算法,以从复杂的雷达信号中提取有用的信息。 ### 回答3: 雷达信号综合分选是一种重要的算法,用于从雷达系统中接收到的混合信号中分辨出不同目标的特征。在csdn网站上,有许多高效的雷达信号综合分选算法代码可以参考。 首先,可以在csdn网站的搜索框中输入相关关键词,如“雷达信号综合分选算法代码”,然后点击搜索按钮。网站将返回与该关键词相关的代码示例。 一种高效的雷达信号综合分选算法是卡尔曼滤波器算法。这个算法可以通过对雷达系统的状态进行估计,来实现对不同目标的跟踪和分选。在csdn上搜索“卡尔曼滤波器雷达信号综合分选代码”可以找到相关的代码示例。 另一种常用的算法是快速傅里叶变换(FFT)。这种算法通过将时域信号转换为频域信号,来提取目标的频率特征。在csdn上搜索“快速傅里叶变换雷达信号综合分选代码”可以找到相关的代码示例。 此外,粒子滤波器算法也是一种常用的雷达信号综合分选算法。它通过使用一组随机采样的粒子,来估计目标的状态。在csdn上搜索“粒子滤波器雷达信号综合分选代码”可以找到相关的代码示例。 总而言之,在csdn网站上可以找到许多高效的雷达信号综合分选算法代码。根据自己的需求和具体情况,可以选择适合的算法代码进行参考和应用。
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值