ตรวจจับพยางค์ในคำหนึ่งคำ


138

ฉันต้องการค้นหาวิธีที่มีประสิทธิภาพพอสมควรในการตรวจสอบพยางค์ในคำ เช่น,

มองไม่เห็น -> in-vi-sib-le

มีกฎบางพยางค์ที่สามารถใช้ได้:

V CV VC CVC CCV CCCV CVCC

* โดยที่ V คือเสียงสระและ C เป็นพยัญชนะ เช่น,

การออกเสียง (5 Pro-nun-ci-a-tion; CV-CVC-CV-V-CVC)

ฉันได้ลองวิธีการสองสามอย่างซึ่งใช้ regex (ซึ่งจะช่วยเฉพาะในกรณีที่คุณต้องการนับพยางค์) หรือการกำหนดกฎการเข้ารหัสแบบยาก (วิธีการบังคับแบบเดรัจฉานซึ่งพิสูจน์ให้เห็นว่าไม่มีประสิทธิภาพมาก) และสุดท้ายก็ใช้ออโต จำกัด ไม่ส่งผลกับสิ่งที่มีประโยชน์)

แอปพลิเคชันของฉันมีวัตถุประสงค์เพื่อสร้างพจนานุกรมของพยางค์ทั้งหมดในภาษาที่กำหนด พจนานุกรมนี้จะใช้สำหรับการตรวจสอบการสะกดคำในภายหลัง (โดยใช้ตัวแยกประเภทเบส์) และการสังเคราะห์ข้อความเป็นคำพูด

ฉันจะขอบคุณถ้ามีใครสามารถให้คำแนะนำในทางเลือกอื่นในการแก้ปัญหานี้นอกเหนือจากวิธีการก่อนหน้าของฉัน

ฉันทำงานใน Java แต่เคล็ดลับใน C / C ++, C #, Python, Perl ... จะทำงานให้ฉัน


คุณต้องการให้คะแนนหารจริงหรือเพียงแค่จำนวนพยางค์ในคำ? หากหลังพิจารณาคำในพจนานุกรมข้อความเป็นคำพูดและนับหน่วยเสียงที่เข้ารหัสเสียงสระ
Adrian McCarthy

วิธีที่มีประสิทธิภาพมากที่สุด (การคำนวณที่ชาญฉลาดไม่ใช่ที่จัดเก็บข้อมูลที่ชาญฉลาด) ฉันเดาว่าจะมีพจนานุกรม Python ที่มีคำเป็นกุญแจและจำนวนพยางค์เป็นค่า อย่างไรก็ตามคุณยังคงต้องการทางเลือกสำหรับคำที่ไม่ได้ทำไว้ในพจนานุกรม แจ้งให้เราทราบหากคุณเคยพบพจนานุกรมดังกล่าว!
Brōtsyorfuzthrāx

คำตอบ:


120

อ่านเกี่ยวกับวิธีการ TeX ของปัญหานี้เพื่อวัตถุประสงค์ในการใส่ยัติภังค์ โดยเฉพาะอย่างยิ่งเห็นแฟรงก์เหลียงวิทยานิพนธ์วิทยานิพนธ์ ของ Word Hy-phen-a-tion โดยดอทคอมใส่เอ้อ อัลกอริทึมของเขาถูกต้องมากแล้วรวมพจนานุกรมข้อยกเว้นเล็ก ๆ สำหรับกรณีที่อัลกอริทึมไม่ทำงาน


52
ฉันชอบที่คุณอ้างถึงวิทยานิพนธ์วิทยานิพนธ์เกี่ยวกับเรื่องนี้มันเป็นคำใบ้เล็กน้อยสำหรับโปสเตอร์ต้นฉบับว่านี่อาจไม่ใช่คำถามง่าย ๆ
คาร์ล

ใช่ฉันรู้ว่านี่ไม่ใช่คำถามง่าย ๆ แม้ว่าฉันจะไม่ได้ทำอะไรมากมาย แต่ฉันก็ประมาทปัญหาฉันคิดว่าฉันจะทำงานในส่วนอื่น ๆ ของแอพและกลับมาที่ปัญหา 'ง่าย' นี้ Silly me :)
user50705

ฉันอ่านกระดาษ disertation และพบว่ามีประโยชน์มาก ปัญหาเกี่ยวกับวิธีการคือฉันไม่มีรูปแบบใด ๆ สำหรับภาษาแอลเบเนียแม้ว่าฉันจะพบเครื่องมือบางอย่างที่สามารถสร้างรูปแบบเหล่านั้นได้ อย่างไรก็ตามสำหรับวัตถุประสงค์ของฉันฉันเขียนแอพพลิเคตามกฎซึ่งการแก้ไขปัญหา ...
user50705

10
โปรดทราบว่าอัลกอริทึม TeX ใช้สำหรับการหาจุดยัติภังค์ที่ถูกต้องซึ่งไม่เหมือนกับแผนกพยางค์ เป็นความจริงที่ว่าจุดยัติภังค์นั้นอยู่ในส่วนของพยางค์ แต่ไม่ใช่ทุกหน่วยงานที่เป็นพยางค์ที่เป็นจุดยัติภังค์ที่ถูกต้อง ตัวอย่างเช่นไม่มีการใช้ยัติภังค์ (ภายในตัวอักษร) ภายในตัวอักษรหนึ่งหรือสองตัวที่ลงท้ายด้วยคำใดคำหนึ่ง ฉันยังเชื่อว่ารูปแบบของ TeX ได้รับการปรับเพื่อแลกเปลี่ยนกับข้อผิดพลาดที่เป็นเท็จสำหรับผลบวกที่ผิดพลาด (อย่าใส่เครื่องหมายยัติภังค์ที่ไม่ได้อยู่ในนั้นแม้ว่าจะหมายถึงโอกาสในการใส่ไฮเฟ็นที่ถูกกฎหมาย)
Adrian McCarthy

1
ฉันไม่เชื่อว่าการใส่ไฮเฟ็นเป็นคำตอบเช่นกัน
Ezequiel

46

ฉันสะดุดข้ามหน้านี้เพื่อค้นหาสิ่งเดียวกันและพบว่ามีการใช้งานกระดาษเหลียงเพียงไม่กี่ที่นี่: https://github.com/mnater/hyphenatorหรือตัวตายตัวแทน: https://github.com/mnater/Hyphenopoly

นั่นคือถ้าคุณเป็นประเภทที่สนุกกับการอ่านวิทยานิพนธ์ 60 หน้าแทนการปรับรหัสที่มีอยู่ได้อย่างอิสระสำหรับปัญหาที่ไม่ซ้ำกัน :)


เห็นด้วย - สะดวกกว่ามากที่จะใช้การฝังที่มีอยู่
hoju

41

นี่เป็นวิธีแก้ปัญหาโดยใช้NLTK :

from nltk.corpus import cmudict
d = cmudict.dict()
def nsyl(word):
  return [len(list(y for y in x if y[-1].isdigit())) for x in d[word.lower()]] 

เฮ้ขอบคุณข้อผิดพลาดเล็ก ๆ น้อย ๆ ในทารกที่ควรจะเป็นฟังก์ชั่น def nsyl (คำ): return [len (รายการ (y สำหรับ y ใน x ถ้า y [-1] .isdigit ())) สำหรับ x ใน d [word.lower ()] ]
Gourneau

6
สิ่งที่คุณจะแนะนำให้เป็นทางเลือกสำหรับคำที่ไม่ได้อยู่ในคลังข้อมูลนั้น?
Dan Gayle

4
@Pureferret cmudictเป็นพจนานุกรมสำหรับออกเสียงคำศัพท์ภาษาอังกฤษอเมริกาเหนือ มันแยกคำเป็นหน่วยเสียงซึ่งสั้นกว่าพยางค์ (เช่นคำว่า 'cat' แบ่งออกเป็นสามหน่วยเสียง: K - AE - T) แต่เสียงสระก็มี "ความเครียดเครื่องหมาย": เช่น 0, 1, หรือ 2 ขึ้นอยู่กับการออกเสียงของคำ (ดังนั้น AE ใน 'cat' กลายเป็น AE1) รหัสในคำตอบจะนับเครื่องหมายของความเครียดและดังนั้นจำนวนของเสียงสระ - ซึ่งให้จำนวนพยางค์ได้อย่างมีประสิทธิภาพ
billy_chapters

1
ส่งคืนจำนวนพยางค์ไม่ใช่การสร้างพยางค์
Adam Michael Wood

19

ฉันพยายามที่จะแก้ไขปัญหานี้สำหรับโปรแกรมที่จะคำนวณคะแนนการอ่านของ flesch-kincaid และ flesch ของบล็อกข้อความ อัลกอริทึมของฉันใช้สิ่งที่ฉันพบในเว็บไซต์นี้: http://www.howmanysyllables.com/howtocountsyllables.htmlและมันเข้าใกล้พอสมควร มันยังคงมีปัญหากับคำที่ซับซ้อนอย่างล่องหนและยัติภังค์ แต่ฉันพบว่ามันอยู่ใน ballpark เพื่อจุดประสงค์ของฉัน

มันมีข้อดีของการใช้งานง่าย ฉันพบว่า "es" สามารถเป็นได้ทั้งพยางค์หรือไม่ มันเป็นการพนัน แต่ฉันตัดสินใจที่จะลบ es ในอัลกอริทึมของฉัน

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;
    }

สำหรับสถานการณ์ง่าย ๆ ของฉันในการค้นหาพยางค์ในชื่อที่เหมาะสมดูเหมือนว่าในตอนแรกจะทำงานได้ดีพอ ขอบคุณที่ฝากไว้ที่นี่
นอร์แมน H

7

นี่เป็นปัญหาที่ยากโดยเฉพาะซึ่งไม่ได้รับการแก้ไขอย่างสมบูรณ์โดยอัลกอริธึมยัติภังค์ LaTeX บทสรุปที่ดีเกี่ยวกับวิธีการบางอย่างที่มีอยู่และความท้าทายที่เกี่ยวข้องสามารถดูได้ในเอกสารการประเมินอัลกอริธึมการสร้างแบบอัตโนมัติสำหรับภาษาอังกฤษ (Marchand, Adsett และ Damper 2007)


5

ทำไมต้องคำนวณ พจนานุกรมออนไลน์ทุกเล่มมีข้อมูลนี้ http://dictionary.reference.com/browse/invisible ใน· vis · i · ble


3
อาจจะต้องใช้กับคำที่ไม่ปรากฏในพจนานุกรมเช่นชื่อ?
Wouter Lievens

4
@WouterLievens: ฉันไม่คิดว่าชื่อจะอยู่ใกล้กับคนที่มีความประพฤติดีพอสำหรับการแยกคำพยางค์อัตโนมัติ โปรแกรมแยกวิเคราะห์พยางค์สำหรับชื่อภาษาอังกฤษจะล้มเหลวอย่างน่าสมเพชในชื่อของแหล่งกำเนิดภาษาเวลส์หรือสก็อตแลนด์ชื่อต้นกำเนิดของอินเดียและไนจีเรีย แต่เพียงผู้เดียว
Jean-François Corbett

เราต้องจำไว้ว่ามันไม่สมเหตุสมผลที่จะคาดหวังผลการดำเนินงานที่ดีกว่าที่มนุษย์สามารถให้ได้เนื่องจากนี่เป็นวิธีการแก้ปัญหาแบบฮิวริสติกล้วนๆ
Darren Ringer

5

ขอบคุณ Joe Basirico ที่แบ่งปันการใช้งานที่รวดเร็วและสกปรกของคุณใน C # ฉันใช้ห้องสมุดขนาดใหญ่และใช้งานได้ แต่โดยปกติแล้วจะช้านิดหน่อยและสำหรับโครงการที่รวดเร็ววิธีการของคุณก็ใช้ได้ดี

นี่คือรหัสของคุณใน Java พร้อมกับกรณีทดสอบ:

public static int countSyllables(String word)
{
    char[] vowels = { 'a', 'e', 'i', 'o', 'u', 'y' };
    char[] currentWord = word.toCharArray();
    int numVowels = 0;
    boolean lastWasVowel = false;
    for (char wc : currentWord) {
        boolean foundVowel = false;
        for (char v : 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 (word.length() > 2 && 
            word.substring(word.length() - 2) == "es")
        numVowels--;
    // remove silent e
    else if (word.length() > 1 &&
            word.substring(word.length() - 1) == "e")
        numVowels--;
    return numVowels;
}

public static void main(String[] args) {
    String txt = "what";
    System.out.println("txt="+txt+" countSyllables="+countSyllables(txt));
    txt = "super";
    System.out.println("txt="+txt+" countSyllables="+countSyllables(txt));
    txt = "Maryland";
    System.out.println("txt="+txt+" countSyllables="+countSyllables(txt));
    txt = "American";
    System.out.println("txt="+txt+" countSyllables="+countSyllables(txt));
    txt = "disenfranchized";
    System.out.println("txt="+txt+" countSyllables="+countSyllables(txt));
    txt = "Sophia";
    System.out.println("txt="+txt+" countSyllables="+countSyllables(txt));
}

ผลลัพธ์เป็นไปตามที่คาดไว้ (ใช้งานได้ดีพอสำหรับ Flesch-Kincaid):

txt=what countSyllables=1
txt=super countSyllables=2
txt=Maryland countSyllables=3
txt=American countSyllables=3
txt=disenfranchized countSyllables=5
txt=Sophia countSyllables=2

5

กระแทก @Tihamer และ @ joe-basirico ฟังก์ชั่นที่มีประโยชน์มากไม่สมบูรณ์แบบแต่ดีสำหรับโครงการขนาดเล็กถึงขนาดกลาง โจฉันได้เขียนการใช้งานโค้ดของคุณใหม่ใน 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

หวังว่าใครบางคนพบว่ามีประโยชน์นี้!


4

Perl มีLingua :: Phonology ::โมดูลพยางค์ คุณอาจลองหรือลองดูอัลกอริทึมของมัน ฉันเห็นโมดูลรุ่นเก่าอีกสองสามตัวที่นั่นเช่นกัน

ฉันไม่เข้าใจว่าทำไมการแสดงออกปกติให้คุณนับพยางค์เท่านั้น คุณควรรับพยางค์ได้เองโดยใช้เครื่องหมายวงเล็บ สมมติว่าคุณสามารถสร้างนิพจน์ทั่วไปที่ใช้งานได้นั่นคือ


4

วันนี้ผมพบว่านี้ใช้ Java ของ algorithmn ยัติภังค์แฟรงก์เหลียงที่มีรูปแบบภาษาอังกฤษหรือเยอรมันซึ่งทำงานค่อนข้างดีและสามารถใช้ได้บน Maven กลาง

Cave: มันเป็นสิ่งสำคัญที่จะลบบรรทัดสุดท้ายของ.texไฟล์รูปแบบเพราะมิฉะนั้นไฟล์เหล่านั้นไม่สามารถโหลดได้ด้วยเวอร์ชันปัจจุบันบน Maven Central

ในการโหลดและใช้งานhyphenatorคุณสามารถใช้ข้อมูลโค้ด Java ต่อไปนี้ texTableเป็นชื่อของ.texไฟล์ที่มีรูปแบบที่ต้องการ ไฟล์เหล่านั้นมีอยู่ในไซต์ GitHub โครงการ

 private Hyphenator createHyphenator(String texTable) {
        Hyphenator hyphenator = new Hyphenator();
        hyphenator.setErrorHandler(new ErrorHandler() {
            public void debug(String guard, String s) {
                logger.debug("{},{}", guard, s);
            }

            public void info(String s) {
                logger.info(s);
            }

            public void warning(String s) {
                logger.warn("WARNING: " + s);
            }

            public void error(String s) {
                logger.error("ERROR: " + s);
            }

            public void exception(String s, Exception e) {
                logger.error("EXCEPTION: " + s, e);
            }

            public boolean isDebugged(String guard) {
                return false;
            }
        });

        BufferedReader table = null;

        try {
            table = new BufferedReader(new InputStreamReader(Thread.currentThread().getContextClassLoader()
                    .getResourceAsStream((texTable)), Charset.forName("UTF-8")));
            hyphenator.loadTable(table);
        } catch (Utf8TexParser.TexParserException e) {
            logger.error("error loading hyphenation table: {}", e.getLocalizedMessage(), e);
            throw new RuntimeException("Failed to load hyphenation table", e);
        } finally {
            if (table != null) {
                try {
                    table.close();
                } catch (IOException e) {
                    logger.error("Closing hyphenation table failed", e);
                }
            }
        }

        return hyphenator;
    }

หลังจากนั้นHyphenatorพร้อมใช้งาน ในการตรวจสอบพยางค์แนวคิดพื้นฐานคือการแยกคำที่มีเครื่องหมายขีดคั่น

    String hyphenedTerm = hyphenator.hyphenate(term);

    String hyphens[] = hyphenedTerm.split("\u00AD");

    int syllables = hyphens.length;

คุณจำเป็นต้องแยก"\u00AD" ตั้งแต่ API "-"ไม่ได้กลับมาเป็นปกติ

วิธีนี้มีประสิทธิภาพสูงกว่าคำตอบของ Joe Basirico เนื่องจากรองรับภาษาต่าง ๆ มากมายและตรวจจับการใส่ไฮเฟ็นเยอรมันได้แม่นยำยิ่งขึ้น


4

ฉันพบปัญหาเดียวกันนี้เมื่อไม่นานมานี้

ฉันลงเอยด้วยการใช้พจนานุกรมการออกเสียง CMUเพื่อค้นหาคำศัพท์ที่รวดเร็วและแม่นยำที่สุด สำหรับคำที่ไม่ได้อยู่ในพจนานุกรมฉันกลับไปที่รูปแบบการเรียนรู้ของเครื่องที่มีความแม่นยำถึง 98% ในการทำนายจำนวนพยางค์

ฉันเก็บทุกอย่างไว้ในโมดูล python ที่ใช้งานง่ายได้ที่นี่: https://github.com/repp/big-phoney

ติดตั้ง: pip install big-phoney

นับพยางค์:

from big_phoney import BigPhoney
phoney = BigPhoney()
phoney.count_syllables('triceratops')  # --> 4

หากคุณไม่ได้ใช้งูหลามและคุณต้องการที่จะลองวิธี ML-แบบจำลองผมสวยรายละเอียดเขียนขึ้นเกี่ยวกับวิธีการรูปแบบการนับพยางค์ทำงานบน Kaggle


นี่สุดยอดมาก มีใครบ้างที่โชคดีในการแปลงโมเดล Keras ที่ได้เป็น CoreML สำหรับใช้บน iOS?
Alexsander Akers

2

ขอบคุณ @ joe-basirico และ @tihamer ฉันได้เปลี่ยนรหัส @ tihamer's เป็น Lua 5.1, 5.2 และ luajit 2 ( ส่วนใหญ่จะทำงานบน lua รุ่นอื่นด้วย ):

countsyllables.lua

function CountSyllables(word)
  local vowels = { 'a','e','i','o','u','y' }
  local numVowels = 0
  local lastWasVowel = false

  for i = 1, #word do
    local wc = string.sub(word,i,i)
    local foundVowel = false;
    for _,v in pairs(vowels) do
      if (v == string.lower(wc) and lastWasVowel) then
        foundVowel = true
        lastWasVowel = true
      elseif (v == string.lower(wc) and not lastWasVowel) then
        numVowels = numVowels + 1
        foundVowel = true
        lastWasVowel = true
      end
    end

    if not foundVowel then
      lastWasVowel = false
    end
  end

  if string.len(word) > 2 and
    string.sub(word,string.len(word) - 1) == "es" then
    numVowels = numVowels - 1
  elseif string.len(word) > 1 and
    string.sub(word,string.len(word)) == "e" then
    numVowels = numVowels - 1
  end

  return numVowels
end

และแบบทดสอบสนุก ๆ เพื่อยืนยันว่ามันใช้งานได้ดี ( เท่าที่ควร ):

countsyllables.tests.lua

require "countsyllables"

tests = {
  { word = "what", syll = 1 },
  { word = "super", syll = 2 },
  { word = "Maryland", syll = 3},
  { word = "American", syll = 4},
  { word = "disenfranchized", syll = 5},
  { word = "Sophia", syll = 2},
  { word = "End", syll = 1},
  { word = "I", syll = 1},
  { word = "release", syll = 2},
  { word = "same", syll = 1},
}

for _,test in pairs(tests) do
  local resultSyll = CountSyllables(test.word)
  assert(resultSyll == test.syll,
    "Word: "..test.word.."\n"..
    "Expected: "..test.syll.."\n"..
    "Result: "..resultSyll)
end

print("Tests passed.")

ฉันเพิ่มอีกสองกรณีทดสอบ "สิ้นสุด" และ "ฉัน" การแก้ไขคือการเปรียบเทียบตัวพิมพ์เล็กและตัวพิมพ์ใหญ่สตริง Ping'ing @ joe-basirico และ tihamer ในกรณีที่ประสบปัญหาเดียวกันและต้องการอัปเดตฟังก์ชั่น
josefnpat

@tihamer American มี 4 พยางค์!
josefnpat

2

ฉันไม่สามารถหาวิธีที่เหมาะสมในการนับพยางค์ดังนั้นฉันจึงออกแบบวิธีการด้วยตนเอง

คุณสามารถดูวิธีการของฉันได้ที่นี่: https://stackoverflow.com/a/32784041/2734752

ฉันใช้การผสมผสานของพจนานุกรมและวิธีอัลกอริทึมในการนับพยางค์

คุณสามารถดูห้องสมุดของฉันได้ที่นี่: https://github.com/troywatson/Lawrence-Style-Checker

ฉันเพิ่งทดสอบอัลกอริทึมของฉันและมีอัตราการหยุดงาน 99.4%!

Lawrence lawrence = new Lawrence();

System.out.println(lawrence.getSyllable("hyphenation"));
System.out.println(lawrence.getSyllable("computer"));

เอาท์พุท:

4
3

1
โดยทั่วไปการเชื่อมโยงไปยังเครื่องมือหรือไลบรารีควรมาพร้อมกับบันทึกการใช้งานคำอธิบายเฉพาะเกี่ยวกับวิธีการใช้ทรัพยากรที่เชื่อมโยงกับปัญหาหรือโค้ดตัวอย่างบางส่วนหรือถ้าเป็นไปได้ทั้งหมดข้างต้น
IKavanagh

ดูเน้นไวยากรณ์ มีปุ่มวิธีใช้ (เครื่องหมายคำถาม) ในตัวแก้ไข SO ซึ่งจะพาคุณไปยังหน้าที่ลิงก์ไว้
IKavanagh

0

หลังจากทำการทดสอบและทดลองใช้ชุดยัติภังค์เป็นจำนวนมากเช่นกันฉันก็เขียนเองตามตัวอย่างจำนวนหนึ่ง ฉันยังลองpyhyphenและpyphenแพ็คเกจที่เชื่อมต่อกับพจนานุกรมการใส่ไฮเฟนเนชัน nltkแพคเกจเป็นเพียงช้าเกินไปสำหรับกรณีการใช้งานนี้

การนำไปใช้ของฉันใน Python เป็นส่วนหนึ่งของคลาสที่ฉันเขียนและรูทีนการนับพยางค์จะถูกวางไว้ด้านล่าง มันประมาณจำนวนของพยางค์เล็กน้อยเนื่องจากฉันยังไม่พบวิธีที่ดีในการอธิบายคำลงท้ายที่เงียบ

ฟังก์ชั่นจะคืนค่าอัตราส่วนของพยางค์ต่อคำตามที่ใช้สำหรับคะแนนการอ่านของ Flesch-Kincaid จำนวนไม่จำเป็นต้องใกล้พอสำหรับการประมาณ

ในซีพียู i7 รุ่นที่ 7 ของฉันฟังก์ชั่นนี้ใช้เวลา 1.1-1.2 มิลลิวินาทีสำหรับข้อความตัวอย่าง 759 คำ

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)

-1

ฉันใช้ jsoup ทำสิ่งนี้ครั้งเดียว ต่อไปนี้เป็นตัวแยกวิเคราะห์พยางค์ตัวอย่าง:

public String[] syllables(String text){
        String url = "https://www.merriam-webster.com/dictionary/" + text;
        String relHref;
        try{
            Document doc = Jsoup.connect(url).get();
            Element link = doc.getElementsByClass("word-syllables").first();
            if(link == null){return new String[]{text};}
            relHref = link.html(); 
        }catch(IOException e){
            relHref = text;
        }
        String[] syl = relHref.split("·");
        return syl;
    }

โปรแกรมแยกวิเคราะห์พยางค์ทั่วไปเป็นอย่างไร? ดูเหมือนว่ารหัสนี้จะค้นหาพยางค์ในพจนานุกรมเท่านั้น
Nico Haase
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.