Friday, October 30, 2020

Analyzing the OCR errors in the extraction of Myanmar dictionary headwords


In the first round of editing of the raw headwords produced from the OCR process, I marked an erroneous headword with an asterisk at the end of the word. To begin with each of the raw headwords has a hyphen character at the end, so that the erroneous headword will now have both a hyphen and an asterisk at the end. The headwords marked with an asterisk were of three kinds: (i)identical headwords with multiple meanings appear multiple times in the list; since I am extracting the distinct headwords, only one of them will be retained, (ii)some raw headwords were superfluous and they would be dropped, and (iIi)for the remaining, corrected headwords were typed in the next line and they don’t have any additional character like “-” or "*".

Using the above information, I extracted the vectors: errList (that shows each of a pair of the erroneous raw headword and the corrected headword), NElist (that shows headwords missed completely by OCR), and DRlist (the superfluous headwords dropped).

The following is the test run for the imported data file, that is, data from the last (seventh) OCR output text file:

library(stringr)
errList <- c()
NElist <- c()
DRlist <- c()
errChrDiff <- c()
missErr <- c()
j <- 1
n <- 1
Q <- 0
r <- 1
tmp <- ""
for (i in 1:length(z0.418)){
  # if marked for error *
  if (grepl("[*]", z0.418[i])){
    if (tmp != "") {
      p <- paste0("<",i-1,">")
      DRlist[r] <- paste(p, tmp)
      r <- r+1
    }
    tmp <- z0.418[i]
    Q <- i
  # not marked for error (= correct or corrected + new entry) with - or none 
  }else{
    # if corrected + new entry (none)
    if (grepl("[\u1000-\u104f]$", z0.418[i])){
       if (Q == 0|Q>1 & i != Q+1) {  #new entry, test
        m <- paste0("<",i,">")
        NElist[n] <- paste(m, z0.418[i])
        n <- n+1
      }else{    #Q > 0, current not marked at all, last element marked
        if (tmp != "") {   #corrected
          k <- paste0("<",i-1,">", tmp)
          # utf8::utf8_print(paste(k, z0.418[i], sep = " ==> "))
          errList[j] <- paste(k, z0.418[i], sep = " ==> ")

          tmp0 <- gsub("[^\u1000-\u104f]", "", tmp)
          eD1 <- intToUtf8(setdiff(utf8ToInt(tmp0), utf8ToInt(z0.418[i])))
          eD2 <- intToUtf8(setdiff(utf8ToInt(z0.418[i]), utf8ToInt(tmp0)))
          u <- paste0("<",i-1,">")
          v <- paste0("<",i,">")
          errChrDiff[j] <- paste0(u, "Raw= ", tmp0, " (Extra= ", eD1, ", ", "Missed= ", eD2, "); ", v, "Correct= ", z0.418[i], collapse = "")
          missErr[j] <- eD2
          tmp <- ""
          j <- j+1
        }
        Q <- 0
      }
    }else{   #(1)with - mark, raw correct; (2)if last mark *, it is dropped
      if (tmp != "") {
        p <- paste0("<",i-1,">")
        DRlist[r] <- paste(p, tmp)
        r <- r+1
        tmp <- ""
      }
    }
  }
}
utf8::utf8_print(errList)
 [1] "<18>စက်ဆန်း- * ==> စက်ဆန်"                "<33>စက်နခရီ- * ==> စက်နာရီ"              
 [3] "<38>စက်ပြေခင်း - * ==> စက်ပြောင်း"        "<58>စက်လှေကး - * ==> စက်လှေကား"          
 [5] "<65>စက်- * ==> စက်သီး"                   "<70>စက္က - * ==> စက္ကတုံး"               
 [7] "<83>စောက်ထိုးမိုးမှော် - * ==> စောက်ထိုးမိုးမျှော်" "<112>စင်စွမ်း - * ==> စင်ပြွမ်း"           
 [9] "<115>စင်ယှဉ်ပြ၁သခ်- * ==> စင်ယှဉ်ပြ၁သာဒ်"     "<121>စင်း၁- * ==> စင်းချော"            
[11] "<124>စမ်းလေး – * ==> စင်းလေး"           "<128>စင်းလျာ - * ==> စင်းလျှော"         
[13] "<130>စကြိ- * ==> စင်္ကြံ"                 "<159>စောင်းနှင့်- * ==> စောင်းငဲ့"          
[15] "<162>စောင်းညှိုး- * ==> စောင်းညှို့"           "<166>စောင်းခင်း - * ==> စောင်းပြား"     
[17] "<172>စောင်းများ – * ==> စောင်းလျား"     "<179>စိုင်လျမ် - * ==> စိုင်လျော်"           
[19] "<183>စိုင်းနင်- * ==> စိုင်းနှင်"              "<196>စစ် - * ==> စစ်ကဲ"                 
[21] "<217>စ်ဆုတ် - * ==> စစ်ဆုတ်"                "<220>စစ်ညခင်း - * ==> စစ်ညောင်း"         
[23] "<237>စစ်ပရိယယ်- * ==> စစ်ပရိယာယ်"           "<239>စစ်ရ- * ==> စစ်ပါရီ"               
[25] "<242>စစ် - * ==> စစ်ပြေး"               "<244>စစ်ဖြန် - * ==> စစ်ပြန်"            
[27] "<262>စစ်ဝက်- * ==> စစ်လျှောက်"             "<270>စစ်သော်- * ==> စစ်သင်္ဘော"           
[29] "<285>စဉ် - * ==> စဉ့်"                   "<304>စည်း - * ==> စည်ကား"              
[31] "<308>စည်ထို- * ==> စည်တို"                  "<312>စည်ပတ်သီး- * ==> စည်ပတ်သံပြား"        
[33] "<314>စည်ဝင်း - * ==> စည်ဖောင်း"           "<339>စည်းဝါး - * ==> စည်းပြေးဝါးပြေး"  
[35] "<383>စိတ်စေ- * ==> စိတ်စော"               "<440>စိတ်- * ==> စိတ်ဖြေ"                
[37] "<444>စိတ် - * ==> စိတ်မနှံ့"                 "<446>စိတ်မာ- * ==> စိတ်မော"              
[39] "<481>စိတ်အး - * ==> စိတ်အား"              "<487>စိတ္တ- * ==> စိတ္တဇ"                
[41] "<499>စုတ်ထိုး - * ==> စုတ်ပဲ့"                "<508>စန္ဒ၁- * ==> စန္ဒာ"               
[43] "<510>စာသ- * ==> စန္ဒြမာသ"              "<520>စန္ဒ၁ - * ==> စန္ဒ၁း"             
[45] "<541>စိန်ဝင်း - * ==> စိန်ပြောင်း"          "<567>စပ်ကြခင်း - * ==> စပ်ကြောင်း"       
[47] "<570>စပ်စေခင်- * ==> စပ်စောင်"            "<584>စပ် - * ==> စပ်နွား"               
[49] "<586>စပ်ပာ- * ==> စပ်ပညာ"               "<588>စပ်- * ==> စပ်ဖာ"                 
[51] "<591>စပ်ပြီ - * ==> စပ်ဖြဲဖြဲ"             "<596>စပ် - * ==> စပ်ရှား"               
[53] "<600>စပ်လေ့- * ==> စပ်လှေ"                "<604>စပ်ယပ်- * ==> စပ်ဟပ်"               
[55] "<630>စိမ့် - * ==> စိမ့်တော"                "<637>စိမ်း - * ==> စိမ်းကား"             
[57] "<642>စိမ်းအံ့- * ==> စိမ်းဆွံ"                "<646>စိမ်းရွှမ်း - * ==> စိမ်းရွမ်း"          
[59] "<655>စုံဆယ်- * ==> စုံဆယ်ဖြာ"               "<657>စုံတွဲ- * ==> စုံဆွဲ"                   
[61] "<671>စုံစုံ - * ==> စုံးစုံး"                 "<677>စ္ဆေ- * ==> စွေ"                  
[63] "<702>စိ- * ==> စွတ်ကပါစိနမ်းပါစိ"           "<707>စွတ်စွတ်နခ- * ==> စွတ်စွတ်နာ"           
[65] "<718>စွန်ပြီး- * ==> စွန်မြီး"              "<720>စွန်ပြီးတော့ - * ==> စွန်မြီးကော့"      
[67] "<722>စွန်ရှိ- * ==> စွန်ရဲ"                  "<754>စွယ်စုံ- * ==> စွယ်ရံ"                 

To find the differences in characters between an erroneous headword produced by OCR and the correct headword. I used the setdiff() function. There are two ways to look at the difference. One is the characters in OCR headword not found in the correct headword, and the other is the characters in correct headword missed by the OCR headword. I called them “extra”, and “missed”. To use this approach, first the pair of raw and correct headwords is broken up into characters (here Unicode codepoints) and then the setdiff() function is applied.
I got this solution from the stackoverflow Q/A, here.

utf8::utf8_print(errChrDiff)
 [1] "<18>Raw= စက်ဆန်း (Extra= း, Missed= ); <19>Correct= စက်ဆန်"               
 [2] "<33>Raw= စက်နခရီ (Extra= ခ, Missed= ာ); <34>Correct= စက်နာရီ"             
 [3] "<38>Raw= စက်ပြေခင်း (Extra= ခ, Missed= ာ); <39>Correct= စက်ပြောင်း"       
 [4] "<58>Raw= စက်လှေကး (Extra= , Missed= ာ); <59>Correct= စက်လှေကား"           
 [5] "<65>Raw= စက် (Extra= , Missed= သီး); <66>Correct= စက်သီး"                 
 [6] "<70>Raw= စက္က (Extra= , Missed= တုံး); <71>Correct= စက္ကတုံး"               
 [7] "<83>Raw= စောက်ထိုးမိုးမှော် (Extra= , Missed= ျ); <84>Correct= စောက်ထိုးမိုးမျှော်" 
 [8] "<112>Raw= စင်စွမ်း (Extra= , Missed= ပြ); <113>Correct= စင်ပြွမ်း"          
 [9] "<115>Raw= စင်ယှဉ်ပြ၁သခ် (Extra= ခ, Missed= ာဒ); <116>Correct= စင်ယှဉ်ပြ၁သာဒ်" 
[10] "<121>Raw= စင်း၁ (Extra= ၁, Missed= ချော); <122>Correct= စင်းချော"       
[11] "<124>Raw= စမ်းလေး (Extra= မ, Missed= င); <125>Correct= စင်းလေး"         
[12] "<128>Raw= စင်းလျာ (Extra= , Missed= ှေ); <129>Correct= စင်းလျှော"         
[13] "<130>Raw= စကြိ (Extra= ိ, Missed= င်္ံ); <131>Correct= စင်္ကြံ"               
[14] "<159>Raw= စောင်းနှင့် (Extra= နှ, Missed= ဲ); <160>Correct= စောင်းငဲ့"         
[15] "<162>Raw= စောင်းညှိုး (Extra= , Missed= ့); <163>Correct= စောင်းညှို့"          
[16] "<166>Raw= စောင်းခင်း (Extra= ခ, Missed= ပြ); <167>Correct= စောင်းပြား"   
[17] "<172>Raw= စောင်းများ (Extra= မ, Missed= လ); <173>Correct= စောင်းလျား"   
[18] "<179>Raw= စိုင်လျမ် (Extra= မ, Missed= ော); <180>Correct= စိုင်လျော်"         
[19] "<183>Raw= စိုင်းနင် (Extra= , Missed= ှ); <184>Correct= စိုင်းနှင်"             
[20] "<196>Raw= စစ် (Extra= , Missed= ကဲ); <197>Correct= စစ်ကဲ"                 
[21] "<217>Raw= စ်ဆုတ် (Extra= , Missed= ); <218>Correct= စစ်ဆုတ်"                
[22] "<220>Raw= စစ်ညခင်း (Extra= ခ, Missed= ော); <221>Correct= စစ်ညောင်း"       
[23] "<237>Raw= စစ်ပရိယယ် (Extra= , Missed= ာ); <238>Correct= စစ်ပရိယာယ်"         
[24] "<239>Raw= စစ်ရ (Extra= , Missed= ပါီ); <240>Correct= စစ်ပါရီ"             
[25] "<242>Raw= စစ် (Extra= , Missed= ပြေး); <243>Correct= စစ်ပြေး"           
[26] "<244>Raw= စစ်ဖြန် (Extra= ဖ, Missed= ပ); <245>Correct= စစ်ပြန်"           
[27] "<262>Raw= စစ်ဝက် (Extra= ဝ, Missed= လျှော); <263>Correct= စစ်လျှောက်"       
[28] "<270>Raw= စစ်သော် (Extra= , Missed= င္ဘ); <271>Correct= စစ်သင်္ဘော"         
[29] "<285>Raw= စဉ် (Extra= , Missed= ့); <286>Correct= စဉ့်"                   
[30] "<304>Raw= စည်း (Extra= , Missed= ကာ); <305>Correct= စည်ကား"             
[31] "<308>Raw= စည်ထို (Extra= ထ, Missed= တ); <309>Correct= စည်တို"               
[32] "<312>Raw= စည်ပတ်သီး (Extra= ီ, Missed= ံြာ); <313>Correct= စည်ပတ်သံပြား"      
[33] "<314>Raw= စည်ဝင်း (Extra= ဝ, Missed= ဖော); <315>Correct= စည်ဖောင်း"       
[34] "<339>Raw= စည်းဝါး (Extra= , Missed= ပြေ); <340>Correct= စည်းပြေးဝါးပြေး"
[35] "<383>Raw= စိတ်စေ (Extra= , Missed= ာ); <384>Correct= စိတ်စော"             
[36] "<440>Raw= စိတ် (Extra= , Missed= ဖြေ); <441>Correct= စိတ်ဖြေ"             
[37] "<444>Raw= စိတ် (Extra= , Missed= မနှံ့); <445>Correct= စိတ်မနှံ့"               
[38] "<446>Raw= စိတ်မာ (Extra= , Missed= ေ); <447>Correct= စိတ်မော"             
[39] "<481>Raw= စိတ်အး (Extra= , Missed= ာ); <482>Correct= စိတ်အား"             
[40] "<487>Raw= စိတ္တ (Extra= , Missed= ဇ); <488>Correct= စိတ္တဇ"               
[41] "<499>Raw= စုတ်ထိုး (Extra= ထိး, Missed= ပဲ့); <500>Correct= စုတ်ပဲ့"             
[42] "<508>Raw= စန္ဒ၁ (Extra= ၁, Missed= ာ); <509>Correct= စန္ဒာ"             
[43] "<510>Raw= စာသ (Extra= , Missed= န္ဒြမ); <511>Correct= စန္ဒြမာသ"         
[44] "<520>Raw= စန္ဒ၁ (Extra= , Missed= း); <521>Correct= စန္ဒ၁း"             
[45] "<541>Raw= စိန်ဝင်း (Extra= ဝ, Missed= ပြော); <542>Correct= စိန်ပြောင်း"     
[46] "<567>Raw= စပ်ကြခင်း (Extra= ခ, Missed= ော); <568>Correct= စပ်ကြောင်း"     
[47] "<570>Raw= စပ်စေခင် (Extra= ခ, Missed= ာ); <571>Correct= စပ်စောင်"         
[48] "<584>Raw= စပ် (Extra= , Missed= နွား); <585>Correct= စပ်နွား"             
[49] "<586>Raw= စပ်ပာ (Extra= , Missed= ည); <587>Correct= စပ်ပညာ"             
[50] "<588>Raw= စပ် (Extra= , Missed= ဖာ); <589>Correct= စပ်ဖာ"               
[51] "<591>Raw= စပ်ပြီ (Extra= ီ, Missed= ဖဲ); <592>Correct= စပ်ဖြဲဖြဲ"            
[52] "<596>Raw= စပ် (Extra= , Missed= ရှား); <597>Correct= စပ်ရှား"             
[53] "<600>Raw= စပ်လေ့ (Extra= ့, Missed= ှ); <601>Correct= စပ်လှေ"               
[54] "<604>Raw= စပ်ယပ် (Extra= ယ, Missed= ဟ); <605>Correct= စပ်ဟပ်"             
[55] "<630>Raw= စိမ့် (Extra= , Missed= တော); <631>Correct= စိမ့်တော"             
[56] "<637>Raw= စိမ်း (Extra= , Missed= ကာ); <638>Correct= စိမ်းကား"            
[57] "<642>Raw= စိမ်းအံ့ (Extra= အ့, Missed= ဆွ); <643>Correct= စိမ်းဆွံ"             
[58] "<646>Raw= စိမ်းရွှမ်း (Extra= ှ, Missed= ); <647>Correct= စိမ်းရွမ်း"           
[59] "<655>Raw= စုံဆယ် (Extra= , Missed= ဖြာ); <656>Correct= စုံဆယ်ဖြာ"           
[60] "<657>Raw= စုံတွဲ (Extra= တ, Missed= ဆ); <658>Correct= စုံဆွဲ"                 
[61] "<671>Raw= စုံစုံ (Extra= , Missed= း); <672>Correct= စုံးစုံး"                
[62] "<677>Raw= စ္ဆေ (Extra= ္ဆ, Missed= ွ); <678>Correct= စွေ"                 
[63] "<702>Raw= စိ (Extra= , Missed= ွတ်ကပါနမး); <703>Correct= စွတ်ကပါစိနမ်းပါစိ"   
[64] "<707>Raw= စွတ်စွတ်နခ (Extra= ခ, Missed= ာ); <708>Correct= စွတ်စွတ်နာ"         
[65] "<718>Raw= စွန်ပြီး (Extra= ပ, Missed= မ); <719>Correct= စွန်မြီး"           
[66] "<720>Raw= စွန်ပြီးတော့ (Extra= ပတ, Missed= မက); <721>Correct= စွန်မြီးကော့"   
[67] "<722>Raw= စွန်ရှိ (Extra= ှိ, Missed= ဲ); <723>Correct= စွန်ရဲ"                 
[68] "<754>Raw= စွယ်စုံ (Extra= ု, Missed= ရ); <755>Correct= စွယ်ရံ"                

Missed characters in OCR errors, sorted by their frequencies in descending order:

missErrDF <- data.frame(t(table(unlist(strsplit(missErr, "")))))
missErrDF.s <- missErrDF[order(-missErrDF$Freq), 2:3]
utf8::utf8_print(paste0(missErrDF.s$Var2," = ", missErrDF.s$Freq))
 [1] "ာ = 25" "ေ = 13" "ပ = 9"  "ြ = 9"  "း = 8"  "ှ = 6"   "က = 5"  "ဖ = 5" 
 [9] "မ = 5"  "ဲ = 5"   "တ = 4"  "န = 4"  "ံ = 4"   "့ = 4"   "ွ = 4"   "င = 3" 
[17] "္ = 3"   "ျ = 3"  "ဆ = 2"  "ဒ = 2"  "ရ = 2"  "လ = 2"  "ါ = 2"  "ီ = 2"  
[25] "် = 2"   "ခ = 1"  "ဇ = 1"  "ည = 1"  "ဘ = 1"  "သ = 1"  "ဟ = 1"  "ု = 1"  

``Some headwords missed entirely by OCR were typed-in. Listed below:

utf8::utf8_print(NElist)
 [1] "<1> စက်"             "<4> စက်ကတ်ကြေး"       "<12> စက်ချုပ်"        
 [4] "<14> စက်စက်"          "<24> စက်တင်"          "<37> စက်ပုန်းခုတ်"      
 [7] "<72> စက္ကဗျူဟာ"       "<80> စောက်ချ"        "<81> စောက်တိစောက်ထိုး"  
[10] "<82> စောက်ထိုး"        "<85> စောက်ဓား"       "<86> စောက်မှန်းကမ်းမှန်း"
[13] "<89> စိုက်ခင်း"         "<91> စိုက်စိုက်"          "<96> စိုက်ပျိုး"        
[16] "<107> စင်တော်"        "<132> စင်္ကြံလျှောက်"    "<137> စောင်မ"       
[19] "<168> စောင်းမြောင်း"  "<181> စိုင်း"          "<198> စစ်ကြော"      
[22] "<214> စစ်ဆင်"         "<232> စစ်တုံ"          "<235> စစ်ထွက်"        
[25] "<296> စဉ်းစားခန်းဝင်"  "<310> စည်ပင်"         "<357> စုဏ္ဏိယ"        
[28] "<361> စိတ်ကူးစိတ်သန်း"    "<388> စိတ်ဆိုးမာန်ဆိုး"    "<392> စိတ်ညီ"         
[31] "<393> စိတ်ညို့"          "<394> စိတ်ညစ်"         "<395> စိတ်ညှို့"         
[34] "<401> စိတ်တောင်း"      "<410> စိတ်ထောင့်"       "<419> စိတ်နု"         
[37] "<424> စိတ်နောက်ကိုယ်ပါ"   "<431> စိတ်ပူ"          "<432> စိတ်ပေါက်"      
[40] "<451> စိတ်မြန်လက်မြန်"   "<461> စိတ်ရှည်"         "<472> စိတ်လျှော့"      
[43] "<483> စိတ်အားလက်အား"   "<506> စန္ဒဗျူဟာ"      "<530> စိန်တံချူ"       
[46] "<535> စိန်နီမြင်းသွား"   "<590> စပ်ဖျဉ်းဖျဉ်း"   "<619> စမ်းသပ်"       
[49] "<626> စိမ်ရည်"         "<633> စိမ့်မြေ"        "<650> စုံ"           
[52] "<673> စွ"            "<674> စွာ"           "<675> စွာကျယ်စွာကျယ်"  
[55] "<676> စွာလောင်စွာလောင်" "<679> စွေ့"           "<680> စွေ့ကနဲ"        
[58] "<681> စွေးစွေး"       "<682> စွဲ"            "<692> စွဲမြဲ"         
[61] "<696> စွံ"            "<704> စွတ်ကယ်စွတ်ကယ်"     "<712> စွန်"          
[64] "<732> စွန့်လွှတ်"         "<734> စွန်းထင်း"       "<737> စွပ်စွ"         
[67] "<756> စွယ်ရောင်ပြ"    

These are the superfluous headwords dropped:

utf8::utf8_print(DRlist)
 [1] "<27> စက်တိုင်၌ - *"     "<30> စက်တန့် - *"      "<53> စက် - *"       
 [4] "<100> စေ့တော့ - *"    "<108> စင့်် - *"       "<120> စင်း- *"      
 [7] "<134> စေခင် - *"     "<152> စောင်း- *"     "<153> စေခင်း- *"    
[10] "<182> စစ်ကြောင်း - *" "<187> စစ်- *"        "<188> စစ်- *"       
[13] "<189> စစ်- *"        "<190> စစ်- *"        "<195> စစ်- *"       
[16] "<211> စစ်စစ် - *"     "<233> စစ်တဲ့ - *"      "<282> စဉ် - *"      
[19] "<283> စဉ် - *"       "<290> စဉ်း- *"       "<291> စဉ်း- *"      
[22] "<302> စည် - *"       "<303> စည်- *"        "<318> စည့် - *"      
[25] "<320> စည်း – *"      "<411> စိတ်ကြောင့် - *"  "<473> စိတ် - *"      
[28] "<493> စုတ် - *"       "<494> စုတ် - *"       "<502> စုတ် - *"      
[31] "<523> စိန် - *"       "<539> စိန်ပန်း - *"    "<563> စပ်- *"       
[34] "<573> စပ်စပ် -*"      "<574> စပ်စပ်- *"      "<607> စိပ်- *"       
[37] "<629> စိမ့်- *"        "<683> စုံစုံ *"         "<684> စေ့စေ့- *"     
[40] "<752> စွယ်တော်- *"    

Friday, October 23, 2020

Extracting headwords from the scanned Myanmar Dictionary


After successfully creating syllable-rhymes level bookmarks for the volume-1 of Abridged Myanmar Dictionary I felt a bit more ambitious and set out to extract all the headwords from the volume-1 of the Abridged Myanmar Dictionary I’m dealing with.

With my earlier experience in converting the Myanmar spelling book to searchable PDF format I know I could use essentially the same workflow. The dictionary is in a two column format like the spelling book so I can shed superfluous text by slicing the pages into left and right columns with just enough space to cover the headwords. This could be done with GIMP software by importing the PDF file into GIMP as layers and slicing them using guides. The procedure had been fully described in my “Making Myanmar Spelling Book searchable -II” post of August 25, 2019. Here, however, the OCR output had been downloaded as plain text files.
In the image below, the left part shows the first two pages of the input PDF file and the right part shows the OCR output opened in Notepad++.

knitr::include_graphics("headWord_1_2.png")

After obtaining the OCR output text (in 7 text files), the workflow for extracting headwords from each of these text files is as follows:

  1. The text files are read-in into R.
  2. Using the pattern to identify a headword, that is, begins with a consonant and ends with a dash, with or without a space in-between, the headwords are extracted using regex.
  3. The extracted headwords were written out to a text file.
  4. The text file is opened in Notepad++, checked with headwords in the Dictionary PGF file, and OCR errors corrected or missed words entered. Note that the programmatically extracted headwords will have a dash character at the end. Words with OCR errors were marked with an "*" at the end, and corrected words or newly entered words are not marked.
  5. Modified text files were read-in into R.
  6. All files combined into one file and OCR errors and omission errors are calculated.
  7. All initially correct and corrected headwords are extracted and written out to a text file.
  8. The extracted headwords were again checked with the Dictionary and again the errors and omissions are corrected and marked using Notepad++.
  9. The corrected final text file is read-in into R, errors calculated and cleaned list of headwords is extracted.
  10. The final list of headwords is written out to a text file.
utf8::utf8_print(y0.1[1:31])
 [1] "က-"          "က -"         "က-"          "က -"        
 [5] "ကကတစ်-"       "ကကူရံ -"       "ကကြီး-"       "ကကြီးထွန်-"    
 [9] "ကကြိုး-"       "ကကြိုး-"       "ကခုန် –"       "ကချေသည်-"    
[13] "ကချော်ကချွတ် -" "ကချင်-"       "ကစား-"       "ကစားစရာ-"   
[17] "ကစားဝိုင်း -"   "ကစီ-"         "က -"         "ကစော် -"     
[21] "က်ပေါက် -"     "ကစဉ်က-"       "ကဆစ်-"        "ကဇာတ်-"      
[25] "ကည-"         "ကညို-"         "ကညင်-"        "ကညင်ဆီ -"     
[29] "ကညင်ဆီတိုင်-"     "ကညစ် -"       "ကညစ်ရေး-"    

The original entries for the above headwords in the first and second page of body text of the dictionary file is seen below. Since I am compiling a list of distinct headwords I dropped the duplicates in my list.

Below is an example of editing I’d done with editing marks made as described in the step-4 of my workflow given earlier. Look carefully and You can see that I had made mistakes in even this early part editing. That’s why I need to go over to a second round of editing!

After this first round of editing I calculated that the OCR errors in the headwords + the number of headwords missed by the OCR process was about 25%.

After completing step-7 and 8 of the workflow, the edited final headwords file was saved as allwords_1.txt. It was read-in into R and processed:

EDall_final <- readLines("allwords_1.txt",encoding = "UTF-8")
library(stringr)
HWall_final <- unlist(str_subset(EDall_final,"[*]", negate = TRUE))
HWcorr2 <- unlist(str_subset(EDall_final,"[+]"))
nHWall <- length(HWall_final)
nHWcorr2 <- length(HWcorr2)
nHWall
[1] 5187
nHWcorr2
[1] 68
# Total corrected+new entries (round-1+2)
paste("Total corrected+new entries (round-1+2) = ", (B + nHWcorr2))
[1] "Total corrected+new entries (round-1+2) =  1345"
#writeLines(y0.7, "418_split.txt", useBytes = TRUE)
# paste("Incorrect entries =",round(aCorr*100/cCorr,1), "%")
# paste("Corrected+new entries =",round(bCorr*100/cCorr,1), "%")

Total numbers of headwords and errors after two rounds of editing was found to be:

Total corrected+new entries (round-1) = 1277
Total correct+corrected+new entries (round-1) = 5189
Total raw entries (round-1) = 6245

Total corrected+new entries (round-1+2) = 1345
Total headwords = Correct+corrected+new entries (after round-2) = 5187
OCR errors corrected + new entries(for OCR misses) = 25.9 %

Extract final “KA” to “SA” (“က” - “စ”) headwords

cleanHWords_KA_SA <- gsub("[\u002d\u2010\u2013*+]", "", HWall_final) %>%
  trimws(.) 
# check if headwords contain characters that are not in Myanmar language
str_subset(cleanHWords_KA_SA, "[\u1000-\u104f]",negate = TRUE)
character(0)
# print a sample of 100 headwords
utf8::utf8_print(str_subset(cleanHWords_KA_SA, "[\u1000-\u104f]")[3440:3539])
  [1] "ဂြိုဟ်ကျ"           "ဂြိုဟ်စာ"           "ဂြိုဟ်စားသက်ရောက်"   
  [4] "ဂြိုဟ်စီးဂြိုဟ်နင်း"     "ဂြိုဟ်ဆိုး"           "ဂြိုဟ်တိုင်"          
  [7] "ဂြိုဟ်ပြေနံပြေ"      "ဂြိုဟ်မွှေ"           "ဂြိုဟ်ဝင်"          
 [10] "ဂြိုဟ်သက်"           "ဂြိုဟ်သိမ်"           "ဂွကလေး"          
 [13] "ဂွချော"           "ဂွဒိုး"             "ဂွေး"            
 [16] "ဂွမ်း"             "ဂွမ်းကပ်"           "ဂွမ်းခံအကျီ"        
 [19] "ဂွမ်းခက်"           "ဂျွတ်"             "ဂျွန်"            
 [22] "ဃ"               "ဃကြီး"            "ဃဋီ"             
 [25] "ဃနာ"             "ဃရာဝါသ"          "ဃောသ"           
 [28] "င"               "ငကျောက်"          "ငကျွဲ"            
 [31] "ငချိပ်"            "ငချိပ်ညိုပြောင်း"     "ငချိပ်သွေး"        
 [34] "ငစိုင်ရှင်"           "ငစဉ်းလဲ"           "ငစည်နှစ်"          
 [37] "ငစိန်"             "ငဆ"              "ငဆစ်သခွား"        
 [40] "ငတိ"              "ငတေ"             "ငနဲ"             
 [43] "ငပေါ"            "ငပုပ်ဖမ်း"          "ငပြေရှင်"         
 [46] "ငပြုပ်"            "ငမိုက်သား"          "ငမြှောင်တောင်"     
 [49] "ငရဲ"              "ငရဲကြီး"           "ငရဲငအုံ"           
 [52] "ငရဲမီး"            "ငရဲသစ်ငုတ်"          "ငရဲအိုး"           
 [55] "ငရံ့ပတူ"            "ငရုတ်"             "ငရုတ်ကောင်း"       
 [58] "ငရုတ်ကျည်ပွေ့"        "ငရုတ်ဆုံ"            "ငလျင်"           
 [61] "ငဟစ်"             "ငါ"              "ငါစား"          
 [64] "ငါစွဲ"             "ငါတကော"          "ငါတကောကော"      
 [67] "ငါတွေ့"            "ငါး"             "ငါးကုလား"        
 [70] "ငါးကင်"           "ငါးကင်း"          "ငါးကန်"          
 [73] "ငါးကန့်ဗျိုင်"        "ငါးကုံး"           "ငါးကျီးကန်း"      
 [76] "ငါးကျည်း"         "ငါးကျည်းခြောက်"    "ငါးကျပ်တိုက်"       
 [79] "ငါးကျပ်တင်"        "ငါးကြီးဆီ"         "ငါးကြီးအန်ဖတ်"     
 [82] "ငါးကြင်း"         "ငါးကြင်းကြေး"     "ငါးကြင်းမျက်ဆန်နီ"  
 [85] "ငါးကြင်းမြီး"      "ငါးကြောင်း"       "ငါးကွဲယင်"         
 [88] "ငါးကွမ်းရှပ်"        "ငါးခူ"            "ငါးခုတ်တုံး"        
 [91] "ငါးခုံးမ"          "ငါးချဉ်"          "ငါးခြောက်"       
 [94] "ငါးခြောက်ငါးခြမ်း" "ငါးခွေးလျှာ"       "ငါးစင်စပ်"        
 [97] "ငါးစင်ရိုင်း"        "ငါးစင်း"          "ငါးစင်းပြား"     
[100] "ငါးစည်ဖောင်း"     
# export all headwords to text file
writeLines(cleanHWords_KA_SA, "HeadWords_myDICTabr_v1.txt", useBytes = TRUE)

Summary: The total number of headwords is broken down by consonants

library(stringr)
KA_words2 <- str_subset(HWall_final, "^[\u1000]")
t1 <- paste0("(\u1000):",length(KA_words2))
KHA_words2 <- str_subset(HWall_final, "^[\u1001]")
t2 <- paste0("(\u1001):",length(KHA_words2))
GAn_words2 <- str_subset(HWall_final, "^[\u1002]")
t3 <- paste0("(\u1002):",length(GAn_words2))
GAg_words2 <- str_subset(HWall_final, "^[\u1003]")
t4 <- paste0("(\u1003):",length(GAg_words2))
NGA_words2 <- str_subset(HWall_final, "^[\u1004]")
t5 <- paste0("(\u1004):",length(NGA_words2))
SA_words2 <- str_subset(HWall_final, "^[\u1005]")
t6 <- paste0("(\u1005):",length(SA_words2))
cat(c(t1,t2,t3,t4,t5,t6),sep = "\n")
(က):1916
(ခ):1337
(ဂ):207
(ဃ):6
(င):466
(စ):1255
# finally export headwords as text file
writeLines(HWall_final, "HWords_myDICT_v1.txt", useBytes = TRUE)

I am sharing this text file of headwords here.
Caution: It may contain errors I’d missed!