速度數百倍之差,有人斷言KNN面臨淘汰,更快更強的ANN將取而代之

2020-12-26 澎湃新聞

選自towardsdatascience

作者:Marie Stephen Leo

機器之心編譯

編輯:小舟、杜偉

數據科學經典算法 KNN 已被嫌慢,ANN 比它快 380 倍。

在模式識別領域中,K - 近鄰算法(K-Nearest Neighbor, KNN)是一種用於分類和回歸的非參數統計方法。K - 近鄰算法非常簡單而有效,它的模型表示就是整個訓練數據集。就原理而言,對新數據點的預測結果是通過在整個訓練集上搜索與該數據點最相似的 K 個實例(近鄰)並且總結這 K 個實例的輸出變量而得出的。KNN 可能需要大量的內存或空間來存儲所有數據,並且使用距離或接近程度的度量方法可能會在維度非常高的情況下(有許多輸入變量)崩潰,這可能會對算法在你的問題上的性能產生負面影響。這就是所謂的維數災難。

近似最近鄰算法(Approximate Nearest Neighbor, ANN)則是一種通過犧牲精度來換取時間和空間的方式從大量樣本中獲取最近鄰的方法,並以其存儲空間少、查找效率高等優點引起了人們的廣泛關注。

近日,一家技術公司的數據科學主管 Marie Stephen Leo 撰文對 KNN 與 ANN 進行了比較,結果表明,在搜索到最近鄰的相似度為 99.3% 的情況下,ANN 比 sklearn 上的 KNN 快了 380 倍。

作者表示,幾乎每門數據科學課程中都會講授 KNN 算法,但它正在走向「淘汰」!

KNN 簡述

在機器學習社區中,找到給定項的「K」個相似項被稱為相似性搜索或最近鄰(NN)搜索。最廣為人知的 NN 搜索算法是 KNN 算法。在 KNN 中,給定諸如手機電商目錄之類的對象集合,則對於任何新的搜索查詢,我們都可以從整個目錄中找到少量(K 個)最近鄰。例如,在下面示例中,如果設置 K = 3,則每個「iPhone」的 3 個最近鄰是另一個「iPhone」。同樣,每個「Samsung」的 3 個最近鄰也都是「Samsung」。

KNN 存在的問題

儘管 KNN 擅長查找相似項,但它使用詳細的成對距離計算來查找鄰居。如果你的數據包含 1000 個項,如若找出新產品的 K=3 最近鄰,則算法需要對資料庫中所有其他產品執行 1000 次新產品距離計算。這還不算太糟糕,但是想像一下,現實世界中的客戶對客戶(Customer-to-Customer,C2C)市場,其中的資料庫包含數百萬種產品,每天可能會上傳數千種新產品。將每個新產品與全部數百萬種產品進行比較是不划算的,而且耗時良久,也就是說這種方法根本無法擴展。

解決方案

將最近鄰算法擴展至大規模數據的方法是徹底避開暴力距離計算,使用 ANN 算法。

近似最近距離算法(ANN)

嚴格地講,ANN 是一種在 NN 搜索過程中允許少量誤差的算法。但在實際的 C2C 市場中,真實的鄰居數量比被搜索的 K 近鄰數量要多。與暴力 KNN 相比,人工神經網絡可以在短時間內獲得卓越的準確性。ANN 算法有以下幾種:

Spotify 的 ANNOY

Google 的 ScaNN

Facebook 的 Faiss

HNSW

分層的可導航小世界(Hierarchical Navigable Small World, HNSW)

在 HNSW 中,作者描述了一種使用多層圖的 ANN 算法。在插入元素階段,通過指數衰減概率分布隨機選擇每個元素的最大層,逐步構建 HNSW 圖。這確保 layer=0 時有很多元素能夠實現精細搜索,而 layer=2 時支持粗放搜索的元素數量少了 e^-2。最近鄰搜索從最上層開始進行粗略搜索,然後逐步向下處理,直至最底層。使用貪心圖路徑算法遍歷圖,並找到所需鄰居數量。

HNSW 圖結構。最近鄰搜索從最頂層開始(粗放搜索),在最底層結束(精細搜索)。

HNSW Python 包

整個 HNSW 算法代碼已經用帶有 Python 綁定的 C++ 實現了,用戶可以通過鍵入以下命令將其安裝在機器上:pip install hnswlib。安裝並導入軟體包之後,創建 HNSW 圖需要執行一些步驟,這些步驟已經被封裝到了以下函數中:

import hnswlibimport numpy as npdef fit_hnsw_index(features, ef=100, M=16, save_index_file=False): # Convenience function to create HNSW graph # features : list of lists containing the embeddings # ef, M: parameters to tune the HNSW algorithm num_elements = len(features) labels_index = np.arange(num_elements) EMBEDDING_SIZE = len(features[0]) # Declaring index # possible space options are l2, cosine or ip p = hnswlib.Index(space='l2', dim=EMBEDDING_SIZE) # Initing index - the maximum number of elements should be known p.init_index(max_elements=num_elements, ef_construction=ef, M=M) # Element insertion int_labels = p.add_items(features, labels_index) # Controlling the recall by setting ef # ef should always be > k p.set_ef(ef) # If you want to save the graph to a file if save_index_file: p.save_index(save_index_file) return p

創建 HNSW 索引後,查詢「K」個最近鄰就僅需以下這一行代碼:

ann_neighbor_indices, ann_distances = p.knn_query(features, k)

KNN 和 ANN 基準實驗

計劃

首先下載一個 500K + 行的大型數據集。然後將使用預訓練 fasttext 句子向量將文本列轉換為 300d 嵌入向量。然後將在不同長度的輸入數據 [1000. 10000, 100000, len(data)] 上訓練 KNN 和 HNSW ANN 模型,以度量數據大小對速度的影響。最後將查詢兩個模型中的 K=10 和 K=100 時的最近鄰,以度量「K」對速度的影響。首先導入必要的包和模型。這需要一些時間,因為需要從網絡上下載 fasttext 模型。

# Imports# For input data pre-processingimport jsonimport gzipimport pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport fasttext.utilfasttext.util.download_model('en', if_exists='ignore') # English pre-trained modelft = fasttext.load_model('cc.en.300.bin')# For KNN vs ANN benchmarkingfrom datetime import datetimefrom tqdm import tqdmfrom sklearn.neighbors import NearestNeighborsimport hnswlib

數據

使用亞[馬遜產品數據集],其中包含「手機及配件」類別中的 527000 種產品。然後運行以下代碼將其轉換為數據框架。記住僅需要產品 title 列,因為將使用它來搜索相似的產品。

# Data: http://deepyeti.ucsd.edu/jianmo/amazon/data = []with gzip.open('meta_Cell_Phones_and_Accessories.json.gz') as f: for l in f: data.append(json.loads(l.strip()))# Pre-Processing: https://colab.research.google.com/drive/1Zv6MARGQcrBbLHyjPVVMZVnRWsRnVMpV#scrollTo=LgWrDtZ94w89# Convert list into pandas dataframedf = pd.DataFrame.from_dict(data)df.fillna('', inplace=True)# Filter unformatted rowsdf = df[~df.title.str.contains('getTime')]# Restrict to just 'Cell Phones and Accessories'df = df[df['main_cat']=='Cell Phones & Accessories']# Reset indexdf.reset_index(inplace=True, drop=True)# Only keep the title columnsdf = df[['title']]# Check the dfprint(df.shape)df.head()

如果全部都可以運行精細搜索,你將看到如下輸出:

亞馬遜產品數據集。

嵌入

要對文本數據進行相似性搜索,則必須首先將其轉換為數字向量。一種快速便捷的方法是使用經過預訓練的網絡嵌入層,例如 Facebook [FastText] 提供的嵌入層。由於希望所有行都具有相同的長度向量,而與 title 中的單詞數目無關,所以將在 df 中的 title 列調用 get_sentence_vector 方法。

嵌入完成後,將 emb 列作為一個 list 輸入到 NN 算法中。理想情況下可以在此步驟之前進行一些文本清理預處理。同樣,使用微調的嵌入模型也是一個好主意。

# Title Embedding using FastText Sentence Embeddingdf['emb'] = df['title'].apply(ft.get_sentence_vector)# Extract out the embeddings column as a list of lists for input to our NN algosX = [item.tolist() for item in df['emb'].values]

基準

有了算法的輸入,下一步進行基準測試。具體而言,在搜索空間中的產品數量和正在搜索的 K 個最近鄰之間進行循環測試。在每次迭代中,除了記錄每種算法的耗時以外,還要檢查 pct_overlap,因為一定比例的 KNN 最近鄰也被挑選為 ANN 最近鄰。

注意整個測試在一臺全天候運行的 8 核、30GB RAM 機器上運行大約 6 天,這有些耗時。理想情況下,你可以通過多進程來加快運行速度,因為每次運行都相互獨立。

# Number of products for benchmark loopn_products = [1000, 10000, 100000, len(X)]# Number of neighbors for benchmark loopn_neighbors = [10, 100]# Dictionary to save metric results for each iterationmetrics = {'products':[], 'k':[], 'knn_time':[], 'ann_time':[], 'pct_overlap':[]}for products in tqdm(n_products): # "products" number of products included in the search space features = X[:products] for k in tqdm(n_neighbors): # "K" Nearest Neighbor search # KNN knn_start = datetime.now() nbrs = NearestNeighbors(n_neighbors=k, metric='euclidean').fit(features) knn_distances, knn_neighbor_indices = nbrs.kneighbors(X) knn_end = datetime.now() metrics['knn_time'].append((knn_end - knn_start).total_seconds()) # HNSW ANN ann_start = datetime.now() p = fit_hnsw_index(features, ef=k*10) ann_neighbor_indices, ann_distances = p.knn_query(features, k) ann_end = datetime.now() metrics['ann_time'].append((ann_end - ann_start).total_seconds()) # Average Percent Overlap in Nearest Neighbors across all "products" metrics['pct_overlap'].append(np.mean([len(np.intersect1d(knn_neighbor_indices[i], ann_neighbor_indices[i]))/k for i in range(len(features))])) metrics['products'].append(products) metrics['k'].append(k) metrics_df = pd.DataFrame(metrics)metrics_df.to_csv('metrics_df.csv', index=False)metrics_df

運行結束時輸出如下所示。從表中已經能夠看出,HNSW ANN 完全超越了 KNN。

以表格形式呈現的結果。

結果

以圖表的形式查看基準測試的結果,以真正了解二者之間的差異,其中使用標準的 matplotlib 代碼來繪製這些圖表。這種差距是驚人的。根據查詢 K=10 和 K=100 最近鄰所需的時間,HNSW ANN 將 KNN 徹底淘汰。當搜索空間包含約 50 萬個產品時,在 ANN 上搜索 100 個最近鄰的速度是 KNN 的 380 倍,同時兩者搜索到最近鄰的相似度為 99.3%。

在搜索空間包含 500K 個元素,搜索空間中每個元素找到 K=100 最近鄰時,HNSW ANN 的速度比 Sklearn 的 KNN 快 380 倍。

在搜索空間包含 500K 個元素,搜索空間中每個元素找到 K=100 最近鄰時,HNSW ANN 和 KNN 搜索到最近鄰的相似度為 99.3%。

基於以上結果,作者認為可以大膽地說:「KNN 已死」。

本篇文章的代碼作者已在 GitHub 上給出:https://github.com/stephenleo/adventures-with-ann/blob/main/knn_is_dead.ipynb

原文連結:https://medium.com/towards-artificial-intelligence/knn-k-nearest-neighbors-is-dead-fc16507eb3e

不氪金玩轉中文超大規模預訓練!

12月22日20:00,百度自然語言處理部資深研發工程師碩環老師將在第二期直播《NLP開發利器解析:中文超大規模預訓練模型精講》中介紹:

語義理解技術簡介

基於預訓練的語義理解技術

文心(ERNIE)技術原理詳解

文心最新技術解讀

文心語義理解技術應用

掃碼進群聽課,還有機會贏取100元京東卡、《智能經濟》實體書、限量百度滑鼠墊多重好獎!

© THE END

轉載請聯繫本公眾號獲得授權

投稿或尋求報導:content@jiqizhixin.com

原標題:《速度數百倍之差,有人斷言KNN面臨淘汰,更快更強的ANN將取而代之》

閱讀原文

相關焦點

  • 比KNN快380倍!我們有了新選擇
    圖源:Google我們正在經歷一場滅絕性的大事件,頗受歡迎的KNN算法正面臨淘汰,而幾乎每門數據科學課上都會學習這種算法!解決方法讓最近鄰在大量的數據中也適用的解決方法就是徹底規避這種暴力的距離計算法,代之以更複雜的一類算法,名為近似最近鄰(ANN)。近似最近鄰(ANN)嚴格來說,近似最近鄰這種算法在最近鄰搜索中允許少量的錯誤。但在現實中的C2C市場裡,「真正的」最近鄰的數字要比被搜索的「K」最近鄰高。相比暴力的KNN,ANN能夠在短時間內達到驚人的準確率。
  • 紙質火車票將被淘汰,電子票時代取而代之,為何有人卻堅決反對?
    根據了解,早在以前就有已經開始推行「廢除紙質火車票」的想法,取而代之的則是電子車票。對於這樣的做法,在海南環島高鐵就已經實行過。可是現在第二批48個車站將在20日推廣電子車票,這48個車站大多數位於浙江、江蘇內部,值得一提的是,在此之前就有第一批45個車站推廣電子車票,這第一批的車站均分布在江蘇、安徽、浙江。
  • 更快、更高、更強!東莞這所學校田徑運動會賽出「速度與激情」
    更快、更高、更強!東莞這所學校田徑運動會賽出「速度與激情」每年的11—12月,東莞各學校都會陸續舉行校園運動會是各大學校運動會的高峰期,同學們迎來了在田徑賽場上展現自我,為班級爭榮譽的機會。華南師範大學附屬東莞學校各學部體育節暨第四屆田徑運動會也如約而至,賽場上的孩子們賽出了速度與激情,將「更快、更高、更強」的奮鬥精神表現得淋漓盡致。跑出速度跑道上運動員奮力衝向終點,或許不是每個人都能一舉奪魁,但永不言敗的精神正是青春的代表。
  • KNN算法原理及代碼實現
    一般在機器學習中我們要將數據集分為訓練集和測試集,用訓練集訓練模型,再用測試集評價模型效果。這裡我們繪製了不同k值下模型準確率。從上圖中我們發現當k=1和k=無窮大時,KNN的誤差都很大。但是在某個點時能夠將誤差降低到最小。在本例中k=10KNN算法偽碼我們現在設計下KNN偽碼:一. 讀取數據二. 初始化k值三.
  • 阿帕奇終於後繼有人,不僅速度更快,還不易發現,更可以客串黑鷹
    現代裝備技術是不斷更新換代的,許多知名的裝備也不得不面臨著淘汰,比如美軍的阿帕奇直升機,早在15年以前,美國就開始研究新一代直升機,代號:FLRAA,中文為:未來遠程突擊飛機,如今阿帕奇終於後繼有人,美國軍方在2020年時,選擇了兩款直升機進入最終的競標,即:SB-1與V280,從實際情況看都可以滿足美國軍方開列出的要求,但是前者的機會更大
  • 基於速度的力量訓練(VBT)—讓你跑的更快,跳的更高,變得更強
    這種形式的訓練通常使用諸如可穿戴加速度計或線性位置換能器之類的技術來測量運動期間的運動速度(例如,後蹲)。這為教練和運動員提供了關於他們的運動表現的信息,並幫助教練提供非常具體的反饋(例如「更快地舉起槓鈴或更具爆發力」)。使用線性位置傳感器和可穿戴加速度計,我們可以準確計算槓鈴速度,從而產生運動員的負荷 - 速度曲線。
  • iPhone13爆料匯總:更「環保」、5G更快、性能更強!
    據了解,國內部分用戶已經收到了來自蘋果官方的郵件,蘋果這一次更直接,明確地詢問用戶是否使用了iPhone12系列隨機附贈的充電線、貼紙、卡針和歡迎指南,其目的很明顯,蘋果有意在下一代手機,也就是iPhone13系列上不再隨機附贈以上提到的物品,不可謂是不「環保」啊,蘋果真會省。
  • 京媒斷言:國安淘汰恆大進決賽
    」值得一提的是,在這期節目中,王長慶預測江蘇蘇寧將淘汰上港,但對於國安和恆大誰晉級,他沒有做出預測。不過,僅僅過了1天,在28日國安0比0戰平恆大後,王長慶一改此前的謹慎,很樂觀地表示國安將淘汰恆大進決賽。
  • 未來5年,個體戶將被淘汰,取而代之的是這3個新模式!
    因為個體戶沒有資源後盾的支持,也無法轉型升級,所以在市場競爭加劇中,就會面臨大淘汰。當然萬物有生有滅,淘汰舊模式,就會迎來新的造富機會。那麼未來5年,想要抓住新的機會,就要讀懂這3個模式!隨著社區團購的興起,大量個體戶都會成為剝削和淘汰的對象,不管你願不願意這都是趨勢。二如果你所在的區域目前還沒有社區團購平臺入駐,作為個體戶來說也不用慶幸,因為線上+線下的連鎖模式,正在橫掃本地市場。
  • 在FIFA20最新數據中,姆巴佩和戴維斯誰的速度更快?
    姆巴佩和戴維斯這兩位年輕的球員,同樣都是年少成名,同樣都是擁有風馳電掣般的速度能力,究竟他倆誰的速度更快呢?拜仁陣中的法國球星科曼表示戴維斯的速度是更快的。但是,科曼作為戴維斯的俱樂部隊友,肯定要為隊友打CALL,所以他說出來的話,並不是為了追求客觀和真實,而是把鼓舞球隊的士氣放在第一位,因為就算姆巴佩和戴維斯本人也不清楚誰的速度更快呢,而雖然科曼和姆巴佩也做過法國國家隊隊友,但是目前歐冠決賽才是最重要的,在目前這個階段更重要的隊友就是戴維斯!
  • 更高更快更強,全新iP登場!
    觸控世界傳動未來 威綸通在即將開幕的2016裡約奧運會上,各國運動健兒將各施技藝,更快更高更強,
  • 福建師範大學體育科學學院更快速度 更高標準 更強實力
    原標題:福建師範大學體育科學學院更快速度 更高標準 更強實力早在2000年,福建師範大學就成功獲批體育教育訓練學二級學科博士點,是當時全國4個體育教育訓練學博士點之一。此後,學校體育學學科建設如火如荼,相繼獲準建立體育學博士後科研流動站、獲批體育學一級學科博士學位授予權。
  • 電商賣家將大量淘汰,取而代之的是「這2個新模式」
    疫情期間不但讓實體店面臨倒閉潮,電商賣家也一樣慘遭大量淘汰。出現這種困境主要有兩個原因所致:一是在疫情常態化下,消費者的整體收入減少,消費力衰弱;二是因為在產能過剩,同質化競爭的情況下,市場會出現兩極分化。
  • 有人認為速度是跑與走區別,我認為跑者之心更重要
    世界上最大的跑步網站runners world,有人管它叫跑步者世界,有人管它叫跑者世界。直到《RW跑者世界》中文版發行,「跑者」一詞才被固定下來,而你翻看2008年之前的文章,很多人稱呼runner,還叫做跑步的人。
  • 「有人認為速度是跑與走區別,我認為跑者之心更重要!」
    世界上最大的跑步網站runners world,有人管它叫跑步者世界,有人管它叫跑者世界。直到《RW跑者世界》中文版發行,「跑者」一詞才被固定下來,而你翻看2008年之前的文章,很多人稱呼runner,還叫做跑步的人。在runners world網站上,會將 runner 和 jogger 做嚴格的區分,runner 更偏向於嚴肅跑者,jogger 更傾向於慢跑者。
  • 「常用詞根詞綴」cord, ann, chron 最常用詞根詞綴速記
    這才是最適合成年人的單詞記憶方式,因為隨著年齡的增長,人的記憶力越來越依靠理解力,只有將事物理解透徹才能更快得將它記住。通過詞根詞綴法,我們看單詞就不再是一坨的,而是一塊一塊的,我們能夠更深入的理解它,更快速的記住它。
  • 快來試試更小更快的差分升級
    快來試試差分升級,立功科技基於AMetal SDK提供了一套完整的差分升級算法,升級固件更小、下載速度更快、大大降低網絡不穩定造成傳輸失敗概率,同時更節省內存。一、差分包原理在講差分升級之前,先簡單介紹一下差分升級的原理和概念:差分升級是將新老固件具有差異的部分剝離出來,例如固件從V1.1.0升級到V1.1.1,兩個固件相比只修改了1K的內容,如下圖紅色部分為不同部分,將該部分剝離出來生成差分包Diff_V1.1.0~V1.11,通過雲端將差分包推送到設備端
  • 火葬或將面臨淘汰?新方法更環保、更高效,已在武漢推行
    然而,隨著現代社會的到來,中國已經開始實行火葬,但當大家已經慢慢接受火葬的時候,火葬可能面臨淘汰,新的殯葬方式更加高效、環保,目前武漢已經實行了殯葬儀式。火葬可能面臨淘汰?新方法更加環保高效。在中國古代,由於技術並不先進,而人的思想又比較傳統,所以厚葬的方式比較流行。由於當時佛教盛行,佛教思想認為"天道輪迴",人活著的時候只要做好事,死後就可以投胎到一個好人家。
  • 何謂更高、更快、更強?讓柳工C系列起重機產品告訴你答案!
    自1896年,雅典舉辦首屆奧運會後,奧林匹克精神——「更高更快更強」便成了運動員們不懈的追求。而對於不斷追求卓越,致力於為市場提供更高作業高度、更快作業速度、更強起重性能產品的安徽柳工而言,這句話同樣適用。自柳工C系列產品面向市場以來,口碑非常不錯,從「嘗鮮」到「玩轉」各種極限工況,從未讓用戶失望。
  • 隨著美元以更快的速度貶值最終將被取代
    歐元區太平洋資本執行長、著名基金經理彼得·希夫(Peter Schiff)表示,美聯儲將創造一種通脹環境,就像一種稅收,將在各個層面損害社會。他說:「我認為,大多數人將會被通貨膨脹稅消滅。所有的政府都不是自由的。