Как определить, что текст написан транслитом?

Интересуют максимально простые и быстрые алгоритмы для определения русскоязычного транслита (privet mir kak dela chto delaesh'). Если такие вообще существуют. Текст от нескольких символов до 1kb.

Язык программирования не так важен (хотя реализовывать буду на Go). Если есть алгоритм, то где посмотреть, почитать. Если существуют конкретные реализации на любом ЯП, то опять же - где посмотреть.

Пока пришла в голову идея взять большой словарь русского языка (тысяч на 100-150 слов), весь его оттранслитить и построить префиксное дерево, затем проверять какую-то часть (выборку) слов на вхождение в дерево. Правда, придется делать токенизацию текста, что, возможно, сильно замедлит детектирование. Хотелось бы обойтись временем не более 50-100msc.

Может быть есть какие-то чисто статистич. подходы?


Ответы (2 шт):

Автор решения: UModeL

Вопрос непростой, и достойный ответ может появиться не так уж скоро. Поэтому добавлю "игрушку", как вариант, чтобы не скучал вопрос в одиночестве :)

oSrcTxt.addEventListener("input", function() { let sSrcTxt = this.value;
  switch (true) {
    case (sSrcTxt == ""): oMsgRes.value = ""; break;
    case (/[а-яё]/gi.test(sSrcTxt)): oMsgRes.value = "Русский"; break;
    case (/\W(s|po|na|ili|v|vse|ne|o|ot|potomu|iz|za|zatem|kak)\W/gi.test(sSrcTxt)): oMsgRes.value = "Похоже на транслит"; break;
    default: oMsgRes.value = "Английский"; break;
  }
});
#oSrcTxt, #oMsgRes { box-sizing: border-box; width: 100%; } #oSrcTxt { height: 100px; } #oMsgRes { text-align: center; border: none; }
<input id="oMsgRes" type="text" placeholder="ПУСТО" readonly>
<textarea id="oSrcTxt" placeholder="Вставьте в это поле текст в одном из следующих форматов:
- Русский
- Английский
- Транслит
Текст должен быть осмысленным и достаточного объёма."></textarea>

Собственно, сам детект транслита основан на поиске предлогов, союзов, частиц и коротких слов, которые транслитерируются всегда и везде одинаково. То есть, всякие я = ya = ja не берём.

Естественно, словарь можно расширить и вынести в отдельный массив, можно сопоставлять другими методами... Но, это всего лишь вариант.

Возьмите текст с любой страницы в Интернете, а транслит можно получить в Google Переводчике

→ Ссылка
Автор решения: Garry Galler

Пока для себя сделал самый простой вариант. Взял гошную библиотеку whatlanggo, которая и так у меня использовалась (она детектит ~80 языков по триграммам) и добавил в нее как новый язык Russian Translit. В качестве триграмм взял триграммы для русского из кода библиотеки и ...транслитерировал их :-) Пришлось, правда урезать некоторые получившиеся 4-x и 5-ти-граммы до 3-х символов.

[]string{" pr", " i ", "rav", "stv", " na", "pra", "go ", "eni", "ove", "vo ", " ka", "ani", "t' ", " v ", " po", " ob", "iya", "svo", " sv", "lov", "na ", " ch", "elo", "o n", " so", "ost", "che", "ie ", "ogo", "et ", "niy", "est", "avo", "yj ", "azh", " im", "nie", "vek", " ne", "l'n", "li ", "ova", "ime", "at'", "pri", "t p", "i p", "kaz", "ili", "obo", " ra", "yh ", "zhd", " do", "dyj", "vob", "ek ", "bod", "va ", "j c", "ego", "sya", "i s", "ii ", "aci", "eet", "no ", "mee", "i i", "len", "oj ", "tva", "nyh", "to ", " il", "k i", "enn", " by", "iyu", " za", "mi ", "tvo", "i n", "o p", "van", "o s", "sto", "al'", " vs", "om ", "o v", "'no", "ih ", "nog", "i v", "nov", "ako", "pro", "ij ", "sti", "i o", "pol", "olz", "dol", "oe ", "bra", "ya ", " os", "nym", "zhe", "raz", "ti ", "nos", "ya ", " vo", "tor", "vse", " eg", "ej ", "tel", "ne ", "i r", "red", "el'", "tve", "odi", " ko", "obs", "o i", " de", "ima", "a i", "che", "nim", "sno", "kak", " li", "shc", "vle", "'sy", "nny", "ast", "t's", "nno", "osu", "e d", " ot", "pre", "she", "a s", "bsh", "osn", "odn", "byt", "sov", "yt'", "lzh", "ran", "niy", "ich", "ak ", "ym ", "vat", "cht", "stu", "che", "e v", " st", "res", "ol'", " ni", "nom", "rod", "lya", "nar", "ven", "du ", "ozh", "ny ", "e i", " to", "ver", "a o", "zov", "m i", "nac", "den", "rin", "tup", "ezh", "str", " ch", "ya ", "ona", "dos", "h i", "j i", "toy", "esp", "lic", "bes", "obr", "oto", "o b", "'ny", "' v", "nii", "e m", "uyu", " mo", "em ", " me", "aro"," re", "ava", "kot", "av ", " vy", "am ", "zhn", "sta", "aya", "pod", "i k", "noe", " k ", " ta", " go", "gos", "sud", "eob", "ya ", "en ", "i d", "moz", "esk", "eli", "avn", "ve ", "ech", "ush", "pec", "dno", "o d", "hod", "ka ", " dl", "dly", "ovo", "ate", "l's", "yu ", "v k", "nen", "cii", "noj", "uda", "vov", " be", "oro", "nst", "ami", "cia", "kon", "sem", "e o", "vno", " et", "azo", "h p", "ni ", "zhd", "m p", "kog", "ot ", "dst", "vny", "st'", "ye ", "o o", "pos", "sre", "tra", "ejs", "tak", "i b", "dov", "mu ", "ya ", "nal", "dru", " dr", "koj", "ter", "' p", "ars", "izn", "soc", "edi", "oln"}

Протестил. Для девяти слов библиотека уже дает 100% уверенность.

package main

import (
    "fmt"

    "github.com/abadojack/whatlanggo"
)

func main() {
    /*
    Language:  Russian Translit Confidence: 0.097778
    Language:  Russian Translit Confidence: 0.186942
    Language:  Russian Translit Confidence: 0.239282
    Language:  Russian Translit Confidence: 1.000000
    Language:  Russian Translit Confidence: 1.000000
    Language:  Russian Translit Confidence: 1.000000
    Language:  Russian Translit Confidence: 1.000000
    */
    
    info := whatlanggo.Detect("privet kak dela")
    fmt.Printf("Language: %17s Confidence: %f\n",
        info.Lang.String(), 
        info.Confidence,
    )
    
    info = whatlanggo.Detect("privet kak dela chto delaesh")
    fmt.Printf("Language: %17s Confidence: %f\n",
        info.Lang.String(), 
        info.Confidence,
    )
    
    info = whatlanggo.Detect("privet kak dela chto delaesh kak zhizn'")
    fmt.Printf("Language: %17s Confidence: %f\n",
        info.Lang.String(), 
        info.Confidence,
    )
    
    info = whatlanggo.Detect("privet kak dela chto delaesh kak zhizn' do svidaniya")
    fmt.Printf("Language: %17s Confidence: %f\n",
        info.Lang.String(), 
        info.Confidence,
    )
   
   info = whatlanggo.Detect("privet kak dela chto delaesh' kak zhizn' do svidaniya eshche uvidimsya")
   fmt.Printf("Language: %17s Confidence: %f\n",
        info.Lang.String(), 
        info.Confidence,
   )
    
   info = whatlanggo.Detect("privet kak dela chto delaesh' kak zhizn' do svidaniya eshche uvidimsya do vstrechi")
   fmt.Printf("Language: %17s Confidence: %f\n",
        info.Lang.String(), 
        info.Confidence,
   )
    info = whatlanggo.Detect(`Solnce svetit i rastet trava,
No tebe ona ne nuzhna.
Vse ne tak i vse ne to,
Kogda tvoya devushka bol'na.`)
    fmt.Printf("Language: %17s Confidence: %f\n",
        info.Lang.String(), 
        info.Confidence,
   ) 

}

P.S. Последний вариант (слова из песни Цоя) - "игрушка", которую предложил UModeL, определяет как транслит. Но все предыдущие - нет.

→ Ссылка