Saya perlu menemukan cara yang cukup efisien untuk mendeteksi suku kata dalam sebuah kata. Misalnya,
Tak terlihat -> in-vi-sib-le
Ada beberapa aturan silabifikasi yang dapat digunakan:
V CV VC CVC CCV CCCV CVCC
* di mana V adalah vokal dan C adalah konsonan. Misalnya,
Pengucapan (5 Pro-nun-ci-a-tion; CV-CVC-CV-V-CVC)
Saya telah mencoba beberapa metode, di antaranya menggunakan regex (yang hanya membantu jika Anda ingin menghitung suku kata) atau definisi aturan hard code (pendekatan brute force yang terbukti sangat tidak efisien) dan akhirnya menggunakan automata keadaan terbatas (yang memang tidak menghasilkan sesuatu yang berguna).
Tujuan aplikasi saya adalah membuat kamus dari semua suku kata dalam bahasa tertentu. Kamus ini nantinya akan digunakan untuk aplikasi pemeriksa ejaan (menggunakan pengklasifikasi Bayesian) dan sintesis teks ke ucapan.
Saya akan sangat menghargai jika seseorang dapat memberi saya tip tentang cara alternatif untuk menyelesaikan masalah ini selain pendekatan saya sebelumnya.
Saya bekerja di Java, tetapi tip apa pun di C / C ++, C #, Python, Perl ... akan berhasil untuk saya.
sumber
Jawaban:
Baca tentang pendekatan TeX untuk masalah ini untuk tujuan tanda hubung. Terutama lihat disertasi tesis Frank Liang Word Hy-phen-a-tion oleh Com-put-er . Algoritmanya sangat akurat, dan kemudian menyertakan kamus pengecualian kecil untuk kasus-kasus di mana algoritme tidak berfungsi.
sumber
Saya menemukan halaman ini mencari hal yang sama, dan menemukan beberapa implementasi dari makalah Liang di sini: https://github.com/mnater/hyphenator atau penerusnya: https://github.com/mnater/Hyphenopoly
Itu kecuali Anda adalah tipe yang suka membaca tesis 60 halaman alih-alih mengadaptasi kode yang tersedia secara bebas untuk masalah non-unik. :)
sumber
Berikut adalah solusi menggunakan NLTK :
sumber
Saya mencoba mengatasi masalah ini untuk program yang akan menghitung skor membaca flesch-kincaid dan flesch dari sebuah blok teks. Algoritme saya menggunakan apa yang saya temukan di situs web ini: http://www.howmanysyllables.com/howtocountsyllables.html dan hasilnya cukup mendekati. Masih bermasalah pada kata-kata rumit seperti tak terlihat dan tanda hubung, tetapi saya telah menemukannya di kasar untuk tujuan saya.
Ini memiliki keuntungan karena mudah diterapkan. Saya menemukan "es" bisa berupa suku kata atau tidak. Ini pertaruhan, tetapi saya memutuskan untuk menghapus es dalam algoritme saya.
private int CountSyllables(string word) { char[] vowels = { 'a', 'e', 'i', 'o', 'u', 'y' }; string currentWord = word; int numVowels = 0; bool lastWasVowel = false; foreach (char wc in currentWord) { bool foundVowel = false; foreach (char v in vowels) { //don't count diphthongs if (v == wc && lastWasVowel) { foundVowel = true; lastWasVowel = true; break; } else if (v == wc && !lastWasVowel) { numVowels++; foundVowel = true; lastWasVowel = true; break; } } //if full cycle and no vowel found, set lastWasVowel to false; if (!foundVowel) lastWasVowel = false; } //remove es, it's _usually? silent if (currentWord.Length > 2 && currentWord.Substring(currentWord.Length - 2) == "es") numVowels--; // remove silent e else if (currentWord.Length > 1 && currentWord.Substring(currentWord.Length - 1) == "e") numVowels--; return numVowels; }
sumber
Ini adalah masalah yang sangat sulit yang tidak sepenuhnya diselesaikan dengan algoritma tanda hubung LaTeX. Ringkasan yang baik dari beberapa metode yang tersedia dan tantangan yang terlibat dapat ditemukan dalam makalah Mengevaluasi Algoritma Silabifikasi Otomatis untuk Bahasa Inggris (Marchand, Adsett, dan Damper 2007).
sumber
Mengapa menghitungnya? Setiap kamus online memiliki info ini. http://dictionary.reference.com/browse/invisible in · vis · i · ble
sumber
Terima kasih Joe Basirico, untuk berbagi implementasi cepat dan kotor Anda di C #. Saya telah menggunakan perpustakaan besar, dan berfungsi, tetapi biasanya agak lambat, dan untuk proyek cepat, metode Anda berfungsi dengan baik.
Berikut kode Anda di Java, bersama dengan kasus pengujian:
Hasilnya seperti yang diharapkan (ini bekerja cukup baik untuk Flesch-Kincaid):
sumber
Menabrak @Tihamer dan @ joe-basirico. Fungsi yang sangat berguna, tidak sempurna , tetapi bagus untuk sebagian besar proyek kecil hingga menengah. Joe, saya telah menulis ulang implementasi kode Anda dengan Python:
def countSyllables(word): vowels = "aeiouy" numVowels = 0 lastWasVowel = False for wc in word: foundVowel = False for v in vowels: if v == wc: if not lastWasVowel: numVowels+=1 #don't count diphthongs foundVowel = lastWasVowel = True break if not foundVowel: #If full cycle and no vowel found, set lastWasVowel to false lastWasVowel = False if len(word) > 2 and word[-2:] == "es": #Remove es - it's "usually" silent (?) numVowels-=1 elif len(word) > 1 and word[-1:] == "e": #remove silent e numVowels-=1 return numVowels
Semoga seseorang menemukan ini berguna!
sumber
Perl memiliki modul Lingua :: Phonology :: Syllable . Anda dapat mencobanya, atau mencoba melihat algoritmanya. Saya juga melihat beberapa modul lama lainnya di sana.
Saya tidak mengerti mengapa ekspresi reguler hanya memberi Anda hitungan suku kata. Anda seharusnya bisa mendapatkan suku kata itu sendiri menggunakan tanda kurung pengambilan. Dengan asumsi Anda dapat membuat ekspresi reguler yang berfungsi, yaitu.
sumber
Hari ini saya menemukan ini implementasi Java hyphenation algorithmn Frank Liang dengan pola untuk bahasa Inggris atau Jerman, yang bekerja cukup baik dan tersedia pada Maven Central.
Gua: Sangat penting untuk menghapus baris terakhir dari
.tex
file pola, karena jika tidak, file tersebut tidak dapat dimuat dengan versi saat ini di Maven Central.Untuk memuat dan menggunakan
hyphenator
, Anda dapat menggunakan potongan kode Java berikut.texTable
adalah nama.tex
file yang berisi pola yang dibutuhkan. File-file tersebut tersedia di situs github proyek.Setelah
Hyphenator
itu siap digunakan. Untuk mendeteksi suku kata, ide dasarnya adalah membagi istilah pada tanda hubung yang disediakan.Anda perlu membagi
"\u00AD
", karena API tidak mengembalikan normal"-"
.Pendekatan ini mengungguli jawaban Joe Basirico, karena mendukung banyak bahasa berbeda dan mendeteksi tanda hubung bahasa Jerman dengan lebih akurat.
sumber
Saya mengalami masalah yang persis sama beberapa waktu yang lalu.
Saya akhirnya menggunakan Kamus Pengucapan CMU untuk pencarian kata yang cepat dan akurat. Untuk kata-kata yang tidak ada dalam kamus, saya kembali ke model pembelajaran mesin yang ~ 98% akurat dalam memprediksi jumlah suku kata.
Saya menyelesaikan semuanya dalam modul python yang mudah digunakan di sini: https://github.com/repp/big-phoney
Install:
pip install big-phoney
Hitung Suku Kata:
Jika Anda tidak menggunakan Python dan ingin mencoba pendekatan berbasis model ML, saya menulis cukup mendetail tentang cara kerja model penghitungan suku kata di Kaggle .
sumber
Terima kasih @ joe-basirico dan @tihamer. Saya telah mem-porting kode @ tihamer ke Lua 5.1, 5.2 dan luajit 2 ( kemungkinan besar akan berjalan di versi lua lain juga ):
countsyllables.lua
Dan beberapa tes menyenangkan untuk memastikannya berfungsi ( sebanyak yang seharusnya ):
countsyllables.tests.lua
sumber
Saya tidak dapat menemukan cara yang memadai untuk menghitung suku kata, jadi saya merancang metode sendiri.
Anda dapat melihat metode saya di sini: https://stackoverflow.com/a/32784041/2734752
Saya menggunakan kombinasi metode kamus dan algoritma untuk menghitung suku kata.
Anda dapat melihat perpustakaan saya di sini: https://github.com/troywatson/Lawrence-Style-Checker
Saya baru saja menguji algoritme saya dan memiliki tingkat serangan 99,4%!
Lawrence lawrence = new Lawrence(); System.out.println(lawrence.getSyllable("hyphenation")); System.out.println(lawrence.getSyllable("computer"));
Keluaran:
sumber
Setelah melakukan banyak pengujian dan mencoba paket tanda hubung juga, saya menulis sendiri berdasarkan sejumlah contoh. Saya juga mencoba paket
pyhyphen
danpyphen
yang berinteraksi dengan kamus tanda hubung, tetapi mereka menghasilkan jumlah suku kata yang salah dalam banyak kasus. Thenltk
paket hanya terlalu lambat untuk kasus penggunaan ini.Implementasi saya dengan Python adalah bagian dari kelas yang saya tulis, dan rutinitas penghitungan suku kata ditempel di bawah ini. Ini sedikit melebih-lebihkan jumlah suku kata karena saya masih belum menemukan cara yang baik untuk menjelaskan akhiran kata diam.
Fungsi tersebut mengembalikan rasio suku kata per kata seperti yang digunakan untuk skor keterbacaan Flesch-Kincaid. Jumlahnya tidak harus tepat, cukup dekat untuk perkiraan.
Pada CPU i7 generasi ke-7 saya, fungsi ini memerlukan waktu 1,1-1,2 milidetik untuk teks sampel 759 kata.
def _countSyllablesEN(self, theText): cleanText = "" for ch in theText: if ch in "abcdefghijklmnopqrstuvwxyz'’": cleanText += ch else: cleanText += " " asVow = "aeiouy'’" dExep = ("ei","ie","ua","ia","eo") theWords = cleanText.lower().split() allSylls = 0 for inWord in theWords: nChar = len(inWord) nSyll = 0 wasVow = False wasY = False if nChar == 0: continue if inWord[0] in asVow: nSyll += 1 wasVow = True wasY = inWord[0] == "y" for c in range(1,nChar): isVow = False if inWord[c] in asVow: nSyll += 1 isVow = True if isVow and wasVow: nSyll -= 1 if isVow and wasY: nSyll -= 1 if inWord[c:c+2] in dExep: nSyll += 1 wasVow = isVow wasY = inWord[c] == "y" if inWord.endswith(("e")): nSyll -= 1 if inWord.endswith(("le","ea","io")): nSyll += 1 if nSyll < 1: nSyll = 1 # print("%-15s: %d" % (inWord,nSyll)) allSylls += nSyll return allSylls/len(theWords)
sumber
Saya menggunakan jsoup untuk melakukan ini sekali. Berikut adalah contoh pengurai suku kata:
sumber