Python学习--Machine-Learning 吴恩达机器学习编程作业 (第六周)

本文介绍了使用Python的sklearn库完成吴恩达机器学习课程的第六周编程作业——支持向量机(SVM)。作业涵盖了线性核函数和高斯核函数的应用,以及如何通过验证集寻找最优参数。在实践中,作者详细展示了SVM用于垃圾邮件分类的过程,并分享了在绘图过程中遇到的挑战和解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Machine-Learning 编程作业

Programming Exercise 6:Support Vector Machines

SVM的简单应用

part1 示例文件1使用线性核函数

part2 示例文件2运用高斯核函数

part3 示例文件3运用验证集找最优参数

part4 垃圾邮件分类

这周的作业SVM的实现因为使用的是sklearn库中的SVM库,所以较为简单。但让我最头秃的就是每一次分类之后分类边界的绘制,matplotlab的学习路途任重而道远啊,花了我一下午时间找到三种绘图方法,,太难了。

线性核函数的应用

导入数据集可视化

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from scipy.io import loadmat
from sklearn.svm import LinearSVC, SVC

raw_data = loadmat('data/ex6data1')
data = pd.DataFrame(raw_data['X'], columns=['X1', 'X2'])
data['y'] = raw_data['y']
print(data)

positive = data[data['y'].isin([1])]
negative = data[data['y'].isin([0])]
fig, ax = plt.subplots(figsize=(6,4))#定义图的大小
ax.scatter(positive['X1'], positive['X2'], s=50,  c='b', marker='o', label='Positive')
ax.scatter(negative['X1'], negative['X2'], s=50,  c='r', marker='x', label='Negative')
ax.legend()#在图形中加入颜色不同的备注
ax.set_xlabel('X1')
ax.set_ylabel('X2')
plt.show()

在这里插入图片描述
评估分类器性能

#下面有两种svm库的使用方法,但几乎都是同样的功能,因为SVC的核函数选为了 线性核函数
# clf = LinearSVC(C=100, loss='hinge', max_iter=1000)
clf = SVC(C=100, kernel='linear', gamma= 0.001)
clf.fit(data[['X1', 'X2']], data['y'])
print(clf.score(data[['X1', 'X2']], data['y']))#评估分类器性能


svc2 = LinearSVC(C=1, loss='hinge', max_iter=1000)
svc2.fit(data[['X1', 'X2']], data['y'])
print(svc2.score(data[['X1', 'X2']], data['y']))

结果如下:
在这里插入图片描述
两个分类结果。第一个表示全部分类正确了,但看下图就知道有些过拟合了。第二个较第一个稍低。

分类结果边界可视化

data['SVM 1 Confidence'] = clf.decision_function(data[['X1', 'X2']])

fig, ax = plt.subplots(figsize=(6,4))
ax.scatter(data['X1'], data['X2'], s=50, c=data['SVM 1 Confidence'], cmap='seismic')
ax.set_title('SVM (C=100) Decision Confidence')
# plt.show()


data['SVM 2 Confidence'] = svc2.decision_function(data[['X1', 'X2']])

fig, ax = plt.subplots(figsize=(6,4))
ax.scatter(data['X1'], data['X2'], s=50, c=data['SVM 2 Confidence'], cmap='seismic')
ax.set_title('SVM (C=1) Decision Confidence')
# plt.show()

分类结果:
在这里插入图片描述
可以看到第一张图中,红色的异常点也检测正确了
在这里插入图片描述
第二章图中,异常点判为了另外一类。但这样看着不太明显,我们试着画出来分类边界的线条吧。

画边界线

def visualize_boundary(clf,X, x_min, x_max, y_min, y_max): #x,y轴的取值范围
    h = .02
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))#在x,y轴上以0.02为间隔,生成网格点
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])#预测每个网格点的类别0/1
    Z = Z.reshape(xx.shape) #转型为网格的形状
    ax.scatter(X['X1'], X['X2'], s=50, c=data['SVM 1 Confidence'], cmap='seismic')  #这里我给第一张图画的边界,,也可以改成第一张图的哦,我太懒了不想改
    plt.contour(xx, yy,Z, level=[0],colors='r')  #等高线图 将0/1分界线(决策边界)画出
    plt.show()

visualize_boundary(clf,data, 0, 4.5, 1.5, 5)

结果如下:
在这里插入图片描述

高斯核函数的应用

这里找了第三种便捷绘制方法,我感觉这一种是最好的,以后就用这个吧。过程几乎一样,我就整体上代码了。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from scipy.io import loadmat

#定义高斯核函数验证其性能
def gaussian_kernel(x1, x2, sigma):
    return np.exp(-(np.sum((x1 - x2) ** 2) / (2 * (sigma ** 2))))

x1 = np.array([1.0, 2.0, 1.0])
x2 = np.array([0.0, 4.0, -1.0])
sigma = 2
# print(gaussian_kernel(x1, x2, sigma))

def visualize_boundary(clf, X, x_min, x_max, y_min, y_max): #x,y轴的取值范围
    h = .02
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))#在x,y轴上以0.02为间隔,生成网格点
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])#预测每个网格点的类别0/1
    Z = Z.reshape(xx.shape) #转型为网格的形状
    plt.contour(xx, yy,Z, level=[0],colors='r')  #等高线图 将0/1分界线(决策边界)画出来
#上面这一小部分是昨夜里要求验证的,和下面内容无关。


#导入训练示例2,并可视化
raw_data = loadmat('data/ex6data2')
data = pd.DataFrame(raw_data['X'], columns=['X1', 'X2'])
data['y'] = raw_data['y']
# print(data)

#可视化数据
positive = data[data['y'].isin([1])]
negative = data[data['y'].isin([0])]
fig, ax = plt.subplots(figsize=(6,4))#定义图的大小
ax.scatter(positive['X1'], positive['X2'], s=5,  c='b', marker='o', label='Positive')
ax.scatter(negative['X1'], negative['X2'], s=5,  c='r', marker='x', label='Negative')
ax.legend()#在图形中加入颜色不同的备注
ax.set_xlabel('X1')
ax.set_ylabel('X2')
plt.show()

X = raw_data['X']
y = raw_data['y'].flatten()
# print(X,y)

clf = SVC(C=100, kernel='rbf', gamma= 10, probability=True)
# # clf = SVC(C=100, gamma=10, probability=True)
clf.fit(X, y)
print(clf.score(data[['X1', 'X2']], data['y']))#评估分类器性能

#准备画图
plot_step = 0.02
# x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
# y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
x_min, x_max = 0, 1.05
y_min, y_max = 0.38, 1.02
xx,yy = np.meshgrid(np.arange(x_min, x_max, plot_step),
                    np.arange(y_min, y_max, plot_step))

Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
cs = plt.contourf(xx, yy, Z, camp=plt.cm.Paired)
plt.axis("tight")

class_name = "AB"
plot_colors = "rb"
for i, n, c in zip(range(2), class_name, plot_colors):
    idx = np.where(y == i)
    plt.scatter(X[idx, 0], X[idx, 1],s=1, c=c, cmap=plt.cm.Paired, label = "Class %s" %n)

plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.legend(loc='upper right')
plt.xlabel('x')
plt.ylabel('y')
plt.title('Decision Boundary')
plt.show()

结果如下:
在这里插入图片描述
在这里插入图片描述
这个真好看,哈哈

找最优参数

上代码,更简单

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import numpy as pd
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from scipy.io import loadmat

raw_data = loadmat('data/ex6data3.mat')

X = raw_data['X']
Xval = raw_data['Xval']
y = raw_data['y'].ravel()
yval = raw_data['yval'].ravel()

C_values = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]
gamma_values = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]

best_score = 0
best_params = {'C': None, 'gamma': None}

for C in C_values:
    for gamma in gamma_values:
        clf = SVC(C=C, gamma=gamma)
        clf.fit(X, y)
        score = clf.score(Xval, yval)

        if score > best_score:
            best_score = score
            best_params['C'] = C
            best_params['gamma'] = gamma

print(best_score, best_params)

结果如下:
在这里插入图片描述

垃圾邮件分类

这个和前面过程也几乎一样。

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from scipy.io import loadmat

spam_train = loadmat('data/spamTrain.mat')
spam_test = loadmat('data/spamTest.mat')
print(spam_train)

X = spam_train['X']
Xtest = spam_test['Xtest']
y = spam_train['y'].ravel()
ytest = spam_test['ytest'].ravel()
print(X.shape, y.shape, Xtest.shape, ytest.shape)

#使用所有默认参数
clf = SVC()    #什么都不填就是默认参数,也可以自己改,详情参考sklearn库中sklearn.svm.SVC函数的使用说明
clf.fit(X, y)
print('Training accuracy = {0}%'.format(np.round(clf.score(X, y) * 100, 2)))
print('Test accuracy = {0}%'.format(np.round(clf.score(Xtest, ytest) * 100, 2)))

结果如下:
在这里插入图片描述
可以自己在SVC函数里设置参数,试试结果。 OK,大功告成!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值