AI相關公司愛考的面試題目(4) How do you detect if a new observation is outlier? What is a bias-variance trade off ?
這是Microsoft微軟 AI/Data Science Related 職位考題的其中一題。
它的全部題目就是: How do you detect if a new observation is outlier? What is a bias-variance trade off ?
也就是問說,如果即將被觀察到的資料點是一個離群值(outlier),我們要怎麼去偵測? 或怎麼得知它就是離群值? 然後請解釋甚麼是 bias-variance trade off。
為什麼這兩個概念會被放在一起考呢?以下我引用一段內容來自Outlier Treatment (Method) | CROS (europa.eu)
The objective of outlier treatment is to make estimates for the population coherent with the real parameters for the population. This means that outlier treatment should be always a trade-off between variance and bias.
代表著離群值的發現和處理是跟variance和bias之間的權衡是息息相關。
什麼是離群值?
對有接觸統計,或機器學習的朋友來說,這個名詞一定不陌生。以機器學習的角度,建立模型的基礎通常是來自資料集,若在收集資料的過程中,因某些狀況導致資料集中有部分資料的性質和內容與整體樣本差異很大,我們就會稱這些資料為離群值。
為什麼離群值需要被關注?
離群值的發生通常是因為資料輸入時發生誤植、筆誤,也有可能是某個群體內的少數特例。在這樣的情況下,離群值的存在會破壞整個樣本的一致性,它會影響機器學習的效果還有預測的準確性,導致分析後的結果難以解釋。
離群值除了會影響到預測的準確性之外,它在某些特殊的應用場景其實扮演了非常重要的角色,例如疾病預測,如果一個人身上有些特殊的指標產生異常,或是一群人中有一小群人發生了異常生理現象,這類的離群值就是一個非常重要的起點。
這類的情況也常用在網路詐騙、信用卡盜刷、網路攻擊等情況,整體來說,就是有一小群特別的資料,但會對整個群體產生重大影響的異常資料,所以離群值的偵測和處理,無論在統計或資料科學,都是一個重要的議題。
如何檢測離群值?
既然離群值會對我們的預測結果帶來重大的影響,找出他們也就變得相當重要。一般離群值的偵測方法會視資料集的特性進行選擇,有基於統計的原理、密度或聚類(clustering)的方式,以下介紹4個經常使用的方法。
- 3倍標準差法 (Three standard deviation method):
常態分布下,和平均值偏離一個標準差以內的數據會佔68.27%,偏離二個標準差以內的數據會到95.45%,偏離三個標準差以內的數據會到99.73%。
那如果跑到3倍標準差外的那些資料屬於小機率事件,這種資料可以歸為離群值。當然如果資料不符合常態分布,那你也可以自行設定遠離平均值外多少倍的標準差當作你認定的離群值。
2.盒箱法 (Boxplots):
這種方法是利用箱型圖(Boxplot)的四分位距(IQR)對離群值進行檢測,其中箱型圖的概念如下:
畫箱型圖的 Pyhton Code 順道附上:
# Inputimport pandas as pd
import matplotlib.pyplot as plt
data = [1, 2, 3, 4, 5, 6, 7, 8]
df = pd.DataFrame(data)
print(df.describe())
df.plot.box(title="Box Chart")
plt.grid(linestyle="--", alpha=0.3)
plt.show()#Output0
count 8.00000 # 條數
mean 4.50000 # 均值
std 2.44949 # 標準差
min 1.00000 # 最小值
25% 2.75000 # 下四分位
50% 4.50000 # 中位數
75% 6.25000 # 上四分位
max 8.00000 # 最大值
四分位距(IQR)就是上四分位與下四分位的差值。而我們通過IQR的1.5倍為標準,規定:超過上四分位+1.5倍IQR距離,或者下四分位-1.5倍IQR距離的點為離群值。
3.DBScan Clustering:
DBScan是一種Cluster-based的演算法,它基於數據間的密度進行分群,可以處理多維度的資料集,其它Cluster-Based的算法還有K-means也可以進行分群分析。
DBScan有3個重要的points :
・Core Point(核心點)
・Board Point (邊界點)
・Noise Point (離群點)
請觀察下圖: 其中N為離群點, B,C為邊界點,A為核心點。
上面這些點是分佈在樣本空間的樣本,我們的目標是把這些在樣本空間中距離相近的歸類成一群。發現A點附近的點密度較大,紅色的圓圈根據一定的規則在這裡分佈,最終集結了A附近的5個點,皆標記為紅色也就是定為同一群(Cluster)。其它沒有被收納的根據一樣的規則成Cluster。
實務上我們在眾多樣本點中隨機選中一個點,圍繞這個被選中的樣本點畫一個圓,規定這個圓的半徑以及圓內最少包含的樣本數,如果在指定半徑內有足夠多的樣本在內,那麼這個圓圈的圓心就轉移到這個內部樣本點,繼續去圈附近其它的樣本,不斷移動的圈,直到發現所圈住的樣本點數量少於預先指定的值(黃色圈圈),就得停止。
那麼我們稱最開始那個點為核心點,如A,停下來的那個點為邊界點,就是B和C,而最後壓根沒被圈到的那些點就是離群點了,那就是N點。
Python Code如下:
print(__doc__)import numpy as npfrom sklearn.cluster import DBSCAN
from sklearn import metrics
from sklearn.datasets import make_blobs
from sklearn.preprocessing import StandardScaler# #############################################################################
# Generate sample data
centers = [[1, 1], [-1, -1], [1, -1]]
X, labels_true = make_blobs(n_samples=750, centers=centers, cluster_std=0.4,
random_state=0)X = StandardScaler().fit_transform(X)# #############################################################################
# Compute DBSCAN
db = DBSCAN(eps=0.3, min_samples=10).fit(X)
core_samples_mask = np.zeros_like(db.labels_, dtype=bool)
core_samples_mask[db.core_sample_indices_] = True
labels = db.labels_# Number of clusters in labels, ignoring noise if present.
n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0)
n_noise_ = list(labels).count(-1)print('Estimated number of clusters: %d' % n_clusters_)
print('Estimated number of noise points: %d' % n_noise_)
print("Homogeneity: %0.3f" % metrics.homogeneity_score(labels_true, labels))
print("Completeness: %0.3f" % metrics.completeness_score(labels_true, labels))
print("V-measure: %0.3f" % metrics.v_measure_score(labels_true, labels))
print("Adjusted Rand Index: %0.3f"
% metrics.adjusted_rand_score(labels_true, labels))
print("Adjusted Mutual Information: %0.3f"
% metrics.adjusted_mutual_info_score(labels_true, labels))
print("Silhouette Coefficient: %0.3f"
% metrics.silhouette_score(X, labels))# #############################################################################
# Plot result
import matplotlib.pyplot as plt# Black removed and is used for noise instead.
unique_labels = set(labels)
colors = [plt.cm.Spectral(each)
for each in np.linspace(0, 1, len(unique_labels))]
for k, col in zip(unique_labels, colors):
if k == -1:
# Black used for noise.
col = [0, 0, 0, 1]class_member_mask = (labels == k)xy = X[class_member_mask & core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
markeredgecolor='k', markersize=14)xy = X[class_member_mask & ~core_samples_mask]
plt.plot(xy[:, 0], xy[:, 1], 'o', markerfacecolor=tuple(col),
markeredgecolor='k', markersize=6)plt.title('Estimated number of clusters: %d' % n_clusters_)
plt.show()
#Ref: Demo of DBSCAN clustering algorithm — scikit-learn 1.0 documentation
Output:
探討: 除了detect這些離群值之外,該怎麼處理它們?
面對這些離群值,我們該怎麼處理? 前面提到關於離群值的檢測方法,那接下來該怎麼處理這些離群值?
以下為四個常見的處理方法:
1.直接刪除:確認過離群值對於資料集來說並無存在特殊意義,直接將該值刪除。
2.視為遺失值:將異常值視為遺失值,後續利用處理缺失值的方法進行。
3.用平均值調整:利用前後兩個資料點的平均值修正該異常值。
4.不處理:忽視異常值,直接對資料集進行後續分析。
接下來處理: What is a bias-variance trade off? 這一題吧。
Bias-Variance Trade-off 是機器學習領域中非常核心與重要的基礎理論。 它的推導過不算難,但要準確地理解它並且能夠靈活運用卻也不是非常容易 。 此QA出發點是結合機器學習中的一些實踐,去剖析此理論,希望力求做到理論與應用的相結合,盡量站在基於理論基礎去探索演算法本質展開。
對於機器學習的新手而言,正則化,交叉檢驗以及隨機森林演算法應該都是耳熟能詳的內容了。 正則化和交叉檢驗基本是模型訓練的標配; 而隨機森林是在深度學習出來之前非常強大的一個bagging演算法,因其效果的穩定與優秀,常被用於作為baseline模型。 現在我們知道他們是有用的,下面我們會做的就是基於Bias-Variance Trade-off去解釋他們為什麼有用,以及他們的應用極限在哪裡。
1. 什麼是偏差?
偏差,顧名思義,就是我們模型的預測值與真實值偏了,距離之差是多少。 所以偏差就是我們模型平均預測值與真實值之間的距離。
偏差大的模型,它通常不怎麼從訓練集里學習到東西,導致模型過於簡單,自然在預測測試集的時候,效果不好。
2. 什麼是方差?
這裡的方差依舊和我們統計學學的方差是一個意思,描述數據分佈的分散程度。 這裏的數據分佈,就是我們模型預測值的數據分佈。 從式子本身來看,是與真實值沒有關係的。
方差大的模型,往往是從訓練集裡學了太多東西,簡稱過擬合。 所以導致在測試集的表現時好時壞,預測值的數據分佈就離散了,方差也就大了。
相信以下這張圖大家都看過,在low variance且low bias的時候是不太好的情形因為overfitting了,資料太過集中也太過準確了。再來High variance,Low bias就變成資料點變散了,但平均下來準確值是夠的,這是最好的狀況。然後是High bias,Low variance,是資料離正確答案雖遠, 但資料集中。最後一個是High Bias,High variance,資料分散且非常不集中,就是所謂underfitting的狀況。
再引入一張被整理過underfitting和overfitting狀況的Matrix圖。
Ref:Bias Variance Trade-off in ML; Introduction for Beginners — Skilllx
3. 偏差和方差之間的權衡( Bias-Variance trade off)
先瞭解數學原理:
看以上式子: 誤差平均值的期望值可以被解剖成三個部分,分別是偏差的平方、方差和不可約的錯誤(因為數據集多少會有一些noise,但這是絕對可以接受的,而且也是無論換什麼模型都無可避免的問題)。
如下圖,通常一個模型Variance很高,意味著它往往很複雜,而複雜的模型往往會對某些樣本點非常敏感,也就很可能Overfitting。 同樣的,一個模型如果Bias很高,意味著他一直都很不準,所以Underfitting。 而我們的目標則是在模型的複雜度之間找到一個平衡,從而使Bias 和Variance都盡可能低,從而得到一個相對最好的Fitting的結果。
比如,對於同樣的數據集,我們訓練一個決策樹,需要設置樹的深度。 我們既不能讓他太深使令模型太複雜,因為複雜的模型往往意味著不具備Generalization,也就很可能Overfitting;也不能太淺使模型太簡單,因為太簡單的決策樹意味著我們並沒有應用足夠的條件去劃分數據,也就是Underfitting。
通常來說模型複雜度和模型的Error的關係可以用下圖表示(對於一個實驗,我們專注於找到最小的Total Error 的模型複雜度)
可以觀察到:
- 在 Underfitting 的時候,不論是在 Training set 還是Testing set 的 Error 都很高。
- 在 Overfitting 的時候,Training set 的 Error 已經將降低了,但 Testing set 上的 Error 會很高。
有了這兩個重要的觀察,在訓練的時候我們就可以較容易的判斷 model fitting 好壞了。
最後來探討一下Overfitting和Underfitting的解決之道:
我們在訓練一個 ML model 的時候,Overfitting 與 Underfitting 是一個非常實際的問題,也非常容易發生,所以也就有一招又一招的解決辦法。
Underfitting
- 發生 Underfitting 的根本原因是由於模型太過簡單,所以根本的解決方案就是提高模型的複雜度,可以透過:
- 增加訓練的疊代次數
- 調整超參數 ( 修改模型架構 )
- 生成更多的特徵來訓練模型
- 如果有使用正規化 ( Regularization ) 可先將其移除
- 更換一個更複雜的模型
Overfitting
- 發生 Overfitting 的根本原因是由於模型太過複雜,所以根本的解決方案就是降低模型的複雜度,可以透過:
- Early Stopping
- 增加訓練資料
- 降低特徵維度
- 如果沒有使用正規化 ( Regularization ) 可以將其加入
- 調整超參數 ( 修改模型架構 )
- 更換一個較為簡單的模型
好的,此篇資訊量就先到這,不再衍生。
I’m Kevin.
See you.