習題
3.1
試析在什么情況下式 \((3.2)\) 中不必考慮偏置項 \(b\) .
書中有提到, 可以把 \(x\) 和 \(b\) 吸收入向量形式 \(\hat{w} = (w;b)\) .此時就不用單獨考慮 \(b\) 了.
其實還有很多情況不用, 比如說使用了 \(\mathrm{one-hot}\) 編碼, 就可以不用考慮偏置項.
更廣泛的情況是, 如果偏置項 \(b\) 可以被 "包含" 在另外的一些離散特征里, 那么就不用考慮. 就是偏置項可以以一定系數加到離散特征中. (可能看了還是不太懂, 我以后有時間會重寫一個的.)
3.2
試證明, 對於參數 \(w\), 對率回歸的目標函數 \((3.18)\) 是非凸的, 但其對數似然函數 \((3.27)\) 是凸的.
計算其海森矩陣, 判斷是否正定. 海森矩陣可以類比成一元函數的二階導, 正定可以類比為二階導恆大於 \(0\) .
3.3
編程實現対率回歸, 並給出西瓜數據集 \(3.0\alpha\) 上的結果.
3.4
選擇兩個 \(\mathrm{UCI}\) 數據集, 比較 \(10\) 折交叉驗證法和留一法所估計出的錯誤率.
3.4
編程實現線性判別分析, 並給出西瓜數據集 \(3.0\alpha\) 上的結果.
3.6
線性判別分析僅在線性可分數據上能獲得理想結果, 試設計一個改進方法, 使其能較好地用於飛線性可分數據.
像 \(6.3\) 節介紹的那樣, 使用核函數, 就可以運用於非線性可分數據.
3.7
令碼長為 \(9\), 類別數為 \(4\) , 試給出海明距離意義下理論最優的 \(\mathrm{ECOC}\) 二元碼並證明之.
首先要給出理論最優, 我們先要確定 '最優' 的指導標准.
對同等長度的編碼, 理論上來說, 任意兩個類別之間的編碼距離越遠, 則糾錯能力越強.
我們要將 '任意兩個類別的編碼距離' 用數學表達, 這樣才能進行求解. 那么怎么用數學表達這個 '距離' 呢? 這里考慮到 '總體距離最大' , 同時我們還要保證每兩個類別之間的反碼的距離也 '最大' , 所以我們淺顯的使用每兩個類別之間的海明距離乘和其反碼的海明距離的積來作為衡量標准(有點繞), 我們定義一個變量 \(L\) 用來表達這個積, 也就是有
\(dis(r_i, r_j)\) 表示第 \(i\) 個編碼和第 \(j\) 個編碼之間的海明距離, \(dis(r_i, r_j)\) 表示第 \(i\) 個編碼和第 \(j\) 個編碼的反碼之間的海明距離. \(L\) 越大代表這種編碼方式越好.
於是我寫了段程序來搜索 \(L\) 的最大值 (直接爆搜) .
#include<iostream>
#include<cmath>
using namespace std;
const int MAXCOL = 9; // 碼長為 9
const int MAXROW = 4; // 類別數為 4
bool code[MAXROW][MAXCOL]; // 記錄最大值時編碼排列
bool temp_code[MAXROW][MAXCOL]; // 表示當前編碼排列
int mmax = 0; // 記錄最大值
int dif_val(bool a[MAXCOL], bool b[MAXCOL]){ // 求兩個編碼之間的海明距離
int cnt1 = 0;
int cnt2 = 0;
for(int i = 0 ; i < MAXCOL ; ++i){
if(a[i] != b[i]) ++cnt1;
if(a[i] == b[i]) ++cnt2;
}
return cnt1 * cnt2;
}
int cost(bool code[MAXROW][MAXCOL]){ // 求當前編碼排列的 L
int res = 1;
for(int i = 0 ; i < MAXROW ; ++i){
for(int j = i + 1 ; j < MAXROW ; ++j){
res *= dif_val(code[i], code[j]);
}
}
return res;
}
void dfs(int row = 2, int col = 0){ // 深度優先搜索, 枚舉每個位置的編碼 (0 和 1)
if(row == MAXROW) return; // 邊界條件
temp_code[row][col] = 1; // 先枚舉 1
int temp = cost(temp_code);
if(mmax < temp){ // 發現更好的編碼排列, 進行更新
mmax = temp;
for(int i = 0 ; i < MAXROW ; ++i)
for(int j = 0 ; j < MAXCOL ; ++j)
code[i][j] = temp_code[i][j];
}
if(col == MAXCOL - 1) dfs(row + 1, 0); // 下一層
else dfs(row, col + 1);
temp_code[row][col] = 0; // 返回再枚舉 0
temp = cost(temp_code);
if(mmax < temp){ // 同上
mmax = temp;
for(int i = 0 ; i < MAXROW ; ++i)
for(int j = 0 ; j < MAXCOL ; ++j)
code[i][j] = temp_code[i][j];
}
if(col == MAXCOL - 1) dfs(row + 1, 0); // 同上
else dfs(row, col + 1);
return ;
}
int main(){
for(int i = 0 ; i < MAXCOL ; ++i){
temp_code[0][i] = 1; // 不失一般性, 令第一個類別的編碼全部為 1
}
for(int i = 1 ; i <= MAXCOL ; ++i){ // 不失一般性, 枚舉第二個類別 1 的數量 (1 ~ 9)
temp_code[1][i - 1] = 1;
dfs();
}
for(int i = 0 ; i < MAXROW ; ++i){ // 打印最終結果
for(int j = 0 ; j < MAXCOL ; ++j){
cout << code[i][j] << ' ';
}
cout << endl;
}
cout << mmax;
return 0;
} // 我的碼風是不是很好看
結果:
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
1 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 |
64000000
當然我們要把 \(0\) 換成 \(-1\).
所以, 我們求出了海明距離下理論最優的, 碼長為 \(9\), 類別數為 \(4\) 的 \(\mathrm{EOOC}\) 二元碼. 至於證明, 在我們定義的衡量標准下, 其正確性是顯然的.
3.8*
\(\mathrm{EOOC}\) 編碼能起到理想糾錯作用的重要條件是: 在每一位編碼上出錯的概率相當且獨立. 試析多分類任務經 \(\mathrm{EOOC}\) 編碼后產生的二類分類器滿足該條件的可能性及由此產生的影響.
\(\mathrm{EOOC}\) 編碼不僅要和其他編碼距離盡量大, 還要和其他編碼的反碼距離也要大. 這是因為每個二類分類器的錯誤可能相似. 考慮一個極端情況, 要是錯誤完全相同, 那么分類器出錯的后果就是輸出碼為原來的反碼.
3.9
使用 \(\mathrm{OvR}\) 和 \(\mathrm{MvM}\) 將多分類任務分解為二分類任務求解時, 試述為何無需專門針對類別不平衡性進行處理.
原文就已經提到
對 \(\mathrm{OvR}\) 、\(\mathrm{MvM}\) 來說, 由於對每個類進行了相同的處理, 其拆解出的二分類任務中類別不平衡的影響會相互抵消, 因此通常不需要專門處理.
3.10*
試推導出多分類代價敏感學習 (僅考慮基於類別的誤分類代價) 使用 "再縮放" 能獲得理論最優解的條件.
原文中提到
再縮放的思想雖簡單, 但實際操作卻並不平凡, 主要因為 "訓練集是真實樣本總體的無偏采樣" 這個假設往往並不成立.
因此假設成立應該也算是獲得理論最優解的一個條件(好水啊).