1. 程式人生 > >吳恩達機器學習作業Python實現(六):SVM支援向量機

吳恩達機器學習作業Python實現(六):SVM支援向量機

1 Support Vector Machines

1.1 Example Dataset 1

%matplotlib inline
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sb
from scipy.io import loadmat
from sklearn import svm

大多數SVM的庫會自動幫你新增額外的特徵 x0x_0 已經 θ0\theta_0,所以無需手動新增。

mat = loadmat('./data/ex6data1.mat')
print
(mat.keys()) # dict_keys(['__header__', '__version__', '__globals__', 'X', 'y']) X = mat['X'] y = mat['y']

def plotData(X, y):
    plt.figure(figsize=(8,5))
    plt.scatter(X[:,0], X[:,1], c=y.flatten(), cmap='rainbow')
    plt.xlabel('X1')
    plt.ylabel('X2')
    plt.legend() 
plotData(X, y)

output_5_1.png

def
plotBoundary(clf, X): '''plot decision bondary''' x_min, x_max = X[:,0].min()*1.2, X[:,0].max()*1.1 y_min, y_max = X[:,1].min()*1.1,X[:,1].max()*1.1 xx, yy = np.meshgrid(np.linspace(x_min, x_max, 500), np.linspace(y_min, y_max, 500)) Z = clf.predict(np.c_[xx.ravel(
), yy.ravel()]) Z = Z.reshape(xx.shape) plt.contour(xx, yy, Z)
models = [svm.SVC(C, kernel='linear') for C in [1, 100]]
clfs = [model.fit(X, y.ravel()) for model in models]
title = ['SVM Decision Boundary with C = {} (Example Dataset 1'.format(C) for C in [1, 100]]
for model,title in zip(clfs,title):
    plt.figure(figsize=(8,5))
    plotData(X, y)
    plotBoundary(model, X)
    plt.title(title)

output_9_2.png

output_9_4.png

可以從上圖看到,當C比較小時模型對誤分類的懲罰增大,比較嚴格,誤分類少,間隔比較狹窄。

當C比較大時模型對誤分類的懲罰增大,比較寬鬆,允許一定的誤分類存在,間隔較大。

1.2 SVM with Gaussian Kernels

這部分,使用SVM做非線性分類。我們將使用高斯核函式。

為了用SVM找出一個非線性的決策邊界,我們首先要實現高斯核函式。我可以把高斯核函式想象成一個相似度函式,用來測量一對樣本的距離,(x(i),y(j))(x^{(i)}, y^{(j)})

image.png

這裡我們用sklearn自帶的svm中的核函式即可。

1.2.1 Gaussian Kernel

def gaussKernel(x1, x2, sigma):
    return np.exp(- ((x1 - x2) ** 2).sum() / (2 * sigma ** 2))

gaussKernel(np.array([1, 2, 1]),np.array([0, 4, -1]), 2.)  # 0.32465246735834974

1.2.2 Example Dataset 2

mat = loadmat('./data/ex6data2.mat')
X2 = mat['X']
y2 = mat['y']
plotData(X2, y2)

output_16_1.png

sigma = 0.1
gamma = np.power(sigma,-2.)/2
clf = svm.SVC(C=1, kernel='rbf', gamma=gamma)
modle = clf.fit(X2, y2.flatten())
plotData(X2, y2)
plotBoundary(modle, X2)

output_17_1.png

1.2.3 Example Dataset 3

mat3 = loadmat('data/ex6data3.mat')
X3, y3 = mat3['X'], mat3['y']
Xval, yval = mat3['Xval'], mat3['yval']
plotData(X3, y3)

output_19_1.png

Cvalues = (0.01, 0.03, 0.1, 0.3, 1., 3., 10., 30.)
sigmavalues = Cvalues
best_pair, best_score = (0, 0), 0

for C in Cvalues:
    for sigma in sigmavalues:
        gamma = np.power(sigma,-2.)/2
        model = svm.SVC(C=C,kernel='rbf',gamma=gamma)
        model.fit(X3, y3.flatten())
        this_score = model.score(Xval, yval)
        if this_score > best_score:
            best_score = this_score
            best_pair = (C, sigma)
print('best_pair={}, best_score={}'.format(best_pair, best_score))
# best_pair=(1.0, 0.1), best_score=0.965
model = svm.SVC(C=1., kernel='rbf', gamma = np.power(.1, -2.)/2)
model.fit(X3, y3.flatten())
plotData(X3, y3)
plotBoundary(model, X3)

output_21_1.png

# 這我的一個練習畫圖的,和作業無關,給個畫圖的參考。
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm

# we create 40 separable points
np.random.seed(0)

X = np.array([[3,3],[4,3],[1,1]])
Y = np.array([1,1,-1])

# fit the model
clf = svm.SVC(kernel='linear')
clf.fit(X, Y)

# get the separating hyperplane
w = clf.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(-5, 5)
yy = a * xx - (clf.intercept_[0]) / w[1]

# plot the parallels to the separating hyperplane that pass through the
# support vectors
b = clf.support_vectors_[0]
yy_down = a * xx + (b[1] - a * b[0])
b = clf.support_vectors_[-1]
yy_up = a * xx + (b[1] - a * b[0])

# plot the line, the points, and the nearest vectors to the plane
plt.figure(figsize=(8,5))
plt.plot(xx, yy, 'k-')
plt.plot(xx, yy_down, 'k--')
plt.plot(xx, yy_up, 'k--')
# 圈出支援向量
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],
            s=150, facecolors='none', edgecolors='k', linewidths=1.5)
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.rainbow)

plt.axis('tight')
plt.show()

print(clf.decision_function(X))

output_22_0.png

[ 1.   1.5 -1. ]

2 Spam Classification

2.1 Preprocessing Emails

這部分用SVM建立一個垃圾郵件分類器。你需要將每個email變成一個n維的特徵向量,這個分類器將判斷給定一個郵件x是垃圾郵件(y=1)或不是垃圾郵件(y=0)。

take a look at examples from the dataset

with open('data/emailSample1.txt', 'r') as f:
    email = f.read()
    print(email)
> Anyone knows how much it costs to host a web portal ?
>
Well, it depends on how many visitors you're expecting.
This can be anywhere from less than 10 bucks a month to a couple of $100. 
You should checkout http://www.rackspace.com/ or perhaps Amazon EC2 
if youre running something big..

To unsubscribe yourself from this mailing list, send an email to:
[email protected]

可以看到,郵件內容包含 a URL, an email address(at the end), numbers, and dollar amounts. 很多郵件都會包含這些元素,但是每封郵件的具體內容可能會不一樣。因此,處理郵件經常採用的方法是標準化這些資料,把所有URL當作一樣,所有數字看作一樣。

例如,我們用唯一的一個字串‘httpaddr’來替換所有的URL,來表示郵件包含URL,而不要求具體的URL內容。這通常會提高垃圾郵件分類器的效能,因為垃圾郵件傳送者通常會隨機化URL,因此在新的垃圾郵件中再次看到任何特定URL的機率非常小。

我們可以做如下處理:

  1. Lower-casing: 把整封郵件轉化為小寫。
  2. Stripping HTML: 移除所有HTML標籤,只保留內容。
  3. Normalizing URLs: 將所有的URL替換為字串 “httpaddr”.
  4. Normalizing Email Addresses: 所有的地址替換為 “emailaddr”
  5. Normalizing Dollars: 所有dollar符號($)替換為“dollar”.
  6. Normalizing Numbers: 所有數字替換為“number”
  7. Word Stemming(詞幹提取): 將所有單詞還原為詞源。例如,“discount”, “discounts”, “discounted” and “discounting”都替換為“discount”。
  8. Removal of non-words: 移除所有非文字型別,所有的空格(tabs, newlines, spaces)調整為一個空格.
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import loadmat
from sklearn import svm
import re #regular expression for e-mail processing

# 這是一個可用的英文分詞演算法(Porter stemmer)
from stemming.porter2 import stem

# 這個英文演算法似乎更符合作業裡面所用的程式碼,與上面效果差不多
import nltk, nltk.stem.porter
def processEmail(email):
    """做除了Word Stemming和Removal of non-words的所有處理"""
    email = email.lower()
    email = re.sub('<[^<>]>', ' ', email)  # 匹配<開頭,然後所有不是< ,> 的內容,知道>結尾,相當於匹配<...>
    email = re.sub('(http|https)://[^\s]*', 'httpaddr', email )  # 匹配//後面不是空白字元的內容,遇到空白字元則停止
    email = re.sub('[^\s][email protected][^\s]+', 'emailaddr', email)
    email = re.sub('[\$]+', 'dollar', email)
    email = re.sub('[\d]+', 'number', email) 
    return email

接下來就是提取詞幹,以及去除非字元內容。

def email2TokenList(email):
    """預處理資料,返回一個乾淨的單詞列表"""
    
    # I'll use the NLTK stemmer because it more accurately duplicates the
    # performance of the OCTAVE implementation in the assignment
    stemmer = nltk.stem.porter.PorterStemmer()
    
    email = preProcess(email)

    # 將郵件分割為單個單詞,re.split() 可以設定多種分隔符
    tokens = re.split('[ \@\$\/\#\.\-\:\&\*\+\=\[\]\?\!\(\)\{\}\,\'\"\>\_\<\;\%]', email)
    
    # 遍歷每個分割出來的內容
    tokenlist = []
    for token in tokens:
        # 刪除任何非字母數字的字元
        token = re.sub('[^a-zA-Z0-9]', '', token);
        # Use the Porter stemmer to 提取詞根
        stemmed = stemmer.stem(token)
        # 去除空字串‘’,裡面不含任何字元
        if not len(token): continue
        tokenlist.append(stemmed)
            
    return tokenlist  

2.1.1 Vocabulary List(詞彙表)

在對郵件進行預處理之後,我們有一個處理後的單詞列表。下一步是選擇我們想在分類器中使用哪些詞,我們需要去除哪些詞。

我們有一個詞彙表vocab.txt,裡面儲存了在實際中經常使用的單詞,共1899個。

我們要算出處理後的email中含有多少vocab.txt中的單詞,並返回在vocab.txt中的index,這就我們想要的訓練單詞的索引。

def email2VocabIndices(email, vocab):
    """提取存在單詞的索引"""
    token = email2TokenList(email)
    index = [i for i in range(len(vocab)) if vocab[i] in token ]
    return index

2.2 Extracting Features from Emails

def email2FeatureVector(email):
    """
    將email轉化為詞向量,n是vocab的長度。存在單詞的相應位置的值置為1,其餘為0
    """
    df = pd.read_table('data/vocab.txt',names=['words'])
    vocab = df.as_matrix()  # return array
    vector = np.zeros(len(vocab))  # init vector
    vocab_indices = email2VocabIndices(email, vocab)  # 返回含有單詞的索引
    # 將有單詞的索引置為1
    for i in vocab_indices:
        vector[i] = 1
    return vector
vector = email2FeatureVector(email)
print('length of vector = {}\nnum of non-zero = {}'.format(len(vector), int(vector.sum())))
length of vector = 1899
num of non-zero = 45

2.3 Training SVM for Spam Classification

讀取已經訓提取好的特徵向量以及相應的標籤。分訓練集和測試集。

# Training set
mat1 = loadmat('data/spamTrain.mat')
X, y = mat1['X'], mat1['y']

# Test set
mat2 = scipy.io.loadmat('data/spamTest.mat')
Xtest, ytest = mat2['Xtest'], mat2['ytest']
clf = svm.SVC(C=0.1, kernel='linear')
clf.fit(X, y)

2.4 Top Predictors for Spam

predTrain = clf.score(X, y)
predTest = clf.score(Xtest, ytest)
predTrain, predTest
(0.99825, 0.989)

相關推薦

機器學習作業Python實現()SVM支援向量

1 Support Vector Machines 1.1 Example Dataset 1 %matplotlib inline import numpy as np import pandas as pd import matplotlib.pyplot

機器學習作業Python實現(一)線性迴歸

單變數線性迴歸 在本部分的練習中,您將使用一個變數實現線性迴歸,以預測食品卡車的利潤。假設你是一家餐館的執行長,正在考慮不同的城市開設一個新的分店。該連鎖店已經在各個城市擁有卡車,而且你有來自城市的利潤和人口資料。 您希望使用這些資料來幫助您選擇將哪個城市擴充

機器學習作業(五)支援向量

目錄 1)資料預處理 2)Scikit-learn支援向量機 3)決策邊界比較 4)非線性SVM 5)最優超引數 6)垃圾郵件過濾器 在本練習中,我們將使用支援向量機(SVM)來構建垃圾郵件分類器。 我們將從一些簡單的2D資料集開始使用SVM來檢視它們的工作原理。

機器學習總結(三)SVM支援向量(面試必考)

基本思想:試圖尋找一個超平面來對樣本分割,把樣本中的正例和反例用超平面分開,並儘可能的使正例和反例之間的間隔最大。 演算法推導過程: (1)代價函式:假設正類樣本y =wTx+ b>=+1,負

機器學習作業程式碼1

一:當訓練集為1維時 #進行資料分析所需庫,可以看做是對numpy工具的補充 import pandas as pd import numpy as np #應該把Seaborn視為matplotlib的補充,作圖所用工具,在大多數情況下使用seaborn就能做出很具有吸引力的圖,而使用matplo

演算法工程師修仙之路機器學習作業(一)

吳恩達機器學習筆記及作業程式碼實現中文版 第一個程式設計作業:單變數線性迴歸(python程式碼實現) 一元線性迴歸 問題描述 在本練習的這一部分中,您將使用只有單變數的線性迴歸方法預測餐車的利潤。 假設你是一家連鎖餐廳的執行長,正在

機器學習筆記 —— 19 應用舉例照片OCR(光學字符識別)

參考 https ocr 噪聲 也說 字符 www. 定位 cnblogs http://www.cnblogs.com/xing901022/p/9374258.html 本章講述的是一個復雜的機器學習系統,通過它可以看到機器學習的系統是如何組裝起來的;另外也說明了一

機器學習筆記 —— 19 應用舉例照片OCR(光學字元識別)

本章講述的是一個複雜的機器學習系統,通過它可以看到機器學習的系統是如何組裝起來的;另外也說明了一個複雜的流水線系統如何定位瓶頸與分配資源。 OCR的問題就是根據圖片識別圖片中的文字: 這種OCR識別的問題可以理解成三個步驟: 文字檢測 字元切分 字元識別 文字檢測 文字的檢測可以用行人的檢測來做

機器學習筆記(十)-推薦系統

第十七章推薦系統問題規劃    這一章中將討論推薦系統的有關內容,它是在機器學習中的一個重要應用。    機器學習領域的一個偉大思想:對於某些問題,有一些演算法可以自動地學習一系列合適的特徵,比起手動設

機器學習筆記59-向量化低秩矩陣分解與均值歸一化(Vectorization: Low Rank Matrix Factorization & Mean Normalization)

接受 span amp 14. 實現 新的 mean 情況 rank 一、向量化:低秩矩陣分解     之前我們介紹了協同過濾算法,本節介紹該算法的向量化實現,以及說說有關該算法可以做的其他事情。   舉例:1.當給出一件產品時,你能否找到與之相關的其它產品。2.一位用

機器學習數學原理(7)——SVM支援向量

機器學習數學原理(7)——SVM支援向量機 這篇博文筆者將預設讀者已經瞭解了最優間隔分類器以及泛化拉格朗日乘子法,如果部分讀者還不是很瞭解,我這裡給出前面一篇博文的連結《機器學習數學原理(6)——最優間隔分類器》。總之,這篇博文將不會再贅述相關的知識,而是直接給出其結論。 由於筆

周志華 《機器學習》之 第章(支援向量)概念總結

在之前就一直總是零零碎碎瞭解過這個熱及一時的統計學方法對樣本進行分類的支援向量機演算法。一直想系統的瞭解一下支援向量機這個很強的分類演算法,有幸在周老師的機器學習這本書中進行系統的學習。 這裡我只列出一些需要重點理解的概念,以方便以後自己進行回顧,在部落格中也

機器學習實戰【5】(SVM-支援向量

本部落格記錄《機器學習實戰》(MachineLearningInAction)的學習過程,包括演算法介紹和python實現。 SVM(支援向量機) SVM是一種分類演算法,通過對訓練集資料的分析找到最好的分隔平面,然後用該平面對新資料進行分類。本

機器學習 | 機器學習第四周程式設計作業(Python版本)

實驗指導書       下載密碼:u8dl 本篇部落格主要講解,吳恩達機器學習第四周的程式設計作業,作業內容主要是對手寫數字進行識別,是一個十分類問題,要求使用兩種不同的方法實現:一是用之前講過的邏輯迴歸實現手寫數字識別,二是用本週講的神經網路實現手寫數字

機器學習 | 機器學習第二週程式設計作業(Python版)

實驗指導書   下載密碼:hso0 本篇部落格主要講解,吳恩達機器學習第二週的程式設計作業,作業內容主要是實現單元/多元線性迴歸演算法。實驗的原始版本是用Matlab實現的,本篇部落格主要用Python來實現。   目錄 1.實驗包含的檔案 2.單元

機器學習 | 機器學習第三週程式設計作業(Python版)

實驗指導書  下載密碼:fja4 本篇部落格主要講解,吳恩達機器學習第三週的程式設計作業,作業內容主要是利用邏輯迴歸演算法(正則化)進行二分類。實驗的原始版本是用Matlab實現的,本篇部落格主要用Python來實現。   目錄 1.實驗包含的檔案 2.使用邏

機器學習 | 機器學習第八週程式設計作業(Python版)

實驗指導書   下載密碼:higl 本篇部落格主要講解,吳恩達機器學習第八週的程式設計作業,主要包含KMeans實驗和PCA實驗兩部分。原始實驗使用Matlab實現,本篇部落格提供Python版本。 目錄 1.實驗包含的檔案 2.KMeans實驗 3.K-me

機器學習 | 機器學習第七週程式設計作業(Python版)

實驗指導書  下載密碼:a15g 本篇部落格主要講解,吳恩達機器學習第七週的程式設計作業,包含兩個實驗,一是線性svm和帶有高斯核函式的svm的基本使用;二是利用svm進行垃圾郵件分類。原始實驗使用Matlab實現,本篇部落格提供Python版本。   目錄 1.

機器學習 | 機器學習週程式設計作業(Python版)

實驗指導書  下載密碼:4t4y 本篇部落格主要講解,吳恩達機器學習第六週的程式設計作業,作業內容主要是實現一個正則化的線性迴歸演算法,涉及本週講的模型選擇問題,繪製學習曲線判斷高偏差/高方差問題。原始實驗使用Matlab實現,本篇部落格提供Python版本。 目錄 1.實驗包

機器學習邏輯迴歸python實現(未正則化)[對應ex2-ex2data2.txt資料集]

寫在前面: ​ 1.筆記重點是python程式碼實現,不敘述如何推導。參考本篇筆記前,要有邏輯迴歸的基礎(熟悉代價函式、梯度下降、矩陣運算和python等知識),沒有基礎的同學可通過網易雲課堂上吳恩達老師的機器學習課程學習。網上也有一些對吳恩達老師課後作業的python實現,大多數都是用