Bloom karşıtı filtre var mı?


25

Bir Bloom filtresi , işleme sırasında çeşitli değerlerle karşılaşılmış olup olmadığını etkin bir şekilde takip etmeyi sağlar. Çok sayıda veri öğesi olduğunda, bir Bloom filtresi bir karma tablo üzerinde önemli bir hafıza tasarrufuna neden olabilir. Bir hash tablosuyla paylaştığı bir Bloom filtresinin temel özelliği, bir öğe yeni değilse her zaman "yeni değil" demesidir, ancak bir öğenin yeni değil "olarak işaretleneceği sıfır olmayan bir olasılık vardır. "Yeni olsa bile.

Karşıt davranışı olan bir "Bloom karşıtı filtre" var mı?

Başka bir deyişle: eğer bir öğe yeniyse "yeni" diyen, ancak yeni olmayan bazı öğeler için "yeni" diyebilecek etkili bir veri yapısı var mı?

Önceden görülen tüm öğelerin (örneğin, sıralanmış bir listede) tutulması ilk gereksinimi karşılar ancak çok fazla bellek kullanabilir. Ben rahat ikinci şartı verilen de, gereksiz olduğunu umuyorum.


Daha resmi tedavi yazma tercih edenler için b(x)=1 Bloom filtresi düşünürse x yenidir, b(x)=0 , aksi takdirde ve yazma n(x)=1 ise x gerçekten yeni ve n(x)=0 aksi takdirde.

Sonra Pr[b(x)=0|n(x)=0]=1 ; Pr[b(x)=0|n(x)=1]=α ; Pr[b(x)=1|n(x)=0]=0; Pr[b(x)=1|n(x)=1]=1α , bazı 0<α<1 .

I soran: yapan bir fonksiyonu uygulamak etkili bir veri yapısı vardır, b bazı 0<β<1 , bu şekilde Pr[b(x)=0|n(x)=0]=β ; Pr[b(x)=0|n(x)=1]=0 ; Pr[b(x)=1|n(x)=0]=1β ; Pr[b(x)=1|n(x)=1]=1 ?


Düzenleme: Bu soru daha önce /programming/635728 ve /cstheory/6596 adresinden /programming/635728 ve /cstheory/6596 olarak soruluyor gibi görünüyor . "ile" yapılabilir, " b " değerlerini tersine çevirerek "yapmak" önemsizdir . Bana "doğru" cevabın ne olduğu henüz belli değil. Ne olduğunu net (Ilmari Karonen önerdiği bir gibi) oldukça iyi çalışıyor çeşit bir LRU önbelleğe alma düzeni, uygulanması kolay olmasıdır, ve benim kod çalıştırmasına için geçen sürede% 50'lik bir azalma ile sonuçlandı.


Bazı nedenlerden dolayı, bunun, önbelleklerin ve önbellek yerleştirme algoritmalarının çözmeye çalıştığı soruna çok benzer olduğunu söylemek için cazip geldim. En az kullanılan (LFU) değiştirmeyi kullanarak bir önbellek düşünün. Teorik olarak en uygun, ancak imkansız bir değiştirme algoritması, önbelleklerde olduğu gibi, en uzun süre tekrar göremeyeceğiniz bir tahliyeyi çıkarmak olacaktır. Önbelleğe almanın, dağıtımın niteliği ile ilgili genel olarak geçerli olmayabilecek bazı varsayımlara dayandığını düşünüyorum, ancak bunun geçerli olup olmadığını düşünmeye değer.
Patrick87,

Aşağıdaki konuşmalar ilginizi çekebilir: Memnuniyete dayalı set üyeliği filtreleri
Kaveh

@Kaveh: işaretçi için teşekkürler, izleyecektir.
András Salamon

Yanıtlar:


12

Patrick87'nin karma fikriyle başa çıkmak, işte neredeyse gereksinimlerinizi karşılayan pratik bir yapı - eski bir değer için yanlış bir şekilde yeni bir değeri yanlış kullanma olasılığı tamamen sıfır değil, kolayca ihmal edilebilir derecede küçük olabilir.

ve k parametrelerini seçin ; pratik değerler, n = 128 ve k = 16 olabilir . Let , H , bir güvenli kriptografik hızlı arama fonksiyonu (en azından) üretilmesi , n + k çıkış bit.nkn=128k=16Hn+k

Let dizisi olarak 2 k , n bitlik bit katarı. Bu dizi depolar toplam kullanılarak filtrenin durumu, n, 2 K bit. (Bu dizinin nasıl başlatıldığının önemi yoktur; onu yalnızca sıfırlarla veya rastgele bitlerle doldurabiliriz.)a2k nn2k

  • xi k j n H ( x ) , bir i = jij=H(x)ikjnH(x)ai=j

  • Filtreye değerinin eklenip eklenmediğini test etmek için yukarıdaki gibi hesaplayın ve olup olmadığını kontrol edin . Eğer evet ise, doğru dönün; aksi halde false döndür.ben xa i = j ij=H(x)ai=j

İstem 1: Yanlış pozitifin olasılığı (= hatalı olduğu iddia edilen yeni değer) . Bu, depolama alanındaki mütevazı bir maliyetle arttırılmasıyla keyfi olarak küçük yapılabilir ; bilhassa, , bu olasılık, pratikte, bir donanım arızası nedeniyle yanlış bir pozitif olasılığından çok daha küçük olduğu için, esasen ihmal edilebilir düzeydedir. , n , n 1281/2n+knn128

Özellikle, farklı değerler kontrol edilip filtreye eklendikten sonra, en az bir yanlış pozitif oluşma olasılığı . Örneğin, ve ,% 50 olasılıkla yanlış bir pozitif elde etmek için gereken farklı değerlerin sayısı yaklaşık .( N- 2 - N ) / 2 N + k + 1 , n = 128 k = 16 2 ( n + k ) / 2 = 2 72N(N2N)/2n+k+1n=128k=162(n+k)/2=272

2. İstem 2: Yanlış negatifin (= önceden yeni eklenen iddia edilen katma değerin değeri) olasılığı, , burada , filtreye eklenen farklı değerlerin sayısıdır (veya daha spesifik olarak, test edilmekte olan belirli değerin filtreye eklenmesinden sonra eklenen farklı değerlerin sayısı ). N1(12k)N1exp(N/2k)<N/2kN


Ps. “İhmal edilebilir derecede küçük” bir perspektifi ortaya koymak için, 128-bit şifrelemenin şu anda bilinen teknolojiyle kırılmaz olduğu düşünülmektedir . Bu şemadan ile yanlış bir pozitif elde etmek , ilk denemede gizli 128-bit şifreleme anahtarınızı doğru tahmin eden biri olabilir . ( ve , aslında bundan yaklaşık 65.000 kat daha az muhtemeldir.)n = 128 k = 16n+k=128n=128k=16

Fakat eğer bu hala sizi irrasyonel olarak gergin hissediyorsa, daima geçebilirsiniz ; depolama gereksinimlerinizi iki katına çıkaracak, ancak güvenli bir şekilde, ile hiç kimsenin yanlış bir pozitif görmeyeceğini ispatlamak istediğiniz herhangi bir miktarla güvenli bir şekilde bahse girebilirim .n = 256n=256n=256


1
Olasılık sadece donanım arızası ile karşılaştırılabilir değildir; Ayrıca ilk denemede SSH girişi için RSA anahtarınızı tahmin eden birinin olasılığı ile karşılaştırılabilir . IMO ikincisi, çözümünüzün pratikliğini eskisinden daha çok taşır.
R. ..

+1 Çok hoş - benim anladığım şey, alan verimliliği problemini, madde aslında yeni olduğunda bazı (çok küçük) yanlış bir şekilde "yeni değil" diye cevaplama şansı vererek çözmektir. Çok pratik ve iyi analiz.
Patrick87,

1
İstem 1, sadece düzgün bir karma fonksiyonunun düşük bir çarpışma ihtimaline sahip olduğunu belirtmektedir. Bu zaten pratikte en az 50 olması durumunda geçerlidir . Uygulamam için, ve basit 64-bit, kriptografik olarak güvenli olmayan, fakat hızlı bir karma işleviyle harika çalışıyor. n = 44 k = 20n+kn=44k=20
András Salamon

@ AndrásSalamon: Doğru, güvenli bir şifreleme hash işlevi aslında biraz daha güçlü bir garanti veriyor olsa da, yani, kasıtlı olarak aramaya çalışsanız bile, çarpışan girdileri bulmanın pratik olmadığı kesindir . Yeterince büyük bir (örneğin , yukarıda belirtildiği gibi ) ile, bu, yanlış bir pozitifin maliyeti yüksek olsa bile ve bir tane bulmaya çalışan aktif bir rakip olsa bile , tüm verileri saklamanın gereksiz olduğu anlamına gelir . Elbette, bu kadar güçlü bir garantiye ihtiyacınız yoksa, biraz daha yüksek çarpışma riski kabul edilebilir. n = 128nn=128
Ilmari Karonen

1
@ Yenitoprak Kriptografik bir karma işlevi belirlememin nedeni , bunlar için, çarpışma oluşturmanın kaba kuvvetten (yani, çok sayıda girdiyi test ederek ve çarpışanları seçerek) veya başka bir yöntemle daha etkili bir şekilde bilinen bir yol bulunmamasıdır. kırık (örneğin, bugünlerde MD5 gibi). Bu nedenle, kriptografik bir karma için, çarpışma hızının ideal bir rastgele karma işlevi için olduğu gibi oldukça güvenli bir şekilde varsayılabilir. Evrensel bir karma işlevi veya anahtarlı bir MAC (rastgele bir gizli anahtarla) kullanmak bu garantiyi daha da güçlü hale getirir.
Ilmari Karonen

8

Hayır, bu özelliklerle etkin bir veri yapısına sahip olmak mümkün değildir, eğer veri yapısının gerçekten yeniyse "yeni" olacağını garanti etmek istiyorsanız (eğer asla, asla "yeni değil" diyecektir. aslında yenidir, yanlış negatiflere izin verilmez). Bu tür bir veri yapısının, "yeni değil" yanıtını vermek için tüm verilerini tutması gerekecektir. Kesin bir gerekçe için pents90’ın cstheory hakkındaki cevabına bakınız .

Buna karşılık, Bloom filtreleri olabilir verimli bir şekilde, olmayan yeni ise veri yapısı "yeni değil" demek olacağını garanti olsun. Özellikle, Bloom filtreleri tüm verileri depolamaktan daha verimli olabilir: her bir ürün oldukça uzun olabilir, ancak Bloom filtresinin boyutu toplam uzunlukları ile değil, öğelerin sayısıyla da ölçeklenir . Sorununuz için herhangi bir veri yapısının , veri öğelerinin sayısını değil, toplam veri uzunluğuyla ölçeklenmesi gerekir .


Ayrıca kabul edilen cevaba bakın, çünkü soru aynı
Joe

-1 Muhtemelen mümkün olmadığını söylerken ne demek istediğinizi nitelendirmelisiniz. Açıkça, etkili bir şekilde yapmak mümkündür ve düşük bir hata oranıyla da yapmak mümkündür, bu nedenle belirli bir uygulamada bir miktar dengeyi yakalamak mümkün olabilir ... özellikle, tam olarak neyin kastedildiğini tam olarak açıklamak faydalı olacaktır. "şimdiye kadar tüm veriler", çünkü sorunun sorusunu tatmin etmek için kesinlikle gerekli değil. Yanlış negatiflere - cevabın "yeni değil" olması gerektiğinde "yeniye" cevap verilmesi - burada izin verilir, bu nedenle tüm verilerin saklanması gerekmez.
Patrick87,

1
Bu cevap tamamen makul ve sorumun mektubunu ele alıyor gibi görünüyor, ama belki de ruhu değil.
András Salamon

@DW Cevabı güncellemeye zaman ayırdığınız için teşekkür ederiz. Şimdi bunu bir cevap olarak bırakmaya meyilliyim, yine de, anti-bloom filtrelerinin verimsizliğini açıklarken kullanılan dile itiraz etmeme rağmen, başvurulan "detaylar" hakkında biraz daha ayrıntılı bilgi vermenin en iyisi olacağını düşünüyorum. .. şimdilik -1 bırakarak. Eski yorumları temizledim.
Patrick87

@DW "Yanlış negatif" ile, cevabın "yeni değil" olması gerektiğinde "yeni" cevabını vermek istiyorum. (Biraz garip bir şekilde, "yeni değil", buradaki olumlu durumdur.) Bunu çıkarmak için "tüm verileri" kaydetmenize gerek yok, ancak tüm öğeleri kaydetmeniz gerektiğine inanmaya meyilli olduğum halde (sadece tüm unsurlar değil - buradaki sorunun diğer cevabına göre, varsayımsal olarak anlamlı bir hata olasılığını kabul etmediğiniz sürece.)
Patrick87

6

Peki ya bir karma tablo? Yeni bir öğe gördüğünüzde hash tablosunu kontrol edin. Öğenin noktası boşsa, "yeni" döndürün ve öğeyi ekleyin. Aksi halde, öğenin spotunun öğe tarafından işgal edilip edilmediğini kontrol edin. Öyleyse, "yeni değil" döndür. Spot başka bir öğe tarafından kullanılıyorsa, "new" döndürün ve spotun üzerine yeni öğenin üzerine yazın.

Maddenin karmasını daha önce hiç görmediyseniz, kesinlikle her zaman doğru bir şekilde "Yeni" yi alırsınız. Yalnızca aynı öğeyi gördüğünüzde öğenin karma değerini gördüyseniz, kesinlikle her zaman doğru bir şekilde "Yeni Değil" alırsınız. Doğru cevap "Yeni Değil" olduğunda "Yeni" olacak tek zaman, A maddesini görüyorsanız, B maddesine bakın, sonra A maddesine tekrar bakın, ve hem A hem de B'ye aynı şeye. Önemli olarak, asla "Yeni Değil" yanlış elde edemezsiniz.


1
Sanırım bu tür bir alan verimliliği sorununu görmezden geliyor ya da bir çiçeklenme filtresinin olduğundan çok daha az verimli, çünkü bir çiçeklenme filtresi gerçekten sadece kova başına bir bit gerektiriyor ve bunun için de alan başına harcadığı kadar kova ihtiyacı var. öğeleri temsil eder. Oh evet ... evren sonlu olmadığı sürece (Wandering Logic'in cevabında olduğu gibi) bence çiçek filtresinin alan verimliliğine çok yaklaşamayacağınızı düşünüyorum.
Patrick87,

Şahsen, cevabın benimkinden çok daha iyi olduğunu düşünüyorum. Çiçeklenme filtresi, % 50'den daha iyi olasılıklar istiyorsanız, kova başına sadece bir bit değildir . Aynı zamanda sabit bir büyüklüktedir ve yarıdan fazla doldurduğunuzda yanlış pozitiflerin olasılığı hızla artar. Genişletmenin uygun bir yolu yoktur, önbellek olarak kullanmanın uygun bir yolu yoktur ve elemanları silmenin uygun bir yolu yoktur. Bir karma tablo alacağım her zaman.
Wandering Logic

@WanderingLogic Tek bit yerine küçük bir doygunluk sayacı kullanmak, silme işleminin desteklenmesine izin verir (kapasite pahasına ve yalnızca sayaç maksimumda değilse).
Paul A. Clayton

4

Maddelerin evreninin sonlu olduğu durumda, evet: sadece setten ziyade hangi elementlerin setten çıktığını kaydeden bir çiçeklenme filtresi kullanın. (Yani, ilgi grubunun tamamlayıcısını temsil eden bir çiçeklenme filtresi kullanın.)

Bunun yararlı olduğu bir yer, sınırlı bir silme biçimine izin vermektir. İki tane çiçek filtresi tuttun. Boş başlarlar. Elementleri eklerken, bunları çiçeklenme filtresi A'ya eklersiniz. Daha sonra bir öğeyi silmek istiyorsanız, o öğeyi çiçeklenme filtresi B'ye eklersiniz. Bir arama yapmak için, ilk önce A çiçek filtresine bakın. Eşleşme bulamazsanız, öğe hiç eklenmedi (olasılık 1 ile). Bir eşleşme bulursanız, öğe eklenmiş olabilir (veya olmayabilir). Bu durumda çiçeklenme B filtresinde arama yaparsınız. Eşleşme bulamazsanız, öğe hiçbir zaman silinmedi. Çiçek filtresi B'de bir eşleşme bulursanız, öğe büyük olasılıkla eklenmiş ve sonra silinmiştir.

Bu, sorunuzu gerçekten cevaplamıyor, ancak bu sınırlı durumda, çiçek filtresi B tam olarak aradığınız "çiçeklenme karşıtı filtre" davranışını gerçekleştiriyor.

Real Bloom filtre araştırmacıları, silmeyi temsil etmek için çok daha etkili yollar kullanırlar, bkz. Mike Mitzenmacher'in yayın sayfası .


Bu soruda, öğeleri işliyoruz ve silinme yok. Çiçek filtresinden eşyaları çıkarmak zorunda kalmadan iltifatın saklanmasının anlamlı bir yolu yoktur
Joe

1
@Joe: Sorunun genel olarak çözülemeyeceğine katılıyorum, bu yüzden tamamlayıcının sınırlı ve küçük olduğu durumlarına verdiğim yanıtı kısıtladım.
Wandering Logic

1

vi

Örnek ip adresleri olabilir ve daha önce hiç görmediğiniz bir şey göründüğünde bilmek istersiniz. Ama yine de sınırlı bir set, yani ne bekleyebileceğini biliyorsun.

Gerçek çözüm basit:

  1. Tüm öğeleri sayma çiçek filtresine ekleyin.
  2. 1
  3. Gerçek bir yeni öğeyi gördükten sonra, onu filtreden çıkarın.

Öyleyse, aslında eski, ancak yeni olarak kabul edilen 'yanlış pozitif' değerlere sahip olabilirsiniz. Ancak, hiçbir zaman yeni bir değer için 'yeni değil' elde edemezsiniz, çünkü değeri hala tüm yuvalarda olacak ve başka hiç kimse onu alamazdı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.