# ISpan - AIML
## 課程內容
* [講義]( https://www.dropbox.com/scl/fi/gxap5x1y21fg7huhq16yn/ML_tutorial_v2023.11.pdf?rlkey=9whcce7uyesw1jtl2etkvrxoh&dl=1)
* [資料集]( https://www.dropbox.com/scl/fi/3142w9biv0e3oah7ceb78/AIEN_ML_v2023.11.tar.gz?rlkey=mx40qg71nc1q58677til19jpv&dl=)
* [Bad Smells](https://hackmd.io/@chweng/SJGYx4SNp)
* [SOLID](https://hackmd.io/@chweng/HyQcnEHNa)
## 補充資訊 (2023/11/26)
* 何謂Gini
* ![IMG_0154](https://hackmd.io/_uploads/SkAHhQeBa.jpg)
* 目標: 做好的決策 (選擇能夠最大化Gini的決策)
* ![IMG_0155](https://hackmd.io/_uploads/rJAr37lS6.jpg)
* 資料檢索
* `dfTest[dfTest["AgeInfo"] == 'children'].head(3) # 選擇是小孩的樣本`
* PCA看單位向量於水平方向夾角
```python=
for j in range(2):
x, y = pca.components_[j]
print(
f"unit vector degree= {np.degrees(np.arctan2(y, x))}"
)
print(
f"unit vector= {pca.components_[j]}\n"
)
```
* DBSCAN調參數使得群數可以自行決定
```python=
for eps in np.linspace(1, 0.01, 100):
db = DBSCAN(eps=eps, min_samples=5, metric='euclidean')
y_db = db.fit_predict(X)
unique_labels = np.unique(y_db) # [-1(outlier), 0, 1, ...]
num_unique_labels = len(unique_labels)
if num_unique_labels >= 3:
break
print(eps, unique_labels)
colors = ['yellow', 'red', 'black']
for j in unique_labels:
plt.scatter(
X[y_db == j, 0],
X[y_db == j, 1],
color=colors[j],
)
plt.show()
```
## 補充資訊 (2023/11/25)
* 套件追加mlxtend (用於畫決策邊界)
* `poetry lock --no-update` # 追加新套件的時候,不要順便把其他的套件更新到允許的最新版本
* `np.stack`, `np.concatenate`操作
```python=
# np.vstack([a, b]) # stack at vertical axis (axis=0); Shape=[ [m, n], [m, n] ] -> [2m, n]
# np.hstack([a, b]) # stack at horizontal axis (axis=1); Shape=[ [m, n], [m, n] ] -> [m, 2n]
# np.stack([a, b], axis=-1) # (用於超過兩個維度的張量; 不太好用; 先不要用)
# 若覺得stack API太複雜,用concatenate就好:
# np.concatenate([a, b], axis=0) # Shape=[ [m, n], [m, n] ] -> [2m, n]
# np.concatenate([a, b], axis=1) # Shape=[ [m, n], [m, n] ] -> [m, 2n]
```
* SVM
![](https://static.javatpoint.com/tutorial/machine-learning/images/support-vector-machine-algorithm.png)
* predict_proba
```python=
classifier = SVC(kernel='rbf', probability=True)
model = classifier.fit(X, y)
pred_prob = model.predict_proba(X) # [num_samples, num_classes]
assert np.all(pred_prob.argmax(axis=-1) == model.predict(X))
thresh = 0.1 # 想要recall高 (寧可錯抓不可漏抓);換句話說: 模型稍微有點相信是1, 就讓他預測是1
(pred_prob[:, 1] >= thresh).astype(int)
thresh = 0.9 # 想要precision高 (寧可漏抓不可錯抓);換句話說: 模型非常相信是1, 才讓他預測是1
(pred_prob[:, 1] >= thresh).astype(int)
```
* LogisticRegression的multi_class
* multi_class=`ovr`
* 建立多個二元分類模型(Logistic classifier)做多元分類
* multi_class=`multinomial`
* 建立單一模型(Softmax classifier)做多元分類
* LogisticRegression的class_weight
* 預設是 None (不做Loss加權)
* 'balanced' (將比較少見的樣本, 其樣本Loss放大. 可使優化器更加關注較少見的樣本, 將較少見的樣本的Loss降低)
* 使用pathlib找檔案
```python=
from pathlib import Path
paths = [(path.parent.stem, str(path)) for path in Path('../datasets/mnist/').glob("**/*.jpg")]
```
* Data Imbalance 怎麼辦?
* Loss
* 使用class_weight對較少見的樣本其樣本Loss加權 -> 讓優化器更加關注於該類樣本誤差優化.
* 嘗試[focal loss](https://arxiv.org/abs/1708.02002) -> 置信度較高的, 易學樣本, 將其樣本Loss降低. 使得模型關注較難的(較低置信度的)樣本.
* 一些常見也好學的樣本, 於訓練過程, 模型會對其屬於某個類別的置信度慢慢提升(例: `>0.8`).
* 不常見或不好學的樣本, 即使訓練到接近末期, 模型還是難以判斷它應該是屬於哪個類別(有低置信度)
* Data
* 製作Dataloader (資料抽樣器). 使得每次取出一個批次的數據量時, 該批次的樣本盡量每個類別數量都差不多.
* 資料若切三分
* train: 訓練模型
* validation: 選擇模型(調參); model selection, hyperparameter fine-tuning
* test:
* 測試最終選出的模型表現如何
* 若測試資料集有額外挑選過, 放入一些較複雜或是較接近真實應用場景的資料, 則有助於驗證模型的泛化(generalizability)能力
* 選出最好模型看分類報告
```python=
predY = dfSorted["classifier"].iloc[0].predict(testX)
print(classification_report(testY, predY))
```
* 到底GridSearchCV建立了幾個模型呢?
* cv=5 (5 fold)
* grid: {'penalty': ['l1', 'l2'], 'c': [0.01, 0.1, 1, 10]} (8 model settings)
* 總共建立了 8 x 5 + 1(最後拿最佳模型設定在整個5-fold上面去訓練出來的一個模型) = 41個模型
* 當你使用model.predict的時候,會拿最佳模型(看過整個5-fold訓練/驗證用資料集)來做預測
## 補充資訊 (2023/11/19)
* 煉丹心法
* Bag of tricks
* https://arxiv.org/abs/1812.01187 (提及Learning rate該如何排程)
* Bag of specials (有價的提升技巧)
* Bag of freebies (免費的提升技巧)
* https://arxiv.org/abs/1902.04103v3
* https://arxiv.org/pdf/2207.02696.pdf
* 建立寫`assert`的習慣, 未來可替自己開發的class/function寫測試(利用[pytest](https://docs.pytest.org/en/7.4.x/)或類似框架)
* 一直做隕石開發的話, 有可能很難從早期的職業生涯開始累積軟工實力, 因為一直應付上級, 疲於奔命(https://disp.cc/b/Soft_Job/aEhO)
* TensorFlow裡面有L1或L2可以用 (https://www.tensorflow.org/api_docs/python/tf/keras/regularizers/L1)
* 01筆記本建議練習(回家作業):
1. 去掉房價離群值, 所有特徵欄位都給予, 看R2表現
2. 去掉房價離群值, 所有特徵欄位都給予, 並追加所有特徵欄位的平方當作額外的特徵欄位, 看R2表現
## 補充資訊 (2023/11/18)
* ![截圖 2023-11-18 上午9.07.25](https://hackmd.io/_uploads/SyyuRtSVp.png)
* 五種壞味道
* 第一個
過於攏長的類 -> 可能包含很多特製業務邏輯 -> 不好復用 (用一次就丟 不夠精實 對別人沒啥幫助)
* 第二個
不正確的繼承 -> 多了一些不恰當的, 父類別給予的方法可以使用. (但其實不是真的能用 -> 導致使用此物件的人要非常小心/要很注意 -> 不好用)
* 第三個
程式碼有防止改動的特性 -> 牽一髮動全身(舉例來說, 改一個網路層會影響另一個完全不相干的"優化器"類別. 那不確定性太大了. 誰敢改?)
* 第四個
過多的不必要耦合性(coupling). 會導致難以修改或復用.
* 第五個
過多垃圾(例如說含有沒必要的屬性), 或是過多的不必要開發(未雨綢繆不一定是好事)
* if-else區塊可用其他架構替代 (https://www.youtube.com/shorts/psu7LYIyQAo)
* 資料表通常有兩個索引來描述. $X_{i}^{(j)}$, 其中i是第i個特徵欄位, j是第j筆資料. X的形狀: `[batch_size, num_features]`.
* Dense層的輸入/輸出張量形狀是`[batch_size, num_features]`.
* 2D捲積層(`Conv2D`)的輸入/輸出張量, 其形狀為何? `[batch_size, height, width, num_channels]`
* 1D捲積層(`Conv1D`)的輸入/輸出張量, 其形狀為何? `[batch_size, width, num_channels]`
* RNN層(`LSTM`)的輸入/輸出張量, 其形狀為何?
`[batch_size, num_time_steps, num_features]`
* Likelihood function和 Loss的關係
* $\hat{y} = wx + b$
* $\xi^{(i)} = \hat{y}^{(i)} - y^{(i)} \sim N(0, 1) \sim exp(-\frac{1}{2}( \hat{y}^{(i)} - y^{(i)})^2)$
* $Likelihood \sim \xi^{(1)}\xi^{(2)}...\xi^{(N)} \sim exp(-\frac{1}{2}( \hat{y}^{(1)} - y^{(1)})^2)exp(-\frac{1}{2}( \hat{y}^{(2)} - y^{(2)})^2)...exp(-\frac{1}{2}( \hat{y}^{(N)} - y^{(N)})^2)$
* $Likelihood \sim exp(-\frac{1}{2} \sum_j ( \hat{y}^{(j)} - y^{(j)})^2)$
* 目標: 調整w, b去最大化Likelihood使得所有樣本誤差於0附近跳動(都很接近0; 符合標準常態分布) <=> 調整w, b去最大化Log Likelihood使得所有樣本誤差於0附近跳動(都很接近0; 符合標準常態分布)
* $Log~Likelihood \sim -\frac{1}{2} \sum_j ( \hat{y}^{(j)} - y^{(j)})^2$
* Let $Loss = -Log~Likelihood$後, 可發現:
* 調整$w$, $b$去**最大化** $Log~Likelihood$ 使得所有樣本誤差於0附近跳動(都很接近0; 符合標準常態分布) <=>
* 調整w, b去**最小化** $Loss(=\frac{1}{2} \sum_j ( \hat{y}^{(j)} - y^{(j)})^2)$使得所有樣本誤差於0附近跳動(都很接近0; 符合標準常態分布) -> 得到 **Mean Square Error Loss **.
## 環境設置
### 建置 virtualenv
開啟anaconda prompt終端機. 執行以下指令, 以使用Anaconda建置本次課程使用的虛擬環境(virtualenv):
```python=
conda create -n ml python=3.10
```
### Poetry 設置
* [Poetry 網站](https://python-poetry.org/docs/#installing-with-the-official-installer)
1. 安裝Poetry
```bash=
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -
```
2. 設定Poetry
依照Poetry建議, 將`C:\Users\Student\AppData\Roaming\Python\Scripts` 加入PATH.加好後重啟終端機, 執行`poetry`, 看是否生效.
```bash=
poetry config virtualenvs.path C:\Users\Student\anaconda3\envs\ml
poetry config virtualenvs.create false
```
3. 安裝課程相關套件
![未命名](https://hackmd.io/_uploads/H1NgzirEp.png)
### Python Coding Style
* Linter: `pylance`
* Formatter: `black`, `isort`
* 設置Black (format on save)
![未命名.png](https://hackmd.io/_uploads/S17227Q7a.png)
* 設置isort (sort on save)
將下述設定加到`settings.json`:
```json
"editor.codeActionsOnSave": {
"source.organizeImports": true
}
```
![未命名2.png](https://hackmd.io/_uploads/rkOLAmX7p.png)
* 加強自己程式碼的易讀性
* 善用`docstring`, `type hint`
* follow, e.g., [Google's Python Coding Style Guide](https://google.github.io/styleguide/pyguide.html)
* vscode常用套件?
* `even better toml`, `reload`, `remote ssh`, `Docker`, ...
* jupyter notebook:
* 搜尋notebook format on save, 把它打勾
* type hint:
* 搜尋type hint, 開啟python analysis -> inlay hint (將function return types那一行打勾)
---
## 參考連結
* Code Refactor: https://refactoring.guru/refactoring/how-to
* Design Pattern, Python basics: https://www.youtube.com/@ArjanCodes
* Find state-of-art model implementations (if papers are with codes :arrow_right: :100:): https://paperswithcode.com
* Understand CNN basics (:100: you must read this, understand every lines of words): https://cs231n.github.io
* karparthy: https://www.youtube.com/results?search_query=karparthy
* Learn Deep Learning basics (Wow! Learning by doing! :100:): https://zh.d2l.ai
* Machine Learning basic theories (:100: for those who wants to understand every general bits of maths in Machine Learning): https://cs229.stanford.edu/notes2022fall/main_notes.pdf
* Understand Backpropagation: https://www.cs.toronto.edu/~hinton/absps/NatureDeepReview.pdf
* Python Machine Learning (Sebastian Raschka)
* Keras book: https://www.manning.com/books/deep-learning-with-python
---
wengchihung@gmail.com