一.SVM
什么是SVM?
SVM主要針對小樣本數(shù)據(jù)進行學習、分類和預測(有時也叫回歸)的一種方法,能解決神經(jīng)網(wǎng)絡不能解決的過學習問題,而且有很好的泛化能力
1.1 SVM原理
舉個例子:
好吧,故事是這樣子的:在很久以前的情人節(jié),大俠要去救他的愛人,但魔鬼和他玩了一個游戲。
魔鬼在桌子上似乎有規(guī)律放了兩種顏色的球,說:“你用一根棍分開它們?要求:盡量在放更多球之后,仍然適用?!?/p>
1.png
于是大俠這樣放,干的不錯?.png
然后魔鬼,又在桌上放了更多的球,似乎有一個球站錯了陣營.png
SVM就是試圖把棍放在最佳位置,好讓在棍的兩邊有盡可能大的間隙.png
現(xiàn)在即使魔鬼放了更多的球,棍仍然是一個好的分界線.png
增加難度
然后,在SVM 工具箱中有另一個更加重要的 trick。 魔鬼看到大俠已經(jīng)學會了一個trick,于是魔鬼給了大俠一個新的挑戰(zhàn).png
現(xiàn)在,大俠沒有棍可以很好幫他分開兩種球了,現(xiàn)在怎么辦呢?當然像所有武俠片中一樣大俠桌子一拍,球飛到空中。然后,憑借大俠的輕功,大俠抓起一張紙,插到了兩種球的中間.png
現(xiàn)在,從魔鬼的角度看這些球,這些球看起來像是被一條曲線分開了.png
再后來
無聊的大人們,把這些球叫做 「data」,把棍子 叫做 「classifier」, 最大間隙trick 叫做「optimization」, 拍桌子叫做「kernelling」, 那張紙叫做「hyperplane」
1.2 SVM實戰(zhàn):線性
直線斜率計算公式:k=(y2-y1)/(x2-x1)
1.導入
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from sklearn.svm import SVC
2.隨機生成數(shù)據(jù),并且進行訓練
np.random.seed(0)
X = np.r_[np.random.randn(20,2) - [2,2], np.random.randn(20,2)+[2,2]]
y = [0]*20 + [1]*20
clf = SVC(kernel='linear')
# 第一步:訓練
clf.fit(X,y)
3.提取系數(shù)獲取斜率
# 提取出系數(shù)
w = clf.coef_[0]
# 斜率 k=(y2-y1)/(x2-x1)
a = -w[0]/w[1]
4.線性方程的截距
# 分類邊界
xx = np.linspace(-5,5)
#intercept截距/X軸方向的系數(shù) == 線性方程的截距
yy = a*xx -(clf.intercept_[0])/w[1]
5.上邊界和下邊界
# 下邊界
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])
6.繪制圖形
# 畫出三個邊界
plt.figure(figsize=(12,8))
plt.plot(xx,yy,'k-')
plt.plot(xx,yy_down,'k--')
plt.plot(xx,yy_up,'k--',c = 'r')
# 畫出支持向量
plt.scatter(clf.support_vectors_[:,0],clf.support_vectors_[:,1],s=200)
# 畫出所有點
plt.scatter(X[:,0],X[:,1],c=y)

1.3 SVM實戰(zhàn):基于半徑(rbf)
1.導入
import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm
2.創(chuàng)造-3到3范圍的點以及meshgrid
xx, yy = np.meshgrid(np.linspace(-3, 3, 500),
np.linspace(-3, 3, 500))
np.random.seed(0)
X = np.random.randn(300, 2)
#xor異或
Y = np.logical_xor(X[:, 0] > 0, X[:, 1] > 0)
3.創(chuàng)造模型(rbf),訓練數(shù)據(jù)
clf = svm.SVC(kernel='rbf')
clf.fit(X, Y)
4.繪制圖形
plt.figure(figsize=(8,8))
# 樣本xy到分離超平面的距離
Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.imshow(Z,extent=(xx.min(), xx.max(), yy.min(), yy.max()),
cmap=plt.cm.PuOr_r)
#繪制輪廓
# contours = plt.contour(xx, yy, Z)
plt.scatter(X[:, 0], X[:, 1], s=30, c=Y, cmap=plt.cm.Paired,
edgecolors='k')
plt.axis('off')
plt.axis([-3, 3, -3, 3])
plt.show()

1.4 SVM實戰(zhàn):使用多種核函數(shù)對iris數(shù)據(jù)集進行分類
1.導入
from sklearn.svm import SVC
from sklearn.svm import LinearSVC
from sklearn import datasets
2.隨機生成數(shù)據(jù),并且進行訓練
iris = datasets.load_iris()
# 只取兩個特征(方便畫圖)
X = iris.data[:,:2]
y = iris.target
# 建立模型
svc_linear = SVC(kernel='linear')
svc_rbf = SVC(kernel='rbf')#Radial Based Function 基于半徑的函數(shù)
svc_poly = SVC(kernel='poly') # poly是多項式的意思
linear_svc = LinearSVC() # SVC(kernel = 'linear')相近方法更多,可以處理更多的數(shù)據(jù)
# 訓練模型
svc_linear.fit(X,y)
svc_rbf.fit(X,y)
svc_poly.fit(X,y)
linear_svc.fit(X,y)
3.圖片背景云點
# 網(wǎng)格密度
h = 0.02
# 設置x軸y軸的界限
x_min,x_max = X[:,0].min()-1, X[:,0].max()+1
y_min,y_max = X[:,1].min()-1, X[:,1].max()+1
# 得到網(wǎng)格的坐標
xx,yy = np.meshgrid(np.arange(x_min,x_max,h),
np.arange(y_min,y_max,h))
4.繪制圖形
# 設置圖片標題
titles = ['svc_linear',
'svc_rbf',
'svc_poly',
'linear_svc']
plt.figure(figsize=(12,8))
# 在2*2子圖中畫出四種SVC
for i,clf in enumerate((svc_linear,svc_rbf,svc_poly,linear_svc)):
plt.subplot(2,2,i+1)
Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])
Z = Z.reshape(xx.shape)
# 等高線以及背景
plt.contourf(xx,yy,Z,alpha=0.2,cmap = 'cool')
# 實際點的圖
plt.scatter(X[:,0],X[:,1],c=y,cmap='rainbow')
plt.title(titles[i])

1.5 使用SVM多種核函數(shù)進行回歸
1.導入
from sklearn.svm import SVR
import numpy as np
2.隨機生成數(shù)據(jù),并且進行訓練
#自定義樣本點
X = 5*np.random.rand(40,1)
X.sort(axis = 0)
y = np.sin(X).ravel()
#添加噪聲
y[::5] += 3*(0.5 - np.random.rand(8))
#建立模型
svr_linear = SVR(kernel='linear')
svr_rbf = SVR(kernel = 'rbf')
svr_poly = SVR(kernel = 'poly')
#訓練并預測
p_y_linear = svr_linear.fit(X,y).predict(X)
p_y_rbf = svr_rbf.fit(X,y).predict(X)
p_y_poly = svr_poly.fit(X,y).predict(X)
3.繪制圖形
# 畫圖
plt.figure(figsize=(12,8))
# 畫出真實樣本點
plt.scatter(X,y,c='k',label='data')
# 畫出預測曲線
plt.plot(X,p_y_linear,c='navy',label='linear')
plt.plot(X,p_y_rbf,c='r',label='rbf')
plt.plot(X,p_y_poly,c='g',label='poly')
plt.legend()

二.K-Means
什么是K-means?
K均值算法(K-means)聚類
關鍵詞:K個種子,均值
聚類的概念:一種無監(jiān)督的學習,事先不知道類別,自動將相似的對象歸到同一個簇中K-Means算法是一種聚類分析(cluster analysis)的算法,其主要是來計算數(shù)據(jù)聚集的算法,主要通過不斷地取離種子點最近均值的算法
K-Means算法的思想很簡單,對于給定的樣本集,按照樣本之間的距離大小,將樣本集劃分為K個簇。讓簇內(nèi)的點盡量緊密的連在一起,而讓簇間的距離盡量的大
2.1 K-Means原理
歐氏距離
歐氏距離.png
步驟圖
步驟圖.png
2.2 K-Means主要最重大的缺陷——都和初始值有關
K是事先給定的,這個K值的選定是非常難以估計的。很多時候,事先并不知道給定的數(shù)據(jù)集應該分成多少個類別才最合適。(ISODATA算法通過類的自動合并和分裂,得到較為合理的類型數(shù)目K)
K-Means算法需要用初始隨機種子點來搞,這個隨機種子點太重要,不同的隨機種子點會有得到完全不同的結果。(K-Means++算法可以用來解決這個問題,其可以有效地選擇初始點)
2.3 K-Means步驟總結
1、從數(shù)據(jù)中選擇k個對象作為初始聚類中心;
2、計算每個聚類對象到聚類中心的距離來劃分;
3、再次計算每個聚類中心;
4、計算標準測度函數(shù),直到達到最大迭代次數(shù),則停止,否則,繼續(xù)操作;
5、確定最優(yōu)的聚類中心
2.4 K-Means算法應用
看到這里,你會說,K-Means算法看來很簡單,而且好像就是在玩坐標點,沒什么真實用處。而且,這個算法缺陷很多,還不如人工呢。是的,前面的例子只是玩二維坐標點,的確沒什么意思。但是你想一下下面的幾個問題:
1)如果不是二維的,是多維的,如5維的,那么,就只能用計算機來計算了。
2)二維坐標點的X,Y 坐標,其實是一種向量,是一種數(shù)學抽象?,F(xiàn)實世界中很多屬性是可以抽象成向量的,比如,我們的年齡,我們的喜好,我們的商品,等等,能抽象成向量的目的就是可以讓計算機知道某兩個屬性間的距離。如:我們認為,18歲的人離24歲的人的距離要比離12歲的距離要近,鞋子這個商品離衣服這個商品的距離要比電腦要近,等等。
2.5 K-Means實戰(zhàn)
- make_blobs隨機生成點
1.導包隨機生成數(shù)據(jù)
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
from sklearn.datasets import make_blobs
#生成樣本點
X_train,y_train = make_blobs(n_samples=300,centers=4,cluster_std= 0.6, random_state = 9)
2.建立模型
# 建立模型
kmeans = KMeans(n_clusters=4)
kmeans.fit(X_train)
y_ = kmeans.predict(X_train)
3.畫圖
#畫圖
plt.figure(figsize = (12,8))
centers = kmeans.cluster_centers_
plt.scatter(X_train[:,0],X_train[:,1],c = y_)
plt.scatter(centers[:,0],centers[:,1],c = 'r',s = 100,alpha = 0.4)

- 三問中國足球幾多愁
1.導包讀取數(shù)據(jù)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from mpl_toolkits.mplot3d import Axes3D
from sklearn.cluster import KMeans
data = pd.read_csv('../data/AsiaZoo.txt',header = None)
2.處理數(shù)據(jù)修改列名
#處理數(shù)據(jù),添加列名
data.columns = ["國家","2006世界杯","2010世界杯","2007亞洲杯"]
3.建立模型
#使用K-Means進行數(shù)據(jù)處理
kMeans = KMeans(n_clusters=3)
X_train = data[['2006世界杯','2010世界杯','2007亞洲杯']]
y_ = kMeans.fit(X_train).predict(X_train)
4.根據(jù)模型將這些國家按照水平進行分類
country = data['國家']
for i in range(3):
ind = np.argwhere(kMeans.predict(X_train) == i)
result = country[ind.ravel()]
for i in result.index:
print(result[i],end = ' ')
print('\n')
#輸出結果是:
伊朗 沙特 烏茲別克斯坦 巴林 朝鮮
日本 韓國
中國 伊拉克 卡塔爾 阿聯(lián)酋 泰國 越南 阿曼 印尼
5.畫圖
#繪制三維立體圖,將各個國家畫到3D圖中
centers = kMeans.cluster_centers_#KMeans算法得到的中心店
x,y,z = data['2006世界杯'],data['2010世界杯'],data['2007亞洲杯']
plt.figure(figsize = (12,8))
ax=plt.subplot(111,projection='3d')
ax.scatter3D(x,y,z,c = kMeans.predict(X_train),cmap='cool')
ax.scatter3D(centers[:,0],centers[:,1],centers[:,2],c = kMeans.predict(centers),s = 300,cmap = "rainbow")
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
plt.show()

- K-Means常見錯誤
1.導包
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
2.建立樣本點
# 建立樣本點
n_samples = 1500
random_state = 170
#默認情況下make_blobs有三個中心點
X,y = make_blobs(n_samples=n_samples,random_state=random_state)
第一種錯誤:incorrect number of cluster
#第一種錯誤,k值不合適,make_blobs默認中心點三個
y_ = KMeans(n_clusters=2).fit_predict(X)
#繪制圖形
plt.figure(figsize = (12,8))
plt.subplot(221)
plt.scatter(X[:,0],X[:,1],c = y_)

第二種錯誤:數(shù)據(jù)偏差
#第二種錯誤,數(shù)據(jù)偏差
trans = [[0.6,-0.6],[-0.4,0.8]]
X2 = np.dot(X,trans)
y2_ = KMeans(n_clusters=3).fit_predict(X2)
#繪制圖形
plt.figure(figsize = (12,8))
plt.subplot(222)
plt.scatter(X2[:,0],X2[:,1],c = y2_)

第三種錯誤:數(shù)據(jù)標準差不同
# 第三個錯誤:標準偏差
X3,y3 = make_blobs(n_samples=n_samples,
cluster_std = [1.0,2.5,0.5],
random_state = random_state)
y3_ = KMeans(n_clusters=3).fit_predict(X3)
plt.figure(figsize = (12,8))
plt.subplot(223)
plt.scatter(X3[:,0],X3[:,1],c=y3_)
plt.title('failed 3: unequal std')

第四種錯誤:樣本數(shù)量不同
# 第四個錯誤:樣本數(shù)量不同
X4 = np.vstack((X[y==0][:500],X[y==1][:100],X[y==2][:10]))
y4_ = KMeans(n_clusters=3).fit_predict(X4)
plt.figure(figsize = (12,8))
plt.subplot(224)
plt.scatter(X4[:,0],X4[:,1],c=y4_)
plt.title('failed 4: unequal number of samples')

2.6 K-Means圖片顏色點分類
1.導包
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.metrics import pairwise_distances_argmin
from sklearn.datasets import load_sample_image
from sklearn.utils import shuffle
n_colors = 64
2.加載圖片/創(chuàng)建模型/訓練數(shù)據(jù)/獲取labels
# 加載圖片
china = load_sample_image("china.jpg")
# 圖片顏色值轉(zhuǎn)換成[0,1]之間float類型數(shù)據(jù)
china = np.array(china, dtype=np.float64) / 255
# 將3D的圖片數(shù)據(jù)轉(zhuǎn)換成2D數(shù)組.
w, h, d = china.shape
image_array = np.reshape(china, (w * h, d))
#使用shuffle打亂數(shù)據(jù),并進行訓練
image_array_sample = shuffle(image_array, random_state=0)[:1000]
kmeans = KMeans(n_clusters=n_colors, random_state=0).fit(image_array_sample)
# 獲取標簽點
labels = kmeans.predict(image_array)
3.使用pairwise_distances_argmin算法生成隨機labels
codebook_random = shuffle(image_array, random_state=0)[:n_colors]
labels_random = pairwise_distances_argmin(codebook_random,image_array,axis=0)
4.創(chuàng)造方法,重新合成圖片
def recreate_image(codebook, labels, w, h):
d = codebook.shape[1]
image = np.zeros((w, h, d))
label_idx = 0
for i in range(w):
for j in range(h):
image[i][j] = codebook[labels[label_idx]]
label_idx += 1
return image
5.數(shù)據(jù)可視化
# 數(shù)據(jù)可視化
plt.figure(1)
plt.clf()
ax = plt.axes([0, 0, 1, 1])
plt.axis('off')
plt.title('Original image (96,615 colors)')
plt.imshow(china)
plt.figure(2)
plt.clf()
ax = plt.axes([0, 0, 1, 1])
plt.axis('off')
plt.title('Quantized image (64 colors, K-Means)')
plt.imshow(recreate_image(kmeans.cluster_centers_, labels, w, h))
plt.figure(3)
plt.clf()
ax = plt.axes([0, 0, 1, 1])
plt.axis('off')
plt.title('Quantized image (64 colors, Random)')
plt.imshow(recreate_image(codebook_random, labels_random, w, h))
plt.show()












