大數據挖掘復習小記


前言

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

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

第1章 大數據簡介


本章主要考填空題:

數據規律化

分類結果評價

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

(真實)/(預測) 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章 數據預處理技術

數據集成

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

數據變換

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

輪廓加權

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

  • 統計表:

  • 修正后統計表:

  • 修正后比例:

分箱

  • 利用np.split對數組分割

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

  • 邊界平滑
    對每一行設為其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值 簇個數需要作為參數指定 自動地確定簇個數
模型 優化問題,即最小化每個點到最近質心的誤差平方和 不基於任何形式化模型


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM