廣義上的可解釋性指:html
在咱們須要瞭解或解決一件事情的時候,咱們能夠得到咱們所須要的足夠的能夠理解的信息。
好比咱們在調試 bug 的時候,須要經過變量審查和日誌信息定位到問題出在哪裏。git
好比在科學研究中面臨一個新問題的研究時,咱們須要查閱一些資料來了解這個新問題的基本概念和研究現狀,以得到對研究方向的正確認識。github
反過來理解,若是在一些情境中咱們沒法獲得相應的足夠的信息,那麼這些事情對咱們來講都是不可解釋的。好比劉慈欣的短篇《朝聞道》中霍金提出的「宇宙的目的是什麼」這個問題一會兒把無所不知的排險者卡住了,由於再高等的文明都沒辦法理解和掌握造物主創造宇宙時的所有信息,這些終極問題對咱們來講永遠都是不可解釋的。面試
在傳通通計中,咱們經過調查大量的數據來構造和驗證假設。咱們創建模型來構建規則,咱們能夠將其歸入咱們的模型中。算法
例如,營銷公司能夠創建一個模型,將營銷活動數據與財務數據相關聯,以肯定構成有效營銷活動的是什麼。這是一種自上而下的數據科學方法,可解釋性是關鍵,由於它是所定義規則和過程的基石。因爲相關性每每不等於因果關係,因此在進行決策和解釋時,須要對模型進行很強的理解。安全
做爲一名數據分析從業者,咱們常常關心微調模型以得到最佳性能。網絡
數據科學一般被定義爲:'給出具備X標籤的數據,並以最小偏差找到模型'。併發
儘管訓練高性能模型的能力對於數據科學家來講是一項關鍵技能,但可以從更大的角度來看是很重要的。app
數據和機器學習模型的可解釋性是在數據科學的 「有用性」中相當重要的方面之一,它確保模型與您想要解決的問題保持一致,可以正確地解釋你的發現是數據科學過程的重要組成部分。dom
而具體到機器學習領域來講,以最用戶友好的決策樹模型爲例,模型每做出一個決策都會經過一個決策序列來向咱們展現模型的決策依據:
好比男性&未婚&博士&禿頭的條件對應「不感興趣」這個決策。
並且決策樹模型自帶的基於信息理論的篩選變量標準也有助於幫助咱們理解在模型決策產生的過程當中哪些變量起到了顯著的做用。
因此在必定程度上,咱們認爲決策樹模型是一個具備比較好的可解釋性的模型。
再以用戶最不友好的多層神經網絡模型爲例,模型產生決策的依據是什麼呢?
大概是以好比 1/(e^-(2*1/(e^(-(2*x+y))+1) + 3*1/(e^(-(8*x+5*y))+1))+1) 是否大於 0.5 爲標準(這已是最簡單的模型結構了),這一連串的非線性函數的疊加公式讓人難以直接理解神經網絡的「腦回路」,因此深度神經網絡習慣性被你們認爲是黑箱模型。
人腦是不擅長理解非線性關係,更不要說是有層層組合後的複雜非線性組合。
因此,一個很天然的思考對策是,須要找一種維度較低的低階近似映射(即找到一種低維度的表徵方法),使得在即不損失太多原高階決策超曲面空間分佈的前提下,找到一種低階的決策曲面。這樣,人類就能夠從低階的決策曲面中得以一窺原始高階決策超曲面的尊容了。
筆者思考:按照這種思路,其實咱們能夠看到,t-SNE、PCA降維後可視化就是一種低階近似映射。
廣義上來講咱們對深度學習模型的可解釋性的需求主要來源於對問題和任務瞭解得還不夠充分。
儘管高度的非線性賦予了多層神經網絡極高的模型表示能力,配合一些合適的調參技術能夠在不少問題上達到很是喜人的表現。
一個很難受的問題是,雖然咱們造出了準確度極高的機器,但最後只能獲得一堆看上去毫無心義的模型參數和擬合度很是高的斷定結果。做爲模型開發者,咱們顯然不能僅僅知足於模型效果好便可。
實際上,對模型可解釋性的探究就是在探尋模型work well的原理,瞭解到了原理,也許就不須要進行不少無用的模型調參工做,優化的方向也會更有方向性。
從模式識別的角度來看,模型自己也意味着知識(或者說模型自己存儲了一些模式知識),咱們但願知道模型究竟從數據中學到了哪些知識(以人類能夠理解的方式表達的)從而產生了最終的決策。從中是否是能夠幫助咱們發現一些潛在的關聯。
好比我想基於深度學習模型開發一個幫助醫生斷定病人風險的應用,除了最終的斷定結果以外,我可能還須要瞭解模型產生這樣的斷定是基於病人哪些因素的考慮。
誤差可能存在於任何數據集中,數據科學家須要肯定並嘗試修正誤差。
1. 數據集的規模可能有限,而且不能表明全部數據。 2. 或者數據捕獲過程可能沒有考慮到潛在的誤差。
在完全進行數據分析後,或者分析模型預測與模型輸入之間的關係時,誤差每每會變得明顯。
請注意,解決誤差問題沒有惟一的解決方案,可是可解釋性的關鍵一步是意識並發現潛在的誤差。
虛擬一個簡歷篩選的場景,咱們對面試者投遞的簡歷進行了分詞後,創建了word index table,可是一個很容易被忽視的問題是,對於一家IT公司的技術部門來講,男性求職者每每佔了絕大多數的比例,所以像相似「技術簡歷」這種詞有更大的可能性會出如今男性求職者的簡歷中。
當使用這些詞向量進行訓練模型時,招聘人員搜索「技術簡介」將使女性履歷保留在最下面。
可是另外一方面咱們也須要注意,若是這種誤差是咱們有意而爲之的,則這種bais就是能夠接受的。例如咱們的目標並非平等地搜索求職者簡歷,而是儘量發現有技術能力的求職者,或者咱們的招聘更傾向於男性,則這種word table index編碼方式就沒有問題。
總之,數據挖掘項目中的誤差須要謹慎對待,它可能對咱們是有益的也多是有害的。
例如當您在小型數據集上訓練目標檢測模型時,一般狀況下圖像的寬度太有限。爲了不只適用於數據中噪音和不重要元素的模型,須要在不一樣環境,不一樣光照條件和不一樣角度下的各類物體圖像。
在非圖像領域,尤爲是NLP文本檢測領域,不一樣文本風格(代碼風格)的樣本數量經常是分佈不均的,這點在WEBSHELL網站後門中很是常見,黑客們會傾向於使用某一種或某幾種WEBSHELL樣本,這種誤差會帶來的最明顯問題是,模型可能會忽視某些很是小衆的黑樣本。
在大多數問題中,您正在使用的數據集僅僅是您正試圖解決的問題的粗略表示,而機器學習模型沒法捕捉到真實任務的完整複雜性。純理論上的無窮大N樣本在實際工程中是很是難達到的。
這個時候,可解釋模型可幫助您瞭解並解釋模型中包含和未包含的因素。
高解釋性模型一般有更好的泛化能力。
可解釋性不是要了解全部數據點的模型的每一個細節。必須將可靠的數據,模型和問題理解結合起來才能得到性能更好的解決方案。
筆者在行業內以及在技術圈子內,近幾年不斷看到不少效果很好的實際工程應用,深度學習模型在海量數據以及大規模深度結構下,取得至關好,甚至超過國際上老牌AV引擎的檢測能力。從結果上看,咱們彷佛也不是那麼須要可解釋性,畢竟結果纔是最重要的,世界上不能解釋的事情太多了,也不見得每件事都能獲得完美的可解釋性。
可是筆者認爲,依然存在一些場景下,咱們會須要可解釋性:
某天下午晴空萬里,咱們正在位子上寫博客,忽然一堆誤報告警響起,你的深度模型遇到了一批誤報。你緊急下線了該模型,平復了一下心情,接下來要作的是找到誤報的緣由。
可是如今問題來了,你的模型有2000w的自有參數,層與層之間徹底是非線性的組合,如何知道究竟是哪些神經元致使了對這批樣本的誤報呢?這批致使誤報的樣本的共性是什麼?其中的哪些特徵模式被模型誤認定爲是一個黑模式了呢?
這一連串的問題,會驅動咱們去更深刻地探究咱們訓練出的深度學習模型的可解釋性。
相信你們在進行模型開發的過程當中,都會經歷一個階段,大量的翻閱google上的學術paper,嘗試各類神經網絡組合,會發現如今有很是多的神經網絡結構被提出,論文裏的實驗結果也很是驚豔,這個時候,咱們會抱着「僥倖心理」去進行大量嘗試,雖然paper裏的問題場景咱們的項目可能並不一致。
最終經過數週的大量實驗,咱們「摸索」出了一種模型結構,在訓練集和驗證集上的表現都很好,都拿到了99.8/99.9的acc,但仍是有少許的誤報(筆者所在的行業是誤報敏感型的,漏報相對還能夠接受),這個時候咱們會面臨一個問題,接下來怎麼優化?繼續增大樣本?仍是繼續翻閱paper,優化模型結構?是否不一樣的神經網絡結構之間存在一些原理上的共性?
想要系統化、工程化的解決這個問題,就須要進行可解釋性的研究。例如咱們經過可解釋性的可視化獲得了模型的熱點權重分佈,即分析出模型對輸入特徵空間中的哪些特徵維度更「看中」,對另一些特徵維度「相對輕視」,而這有可能偏偏就是致使咱們誤報的緣由之一。
Relevant Link:
https://www.leiphone.com/news/201805/Ti3mOdeRlWTplIlZ.html https://cloud.tencent.com/developer/article/1096716 https://zhuanlan.zhihu.com/p/38151985 https://www.jiqizhixin.com/articles/2018-01-10
機器學習的目的是從數據中發現知識或解決問題,那麼在這個過程當中只要是可以提供給咱們關於數據或模型的能夠理解的信息,有助於咱們更充分地發現知識、理解和解決問題的方法,那麼均可以歸類爲可解釋性方法。若是按照可解釋性方法進行的過程進行劃分的話,大概能夠劃分爲三個大類:
1. 在建模以前的可解釋性方法 2. 創建自己具有可解釋性的模型 3. 在建模以後使用可解釋性方法對模型做出解釋
這一類方法其實主要涉及一些數據預處理或數據展現的方法。機器學習解決的是從數據中發現知識和規律的問題,若是咱們對想要處理的數據特徵所知甚少,期望對所要解決的問題自己有很好的理解是不現實的。所以,在建模以前的可解釋性方法的關鍵在於幫助咱們迅速而全面地瞭解數據分佈的特徵,從而幫助咱們考慮在建模過程當中可能面臨的問題並選擇一種最合理的模型來逼近問題所能達到的最優解。
數據可視化方法就是一類很是重要的建模前可解釋性方法。大多數時候,咱們在真正要研究一個數據問題以前,經過創建一系列方方面面的可視化方法來創建咱們對數據的直觀理解是很是必須的,特別是當數據量很是大或者數據維度很是高的時候,好比一些時空高維數據,若是能夠創建一些一些交互式的可視化方法將會極大地幫助咱們從各個層次角度理解數據的分佈。
這方面的相關討論,能夠參閱個人另外一篇blog。
還有一類比較重要的方法是探索性質的數據分析,能夠幫助咱們更好地理解數據的分佈狀況。好比一種稱爲 MMD-critic 方法中,能夠幫助咱們找到數據中一些具備表明性或者不具表明性的樣本。
特徵重要性是解釋模型的一種基本方法
模型自己具有可解釋性是最好也是最直接的一類可解釋性方法,一樣也是一類要求和限定很高的方法(深度神經網絡在不少狀況下就不具有可解釋性),具有可解釋性模型大概能夠分爲如下幾種
1. 基於規則的方法(Rule-based) 2. 基於單個特徵的方法(Per-feature-based) 3. 基於實例的方法(Case-based) 4. 稀疏性方法(Sparsity) 5. 單調性方法(Monotonicity)
基於規則的方法好比咱們提到的很是經典的決策樹模型。這類模型中任何的一個決策鏈均可以對應到一個邏輯規則表示。在決策樹中,可解釋性經過一連串的 if-else 邏輯組合來表達,
但當規則表示過多或者原始的特徵自己就不是特別好解釋的時候,基於規則的方法有時候也不太適用。
基於單個特徵的方法主要是一些很是經典的線性模型,好比線性迴歸、邏輯迴歸、廣義線性迴歸、廣義加性模型等,這類模型能夠說是如今可解釋性最高的方法。線性迴歸方程中的 w 和 b 自己就有很是強的可解釋性。
線性迴歸可謂是一種很是經典的數學模型,在計量經濟學中,大半本書都在討論線性模型,包括經濟學及相關領域的論文其實大多數也都是使用線性迴歸做爲方法來進行研究。這種很是經典的模型全世界每秒都會被用到大概 800 多萬次。
爲何你們這麼青睞這個模型呢?除了模型的結構比較簡單以外,更重要的是線性迴歸模型及其一些變種擁有很是 solid 的統計學基礎,統計學能夠說是最看重可解釋性的一門學科了,上百年來無數數學家統計學家探討了在各類不一樣狀況下的模型的參數估計、參數修正、假設檢驗、邊界條件等等問題,目的就是爲了使得在各類不一樣狀況下都能使模型具備有很是好的可解釋性。
基於實例的方法主要是經過一些表明性的樣原本解釋聚類/分類結果的方法。經過觀察表明性的樣本,咱們能夠直觀得得到其對應族類的樣本宏觀特徵。
好比下圖所展現的貝葉斯實例模型(Bayesian Case Model,BCM),咱們將樣本分紅三個組團,能夠分別找出每一個組團中具備的表明性樣例和重要的子空間。
對於下面第一類聚類來講:
綠臉是具備表明性的樣本;而綠色、方塊是具備表明性的特徵子空間(包含2個特徵維度)。
由此,咱們能夠獲得初步判斷,第一類的宏觀特徵是一堆綠臉方塊。
筆者思考:社區發現的聚類中心、Kmeans聚類的聚類質心本質上也能夠提供一種基於實例的數據可視化視角。
關於社區發現的相關討論,能夠參閱個人另外一篇blog。
基於稀疏性的方法主要是利用信息的稀疏性特質,將模型儘量地簡化表示。
好比以下圖的一種圖稀疏性的 LDA 方法,根據層次性的單詞信息造成了層次性的主題表達,這樣一些小的主題就能夠被更泛化的主題所歸納,從而可使咱們更容易理解特定主題所表明的含義。
在不少機器學習問題中,有一些輸入和輸出之間存在正相關/負相關關係,若是在模型訓練中咱們能夠找出這種單調性的關係就可讓模型具備更高的可解釋性。
好比醫生對患特定疾病的機率的估計主要由一些跟該疾病相關聯的高風險因素決定,找出單調性關係就能夠幫助咱們識別這些高風險因素。
可是同時另外一方面,不少狀況下,輸入數據的特徵空間是高維特徵,例如筆者所在的安全領域,抽象後的向量特徵經常高達上萬,面對這種高維數據,尋找input-ouput之間的線性相關,是很是困難的。
建模後的可解釋性方法主要是針對具備黑箱性質的深度學習模型而言的,主要分爲如下幾類的工做:
1. 隱層分析方法 2. 模擬/代理模型 3. 敏感性分析方法
Relevant Link:
https://www.leiphone.com/news/201805/Ti3mOdeRlWTplIlZ.html https://new.qq.com/omn/20180117/20180117A0T4JE.html
Lime可經過可視化的方式向咱們展現機器學習決策器是根據哪些「因素」進行了綜合決策的。
直觀上說,Lime採用了局部線性近似來對目標模型進行模擬。雖然目標模型自己可能在全局上很是複雜,可是咱們卻能夠較容易地針對一個特徵的局部實例進行近似模擬。
咱們將目標模型視做一個黑盒,經過不斷的漸進試探以學習到一個低維稀疏的線性模型,做爲一個解釋。
下圖是一個複雜模型的決策函數,藍色/粉色背景表示兩個決策面,很顯然,這是非線性的。
圖中亮紅色的叉叉就是Lime獲得的解釋實例,咱們圍繞解釋實例 X 進行採樣,採樣的權重標準就是和 X 的近似程度(在這裏就是size),咱們隨後獲得一個線性模型,即虛線。
顯然,這是一個局部近似的線性模型,不是全局的。
# -*- coding: utf-8 -*- import lime import sklearn import numpy as np import sklearn import sklearn.ensemble import sklearn.metrics # For this tutorial, we'll be using the 20 newsgroups dataset. In particular, for simplicity, we'll use a 2-class subset: atheism and christianity. from sklearn.datasets import fetch_20newsgroups categories = ['alt.atheism', 'soc.religion.christian'] newsgroups_train = fetch_20newsgroups(subset='train', categories=categories) newsgroups_test = fetch_20newsgroups(subset='test', categories=categories) class_names = ['atheism', 'christian'] # Let's use the tfidf vectorizer, commonly used for text. vectorizer = sklearn.feature_extraction.text.TfidfVectorizer(lowercase=False) train_vectors = vectorizer.fit_transform(newsgroups_train.data) test_vectors = vectorizer.transform(newsgroups_test.data) # Now, let's say we want to use random forests for classification. It's usually hard to understand what random forests are doing, especially with many trees. rf = sklearn.ensemble.RandomForestClassifier(n_estimators=500) rf.fit(train_vectors, newsgroups_train.target) pred = rf.predict(test_vectors) res = sklearn.metrics.f1_score(newsgroups_test.target, pred, average='binary') print res # Explaining predictions using lime from lime import lime_text from sklearn.pipeline import make_pipeline c = make_pipeline(vectorizer, rf) print(c.predict_proba([newsgroups_test.data[0]])) # Now we create an explainer object. We pass the class_names a an argument for prettier display. from lime.lime_text import LimeTextExplainer explainer = LimeTextExplainer(class_names=class_names) # We then generate an explanation with at most 6 features for an arbitrary document in the test set. idx = 83 exp = explainer.explain_instance(newsgroups_test.data[idx], c.predict_proba, num_features=6) print('Document id: %d' % idx) print('Probability(christian) =', c.predict_proba([newsgroups_test.data[idx]])[0,1]) print('True class: %s' % class_names[newsgroups_test.target[idx]]) # The classifier got this example right (it predicted atheism). # The explanation is presented below as a list of weighted features. print exp.as_list() # These weighted features are a linear model, which approximates the behaviour of the random forest classifier in the vicinity of the test example. # Roughly, if we remove 'Posting' and 'Host' from the document , the prediction should move towards the opposite class (Christianity) by about 0.27 (the sum of the weights for both features). # Let's see if this is the case. print('Original prediction:', rf.predict_proba(test_vectors[idx])[0,1]) tmp = test_vectors[idx].copy() tmp[0,vectorizer.vocabulary_['Posting']] = 0 tmp[0,vectorizer.vocabulary_['Host']] = 0 print('Prediction removing some features:', rf.predict_proba(tmp)[0,1]) print('Difference:', rf.predict_proba(tmp)[0,1] - rf.predict_proba(test_vectors[idx])[0,1]) # The explanations can be returned as a matplotlib barplot: fig = exp.as_pyplot_figure() # The explanations can also be exported as an html page (which we can render here in this notebook), using D3.js to render graphs. exp.show_in_notebook(text=False) # Alternatively, we can save the fully contained html page to a file: exp.save_to_file('./oi.html') # Finally, we can also include a visualization of the original document, with the words in the explanations highlighted. Notice how the words that affect the classifier the most are all in the email header. exp.show_in_notebook(text=True)
Relevant Link:
https://github.com/marcotcr/lime https://www.oreilly.com/learning/introduction-to-local-interpretable-model-agnostic-explanations-lime