拓撲機器學習的神聖三件套:Gudhi,Scikit-Learn和Tensorflow(附...

2021-01-10 AI科技大本營

來源 | 數據派THU

Hi大家好。今天,我想強調下在機器學習中拓撲數據分析(TDA,Topological Data Analysis)的力量,並展示如何配合三個Python庫:Gudhi,Scikit-Learn和Tensorflow進行實踐。

拓撲數據分析?

首先,讓我們談談TDA。它是數據科學中相對小眾的一個領域,尤其是當與機器學習和深度學習對比的時候。但是它正迅速成長,並引起了數據科學家的注意。很多初創企業和公司正積極把這些技術整合進它們的工具箱中(比如IBM,Fujitsu,Ayasdi),原因則是近年來它在多種應用領域的成功,包括生物學、時間序列、金融、科學可視化、計算機圖形學等。未來我可能會寫一個關於TDA一般用途和最佳實踐的帖子,所以請大家等待下。

TDA:

https://en.wikipedia.org/wiki/Topological_data_analysis

IBM:

https://researcher.watson.ibm.com/researcher/view_group.php?id=6585

Fujitsu:

https://www.fujitsu.com/global/about/resources/news/press-releases/2016/0216-01.html

Ayasdi:

https://www.ayasdi.com/platform/technology/

生物學:

https://www.ncbi.nlm.nih.gov/pubmed/28459448

時間序列:

https://www.ams.org/journals/notices/201905/rnoti-p686.pdf

金融:

https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2931836

科學可視化:

https://topology-tool-kit.github.io/

計算機圖形學:

http://www.lix.polytechnique.fr/~maks/papers/top_opt_SGP18.pdf

TDA的目標是對你數據的拓撲性質進行計算和編碼,這意味著記錄數據集中多樣的連接成分,環,腔和高維結構。這非常有用,主要是因為其他描述符不可能計算這類信息。所以TDA真的儲存了一組你不可能在其他地方找到的數據特徵。現實情況是這類特徵已被證明對提升機器學習預測能力很有用,所以如果你以前還沒見過或聽過這類特徵,我來帶你快速了解一下。

我已經寫過很多這個主題的文章,你可以在Medium找到關於TDA的很多其他帖子,所以我不打算浪費時間在數學定義上面,而是通過解釋TDA文獻中的典型例子,來展示如何在你的數據集上應用TDA。

文章:

https://towardsdatascience.com/mixing-topology-and-deep-learning-with-perslay-2e60af69c321

帖子:

https://towardsdatascience.com/applied-topological-data-analysis-to-deep-learning-hands-on-arrhythmia-classification-48993d78f9e6

TDA的參考示例:點雲分類

這個數據集在一篇開創性的TDA文章上介紹過。它由通過下述動力系統生成的軌跡來得到的點雲集組成

開創性的TDA文章

http://jmlr.org/papers/v18/16-337.html

一個動力系統的方程

這意味著我們將從一個單位正方形內隨機抽取一個初始點,並通過上面的方程生成一個點的序列。這將給我們一個點雲。現在我們可以根據意願重複這個操作,得到一堆點雲。這些點雲的一個有趣的屬性在於,根據你用來生成點序列的r參數的值,點雲會有非常不一樣且有意思的結構。比如,如果r=3.5,得到的點雲似乎覆蓋了整個單位正方形,但如果r=4.1,單位正方形的一些區域就是空的:換句話說,在你的點雲裡有好多洞。這對我們是個好消息:TDA可以直接計算這些結構是否能出現。

r=3.5(左)和r=4.1(右)計算出的點雲。相當明顯的是後者有個洞,但前者沒有

TDA跟蹤這些洞的方式實際上相當簡單。想像給定半徑為R的每個球的圓心都在你點雲的每個點上。如果R=0,這些球的併集就是點雲本身。如果R為無窮,那麼球的併集是整個單位正方形。但如果R被很精心的選擇,球的併集可能存在很多拓撲結構,比如,洞。

球併集的例子。對於中間圖的併集,它清晰的組成了一個洞。整張圖片被我「不要臉」地借用自我之前的一個帖子

帖子:

https://towardsdatascience.com/a-concrete-application-of-topological-data-analysis-86b89aa27586

那麼,為了避免人工選擇R的「好值」,TDA將針對每一個可能的R值(從0到無窮)計算球的併集,並記錄每個洞出現或者消失時的半徑,並對一些點使用這些半徑值作為二維坐標。TDA的輸出則是另一個點雲,其中每個點代表一個洞:這叫做Rips持續圖(Rips persistence diagram)。假設點雲在一個numpy數組X中儲存(shape為N*2),通過Gudhi,這個圖可以用兩行代碼計算出來:

import gudhirips = gudhi.RipsComplex(points=X).create_simplex_treedgm = rips.persistence

這個漂亮的持續圖由r=4.1對應的點雲計算出。紅色的點代表相連的成分,藍色的點代表洞

接下來我們將解決的任務則是給定點雲預測r的值。

通過Gudhi+Scikit-Learn進行拓撲機器學習

持續圖很簡潔,是不是?它們存在的問題則是,從不同點雲計算出的持續圖可能有不同數量的點(因為點雲可能有不同數量的洞)。所以如果你想用Scikit-Learn從持續圖中預測r,不幸的是,沒有直接的方法,因為這些庫預期輸入是一個結構化的向量。這也是為什麼目前大量的工作是關於將這些持續圖轉化為固定長度的歐幾裡得向量,或者是開發對應的核。這很棒,但是你應該使用哪種呢?

不要擔心!Gudhi再一次給你解決辦法。通過它的表達(representation)模塊,你不僅可以計算所有的向量和核,甚至也可以使用Scikit-Learn來交叉驗證並且(或)選擇最佳的一種。就像下面這麼簡單:

表達

https://gudhi.inria.fr/python/latest/representations.html

import gudhi.representations as tdafrom sklearn.pipeline importPipelinefrom sklearn.svm importSVCfrom sklearn.ensemble importRandomForestClassifier as RFfrom sklearn.neighbors importKNeighborsClassifier as kNNfrom sklearn.model_selection importGridSearchCV

pipe = Pipeline([("TDA", tda.PersistenceImage()), ("Estimator", SVC())])param = [{"TDA": [tda.SlicedWassersteinKernel()], "TDA__bandwidth": [0.1, 1.0], "TDA__num_directions": [20], "Estimator": [SVC(kernel="precomputed")]}, {"TDA": [tda.PersistenceWeightedGaussianKernel()], "TDA__bandwidth": [0.1, 0.01], "TDA__weight": [lambda x: np.arctan(x[1]-x[0])], "Estimator": [SVC(kernel="precomputed")]}, {"TDA": [tda.PersistenceImage()], "TDA__resolution": [ [5,5], [6,6] ], "TDA__bandwidth": [0.01, 0.1, 1.0, 10.0], "Estimator": [SVC()]}, {"TDA": [tda.Landscape()], "TDA__resolution": [100], "Estimator": [RF()]}, {"TDA": [tda.BottleneckDistance()], "TDA__epsilon": [0.1], "Estimator: [kNN(metric="precomputed")]} ]model = GridSearchCV(pipe, param, cv=3)model = model.fit(diagrams, labels)

在前面的代碼中,我嘗試了帶切片Wasserstein核和持續權重Gaussian核的核SVM、帶有Persistence Images的C-SVM,帶有Persistence Landscapes的隨機森林,和一個帶有所謂的持久圖之間瓶頸距離(bottleneck distance)的簡單KNN。在Gudhi中還有許多其他的可能,所以你一定要試試!如果想了解更多細節你也可以看看Gudhi的Tutorial。

帶切片Wasserstein核:

http://proceedings.mlr.press/v70/carriere17a/carriere17a.pdf

持續權重Gaussian核:

http://proceedings.mlr.press/v48/kusano16.html

Persistence Images:

http://jmlr.org/papers/v18/16-337.html

Persistence Landscapes:

http://www.jmlr.org/papers/volume16/bubenik15a/bubenik15a.pdf

Gudhi的Tutorial:

https://github.com/GUDHI/TDA-tutorial/blob/master/Tuto-GUDHI-representations.ipynb

用Gudhi和Tensorflow/Pytorch進行拓撲優化

我很確信你目前已經成為了TDA的愛好者。如果你仍不相信,我還有其他的東西給你,這是受這篇論文啟發。想像你現在想解決一個更難的問題:我想讓你給我一個點雲,這個點雲的持續圖有儘可能多的點。換句話說,你需要生成一個有好多洞的點雲。

論文:

https://arxiv.org/abs/1905.12200

我可以看見你額頭上出汗了。但我是很仁慈的,轉眼間就能讓你知道Gudhi(1)可以做這個。想一想:當你生成一個持續圖時,這個圖中不同點的坐標並不受全部的初始點雲影響,是不是?對於這個持續圖的一個給定點p,p的坐標僅依賴於在初始點雲中組成p對應洞的點的位置,以一種簡單的方式:這些坐標僅是球的併集使得這個洞出現或者消失時候的半徑;或者,等價表達是,這些點中的最大的成對距離。而Gudhi(2)可以通過它的persistence_pairs函數找出這些關係。梯度則可以簡單的定義成歐幾裡得距離函數的導數(正式定義見這篇論文)。

Gudhi(1):

http://gudhi.gforge.inria.fr/python/latest/

Gudhi(2):

https://gudhi.inria.fr/python/latest/

這篇論文:

https://sites.google.com/view/hiraoka-lab-en/research/mathematical-research/continuation-of-point-cloud-data-via-persistence-diagram

接下來讓我們寫兩個函數,第一個從點雲中計算Rips持續圖,第二個計算持續圖點集的導數。為了可讀性我簡化了一點點代碼,實際的代碼可以從這裡找到。

https://github.com/GUDHI/TDA-tutorial/blob/master/Tuto-GUDHI-optimization.ipynb

defcompute_rips(x): rc = gd.RipsComplex(points=x) st = rc.create_simplex_tree dgm = st.persistence pairs = st.persistence_pairsreturn[dgm, pairs]

defcompute_rips_grad(grad_dgm, pairs, x): grad_x = np.zeros(x.shape, dtype=np.float32) for i in range(len(dgm)): [v0a, v0b] = pairs[i][0] [v1a, v1b] = pairs[i][1] grad_x[v0a,:]+=grad_dgm[i,0]*(x[v0a,:]-x[v0b,:])/val0 grad_x[v0b,:]+=grad_dgm[i,0]*(x[v0b,:]-x[v0a,:])/val0 grad_x[v1a,:]+=grad_dgm[i,1]*(x[v1a,:]-x[v1b,:])/val1 grad_x[v1b,:]+=grad_dgm[i,1]*(x[v1b,:]-x[v1a,:])/val1returngrad_x

現在讓我們把函數封裝進Tensorflow函數中(對Pytorch同樣簡單),並定義一個損失loss,這個損失是持續圖點到其對角線的距離的相反數。這將迫使圖有很多點,它們的縱坐標比橫坐標大得多。這樣的話,一個點雲會有很多大尺寸的洞。

import tensorflow as tffrom tensorflow.python.framework importopsdefpy_func(func, inp, Tout, stateful=True, name=None, grad=None): rnd_name = "PyFuncGrad" + str(np.random.randint(0, 1e+8)) tf.RegisterGradient(rnd_name)(grad) g = tf.get_default_graphwithg.gradient_override_map({"PyFunc": rnd_name}):returntf.py_func(func, inp, Tout, stateful=stateful, name=name)defRips(card, hom_dim, x, Dx, max_length, name=None):withops.op_scope([x], name, "Rips")asname:returnpy_func(compute_rips, [x], [tf.float32], name=name, grad=_RipsGrad)def_RipsGrad(op, grad_dgm): pairs = op.outputs[1] x = op.inputs[0] grad_x = tf.py_func(compute_rips_grad, [grad_dgm,pairs,x], [tf.float32])[0]return[None,None, grad_x,None,None]

tf.reset_default_graphx = tf.get_variable("X", shape=[n_pts,2], initializer=tf.random_uniform_initializer(0.,1.), trainable=True)dgm, pairs = Rips(x)loss = -tf.reduce_sum(tf.square(dgm[:,1]-dgm[:,0]))opt = tf.train.GradientDescentOptimizer(learning_rate=0.1)train = opt.minimize(loss)

現在我們開始優化!這是epochs 0,20,90的結果:

好多洞,好漂亮……我們是不是在夢裡。如果你想往前看看,使用其它的損失,查閱這個Gudhi的tutorial。

https://github.com/GUDHI/TDA-tutorial/blob/master/Tuto-GUDHI-optimization.ipynb

最後的話

這個帖子僅是一瞥由Gudhi,Scikit-Learn和Tensorflow提供的眾多可能性。我希望我可以使你相信,在你的流程中整合TDA已經成為很簡單的事情。即使許多TDA應用已經在文獻中出現,肯定還有更多的應用需要去發現!

原文標題:

The Holy Trinity of Topological Machine Learning: Gudhi, Scikit-Learn and Tensorflow

原文連結:

https://towardsdatascience.com/the-holy-trinity-of-topological-machine-learning-gudhi-scikit-learn-and-tensorflow-pytorch-3cda2aa249b5

【end】

曠視提Circle Loss,統一優化視角,革新深度特徵學習範式 | CVPR 2020清華學霸組團的工業AIoT創企再獲數千萬融資:玩家應推動在邊緣 AI 晶片上跑算法騰訊內測全新 Tim 3.0,支持微信登錄;滴滴順風車上線夜間服務;Angular 9.1發布為何你的 SaaS 想法總是失敗?沒想清楚這 4 個原因可能會繼續失敗!GitHub 疑遭中間人攻擊,無法訪問,最大暗網託管商再被黑!萬字好文:智能合約編寫之Solidity的編程攻略,建議收藏!你點的每個「在看」,我都認真當成了AI

相關焦點

  • 乾貨| 請收下這份2018學習清單:150個最好的機器學習,NLP和Python...
    在今年秋季開始準備博士項目的時候,我已經精選了一些有關機器學習和NLP的優質網絡資源。一般我會找一個有意思的教程或者視頻,再由此找到三四個,甚至更多的教程或者視頻。猛回頭,發現標收藏夾又多了20個資源待我學習(推薦提升效率工具Tab Bundler)。
  • ...請收下這份2018學習清單:150個最好的機器學習,NLP和Python教程
    在今年秋季開始準備博士項目的時候,我已經精選了一些有關機器學習和NLP的優質網絡資源。一般我會找一個有意思的教程或者視頻,再由此找到三四個,甚至更多的教程或者視頻。猛回頭,發現標收藏夾又多了20個資源待我學習(推薦提升效率工具Tab Bundler)。
  • 乾貨 | 請收下這份2018學習清單:150個最好的機器學習,NLP和Python教程
    在今年秋季開始準備博士項目的時候,我已經精選了一些有關機器學習和NLP的優質網絡資源。一般我會找一個有意思的教程或者視頻,再由此找到三四個,甚至更多的教程或者視頻。猛回頭,發現標收藏夾又多了20個資源待我學習(推薦提升效率工具Tab Bundler)。
  • TensorFlow極速入門
    最後給出了在 tensorflow 中建立一個機器學習模型步驟,並用一個手寫數字識別的例子進行演示。1、tensorflow是什麼?tensorflow 是 google 開源的機器學習工具,在2015年11月其實現正式開源,開源協議Apache 2.0。
  • 收藏 | 機器學習、NLP、Python和Math最好的150餘個教程
    最近,我一直在網上尋找關於機器學習和NLP各方面的好資源,為了幫助到和我有相同需求的人,我整理了一份迄今為止我發現的最好的教程內容列表。通過教程中的簡介內容講述一個概念。避免了包括書籍章節涵蓋範圍廣,以及研究論文在教學理念上做的不好的特點。我把這篇文章分成四個部分:機器學習、NLP、Python和數學。
  • WePay機器學習反欺詐實踐:Python+scikit-learn+隨機森林
    【編者按】將機器學習算法用於金融領域的一個很好的突破口是反欺詐,在這篇博文中,WePay介紹了支付行業構建機器學習模型應對很難發現的shell selling欺詐的實踐心得。WePay採用了流行的Python、scikit-learn開源學習機器學習工具以及隨機森林算法。
  • TensorFlow極簡教程:創建、保存和恢復機器學習模型
    TensorFlow 機器學習範例——Naked Tensor連結:https://github.com/jostmey/NakedTensor?bare在每個例子中,我們用一條直線擬合一些數據。使用梯度下降(gradient descent)確定最適合數據的線的斜率和 y 截距的值。
  • 如何在Apache Pyspark中運行Scikit-learn模型
    在本文中,我們將了解如何在Apache Pyspark中運行Scikit-learn模型,並討論有關每個步驟的細節。如果您已經準備好了機器學習模型,則可以直接跳到「 pyspark wrapper」部分,也可以通過以下步驟創建一個簡單的scikit learn機器學習模型。
  • 利用Spark 和 scikit-learn 將你的模型訓練加快 100 倍
    當我們使用 Spark 進行數據處理時,我們首選的機器學習框架是 scikit-learn。隨著計算機變得越來越便宜,機器學習解決方案的上市時間變得越來越關鍵,我們探索了加快模型訓練的各種方法。其中一個解決方案是將 Spark 和 scikit-learn 中的元素組合到我們自己的混合解決方案中。
  • TensorFlow 攜手 NVIDIA,使用 TensorRT 優化 TensorFlow Serving...
    HTTP/REST API at:localhost:8501 …$ curl -o /tmp/resnet/resnet_client.py https://raw.githubusercontent.com/tensorflow/serving/master/tensorflow_serving/example/resnet_client.py
  • CDA承接的全球頂級機器學習Scikit-learn 中文社區上線啦!
    (注:scikit-learn的官網是www.scikit-learn.org,CDA承接的中文社區網址是www.scikit-learn.org.cn,這同時也標誌著CDA與全球頂級深度學習和機器學習框架更進一步融合,CDA認證更加得到全球頂級技術框架的認可!
  • Scikit-learn玩得很熟了?這些功能你都知道嗎?
    Scikit-learn是Python所有的機器學習程序包中,你必須掌握的最重要的一個包,它包含各種分類算法,回歸算法和聚類算法,其中包括支持向量機、隨機森林、梯度提升、k均值和基於密度的聚類算法(DBSCAN),且旨在與Python數值庫NumPy和科學庫SciPy進行相互配合。它通過一個接口,提供了一系列的有監督和無監督算法。
  • TensorFlow 資源大全中文版
    ,請點擊 → 這裡了解詳情jtoy 發起整理的 TensorFlow 資源,包含一些很棒的 TensorFlow 工程、庫、項目等。生成手寫體 – 實現Alex Grave的論文中關於生成手寫體的部分TensorFlow實現神經圖靈機 – TensorFlow實現神經圖靈機基於物體搜索和過濾視頻 – 使用卷積神經網絡基於視頻中的物品、地點等來搜索、過濾和描述視頻使用TensorFlow來轉換莎士比亞作品和現代版本的英語 – 實現莎士比亞作品和現代版本的英語的單語轉換聊天機器人 – 一個
  • Keras和TensorFlow究竟哪個會更好?
    Keras 的 API 類似於 scikit-learn 的,都可稱為機器學習的優質 API。 Keras 的 API 是模塊化的、基於 Python ,並且極其易於使用。 當你需要實現一個自定義的層或更複雜的損失函數時,你可以深入使用 TensorFlow,將代碼自動地與 Keras 模型相結合。
  • Python機器學習5:使用scikit-learn實現三種集成學習Bagging算法
    在這篇文章中,將主要講解Bagging算法的常見三種模型,並介紹如何使用scikit-learn實現這三種模型。後面幾篇文章將講解Boosting和Majority Voting算法。Bagging算法Bagging算法指的是利用數據集訓練多個子模型,然後對多個子模型進行綜合,最終對所有子模型預測結果取平均值,作為最終的模型預測結果。
  • 玩轉TensorFlow?你需要知道這30功能
    地址是:tensorflow.org/tfx/?網址是:https://www.tensorflow.org/serving/?在種子庫的機器學習項目裡面,甚至有關注公平和偏見的實例!歡迎社會各界的貢獻和建議!馬上去問問 @billylamberta 學習如何開始吧!風格指南:https://www.tensorflow.org/community/documentation反饋問題:https://github.com/tensorflow/tensorflow/issues?
  • python應用之基於tensorflow的數據擬合:深度學習之預測入門篇
    實驗目的:1、了解python在深度學習領域的應用2、學習安裝python第三方依賴庫實驗環境:已正確安裝python3.5以及依賴庫tensorflow、matplotlib預測過程展示:1、應用領域python是一種高級面向對象的動態類型語言,具有開發高效,學習簡單的特點,主要應用於大數據、深度學習、
  • 開源機器學習框架:Scikit-learn API簡介
    而在這些分支版本中,最有名,也是專門面向機器學習的一個就是Scikit-learn。和其他眾多的開源項目一樣,Scikit-learn目前主要由社區成員自發進行維護。可能是由於維護成本的限制,Scikit-learn相比其他項目要顯得更為保守。
  • Python粉都應該知道的開源機器學習框架:Scikit-learn入門指南
    而在這些分支版本中,最有名,也是專門面向機器學習的一個就是Scikit-learn。Scikit-learn項目最早由數據科學家 David Cournapeau 在 2007 年發起,需要NumPy和SciPy等其他包的支持,是Python語言中專門針對機器學習應用而發展起來的一款開源框架。