數據預處理——分類(線性可分SVM與決策樹)


[toc]
## 第二次作業

 

#### 第一題
<b>題目描述</b><br>
1.如下表數據,前四列是天氣情況(陰晴outlook,氣溫temperature,濕度humidity,風windy);最后一列是類標簽,表示根據天氣情況是否出去玩。
(1)“信息熵”是度量樣本集合純度最常用的一種指標,假定當前樣本集合D中第k類樣本所占的比例為 (k=1, 2, …, K),請問當什么條件下,D的信息熵Ent(D)取得最大,最大值為多少?
(2)根據表中訓練數據,基於信息增益決策樹應該選哪個屬性作為第一個分類屬性?
(3)對於含有連續型屬性的樣本數據,決策樹和朴素貝葉斯分類能有哪些處理方法? 
(4)在分類算法的評價指標中,recall和precision分別是什么含義?
(5)若一批數據中有3個屬性特征,2個類標記,則最多可能有多少種不同的決策樹?(不同決策樹指同一個樣本在兩個兩個決策下可能得到不同的類標記)
|  outlook   | temperature  | humidity  | windy  | play  |
|  ----  | ----  | ----  | ----  | ----  |
| sunny  | hot | high | FALSE | no |
| sunny  | hot | high | TRUE | no |
| rainy  | cool | normall | TRUE | no |
| sunny  | mild | high | FALSE | no |
| sunny  | cool | normal | FALSE | yes |
| rainy  | mild | normal | FALSE | yes |
| overcast  | cool | normal | TRUE | yes |
| rainy  | cool | normal | FALSE | yes |
| rainy  | mild | high | FALSE | yes |
| overcast  | hot | high | FALSE | yes |

 

<b>解答</b><br>
<b>(1)</b>

 

 

<b>(2)</b>

 

 

 

 

<b>(3)</b><br>
對於決策樹來說,當含有連續型屬性樣本數據時,可以進行如下操作:
離散化,假如連續屬性出現的n(假設出現了n中不同的值),那么可排序為(a1, a2, ..., an);這樣就形成了n - 1個區間;對於每個區間來說,可以設(a(i) + a(i + 1)) / 2來代表整個區間;從而將這些連續型的樣本數據轉化成了n - 1個划分點的數據集合,從而可以像計算離散數據那樣去計算連續型數據樣本。
<b>(4)</b><br>
recall:召回率;recall = 預測為正樣本且預測正確的樣本數 / 真實的正樣本數目;recall = TP / TP + FN<br>
precision:准確率;precision = 預測為正樣本且預測正確的樣本數 / 預測為正樣本的數目;TP / TP + FP<br>
<b>(5)</b><br>
3個特征,2個類別;構造出的決策樹一共有三層,第i層由第i個特征進行划分,這樣決策樹的種類樹是P(3, 3) = 6種。<br>

 

#### 第二題
<b>題目描述</b><br>
2. 已知正例點 x1 = (2,3)T,x2 = (3, 2)T,負例點 x3 = (1, 1)T
(1) 試用 SVM 對其進行分類,求最大間隔分離超平面,並指出所有的支持向量。<br>
(2) 現額外有一個點能被 SVM 正確分類且遠離決策邊界,如果將該點加入到訓練集,SVM 的決策邊界會受影響嗎?為什么?<br>

 

<b>解答</b><br>
<!-- <b>問題</b> -->
<!-- SVC(kernel = 'linear') or  LinearSVC  的區別? -->
<b>(1)</b><br>
<b>答案</b><br>
支持向量:(1, 1), (2, 3), (3, 2);即三個里超平面最近的三個點。
<b>推導</b>

 

 

 

 

 

 

<b>代碼</b>

 

import numpy as np
import matplotlib.pyplot as plt
from sklearn import svm

 

# 線性可分;導入數據
array = np.random.randn(20,2)
X= np.array([[2, 3], [3, 2], [1, 1]])
y = [1, 1, -1]
# 建立svm模型並訓練
clf = svm.SVC(kernel='linear')
clf.fit(X,y)
w = clf.coef_
b = clf.intercept_
print("w:\n", w)
print("b:\n", b)
print("支持向量:\n", clf.support_vectors_)

 

# 畫圖
X1 = []
X2 = []
for i in range(5):
    X1.append(i + 1)
    X2.append(((-1) * b - w[0][0] * (i + 1)) / w[0][1])
X3 = [2, 3, 1]
X4 = [3, 2, 1]

 

plt.plot(X1, X2, c = "blue")
plt.scatter(X3, X4, c = "red")
plt.show()

 

 

 

 

<b>(2)</b><br>
答:如果將該點加入到訓練集中,SVM的決策邊界不會受到影響,因為SVM在去尋找超平面的時候,其最大化的是數據集中幾何間隔最小的那個;因此添加一個正確分類且遠離決策邊界的並不會產生影響。(新加入的點的幾何間隔小於最小的幾何間隔)

 

#### 第三題
<b>題目描述</b>

 

 

<b>解答</b><br>
<br><b>(1)</b><br>
錯誤率最低的特征為當前的划分標准<br>
年齡:青年和中年 同意貸款;錯誤率;<br>
工作:有工作 同意貸款;錯誤率:<br>
房子:有房子 同意貸款:<br>
信貸情況:非常好與好 同意貸款:<br>

 

第一次划分:信貸情況<br>
(節點1)
|  特征   | 錯誤率  |
|  ----  | ----  |
| 年齡  | 3/5 |
| 工作  | 4/15 |
| 房子  | 4/15 |
| 信貸情況 | 1/5 |
第二次划分:房子<br>
(節點3)
|  特征   | 錯誤率  |
|  ----  | ----  |
| 年齡  | 6/10 |
| 工作  | 4/10 |
| 房子  | 3/10 |
第三次划分:年齡<br>
(節點5)
|  特征   | 錯誤率  |
|  ----  | ----  |
| 年齡  | 2/5 |
| 工作  | 4/5 |
第四次划分:工作<br>
(節點7)<br>
有工作則貸款<br>
無工作則不貸款<br>

 

 

 

<br><b>(2)</b>
答:對屬性值為(中年,無工作,無自己的房子,信貸情況好)的申請者不進行放貸。
<br><b>(3)</b>
1. 進行預剪枝;可以預先設定一份閾值,當熵或者某種目標函數值小於這個閾值的時候就停止繼續創建分支,例如給XGBoos的目標函數值設置閾值;
2. 進行后剪枝;例如REP,錯誤率降低剪枝。(這個思路很直接,完全的決策樹不是過度擬合么,我再搞一個測試數據集來糾正它。對於完全決策樹中的每一個非葉子節點的子樹,我們嘗試着把它替換成一個葉子節點,該葉子節點的類別我們用子樹所覆蓋訓練樣本中存在最多的那個類來代替,這樣就產生了一個簡化決策樹,然后比較這兩個決策樹在測試數據集中的表現,如果簡化決策樹在測試數據集中的錯誤比較少,那么該子樹就可以替換成葉子節點。該算法以bottom-up的方式遍歷所有的子樹,直至沒有任何子樹可以替換使得測試數據集的表現得以改進時,算法就可以終止)

 

<br><b>(4)</b>
1. 對連續的數據進行離散化,去每個區間的中間值代表這個區間,這樣就把連續數據變成了離散的一個一個點;
2. 對條件進行變化,例如在實數范圍內,設置條件為 是否小於4,這樣也可以進行划分。

 

#### 第四題
<b>題目描述</b><br>
4. 請評價兩個分類器 M1 和 M2 的性能。所選擇的測試集包含 26 個二值屬性,記作 A 到 Z。 表中是模型應用到測試集時得到的后驗概率(圖中只顯示正類的后驗概率)。因為這是二類問題,所以 P(-)=1-P(+),P(-|A,…,Z)=1-P(+|A,…,Z)。假設需要從正類中檢測實例
1) 畫出 M1 和 M2 的 ROC 曲線(畫在一幅圖中)。哪個模型更多?給出理由。
2) 對模型 M1,假設截止閾值 t=0.5。換句話說,任何后驗概率大於 t 的測試實例都被看作正例。計算模型在此閾值下的 precision,recall 和 F-score。
3) 對模型 M2 使用相同的截止閾值重復(2)的分析。比較兩個模型的 F-score,哪個模型更好?所得結果與從 ROC 曲線中得到的結論一致嗎?
4) 使用閾值 t=0.1 對模型 M2 重復(2)的分析。t=0.5 和 t=0.1 哪一個閾值更好?該結果和你從 ROC 曲線中得到的一致嗎?

 

 

 

<br><b>(1)</b>
從圖中可以看到M1的ROC圍成的面積(AUC)是大於M2的;而AUC考慮的是樣本預測的排序質量,其loss定義為:

 

 

而AUC是計算圍成的多個梯形的面積之和,有:

 

 

即有:AUC = 1 - loss;
***
所以AUC面積越大,說明Loss越小,所以AUC面積更大的模型性能更好,所以M1模型的性能更好。

 

 

<b>(2)</b><br>
當 t = 0.5時,對模型M1進行分析<br>
precision = TP / TP + FP = 3 / 4<br>
recall = TP / TP + NF = 3 / 5<br>
F-score = 2 * P * R / (P + R) = 2 / 3<br>
<br><b>(3)</b>
當 t = 0.5時,對模型M2進行分析<br>
precision = TP / TP + FP = 1 / 2<br>
recall = TP / TP + NF = 1 / 5<br>
F-score = 2 * P * R / (P + R) = 2 / 7<br>
***
模型M1的F1值大於M2的F1數值,表示模型M1性能更好;所得結果和ROC曲線中得到的結論是一致的。<br>

 

<b>(4)</b><br>
當t = 0.1時,對模型M2進行恩熙<br>
precision = TP / TP + FP = 2 / 5<br>
recall = TP / TP + NF = 2 / 5<br>
F-score = 2 * P * R / (P + R) = 2 / 5<br>
***
對模型M2分析,當t = 0.5與t = 0.1的時候,t = 0.1的時候更好,因為F1數值更高了;當對t = 0.1時來分析M2模型,還是比不上M1模型的F1數值,和ROC曲線的結果是一樣。<br>
這個地方,閾值的大小,其實要看是更看重查准率還是查全率;當更看重查全率的時候,可以把閾值設置為(從小到大)排序后更靠左邊的位置;若是更看重查准率,設置為靠右邊的位置。



#### 第五題
<b>題目描述</b>

 

 

<b>解答</b><br>
<b>計算TPR與FPR</b><br>
TP: {1, 3, 4, 6}<br>
FP: {2, 5, 7, 8, 9}<br>
TN: 空集<br>
FN: {10}<br>
所以它們各自的數目為:<br>
TP: 4; FP: 5; TN: 0; FN: 1;<br>
<b>(閾值為0.5)</b><br>
TPR = TP / (TP + FN) = 4 / 4 + 1 = 4 / 5<br>
FPR = FP / (TN + FP) = 1 / 0 + 5 = 1 / 5<br>
<b>手繪ROC曲線</b>

 

 

<b>程序畫的ROC曲線</b>

 

import matplotlib.pyplot as plt
 

X = [0, 0, 0.2, 0.2, 0.2, 0.4, 0.4, 0.6, 0.8, 1.0, 1.0]
Y = [0, 0.2, 0.2, 0.4, 0.6, 0.6, 0.8, 0.8, 0.8, 0.8, 1.0]
 

plt.plot(X, Y)
plt.show()

  

 

 

 

#### 第六題
<b>題目描述</b><br>
6. 假設兩個預測模型 M 和 N 之間進行選擇。已經在每個模型上做了 10 輪 10-折交叉驗證,其中在第 i 輪,M 和 N 都是用相同的數據划分。M 得到的錯誤率為 30.5、32.2、 20.7、20.6、31.0、41.0、27.7、28.0、21.5、28.0。N 得到的錯誤率為 22.4、14.5、22.4、 19.6、20.7、20.4、22.1、19.4、18.2、35.0。評述在 1%的顯著水平上,一個模型是否顯著地比另一個好。<br>
<b>解答</b><br>
<b>這兩個模型的性能沒有明顯的顯著差異</b><br>

 

 

 

M = [30.5, 32.2, 20.7, 20.6, 31.0, 41.0, 27.7, 28.0, 21.5, 28.0]
N = [22.4, 14.5, 22.4, 19.6, 20.7, 20.4, 22.1, 19.4, 18.2, 35.0]
X = []
for i, j in zip(M, N):
    X.append(i - j)
def get_u(X):
    num = 0
    for i in X:
        num += i
    return num / len(X)
def get_variance(X, u):
    sum = 0
    for i in X:
        sum += (i - u) * (i - u)
    sum = sum / len(X)
    return sum
def get_T(u, variance, k):
    sum = (k ** 0.5) * u / (variance ** 0.5)
    return abs(sum)
#計算均值與方差,t以及兩個模型的平均值
u = get_u(X)
variance = get_variance(X, u)
T = get_T(u, variance, len(X))
t = 3.25
M_average = get_u(M)
N_average = get_u(N)
 

print("T: ", T)
if(T < t):
    print("兩個模型沒有顯著差別")
elif(M_average > N_average):
    print("模型N性能更優")
else:
    print("模型M性能更優")

 

 

 

 

#### 存在的問題
1. SMO算法還需要去手推一下;
2. SVM的核函數需要去學習一下,這次作業沒有涉及到。 


免責聲明!

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



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