大數據挖掘複習小記

前言

本文基於教材《大數據挖掘與應用》王振武,出於期末複習目的,對部分算法利用python進行實現,順便學習numpy構建思惟導圖,幫助理解。
全部代碼、結果都以jupyter的形式放在了github上。
題型

選擇題和判斷題可能從裏面出,題目與答案的word版一樣放入了github中。html

第1章 大數據簡介


本章主要考填空題:python

數據規律化

分類結果評價

混淆矩陣:運用於二分類問題git

(真實)/(預測) 0 1 總計
0 預測0正確(TN) 預測0錯誤(FP) P(YES)
1 預測1錯誤(FN) 預測1正確(TP) N(NO)
總計 P' N' P+N

批量(評價)指標

  • 批量指標
    書裏沒有、PPT沒有、上課沒聽=全靠谷歌
    谷歌只找到AML,批量預測是指,當您想要一次性爲一組觀察生成預測,而後對特定百分比或特定數量的觀察採起操做時,批量預測很是有用。一般狀況下,您對於此類應用程序沒有低延遲要求。例如,當您想要決定將哪些客戶做爲某個產品廣告活動目標的一部分時,您能夠得到全部客戶的預測分數,排序模型預測來肯定哪些客戶最有可能購買,而後能夠定位最可能購買客戶的前 5%。
    批量預測指標是指,用戶建立批量預測後,它會提供兩個指標:Records seen 和 Records failed to process。Records seen 說明 Amazon ML 在運行您的批量預測時查看多少條記錄。Records failed to process 說明 Amazon ML 沒法處理多少條記錄。
  • 評價指標

查重率(查全率)與查準率

  • 查重率
    通常指論文中與現有論文中的重合度,這裏多是指預測出的模型之間的類似度?
  • 查全率
    查全率 = 召回率 = 正確識別的正樣本總數 / 測試集中存在的正樣本總數 = \({\frac {TP} {TP+FN}}\)
  • 查準率
    查準率 = 精準率 = 正確識別的正樣本總數 / 識別爲正樣本的個體總數 = \({\frac {TP} {TP+FP}}\)
    注意查準率與準確率的區別,準確率 = 正確識別爲正+負樣本的個體總數/測試集中樣本老是 =\({\frac {TP+TN}{TP+FN+FP+TN}}\)

第2章 數據預處理技術

數據集成

定義:合併多個數據源中的數據,存放在一個一致的數據儲存(如數據倉庫)中。github

數據變換

定義:將數據轉換或統一成適合於挖掘的形式。算法

輪廓加權

修正係數=\(w_{nr}=w_d * {\frac N {n_r}}={\frac N n}*{\frac n {n_r}}\)bootstrap

  • 統計表:
    數組

  • 修正後統計表:
    網絡

  • 修正後比例:
    app

分箱

  • 利用np.split對數組分割
    dom

  • 平均值平滑
    對每一行設爲其行平均值

  • 邊界平滑
    對每一行設爲其round(\({\frac {索引} {每行元素個數}}\))向上取整的值

規範化

d = np.array([200,300,400,600,1000])

最小-最大規範化

\(min=0,max=1\)
(d.max() - d) / (d.min() - d) * (1.0 - 0.0)

z-score規範化

\({\frac {{原值}-{均值}} {標準差}}\)
(d - np.average(d)) / np.std(d)

z-score規範化2

\({\frac {{原值}-{均值}} {平均絕對誤差}}\)
(d - np.average(d)) / np.mean(np.absolute(d - np.mean(d)))

小數定標規範化

\({\frac {原值}{數組絕對值後的最大值對10求導向上取整再對10求冪}}\)

import math
d / math.pow(10, math.ceil(math.log(np.max(np.abs(d)), 10)))

數據規約

主要考名詞解釋

數據壓縮

數據壓縮是指使用數據編碼或變換以便將原始數據集合成一個較小的數據集合。

數值規約

數值規約是指選擇替代的、「較小的」數據表示形式減小數據量。

特徵選擇與特徵提取

  • 區別:特徵選擇是指從一組數量爲N的特徵中選擇出一組數量爲M的最優特徵(N>M),特徵值不會被改變;特徵提取則是利用已有特徵參數構造一個較低維數的特徵空間,將原始特徵中蘊含的有用信息映射到少數幾個特徵上,特徵值會發生改變。
  • 聯繫:二者都是用來獲取對分類識別具備重要做用的特徵的方法。

第3章 關聯規則挖掘

概念

  • 對於關聯規則挖掘,舉個最簡單的例子:
    某超市查看銷售記錄後發現,購買肥宅快樂水的人有很大概率購買薯片。
  • 錯誤理解:關聯規則挖掘過程是發現知足最小支持度的全部項集表明的規則。
    正確理解:關聯規則挖掘過程是發現知足最小支持度的全部項集表明,再利用表明生成生成須要的關聯規則,根據用戶設定的最小置信度進行取捨,最後獲得強關聯規則。
  • 對於給定頻繁項集,生成關聯規則
    定義指出頻繁項集的全部非空子集也必定是頻繁項集。
    例題:設\(X=\{1,2,3\}\)是頻繁項集,則可由X產生()個關聯規則
    • 對於頻繁項集X,產生X的全部非空子集;
    • 對於X的每一個非空子集s,若是\({\frac {sup(X)} {sup(s)}} \ge {minsup}\),則生成關聯規則$s \Longrightarrow X-s $
    • 對於本題,生成非空子集\(\{1\},\{2\},\{3\},\{1,2\},\{2,3\},\{1,3\}\)(不包括自身),可生成6個關聯規則
      \(\{1\} \Longrightarrow \{2, 3\}\)
      \(\{2\} \Longrightarrow \{1, 3\}\)
      \(\{3\} \Longrightarrow \{1, 2\}\)
      \(\{1, 2\} \Longrightarrow \{3\}\)
      \(\{1, 3\} \Longrightarrow \{2\}\)
      \(\{2, 3\} \Longrightarrow \{1\}\)

Apriori

原理書上說的很明白了,直接經過例題理解。

例題

利用Apriori算法計算頻繁項集能夠有效下降計算頻繁集的時間複雜度。在如下的購物籃中產生支持度不小於3的候選3-項集,在候選2-項集中須要剪枝的是()
ID 項集
1 麪包、牛奶
2 麪包、尿布、啤酒、雞蛋
3 牛奶、尿布、啤酒、可樂
4 麪包、牛奶、尿布、啤酒
5 麪包、牛奶、尿布、可樂
A、啤酒、尿布
B、啤酒、麪包
C、麪包、尿布
D、啤酒、牛奶

  • 導入數據:
import numpy as np 
data = np.array([['麪包','牛奶'],
        ['麪包','尿布','啤酒','雞蛋'],
        ['牛奶','尿布','啤酒','可樂'],
        ['麪包','牛奶','尿布','啤酒'],
        ['麪包','牛奶','尿布','可樂']])
min_support = 3
data
  • 第一次掃描:
    • 生成候選1-項集:
C1 = set()
for t in data:
    for item in t:
        item_set = frozenset([item])
        C1.add(item_set)
C1

* 計算支持度計數:
item_count = {}
for t in data:
    for item in C1:
        if item.issubset(t):
            if item not in item_count:
                item_count[item] = 1
            else:
                item_count[item] += 1
for item in item_count:
    print(item,item_count[item])

* 根據支持度計數生成頻繁1-項集
for item in item_count:
    if(item_count[item]<min_support):
        C1.remove(item)
C1

  • 第二次掃描:
    • 生成C1的笛卡兒積並減枝:
      減枝:對於數據集L與生成的項集S,若是L-S不在L中,則認爲S不是頻繁項集。
Clist = list(C1)
C2 = set()
for i in range(len(Clist)):
    for j in range(i+1,len(Clist)):
        Ctmp = Clist[i]|Clist[j]
        # 檢查是不是頻繁項集
        check = 1
        for item in Ctmp:
            sub_Ck = Ctmp - frozenset([item])
            if sub_Ck not in Clist:
                check = 0
        if check:
            C2.add(Ctmp)
C2


- 根據支持度計數生成頻繁2-項集

item_count = {}
for t in data:
    for item in C2:
        if item.issubset(t):
            if item not in item_count:
                item_count[item] = 1
            else:
                item_count[item] += 1
for item in item_count:
    print(item,item_count[item])
for item in item_count:
    if(item_count[item]<min_support):
        C2.remove(item)
C2


減去的是BD。

  • 重複以上過程,直到不存在頻繁項集。

第4章 邏輯迴歸

說到邏輯迴歸,昨天刷V2的時候纔看到一個帖子工做兩年的同事不知道邏輯迴歸是什麼,這個正常嗎?
因爲本章不考應用題,僅羅列概念。

注意:分類和迴歸均可用於預測,分類的輸出是離散的類別值,而回歸的輸出是連續數值。

迴歸

迴歸是指研究一組隨機變量和另外一組變量之間關係的統計方法,又稱多重回歸分析。

線性迴歸

線性迴歸是指利用稱爲線性迴歸方程的最小平方函數對一個或多個自變量與因變量之間關係進行建模的一種迴歸分析。

邏輯迴歸

  • 二分類邏輯迴歸
    邏輯迴歸的本質上是線性迴歸,只是在特徵到結果的映射中加入了一層函數映射,即先把特徵線性求和,而後使用邏輯迴歸函數\(g(z)\)做爲最終假設函數預測。
  • 多分類邏輯迴歸

第5章 KNN算法

概念

KNN算法又稱K-最近鄰算法,根據距離函數計算待分類樣本X和每一個訓練樣本之間的距離(做爲類似度),選擇與待分類樣本距離最小的K個樣本做爲X的K個最近鄰,最後以X的K個最近鄰中的大多數樣本所屬的類別做爲X的類別。

注意:

  • KNN不是基於全局信息進行預測的,只基於最近鄰的信息。
  • KNN可以較好地避免樣本的不平衡問題。
  • KNN最近鄰在樣本較少但典型性好的狀況下效果較好

例題1

有下列數據集,對於測試樣本\(T=\{18,8\}\),求所屬類別

序號 特徵1 特徵2 類別
T1 2 4 L1
T1 4 3 L2
T1 10 6 L3
T1 12 9 L2
T1 3 11 L3
T1 20 7 L2
T1 22 5 L2
T1 21 10 L1
T1 11 2 L3
T1 24 1 L1
  • 求歐幾里得距離:
import numpy as np
data = np.array([[2,4],[4,3],[10,6],[12,9],[3,11],[20,7],[22,5],[21,10],[11,2],[24,1]])
f = np.array([1,2,3,2,3,2,2,1,3,1])
T = np.array([18,8])
np.linalg.norm(T-data,ord=2,axis=1)

  • 令K=4,求最近樣本
k = 4
s = np.argsort(np.linalg.norm(T-data,ord=2,axis=1))[:k]
s

  • 查看樣本標籤
f[s]

  • 出現最多的標籤
np.argmax(np.bincount(f[s]))

例題2

k=5,數據集以下,對\(x=(1,2)\)分類

經過np.random()隨機生成數據:
n = 40
x = np.random.rand(n, 2) * 2
y = np.random.randint(1,4,size=n)
for i in range(len(x)):
    print("| $T_{"+str(i+1)+"}$ |",x[i][0],"|",x[i][1],"|",y[i],"|")
實例 橫座標 縱座標 類別
\(T_{1}\) 1.6786053339467983 0.15487473902042592 3
\(T_{2}\) 1.903750045541173 1.6775903335564164 2
\(T_{3}\) 0.15144619402840243 1.543485488927614 1
\(T_{4}\) 1.7015965993474789 1.552612092889784 3
\(T_{5}\) 1.9723048073918905 1.8052157775896671 3
\(T_{6}\) 0.7477259494384572 1.433438461194146 1
\(T_{7}\) 1.9302135013005466 1.9269776190658305 1
\(T_{8}\) 0.24207606669714932 1.894010458348885 2
\(T_{9}\) 0.21842554513045265 1.9478022428563655 1
\(T_{10}\) 1.7494723363303561 0.7672192141953507 3
\(T_{11}\) 1.9906629300385918 1.0869545317058076 1
\(T_{12}\) 1.63510361868541 0.8617001535631279 3
\(T_{13}\) 0.6459535122987747 1.0827522985620026 2
\(T_{14}\) 0.3144944541356516 1.9091634904941777 1
\(T_{15}\) 1.5689608732625806 0.39157113233171503 2
\(T_{16}\) 1.8363603823958718 1.2276694755874005 2
\(T_{17}\) 1.4337847229694787 1.8034165435084824 1
\(T_{18}\) 0.45600475381462724 0.3148736825002354 1
\(T_{19}\) 0.42574632497710296 0.5997987868811052 2
\(T_{20}\) 1.1773573959790524 1.748304458676117 2
\(T_{21}\) 1.6423369352181407 0.37773395675275623 1
\(T_{22}\) 1.7097476306439856 1.9885829599019398 3
\(T_{23}\) 0.24618239172597223 0.07728932157603396 2
\(T_{24}\) 1.7603811296081917 1.748070452804373 2
\(T_{25}\) 0.002840121920356653 1.2658785281393257 3
\(T_{26}\) 1.8250450796924662 0.9212481743931855 3
\(T_{27}\) 0.27403996814324993 1.5629091001024709 1
\(T_{28}\) 0.4159278127296058 0.8888387282888994 2
\(T_{29}\) 1.7620478294700856 1.2516409761386298 3
\(T_{30}\) 0.4351390216463453 0.03836283116041028 3
\(T_{31}\) 1.1043330594244645 0.8946100006511641 1
\(T_{32}\) 1.2059961685894143 1.891497200080938 3
\(T_{33}\) 0.6245753790375235 1.6229014671236641 2
\(T_{34}\) 0.7155919663569039 0.7721262392930481 1
\(T_{35}\) 0.9074113329307563 0.12869596969464703 1
\(T_{36}\) 0.85636723383494 0.8891063898237037 1
\(T_{37}\) 0.375263657366401 0.3075941820847998 1
\(T_{38}\) 1.2824196407500417 0.8380355595664228 2
\(T_{39}\) 0.9577673955193708 1.4249046312912836 3
\(T_{40}\) 0.14893382442377834 1.783124207544456 1
  • 分類結果:
k = 5
T = (1,2)
s = np.argsort(np.linalg.norm(T-x,ord=2,axis=1))[:k]
np.bincount(y[s])

第6章 樸素貝葉斯

概念

貝葉斯方法是一種研究不肯定性的推理方法,不肯定性經常使用貝葉斯機率表示,它是一種主觀機率

  • 注意:
    • Bayes法是一種在已知先驗機率與類條件機率的狀況下的模式分類方法,待分樣本的分類結果取決於各種域中樣本的全體
    • Bayes法不是基於規則的,而是基於機率的分類方法。
    • Bayes法不能避免樣本中不平衡的問題。

Bayes

樸素貝葉斯能夠被認爲機率統計中事件A發生的前提下B發生的機率,即\(P(B|A)={\frac {P(A)∗P(B|A)} {P(B)}}\)

序號 家庭經濟情況 月收入 購買汽車
1 通常 優秀 10
2 優秀 12
3 通常 優秀 6
4 通常 良好 8.5
5 通常 良好 9
6 通常 優秀 7.5
7 通常 22
8 通常 通常 9.5
9 通常 良好 7
10 良好 12.5
  • 導入數據
import numpy as np
data = np.array([['通常', '優秀', 10, 1],
        ['好', '優秀', 12, '1'],
        ['通常', '優秀', 6, '1'],
        ['通常', '良好', 8.5, '0'],
        ['通常', '良好', 9, '0'],
        ['通常', '優秀', 7.5, '1'],
        ['好', '通常', 22, '1'],
        ['通常', '通常', 9.5, '0'],
        ['通常', '良好', 7, '1'],
        ['好', '良好', 12.5, '1']])
data
  • 計算先演機率
p_1 = np.sum(data=='1')/len(data)
p_0 = np.sum(data=='0')/len(data)
p_1,p_0

  • 計算條件機率
X = np.array(['通常','優秀','12'])
p_1_s = 1
p_0_s = 1
data_1 = data[data[:,3]=='1'] # 購買汽車的訓練數據
data_0 = data[data[:,3]=='0'] # 不買汽車的訓練數據
for i,x in enumerate(X):
    print(x, np.sum(data_1==x),np.sum(data_0==x))
    p_1_s *= np.sum(data_1==x)/len(data)
    p_0_s *= np.sum(data_0==x)/len(data)
p_1_s*p_1,p_0_s*p_0


認爲該測試樣本的預測結果爲1。

第7章 隨機森林算法

7醬昨天沒上場

概念

隨機森林方法是一種統計學習理論,它利用bootstrap重抽樣方法從原始樣本中抽取多個樣本,對每一個bootstrap樣本進行決策樹建模,而後組合多棵決策樹的預測,經過投票得出最終預測結果。

考完補足隨機森林算法可視化例子

第8章 支持向量機(SVM)

看到名字就想到AC自動機

概念

支持向量機根據有限的樣本信息在模型的複雜性和學習能力間尋求最佳折中,以期得到最好的推廣能力。
wiki上的解釋比書上好懂多了。

  • svm不能避免樣本之間的不平衡問題
  • 對於SVM分類算法,待分樣本集中的大部分樣本不是支持向量,移去或者減小這些樣本對分類結果沒有影響。(由於這些向量距離最大間隔超平面較遠)
  • SVM是這樣一個分類器,他尋找具備最大邊緣的超平面,所以它也常常被稱爲最小邊緣分類器3
  • logistic核函數不是SVM的核函數
  • 樣本->支持向量

    對於n點測試集\((\overrightarrow{x_1},y_1),\dotso,(\overrightarrow{x_n},y_n)\),其中\(y_i\)的取值是1或-1,爲了把\(y_i= 1\)\(y_i= -1\)的點分開,找到一條函數爲\(\overrightarrow x * \overrightarrow w +b=0\)的線,由它生成的超平面知足全部的點離該超平面足夠遠。
    若是這些訓練數據是線性可分的,能夠選擇分離兩類數據的兩個平行超平面,使得它們之間的距離儘量大。在這兩個超平面之間的區域被稱爲「間隔」,最大間隔超平面是位於它們正中間的超平面。
    這些超平面能夠由方程族:\({ {\vec {w}}\cdot {\vec {x}}-b=1\,}\)\({ {\vec {w}}\cdot {\vec {x}}-b=-1\,}\)表示。
    這超平面之間的距離是 \({ {\tfrac {2}{\|{\vec {w}}\|}}}\),要使間隔最大,\({ \|{\vec {w}}\|}\)應當儘量的小。同時爲了使得樣本數據都在超平面的間隔區以外,對於全部的 \({ i}\) 應知足:
    \({ {\vec {w}}\cdot {\vec {x}}_{i}-b\geq 1,}\)\({ y_{i}=1}\)
    \({ {\vec {w}}\cdot {\vec {x}}_{i}-b\leq -1,}\)\({ y_{i}=-1.}\)
    這些約束約束條件代表每一個數據點都必須位於間隔的正確一側。
    這兩個式子也能夠寫做:\({ y_{i}({\vec {w}}\cdot {\vec {x}}_{i}-b)\geq 1,\quad {\text{ for all }}1\leq i\leq n.\qquad \qquad (1)}\)
    也就是說,當\({ y_{i}({\vec {w}}\cdot {\vec {x_{i}}}-b)\geq 1}\)時,最小化 \({ \|{\vec {w}}\|}\),對於 \({ i=1,\,\ldots ,\,n}\)
    該方程的解 \(\vec w\)\(b\) 決定了分類器 \({ {\vec {x}}\mapsto \operatorname {sgn}({\vec {w}}\cdot {\vec {x}}-b)}\)
    因而可知,最大間隔超平面是由最靠近它的 \({ {\vec {x}}_{i}}\)肯定的。這些 \({ {\vec {x}}_{i}}\)叫作支持向量。

第9章 人工神經網絡算法(BP)

概念

人工神經網絡是一種模仿生物神經網絡的結構和功能的數學模型或計算模型,用於對函數進行估計或近似。這裏僅對反向傳播算法(BP)進行說明
算法分爲兩個階段

  • 第一階段輸入信息從輸入層經隱含層計算各單元的輸出值。
  • 第二階段輸出偏差逐層向前算出各隱含各單元的偏差,並由此偏差修正權值。
  • 輸入層-隱含層-輸出層公式:
    輸入層\(O_i=x_i,i=0,1,2,...,I-1\)
    隱含層\({net}_j={\sum_{i=0}^{I}{v_{ij}O_i}}\)
    相比WIKI知乎上講的比較好。

例9.2

\(x_1\) \(x_2\) \(x_31\) \(x_{14}\) \(x_{15}\) \(x_{24}\) \(x_{25}\) \(x_{34}\) \(x_{35}\) \(x_{46}\) \(x_{56}\) \(\theta_4\) \(\theta_5\) \(\theta_6\)
1 0 1 0.2 -0.3 0.4 0.1 -0.5 0.2 -0.3 -0.2 -0.4 0.2 0.1
  • 計算各隱含層以及輸出層的輸入、輸出值
    公式
    • 輸入層:\(O_i=x_o,(i=0,1,2,...,I-1)\)
    • 隱含層:
      輸入爲\(x_j = net_j=\sum_{i=0}^I{v_{ij}*O_i}+\theta_j\)
      輸出爲\(O_j=f(net_j)\)
      單極Sigmoid函數做爲f
      則輸出爲\(O_j=f(net_j)=\frac{1}{1+e^{-net_j}}\)
    • 輸出層與隱含層同理。
      對本題進行解析:
結點 網格輸入值 輸出值
4 \(x_1*x_{14}+x_2*x_{24}+x_3*x_{34}+\theta_4=1*0.2+0*0.4+1*-0.5-0.4=-0.7\) $\frac {1} {1+e^{0.7}}=0.332 $
5 \(x_1*x_{15}+x_2*x_{25}+x_3*x_{35}+\theta_5=1*-0.3+0*0.1+1*0.2+0.2=0.1\) $\frac {1} {1+e^{-0.1}}=0.1 $
6 \(o_4*x_{46}+o_5*x_{56}+\theta_6=-0.3*0.332+-0.2*0.525+0.1=-0.105\) \(\frac {1} {1+e^{0.105}}\)
  • 反推各層修正係數
    首先對\(f(net_j)=\frac{1}{1+e^{-net_j}}\)(求導)[https://zs.symbolab.com/solver/derivative-calculator/\frac{d}{dx}\left(\frac{1}{1%2Be^{-x}}\right)?or=sug]
    化簡後\(=\frac{1}{1+e^{-net_j}}*\frac{e^{-net_j}}{1+e^{-net_j}}=\frac{1}{1+e^{-net_j}}*(1-\frac{1}{1+e^{-net_j}})=f(net_j)*(1-f(net_j))\)
    計算偏差對權重 {\displaystyle w_{ij}} w_{{ij}} 的偏導數是兩次使用鏈式法則獲得的:
    \({\frac {\partial E}{\partial w_{{ij}}}}={\frac {\partial E}{\partial o_{j}}}{\frac {\partial o_{j}}{\partial {\mathrm {net_{j}}}}}{\frac {\partial {\mathrm {net_{j}}}}{\partial w_{{ij}}}}\)
    在右邊的最後一項中,只有加權和\({\displaystyle \mathrm {net_{j}} }\)取決於${\displaystyle w_{ij}} \(,所以 \){\displaystyle {\frac {\partial \mathrm {net_{j}} }{\partial w_{ij}}}={\frac {\partial }{\partial w_{ij}}}\left(\sum {k=1}^{n}w{kj}o_{k}\right)=o_{i}}$.
    神經元 \({\displaystyle j}\)的輸出對其輸入的導數就是激活函數的偏導數
    \({\frac {\partial o_{j}}{\partial {\mathrm {net_{j}}}}}={\frac {\partial }{\partial {\mathrm {net_{j}}}}}\varphi ({\mathrm {net_{j}}})=\varphi ({\mathrm {net_{j}}})(1-\varphi ({\mathrm {net_{j}}}))\)
    偏差函數:\(\delta=f'(net_j)\sum_{k=0}^{K-1}\delta_k*w_{jk}\)
    輸出層:\(\varDelta w_{jk}=\eta O_j(d_k-O_k)f'(net_j)=\eta O_j(d_k-O_k)*O_k(1-O_k)\)
    隱含層:\(\varDelta v_{jk}=\eta *f'(net_j)\sum_{k=0}^{K-1}\delta_kw_{jk}*O_i\)
結點 係數修正 權係數變化值
6 \(\eta=f'(net_6)*E=O_6*(1-O_6)*(1-O_6)\) 0.1311
5 \(\varDelta 5=\eta f'(net_5)*x_{56}=\eta O_5*(1-O_5)*{w_56}\) -0.0065
4 \(\varDelta 4=\eta f'(net_4)*x_{46}=\eta O_4*(1-O_4)*{w_46}\) -0.0087
  • 新系數
    舉例:\(w_{46}=x_{46}+0.9*\eta*O_4\)
    \(\theta_4 = \theta_4+0.9*\varDelta 4\)

習題

輸入樣本\(x_1=1,x_2=0\) 輸出結點的指望輸出爲1,對於第k次學習獲得的權值爲\(w_{11}(k)=0,w_{12}(k)=2,w_{21}(k)=1,w_{22}=1,T_1(k)=1,T_2(k)=1\),求\(z(k),z(k+1)\)

  • 求正向傳導
    隱含層:\(net_i = \sum_{(j=1)}^k w_{ji} x_j+θ_i\)
    輸出層:\(net_z = ∑_{(j=1)}^2 w_{jz} y_j^1+θ_z\)
    \(y_1(k)=x_1*w_{11}(k)+x_2*w_{21}(k)=1*0+0*2=0<1\ f(net_1)=1\)
    \(y_2(k)=x_1*w_{12}(k)+x_2*w_{22}(k)=1*2+0*2=2>=1\ f(net_2)=2\)
    \(z(k)=T_1(k)*f(net_1)+T_2(k)*f(net_2)=1*1+2*1=3\)

  • 反向求修正係數
    輸出層:\(δ_z^k=y_z^k (d_z^1-y_z^k)(1-y_z^k)\)
    隱含層:\(δ_i^k=δ_z^k w_iz (k)y_i^k (1-y_i^k)\)
    \(\delta_{k} =\triangle z(k) = f'(net_3)*(E-z(k))=(1-3)*3*(1-3)=2*3*2=12\)
    \(\varDelta y_1 = f\prime(net_1) *\delta_{k} * net_1 = 1*(1-1)*12*1 =0\)
    \(\varDelta y_2 = f\prime(net_2) *\delta_{k} * net_2 = 2*(1-2)*12*2 =-24\)

  • 經過修正係數求修正值
    \(w_{iz}(k+1)=w_{iz} (k)+ηδ_z^k y_i^k\)
    \(T_1(k+1) = T_1(k) + \delta_{k} * \eta * f(net_1)_k =1+12*1*1 = 13\)
    \(T_2(k+1) = T_2(k) + \delta_{k} * \eta * f(net_2)_k=1+12*1*2 = 25\)
    \(w_{11}(k+1) = w_{11}(k) +\varDelta y_1*\eta*x_{1} =0 + 12*1*0 = 0\)
    \(w_{12}(k+1) = w_{12}(k) +\varDelta y_2*\eta*x_{1} =2 -24*1*1 = -22\)
    \(w_{21}(k+1) = w_{21}(k) +\varDelta y_1*\eta*x_{2} =2 + 12*1*0 = 2\)
    \(w_{22}(k+1) = w_{22}(k) +\varDelta y_2*\eta*x_{2} =1 -24*1*0 = 1\)

  • 求第k+1次的正向傳導輸出值
    \(y_1(k+1)=x_1*w_{11}(k+1)+x_2*w_{21}(k+1)=1*0+0*2=0<1\ f(net_1)=1\)
    \(y_2(k+1)=x_1*w_{12}(k+1)+x_2*w_{22}(k+1)=1*(-22)+0*2=-22<=1\ f(net_2)=1\)
    \(z(k+1)=T_1(k+1)*f(net_1)+T_2(k+1)*f(net_2)=1*13+1*25=38\)

第10章 決策樹分類算法

概念

從數據中生成分類器的一個特別有效的方法是生成一棵決策樹。決策樹表示方法是應用最普遍的邏輯方法之一,它從一組無次序、無規則的事例中推理出決策樹表示形式的分類準則。

ID3

  • 隨機生成數據:
import numpy as np
import random
outlook = [
    'sunny',
    'overcast',
    'rainy'
]
temperature = [
    'hot',
    'mild',
    'cool'
]
humidity = [
    'high',
    'normal',
]
windy = [
    'false',
    'true'
]
play = [
    'no',
    'Yes'
]
data = []
for i in range(20):
    data.append([outlook[random.randint(0,len(outlook)-1)],
                temperature[random.randint(0,len(temperature)-1)],
                humidity[random.randint(0,len(humidity)-1)],
                windy[random.randint(0,len(windy)-1)],
                play[random.randint(0,len(play)-1)]])
data = np.array(data)
data
編號 outlook temperature humidity windy play
1 rainy mild high true Yes
2 overcast hot normal false no
3 sunny hot normal true no
4 sunny cool normal false no
5 rainy hot high false no
6 sunny mild high true no
7 overcast mild high true Yes
8 rainy cool normal false Yes
9 sunny cool normal true no
10 sunny mild high true Yes
11 overcast cool high false Yes
12 rainy cool high false Yes
13 sunny mild high false Yes
14 overcast cool normal true Yes
15 rainy hot normal false Yes
16 overcast mild normal false Yes
17 sunny hot normal false Yes
18 sunny cool normal true no
19 rainy mild normal false no
20 rainy cool normal true no
  • 首先算出初始熵值\(entropy(S)=-\sum_{i=0}^{n}{p_i log_2 p_i}\)
import math
def entropy(a,b):
    return 0.0-a/(a+b)*math.log(a/(a+b),2)-b/(a+b)*math.log(b/(a+b),2)
entropy(np.sum(data=='Yes'),np.sum(data=='no'))

\(entropy(S)=-\sum_{i=0}^{n}{p_i log_2 p_i}=0.9927744539878084\)

  • 計算outlook的熵
ans = 0
for o in outlook:
    pos = np.sum(np.where(data[np.where(data=='Yes')[0]]==o))
    neg = np.sum(np.where(data[np.where(data=='no')[0]]==o))
    print('| $entropy(S_{'+o+'})$ | $-\\frac {'+
          str(pos)+"} {"+str(neg+pos)+"} \\log_2\\frac {"+
          str(pos)+"} {"+str(neg+pos)+"} -\\frac {"+
          str(neg)+"} {"+str(neg+pos)+"} \\log_2\\frac {"+
          str(neg)+"} {"+str(neg+pos)+"} $ | "
          ,str(entropy(pos,neg))," |"
         )
    ans = ans + len(np.where(data == o)[0])/ len(data) *entropy(pos,neg)
ans
指望信息 公式 結果
\(entropy(S_{sunny})\) $-\frac {3} {8} \log_2\frac {3} {8} -\frac {5} {8} \log_2\frac {5} {8} $ 0.9544340029249649
\(entropy(S_{overcast})\) $-\frac {4} {5} \log_2\frac {4} {5} -\frac {1} {5} \log_2\frac {1} {5} $ 0.7219280948873623
\(entropy(S_{rainy})\) $-\frac {4} {7} \log_2\frac {4} {7} -\frac {3} {7} \log_2\frac {3} {7} $ 0.9852281360342516

\(gain(S,outlook)=0.08568898148399373\)
同理可得,\(gain(S,temperature)=0.0008495469303535508\)\(gain(S,humidity)=0.3658730455992085\)\(gain(S,windy)=0.3654369784855406\)
屬性humidity的信息增量更大,選取humidity做爲根結點的測試屬性。

  • 利用sklearn來生成決策樹:
from sklearn import tree
clf = tree.DecisionTreeClassifier(criterion="entropy",class_weight="balanced",min_samples_split=2)
from sklearn import preprocessing
feature = ['outlook','temperature','humdity','windy']
le = preprocessing.LabelEncoder()
data_sk = data.copy()
for i in range(5):
    data_sk[:,i] = le.fit_transform(data_sk[:,i])
clf = clf.fit(data_sk[:,:4],data_sk[:,4])
import graphviz 
dot_data = tree.export_graphviz(clf, out_file=None,feature_names=feature,class_names=np.array(['Yes','no']),filled=True, rounded=True,  
                     special_characters=True)
graph = graphviz.Source(dot_data) 
graph

sklearn運用的是cart算法,只能生成二叉樹:

  • 用ID3-python來生成多叉樹:
from sklearn.datasets import load_breast_cancer
from id3 import Id3Estimator
from id3 import export_graphviz

bunch = load_breast_cancer()
estimator = Id3Estimator()
data = []
for i in range(20):
    data.append([outlook[random.randint(0,len(outlook)-1)],
                temperature[random.randint(0,len(temperature)-1)],
                humidity[random.randint(0,len(humidity)-1)],
                windy[random.randint(0,len(windy)-1)],
                play[random.randint(0,len(play)-1)]])
data = np.array(data)
estimator.fit(data[:,:4],data[:,4], check_input=True)
export_graphviz(estimator.tree_, 'tree.dot', feature)
from subprocess import check_call
check_call(['dot', '-Tpng', 'tree.dot', '-o', 'tree.png'])

C4.5

C4.5是ID3的一種改進算法,用信息增益比代替了信息增熵進行分支。

  • 對outlook屬性求信息增益比
ans = 0
for o in outlook:
    pos = np.sum(np.where(data[np.where(data=='Yes')[0]]==o))
    neg = np.sum(np.where(data[np.where(data=='no')[0]]==o))
    ans = ans + len(np.where(data == o)[0])/ len(data) *entropy(pos,neg)

ans2 = 0
def entropy2(a,b):
    return 0.0-a/b*math.log(a/b,2)
for o in outlook:
    ans2 = ans + entropy2(len(np.where(data==o)[0]),len(data))
ans/ans2
指望信息 公式 結果
\(entropy(S_{sunny})\) $-\frac {3} {8} \log_2\frac {3} {8} -\frac {5} {8} \log_2\frac {5} {8} $ 0.9544340029249649
\(entropy(S_{overcast})\) $-\frac {4} {5} \log_2\frac {4} {5} -\frac {1} {5} \log_2\frac {1} {5} $ 0.7219280948873623
\(entropy(S_{rainy})\) $-\frac {4} {7} \log_2\frac {4} {7} -\frac {3} {7} \log_2\frac {3} {7} $ 0.9852281360342516

$entropy(overlook)= 0.9070854725038147 \( \)gain(overlook) =entropy(play)-entropy(overlook)= 0.08568898148399373 \( \)splitInfo(overlook)=-\frac{8} {20}\log_2(\frac{8} {20})-\frac{5} {20}\log_2(\frac{5} {20})-\frac{7} {20}*\log_2(\frac{7} {20})\(=1.4371860829942302 \)gainratio(overlook)= \frac {gain(overlook)}{splitInfo(overlook)}= 0.6311538103778426 \( \)gainratio(windy)= \frac {gain(windy)}{splitInfo(windy)}= 0.6457015657437329 \( \)gainratio(humidity)= \frac {gain(humidity)}{splitInfo(humidity)}= 0.6325210109574498 \( \)gainratio(temperature)= \frac {gain(temperature)}{splitInfo(temperature)}=0.6405928106112709 $
顯然windy最大,根據windy構建決策樹。

第11章 K均值算法(k-means)

概念

k-means把n個點(能夠是樣本的一次觀察或一個實例)劃分到k個聚類中,使得每一個點都屬於離他最近的均值(此即聚類中心)對應的聚類,以之做爲聚類的標準。

與KNN區別

k-means KNN
聚類問題 分類問題
訓練集無特徵 訓練集有特徵
具備先驗過程 沒有先驗過程

應用

以做業第三題爲例:
分別取k=2和3,利用K-means聚類算法對如下的點聚類,(2, 1), (1, 2), (2, 2), (3, 2), (2, 3), (3, 3), (2, 4), (3, 5), (4, 4), (5, 3),並討論k值以及初始聚類中心對聚類結果的影響。

  • 當k=2時:
import numpy as np
import matplotlib.pyplot as plt
X = np.array([[2, 1], [1, 2], [2, 2], [3, 2], [2, 3], [3, 3], [2, 4], [3, 5], [4, 4], [5, 3]])
plt.scatter(X[:, 0], X[:, 1], marker='o')
plt.show()
print(X)

使用題中數據,畫出散點圖

import numpy as np
import matplotlib.pyplot as plt

X = np.array([[2, 1], [1, 2], [2, 2], [3, 2], [2, 3], [3, 3], [2, 4], [3, 5], [4, 4], [5, 3]])

from sklearn.cluster import KMeans

x_init = np.array([[2, 1], [1, 2]])  # 將前2個點設爲初始聚類中心,迭代次數爲1次
y_pred = KMeans(n_clusters=2, max_iter=1, init=x_init).fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()

第一次迭代結果

使用第一次迭代結果的質心做爲聚類中心

x_init = np.array([[3.16, 2.5], [2, 3.5]])  # 將第一次分類結果的質心設爲初始聚類中心,迭代次數爲1次
y_pred = KMeans(n_clusters=2, max_iter=1, init=x_init).fit_predict(X)
print(y_pred)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()

結果與第一次同樣

計算矩陣:

import math

m1_x = 0.0
m1_y = 0.0
m2_x = 0.0
m2_y = 0.0
for i, y in enumerate(y_pred):
    if not y:
        m1_x += X[i][0]
        m1_y += X[i][1]
    else:
        m2_x += X[i][0]
        m2_y += X[i][1]
m1_x = m1_x / y_pred[y_pred == 0].size
m1_y = m1_y / y_pred[y_pred == 0].size
m2_x = m2_x / y_pred[y_pred == 1].size
m2_y = m2_y / y_pred[y_pred == 1].size
print("M1':" , m1_x, m1_y, "M2':" , m2_x, m2_y)
for i, x in enumerate(X):
    print(math.sqrt(math.pow(x[0] - m1_x, 2) + math.pow(x[1] - m1_y, 2)),
          math.sqrt(math.pow(x[0] - m2_x, 2) + math.pow(x[1] - m2_y, 2)))

結果:

  • 當k=3時:
  • 第一次迭代結果:
# 當k=3時
x_init = np.array([[2, 1], [1, 2], [2, 2]])  # 將前3個點設爲初始聚類中心,迭代次數爲1次
y_pred = KMeans(n_clusters=3, max_iter=1, init=x_init).fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
print(y_pred)
m1 = np.mean(X[np.where(y_pred == 0)], axis=0)  # axis==0 計算每一列均值
m2 = np.mean(X[np.where(y_pred == 1)], axis=0)
m3 = np.mean(X[np.where(y_pred == 2)], axis=0)
print("M1':", m1, "M2':", m2, "M3':", m3)

結果:

  • 第二次迭代結果:
y_pred = KMeans(n_clusters=3, max_iter=2, init=x_init).fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
m1 = np.mean(X[np.where(y_pred == 0)], axis=0)  # axis==0 計算每一列均值
m2 = np.mean(X[np.where(y_pred == 1)], axis=0)
m3 = np.mean(X[np.where(y_pred == 2)], axis=0)
print("M1':", m1, "M2':", m2, "M3':", m3)

結果:

  • 第三次迭代結果:
y_pred = KMeans(n_clusters=3, max_iter=3, init=x_init).fit_predict(X)
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()
m1 = np.mean(X[np.where(y_pred == 0)], axis=0)  # axis==0 計算每一列均值
m2 = np.mean(X[np.where(y_pred == 1)], axis=0)
m3 = np.mean(X[np.where(y_pred == 2)], axis=0)
print("M1':", m1, "M2':", m2, "M3':", m3)

與第二次同樣:

影響

k值的影響

在 K-means 算法中 K 是事先給定的,這個 K 值的選定是很是難以估計的。不少時候,事先並不知道給定的數據集應該分紅多少個類別才最合適。K值太小,類內類似性變小,聚類結果將沒法知足應用須要;K值過大,類間間距變小,意味着應用中將會增長成本。這也是 K-means 算法的一個不足。

初始聚類中心選擇的影響

初始聚類中心的選擇對聚類結果有較大的影響,一旦初始值選擇的很差,可能沒法獲得有效的聚類結果,甚至若是選到噪聲數據和孤立點,將使算法的迭代次數增多,算法的時間性能變差,另外,受噪聲數據和孤立點的影響算法還容易陷入局部極值。若是這也成爲 K-means算法的一個主要問題。

第12章 k中心點聚類算法(K-medoids)

除了中心點選取算法與k-means不一致外,其餘算法過程一致。

  • 區別:
    • K-means裏每一個聚類的中心點是平均值點
    • K-medoids裏每一個聚類的中心點是離平均值點最近的樣本點

應用

【例12.1】,當初始中心點爲{D,E}時,試運用K-中心點聚類算法給出第一次迭代後生成的兩個簇。
sklearn中彷佛沒有該算法,不過wiki中講的很詳細。

  • 第一步創建過程:
% matplotlib inline
import numpy as np
import matplotlib.pyplot as plt

X = np.array([[0, 1, 2, 2, 3],
              [1, 0, 2, 4, 3],
              [2, 2, 0, 1, 5],
              [2, 4, 1, 0, 3],
              [3, 3, 5, 3, 0]])
k = [3, 4]
y = []
for i, x in enumerate(X):
    if x[k[0]] <= x[k[1]]:
        print(x[k[0]], x[k[1]], "0")
        y.append(0)
    else:
        print(x[k[0]], x[k[1]], "1")
        y.append(1)
y = np.array(y)
print("COST:", np.sum(X[np.where(y == 0)], axis=0)[k[0]], np.sum(X[np.where(y == 1)], axis=0)[k[1]])

結果:

  • 第二步交換過程:
    • 將D替換爲A
k = [0, 4]
y = []
for i, x in enumerate(X):
    if x[k[0]] <= x[k[1]]:
        print(x[k[0]], x[k[1]], "0")
        y.append(0)
    else:
        print(x[k[0]], x[k[1]], "1")
        y.append(1)
y = np.array(y)
print("COST:", np.sum(X[np.where(y == 0)], axis=0)[k[0]], np.sum(X[np.where(y == 1)], axis=0)[k[1]])
ans_da = np.sum(X[np.where(y == 0)], axis=0)[k[0]] + np.sum(X[np.where(y == 1)], axis=0)[k[1]]
print(ans_da - ans)

結果:

- 替換k中的值,得出不一樣結果,選擇第一個代價最小的結果,即用A替換D。

第13章 自組織神經網絡聚類算法(SOM)

概念

一個神經網絡接受外界輸入模式時,將會分爲不一樣的對應區域,各區域對輸入模式具備不一樣的響應特徵,並且這個過程是自動完成的。SOM經過自動尋找樣本中的內在規律和本質屬性,自組織、自適應地改變網絡參數與結構。

  • SOM是一種屬於基於原型的聚類算法。

第14章 基於密度的空間的數據聚類方法(DBSCAN)

概念

DBSCAN是一個基於高密度鏈接區域地密度聚類算法,該算法將簇定義爲密度相連的點的最大集,將具備高密度的區域劃分爲簇。

  • DBSCAN是相對抗噪聲的,丟棄被它識別爲噪聲的對象,而且可以處理任意形狀和大小的簇。
  • DBSCAN使用基於密度的概念,會合並有重疊的簇。
  • DBSCAN在最壞狀況下的時間複雜度是\(O(m^2)\)

與K-means比較

k-means DBSCAN
劃分聚類 聚類全部對象 丟棄被它識別爲噪聲的對象
基準 原型 密度
處理數據 難處理非球形的簇和不一樣大小的簇 能夠處理不一樣大小或形狀的簇
處理數據 只能用於具備明肯定義的質心(好比均值或中位數)的數據 要求密度定義(基於傳統的歐幾里得密度概念)
處理數據 能夠用於稀疏的高維數據,如文檔數據 對於高維數據,傳統的歐幾里得密度定義不能很好處理它們
架設 假定全部的簇都來自球形高斯分佈,具備不一樣的均值,但具備相同的協方差矩陣 不對數據的分佈作任何假定
合併 能夠發現不是明顯分離的簇,即使簇有重疊也能夠發現 合併有重疊的簇
時間複雜度 \(O(m)\) \(O(m^2)\)
屢次運行 使用隨機初始化質心,不會產生相同的結果 會產生相同結果
K值 簇個數須要做爲參數指定 自動地肯定簇個數
模型 優化問題,即最小化每一個點到最近質心的偏差平方和 不基於任何形式化模型
相關文章
相關標籤/搜索