用於拓撲機器學習的Python庫giotto-learn入門

由Lewis Tunstall,ColinKälin,Francesco Palma和Thomas Boys撰寫

用於拓撲機器學習的Python庫giotto-learn入門

介紹

在L2F,我們圍繞giotto學習和拓撲機器學習遇到的最常見問題之一是"我從哪裡開始?"。

在本指南中,我們概述了基本概念和工作流程,以便您可以在機器學習管道中開始使用giotto-learn。 可以在GitHub上獲得用於重現分析的代碼。

什麼是拓撲機器學習?

拓撲機器學習是指將代數拓撲中的元素與統計學習結合在一起的一組技術。 通過關注數據的整體屬性(例如形狀和連接性),這些拓撲方法可以捕獲傳統機器學習方法可能會遺漏的模式。

例如,拓撲機器學習已在藥物設計和圖形分類中產生了最先進的結果,並導致了對蛋白質結合的新穎見解。

這些技術的主要成分被稱為持久同源性。 持久同源性度量了各種長度範圍內拓撲不變性(如連接的組件,孔和空隙)的存在。 這些不變量的"出生"和"死亡"通過持久性圖表進行了總結,這是生成新型特徵以饋送到下游機器學習任務的最常見,最直觀的方式。 有關這些概念的出色概述,請參見Gary Koplik的文章或Matthew Wright的視頻。

用於拓撲機器學習的Python庫giotto-learn入門

Birth and death of a hole by connecting neighbouring points with circles of increasing radius (left). The corresponding persistence diagram is also shown (right). Credit:

概括地說,拓撲機器學習的關鍵步驟是:

  • 使用持久性同源性從輸入數據中提取拓撲特徵。
  • 使用監督或非監督方法將這些功能與機器學習方法結合起來。

giotto學習庫旨在簡化這些步驟,並使更廣泛的數據科學界可以訪問拓撲機器學習。 它基於scikit-learn的fit-transform範例,並與流行的框架緊密集成。 giotto-learn入門就像運行一樣簡單:

<code>pip install giotto-learn/<code>


預測分子性質

為了展示giotto-learn的作用,我們將使用Kaggle上Predicting Molecular Properties競賽中的CHAMPS數據集。 此處的任務是預測分子中兩個原子之間的磁性相互作用或"標量耦合常數"。 由於這些耦合取連續值,因此學習任務是一種迴歸。

用於拓撲機器學習的Python庫giotto-learn入門

For a given molecule, the learning task is to predict the strength of the couplings between each atom pair.

探索數據

訓練數據由分子中的原子對組成,每對原子均以標量耦合的類型和每個原子的(x,y,z)座標為特徵。 為了簡化分析,我們將重點介紹100個最大的分子,即原子數最大的分子。 如下圖所示,這些分子具有五種不同的偶聯,其強度取決於偶聯的類型。

用於拓撲機器學習的Python庫giotto-learn入門

Coupling strength per coupling type for the 100 largest molecules in the data.


從數據到持久圖

我們的拓撲機器學習管道的第一步是從訓練數據構建持久性圖。

在giotto-learn中,有兩種主要方法可以實現此目的:

  • 將數據表示為點雲:將每個觀測值視為空間中的一個點,並使用度量標準來計算成對的觀測值之間的距離。 在我們的上下文中,單個分子的點雲可以簡單地是每個原子相對於所有原子的平均值(x̅,y̅,z̅)的(x,y,z)座標。 在下面的代碼片段中,homology_dimensions指定要跟蹤的拓撲不變量的類型(" 0"表示連接的組件," 1"表示孔," 2"表示空隙),而歐幾里得定義了我們希望在持久性同源性中應用的度量 計算。
<code>import giotto.homology as hl# represent data as a point cloudpoint_cloud = ...# define topological features to trackhomology_dimensions = [0, 1, 2]# define simplicial complex to constructpersistence = hl.VietorisRipsPersistence(    metric="euclidean", homology_dimensions=homology_dimensions)# calculate persistence diagrampersistence_diagram = persistence.fit_transform(point_cloud)/<code>
  • 將數據表示為距離矩陣:計算每個觀測值之間的成對距離,其中"距離"不必一定是度量。 如果我們將單個分子視為圖,則兩個原子之間的距離可能是沿著連接它們的最短路徑的邊數。 在下面的代碼片段中,我們只需要指定度量是預先計算的,並確保輸入是距離矩陣即可。
<code>import giotto.homology as hl# represent data as a matrix of pairwise distancesdistance_matrix = ...# define topological features to trackhomology_dimensions = [0, 1, 2]# define simplicial complex to constructpersistence = hl.VietorisRipsPersistence(    metric="precomputed", homology_dimensions=homology_dimensions)# calculate persistence diagrampersistence_diagram = persistence.fit_transform(distance_matrix)/<code>

對於每個輸入點雲或距離矩陣,我們得到一個持久性圖。 在訓練數據中,每個觀察都是一個原子對,因此將這些對分組以形成100個分子時,我們獲得100個點雲,從而獲得100個餘輝圖。

持久性圖中距離對角線死亡=出生線最遠的點對應於最持久的拓撲特徵。

用於拓撲機器學習的Python庫giotto-learn入門

用於拓撲機器學習的Python庫giotto-learn入門

A point cloud for a single molecule (left) and its corresponding persistence diagram (right). Connected components (H0) are shown in red, holes (H1) in cyan, and voids (H2) in purple.

從持久性圖到機器學習功能

儘管持久性圖是數據的有用描述符,但是它們不能直接用於機器學習應用程序。 這是因為不同的持久性圖可能具有不同的點數,並且沒有很好地定義基本操作(例如,圖的加法和乘法)。

為了克服這些限制,已經提出了各種建議,以通過嵌入或內核將持久化圖"向量化",這些嵌入或內核非常適合機器學習。 在giotto-learn中,我們通過giotto.diagrams模塊提供對最常見矢量化的訪問。

例如,可以通過選擇度量來實現計算持久性圖的"振幅",如下面的代碼片段所示。

<code>import giotto.diagrams as diagrams# calculate persistence diagrampersistence_diagram = ...# define type of amplitude to calculateamplitude = diagrams.Amplitude(metric="wasserstein")# calculate amplitude of diagrampersistence_diagram_amplitude = amplitude.fit_transform(persistence_diagram)/<code>

另外,您可以創建自己的自定義拓撲功能! 由於giotto-learn中的持久性圖是出生-死亡-維三元組的數組,因此使用NumPy或Pandas操作它們很簡單。 例如,下面的代碼片段顯示瞭如何計算每個homology_dimension點的平均壽命。

<code>import pandas as pd# define topological features to trackhomology_dimensions = [0, 1, 2]# calculate persistence diagrampersistence_diagram = ...# convert NumPy array of triples to DataFramepersistence_table = pd.DataFrame(    persistence_diagram, columns=["birth", "death", "homology_dim"])# calculate the lifetime per pointpersistence_table["lifetime"] = persistence_table["death"] - persistence_table["birth"]# calculate average lifetimes per homology dimensionaverage_lifetimes = [    persistence_table.query(f"homology == {homology_dim}")["lifetime"].mean()    for homology_dim in homology_dimensions]/<code>

在對CHAMPS數據集的全面分析中,我們提取了各種各樣的拓撲特徵-有關詳細信息,請參見隨附的代碼。

訓練模型

有了拓撲特徵,下一步就是訓練迴歸器。 在scikit-learn約定中,這等於將所有相關功能和目標變量組合到數組X和y中。 對於本指南,我們採用本Kaggle提交中採用的方法,並使用XGBoostRegressor進行預測。 為了評估功能部件對性能的影響,我們比較了具有和不具有拓撲功能部件的經過5倍交叉驗證訓練的模型的結果。 此步驟的代碼段是標準的,並在下面複製。

<code>def cv_model(X, y, features, n_fold=5, random_state=45245, params=None):    """Evaluate a score by cross validation.        Parameters    ----------        X : pandas.DataFrame        The data to fit.            y : pandas.DataFrame or pandas.Series        The scalar coupling constants as target variables.            features : list        The list of features to use during training.            n_fold : int, default `5`        The number of fold to use in cross validation.        random_state : int, default `45245`        The seed for the KFold split            params : dict, default `None`        The parameter dictionary for XGBRegressor            Returns    -------        results_mean : list        List of the scores for each coupling type, averaged over all folds.            results_details : list        List of all the scores as a list of lists.    """    X = X[features]    folds = KFold(n_splits=n_fold, shuffle=True, random_state=random_state)    model = XGBRegressor(**params)    results_mean = []    results_details = []    for fold_n, (train_index, valid_index) in enumerate(folds.split(X)):        X_train, X_valid = X.iloc[train_index], X.iloc[valid_index]        y_train, y_valid = y.iloc[train_index], y.iloc[valid_index]        model.fit(X_train, y_train)        y_pred = model.predict(X_valid)        scores = group_mean_log_mae(y_pred, y_valid, X_valid["type"])        results_mean.append(scores[0])        results_details.append(list(scores[1]))    print(        "After {}-fold CV: Mean: ".format(n_fold),        np.mean(results_mean),        "Std.:",        np.std(results_mean),    )    return results_mean, results_details/<code>

得分預測

最後一步是對我們模型的預測進行評分。 競賽的指標是平均絕對誤差的對數的平均值(是的,這有點複雜-可以將其視為多個分數,每種債券類型均得分。對於每種類型,計算平均絕對誤差,取對數, 這些結果,最後計算所有債券類型的均值):

用於拓撲機器學習的Python庫giotto-learn入門

這裡:

  • T是標量耦合類型的數量(在我們的示例中為5)
  • nₜ是類型t的觀測數
  • yᵢ是觀測的標量耦合常數
  • ŷᵢ是預測的標量耦合常數

由於對數,我們可以獲得負值,因此說-0.5的得分比-0.3的得分更好。

下圖顯示了每種耦合類型的分數,並將包含拓撲特徵的模型與沒有拓撲特徵的模型進行了比較。

用於拓撲機器學習的Python庫giotto-learn入門

我們可以清楚地看到,拓撲功能有助於將分數提高多達5.5%,平均提高3.6%。 在Kaggle競賽中,這些小的改進可以在最終排行榜中產生很大的不同,並很好地演示了拓撲如何為常規特徵提取方法提供補充信息。

展望及下一步

本指南僅簡單涉及了giotto學習可能的內容。 除了我們的迴歸示例之類的核心機器學習任務外,該庫當前還支持將持久同源性應用於圖形和時間序列數據。

例如,giotto-learn已用於檢測股市崩潰,研究甲蟲種群的種群動態,或預測分子是否抑制HIV的傳播。

如果您對如何使用giotto學習有疑問,請隨時通過Slack與我們聯繫。

如果您想了解有關拓撲機器學習的更多信息,請查閱以下內容。

參考

  • 拓撲數據分析簡介:數據科學家的基本和實踐方面
  • 基於持久同源性的機器學習及其應用—一項調查

(本文翻譯自Lewis Tunstall的文章《Getting started with giotto-learn》,參考:https://towardsdatascience.com/getting-started-with-giotto-learn-a-python-library-for-topological-machine-learning-451d88d2c4bc)


分享到:


相關文章: