Bir bilgisayarın, kullanıcı tarafından sağlanan örneklerle bir düzenli ifadeyi "öğrenmesi" mümkün müdür?


95

Bir bilgisayarın, kullanıcı tarafından sağlanan örneklerle bir düzenli ifadeyi "öğrenmesi" mümkün müdür?

Netleştirmek için:

  • Ben do not normal ifadeler öğrenmek istiyorum.
  • Bir kullanıcı tarafından etkileşimli olarak sağlanan örneklerden düzenli ifadeyi "öğrenen" bir program yaratmak istiyorum, örneğin bir metinden bölümler seçerek veya başlangıç ​​veya bitiş işaretlerini seçerek.

Mümkün mü? Google’ın kullanabileceği algoritmalar, anahtar kelimeler vb. Var mı?

DÜZENLEME : Cevaplar için teşekkür ederim, ancak bu özelliği sağlayan araçlarla ilgilenmiyorum . Makaleler, öğreticiler, kaynak kodu, algoritma adları gibi teorik bilgiler arıyorum, böylece kendim için bir şeyler yaratabilirim.


4
Kimsenin Regex'ten
tripleee

Yanıtlar:


44

Hesaplamalı Öğrenme Teorisine Giriş kitabı , sonlu bir otomatı öğrenmek için bir algoritma içerir. Her normal dil, sonlu bir otomata eşdeğer olduğundan, bir program tarafından bazı düzenli ifadeleri öğrenmek mümkündür. Kearns ve Valiant , sonlu bir otomat öğrenmenin mümkün olmadığı bazı durumlar gösteriyor. Bununla ilgili bir problem, bir karakter dizisini tanımlayabilen olasılıksal otomatlar olan gizli Markov Modellerini öğrenmektir . Programlama dillerinde kullanılan çoğu modern "normal ifadeler" aslında normal dillerden daha güçlüdür ve bu nedenle bazen öğrenmesi daha zordur.


44

Evet, mümkün, örneklerden normal ifadeler oluşturabiliriz (metin -> istenen ayıklamalar). Bu, işi yapan, çalışan bir çevrimiçi araçtır: http://regex.inginf.units.it/

Regex Generator ++ çevrimiçi aracı, bir GP arama algoritması kullanarak sağlanan örneklerden bir normal ifade oluşturur. GP algoritması, daha yüksek performans ve daha basit çözüm yapısına (Occam's Razor) yol açan çok amaçlı bir uygunluk tarafından yönlendirilir. Bu araç, Machine Lerning Lab, Trieste Univeristy (Università degli studi di Trieste) tarafından yapılan demostatif bir uygulamadır. Video eğitimi bakınız burada .

Bu bir araştırma projesidir, bu yüzden burada kullanılan algoritmalar hakkında okuyabilirsiniz .

Seyretmek! :-)

Örneklerden anlamlı bir normal ifade / çözüm bulmak, ancak ve ancak sağlanan örnekler sorunu iyi açıklarsa mümkündür. Bir çıkarma görevini açıklayan bu örnekleri düşünün, biz belirli ürün kodlarını arıyoruz; örnekler metin / çıkarma çiftleridir:

"The product code is 467-345A" -> "467-345A"
"The item 789-345B is broken"  -> "789-345B"

Örneklere bakan (insan) bir adam şunu söyleyebilir: "öğe kodları \ d ++ - 345 [AB] gibi şeylerdir"

Ürün kodu daha izin verici olduğunda, ancak başka örnekler vermediğimizde, sorunu iyi anlamak için kanıtlarımız yok. İnsan tarafından oluşturulan çözümü \ d ++ - 345 [AB] aşağıdaki metne uygularken başarısız olur:

"On the back of the item there is a code: 966-347Z"

Eşleşmenin ne olduğunu ve neyin istenen eşleşme olmadığını daha iyi açıklamak için başka örnekler vermelisiniz: --ie:

"My phone is +39-128-3905 , and the phone product id is 966-347Z" -> "966-347Z"

Telefon numarası bir ürün kimliği değildir, bu önemli bir kanıt olabilir.


5
Bu en iyi cevap olmalı. Mümkün ve bu bunu gösteriyor. Kaynağa buradan ulaşabilirsiniz: github.com/MaLeLabTs/RegexGenerator
rjurney

Ürün kodları örneğiniz, sınırlı sayıda örnek ürün kodundan normal ifadeyi çıkarmaya çalışmak yerine, söz konusu insanın neden ürün kodları için spesifikasyona bakması ve spesifikasyona göre normal ifadeyi yazması gerektiğini göstermektedir (kişi veya bir program normal ifadeyi çıkarmaya çalışıyor).
Jan Goyvaerts

2
İşleri yapmanın doğru yolu budur. Örneğim, sorunu kavramsal olarak açıklamanın yalnızca bir yoludur. Bazen bir şartname yoktur veya adam normal ifadeyi (bilgi eksikliği) kendi başına yazamaz.
Fabiano Tarlao

Daha kesin ve net olmak gerekirse :-), "İşleri yapmanın doğru yolu budur" -> "Haklısın, işleri yapmanın en iyi yolu, her zaman mümkün olduğunda spesifikasyonlardan başlamalısın"
Fabiano Tarlao

2
"Örnekler Metin Ekstraksiyon için Normal İfade Çıkarım" makale algoritması ayrıntılı bir açıklama içermektedir machinelearning.inginf.units.it/publications/...
mimmuz

36

Hiçbir bilgisayar programı, yalnızca geçerli eşleşmeler listesine dayalı olarak anlamlı bir düzenli ifade oluşturamaz . Size nedenini göstereyim.

Bilgisayarın aşağıdakileri oluşturması durumunda 111111 ve 999999 örneklerini sağladığınızı varsayalım:

  1. Tam olarak bu iki örnekle eşleşen bir normal ifade: (111111|999999)
  2. 6 aynı basamakla eşleşen bir normal ifade (\d)\1{5}
  3. 6 birler ve dokuzlarla eşleşen bir normal ifade [19]{6}
  4. Herhangi bir 6 basamakla eşleşen bir normal ifade \d{6}
  5. Yukarıdaki üçten herhangi biri, kelime sınırları ile, ör. \b\d{6}\b
  6. İlk üçten herhangi biri, öncesinde veya sonrasında bir rakam gelmez, ör. (?<!\d)\d{6}(?!\d)

Gördüğünüz gibi, örnekleri bir normal ifadeye genelleştirmenin birçok yolu vardır. Bilgisayarın öngörülebilir bir normal ifade oluşturmasının tek yolu, tüm olası eşleşmeleri listelemenizi istemektir . Daha sonra bu eşleşmelerle tam olarak eşleşen bir arama modeli oluşturabilir.

Tüm olası eşleşmeleri listelemek istemiyorsanız, daha yüksek düzeyde bir açıklamaya ihtiyacınız vardır. Normal ifadelerin tam olarak sağlamak için tasarlandığı şey budur. 6 basamaklı sayılardan oluşan uzun bir liste sağlamak yerine, programa "herhangi bir altı basamakla" eşleşmesini söyleyin. Normal ifade sözdiziminde bu, \ d {6} olur.

Normal ifadeler kadar esnek olan üst düzey bir açıklama sağlamanın herhangi bir yöntemi de normal ifadeler kadar karmaşık olacaktır. RegexBuddy gibi tüm araçların yapabileceği, üst düzey açıklamayı oluşturmayı ve test etmeyi kolaylaştırmaktır. Doğrudan düzenli ifade sözdizimini kullanmak yerine, RegexBuddy, düz İngilizce yapı taşlarını kullanmanızı sağlar. Ancak sizin için üst düzey tanımlamayı yaratamaz çünkü örneklerinizi ne zaman genellemesi gerektiğini ve ne zaman genellememesi gerektiğini sihirli bir şekilde bilemez.

Normal bir ifade oluşturmak için kullanıcı tarafından sağlanan kılavuzlarla birlikte örnek metni kullanan bir araç oluşturmak kesinlikle mümkündür. Böyle bir aracı tasarlamanın zor kısmı, kullanıcının ihtiyaç duyduğu yol gösterici bilgileri, aracı normal ifadelerden daha zorlaştırmadan ve aracı genel düzenli ifadelerle veya basit normal ifadelerle sınırlamadan nasıl istemesidir.


Haklısın, sorumu gönderdikten sonra bulduğum birçok öğrenme algoritması olumlu ve olumsuz bilgiler gerektiriyor. Anladığım kadarıyla, açık bir "daha yüksek seviyeli açıklama" gerekli değil çünkü kullanıcı bunu soruları cevaplayarak sağlıyor.
Daniel Rikowski

Bir araç sorular sorarsa, soruların ve verilen cevapların kombinasyonu üst düzey açıklamayı oluşturur. Bu tür araçların kalitesi büyük ölçüde sorduğu sorulara bağlıdır.
Jan Goyvaerts

Bu aptalca çünkü başka bir örnek verirseniz, bu olasılıklardan bazılarını ayıklayabilirsiniz. Başka bir örnek daha fazla ayıklıyor.
Cris

2
@Cris: Kaç örnek sağladığınızdan bağımsız olarak prensip kalır. Sadece olasılıkları değiştirir. Örneğin, 123456'nın eklenmesi # 2'yi (\ d) \ 1 {5} | 123456 ve # 3'ü [19] {6} | 123456 olarak değiştirir. Veya # 3'ü [1-69] {6} olarak değiştirebilir. Hatta istenen model, her bir rakamın önceki rakamdan bir büyük olduğu 6 aynı rakam veya 6 rakam ile eşleşebilir. 6 basamaklı sayılardan oluşan 10.000 örnek sağlasanız bile, program, kullanıcıdan ekstra talimatlar olmadan # 1, # 4, # 5 veya # 6'yı ayırt edemez.
Jan Goyvaerts

Bu sorunun şu şekilde kolayca çözülebileceğini hissediyorum: Program mümkün olduğunca genel olmaya çalışıyor (mantık dahilinde) ve sonra size eşleşeceğini düşündüğü diğer şeylere örnekler veriyor. Önerilen eşleşmelere sadece 'evet' ve 'hayır' diyerek, aslında yakalamaya çalıştığınız şeyin sınırlarını anlamasına yardımcı olabilirsiniz. Bir metin düzenleyicide bu kavramı kullanan ve şu anda açık olan dosyadaki eşleşmeleri öneren bir araç görmeyi çok isterim.
Jon McClung

9

Evet, kesinlikle "mümkün"; İşte sözde kod:

string MakeRegexFromExamples(<listOfPosExamples>, <listOfNegExamples>)
{
   if HasIntersection(<listOfPosExamples>, <listOfNegExamples>)
     return <IntersectionError>

   string regex = "";
   foreach(string example in <listOfPosExamples>)
   {
      if(regex != "")
      {
         regex += "|";
      }
      regex += DoRegexEscaping(example);
   }
   regex = "^(" + regex + ")$";

   // Ignore <listOfNegExamples>; they're excluded by definition

   return regex;
}

Sorun, bir örnek listesiyle eşleşen sonsuz sayıda normal ifade olmasıdır. Bu kod, kümedeki en basit / en aptal normal ifadeyi sağlar, temelde olumlu örnekler listesindeki herhangi bir şeyle eşleşir (ve olumsuz örnekler dahil hiçbir şey dahil değildir).

Sanırım asıl zorluk, tüm örneklerle eşleşen en kısa normal ifadeyi bulmak olacaktır, ancak o zaman bile, kullanıcının ortaya çıkan ifadenin "doğru olan" olduğundan emin olmak için çok iyi girdiler sağlaması gerekir.


3
Kullanıcı pozitif ve negatif örnekler girdiğinde ilginçleşmeye başlar . Normal ifade, pozitif örneklerle eşleşmeli ve negatif örneklerle eşleşmemelidir.
user55400

@blixtor - Aslında oldukça kolay. Olumsuz örneklerden hiçbirini oluşturulmuş normal ifadeye koymayın, reddedilecektir. Unutmayın, kodun oluşturduğu kod yalnızca olumlu örnekle eşleşir; olumsuz örnekler (ve diğer her şey) tanım gereği hariç tutulmuştur!
Daniel LeCheminant

Daniel haklı. Daha yüksek düzeyde bir açıklama olmadan, bir örnek listesinden tutarlı ve doğru bir şekilde çıkarılabilecek tek şey bir alternatifler listesidir.
Jan Goyvaerts

6

Terimin "indüksiyon" olduğuna inanıyorum. Düzenli bir dilbilgisi oluşturmak istiyorsunuz.

Sonlu bir dizi örnekle (olumlu veya olumsuz) bunun mümkün olduğunu sanmıyorum. Ancak, doğru hatırlıyorsam, danışılabilecek bir Oracle varsa yapılabilir. (Temel olarak, programın içeriği olana kadar kullanıcıya evet / hayır soruları sormasına izin vermeniz gerekir.)


Evet, yapmak istediğim bu, kullanıcıya etkileşimli olarak sorun.
Daniel Rikowski

Yuval F'nin referansları aklımdaki gibi görünüyor, onlara bir göz atmanızı öneririm.
Jay Kominek


4

Prolog'a dayanan bu gibi problemlere adanmış bir dil var. Buna progol denir .

Diğerlerinin de belirttiği gibi, temel fikir, yapay zeka çevrelerinde genellikle ILP ( tümevarımlı mantık programlama ) olarak adlandırılan tümevarımlı öğrenmedir .

İkinci bağlantı, konu hakkında daha fazla bilgi edinmek istiyorsanız, birçok yararlı kaynak materyal içeren ILP hakkındaki wiki makalesidir.


2

@ Yuval doğru. Hesaplamalı öğrenme teorisine veya "tümevarımlı çıkarım" a bakıyorsunuz.

Soru düşündüğünüzden daha karmaşıktır, çünkü "öğrenmek" in tanımı önemsiz değildir. Yaygın bir tanım, öğrencinin istediği zaman cevaplar verebilmesidir, ancak sonunda ya cevapları tükürmeyi bırakmalı ya da her zaman aynı cevabı söylemelidir. Bu, sonsuz sayıda girdi varsayar ve programın ne zaman karara varacağına dair kesinlikle hiçbir ipucu vermez. Ayrıca, kararına ne zaman ulaştığını bilemezsiniz çünkü daha sonra yine de farklı bir şey çıktı verebilir.

Bu tanıma göre, normal dillerin öğrenilebilir olduğundan oldukça eminim. Diğer tanımlara göre, o kadar değil ...



0

Bir kişinin düzenli bir ifadeyi öğrenmesi mümkünse, o zaman bir program için temelde mümkündür. Ancak, bu programın öğrenilebilmesi için doğru şekilde programlanması gerekecektir. Neyse ki, bu oldukça sınırlı bir mantık alanıdır, bu nedenle bir programa nesneleri veya bunun gibi bir şeyi görebilmeyi öğretmek kadar karmaşık olmaz.


1
Doğru değil, Turing makinelerinde kararsız olan problemlere bakmalısınız.
Stephen Curial

Adil olmak gerekirse, bir kişi bir REGEX öğrenebilirse, bir makine öğrenebilir dedim. Genel olarak onu kastetmedim.
cjk

@scurial Turing makinelerinde insanlar tarafından çözülebilir ancak karar verilemeyen sorunlar olduğunu sanmıyorum, değil mi?
Sunny88
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.