НӨАТ-ын сугалааны анализ. Хэсэг I

Nyamkhuu Demberelsuren
Beyond Data Science
6 min readSep 1, 2019

Та НӨАТ-ийн сугалаанд хэдэн удаа хожиж байсан бэ? Би 545 баримт уншуулсан боловч одоогоор нэг ч удаа хожиж байгаагүй. Гэтэл зарим хүмүүс аль хэдийн 2–3 удаа хожсон гэх үед би азгүй байна уу аль эсвэл сугалааны тохирол асуудалтай байна уу гэсэн асуулт өөрийн эрхгүй төрдөг. Энэ асуудлын учрыг олохоор НӨАТ-ийн сугалааны өгөгдөлд анализ хийсэн бөгөөд хэрхэн хийсэн талаараа хүргэж байна.

Өгөгдөл

Шинжилгээ хийхэд мэдээж ямар нэгэн өгөгдөл хэрэгтэй. Юуны өмнө тохирол хэрхэн явагддагийг харья:

Сугалааны дугаарууд хэрхэн тодордог процесс

Дээрх бичлэгт үзүүлсэнчлэн хожлын сугалааны дугаарыг тодорхойлохын тулд шилэн хоргонд 10 бөмбөлөг эргэлдүүлдэг бөгөөд эдгээрээс санаандгүй байдлаар нэгийг нь сонгон гаргаж ирдэг. Энэ процесс 8 удаа давтагдаж гарч ирсэн тоонуудаас хожлын сугалааны дугаар бий болно. Супер шагналын дугаар мөн адил байдлаар тодроно.

Тохирол болсоны дараа сугааланы мэдээлэл бид нарын ашиглах http://sugalaa.ebarimt.mn/ сайт дээр нийтлэгддэг. Мэдээж бүх сугааланы мэдээллийг гараараа нэг нэгээр нь оруулж болно, гэхдээ энэ нь уйтгартай мөн цаг их шаардах учраас автоматаар бүх сугааланы мэдээллийг татаж авсан. Татаж авсан мэдээлэл маань зураг хэлбэрээр хадгалагдсан байсан тул тэдгээрээс тоонуудыг нь таньж боловсруулах шаардлага үүссэн юм.

Юу хэрэгтэй вэ?

Энэхүү шинжилгээнд ашигласан кодуудыг ажлуулахад дараах програмуудыг суулгасан байх шаардлагатай:

Мөн Python, HTML-ийн мэдлэгтэй бол энэхүү шинжилгээнд ашигласан кодыг ойлгоход дөхөм байх болвуу.

Алхам 1. Сайтаас зурагнуудыг татаж авах

Дээрх зурагт харуулсанчлан, тохирлын мэдээлэл зураг хэлбэрээр тавигдсан байгаа. Зурагнуудыг татаж авахын тулд http://sugalaa.ebarimt.mn/ хуудасны HTML кодыг шалган зурагнуудын байршлыг нь олсон.

Хэрвээ сайтын HTML кодыг сайн анзаарах юм бол “container” гэсэн class-тай <div> дотор бидэнд хэрэгтэй бүх мэдээллүүд байгааг харж болно. Тэр дотроо “ebl-header-title” гэсэн class-тай <div> сугааланд хамаарах баримтуудын өдрүүд, “ebl-box-body-content” гэсэн class-тай <div> сугалааны дугааруудын зурагнуудын хаягыг тус тус агуулж байна. Олж авсан мэдээлэл дээрээ үндэслэн BeautifulSoup4 санг ашиглан зурагнуудыг татаж авъя.

Хэрвээ та дээрх кодыг уншуулсан бол дараах бүтэцтэй folder үүссэн байх естой:

Алхам 2. Зурагнаас тоо таних

Зурагаа татаж авсны дараа зурагнаасаа сугалааны дугаарыг таних хэрэгтэй. Уг таних процесийг OCR буюу Optical Character Recognition гэж нэрлэдэг. Үүний тулд бид OpenCV сангаар зурагаа бэлдэж, Tesseract (pytesseract) гэсэн сангаар зурагнаасаа тоонуудаа танина.

Хэрвээ ямар нэгэн нэмэлт боловсруулалтгүйгээр Tesseract санг ашиглаж шууд таних гэж үзвэл үр дүн муутай байхыг анхаарна уу. Жишээ болгож харуулахад доорх зургийг дараах байдлаар таньсан байна.

MO ©2000000]

HE 50,000,000 F | 10,000,000 | [EZEK@ 5,000,000 7 |
1,000,000 F | ERZZ¥@ 200,0007F | 50,000F |

unit 22,724 asta TogoPcond
df

Үүнийг сайжруулах 2 үндсэн арга байдаг:

  1. Ашиглаж буй зураг дээрээ нэмэлт боловсруулалт хийж цэвэрлэх (жишээ нь, ямар нэгэн тоо агуулаагүй улаан бөмбөлөгийг зурагнаас арилгах)
  2. Ашиглаж буй загвараа сайжруулах

Эхний аргын хувьд, зураг дээрээ ямар боловсруулалт хийх шаардлагатай вэ гэдгийг тодорхойлхоос өмнө нэг зүйлийг тэмдэглээд авъя — сугалааны дугаарууд адил хэмжээтэй бөмбөлөг дотор байршиж байгаа бөгөөд нийт 8 ширхэг байна. Тэгэхээр, бид зурагнаасаа адил хэмжээтэй 8 бөмбөлөг олох бөгөөд бөөрөнхий болгонд байгаа тоог тус тусд нь танин дараа нь нэгтгэх нь илүү үр дүнтэй байх юм.

Дээрх бичсэн “recognise” гэсэн функц нь анх байсан зурагыг доорх хар цагаан зурагруу хөрвүүлж адил хэмжээтэй 8 бөөрөнхийг олох бөгөөд үүний дараа pytesseract.image_to_string гэсэн функцийг ашиглан бөмбөлөг болгоны зураг дээр танилт хийдэг байгаа.

Жишээ танилт

Дараагийн арга болох загвараа сайжруулахын тулд дараах зүйлсүүдийг хийх хэрэгтэй:

  1. Tesseract-ийг суулгахад хамт ирдэг модель нь зөвхөн тоо гэлтгүй бусад бүх төрлийн үсэг тэмдэгтийг таньдаг. Иймд, зөвхөн тоон өгөгдөлд төвлөрч сургагдсан загвар нь бидний тохиолдолд илүү сайн ажиллана. Бид өөрсдөө шинээр модель сургахын оронд, бэлэн сургасан https://github.com/Shreeshrii/tessdata_shreetest/ -ийн “digits_comma” гэсэн моделийг ашиглая. Учир нь, бусад сургасан загваруудтай харьцуулхад, олон төрлийн фонтоор бичсэн тоог таних чадвартай тул сонгов. Эхлээд “digits_comma.traineddata”-г татаж авах шаардлагатай бөгөөд үүнийгээ tesseract-ийн модель байршилдаг folder-луу хуулах хэрэгтэй (миний хувьд Ubuntu 18.04 дээр ажиллаж байгаа тул “/usr/share/tesseract-ocr/4.00/tessdata”-луу хуулах хэрэгтэй байсан).
  2. Tesseract-ийн тохиргоог солих. Гол тохиргоо болох PageSegMode буюу PSM нь үр дүнд хамгийн их нөлөөтэй. Уг тохиргоо нь зурагныхаа төрлийг зааж өгөх боломжийг олгодог. Жишээ нь, тухайн зураг маань нэг мөр текст агуулж байгаа, аль эсвэл нэг үсэг агуулж байгаа гэдгийг энэхүү тохиргоог ашиглан моделдоо хэлж өгнө. Бидний тохиолдолд, "Treat the image as a single word in a circle” (Дугаар 9) гэсэн төрөл нь тохирч байна, учир нь бидний таних шаардлагатай тоо бөөрөнхий дотор байгаа.

Дээрх засваруудыг хийсний дараа, бидний код ийм болж хувирна:

digit_text = pytesseract.image_to_string(digit, lang=”digits”, config='-- psm 9')

Одоо зурагнуудаа таниулахын тулд татаж авсан зураг бүрийг нээн үр дүн болгоныг dataframe хэлбрээр хадгалъя:

Хэрвээ дээрх кодыг ажилуулвал дараах үр дүн гарч байна:

 start_date    end_date      main      super
0 2016-01-01 2016-01-10 55020762 26003690
1 2016-01-01 2016-01-20 35577825 48830941
2 2016-01-01 2016-01-31 52346699 69827600
3 2016-01-01 2016-02-20 17901740 98483936
4 2016-01-01 2016-02-29 02870088 47015520
5 2016-01-01 2016-03-15 80096100 26024190
6 2016-02-01 2016-02-10 22633808 60515447
7 2016-03-01 2016-03-31 36796987 10506598
8 2016-04-01 2016-04-15 67808111 58152005
9 2016-04-01 2016-04-30 06868818 69034117
10 2016-05-01 2016-05-15 62061197 62817812
11 2016-05-01 2016-05-31 54826899 12803350
12 2016-06-01 2016-06-30 51794784 35479923
13 2016-07-01 2016-07-31 33354738 27658285
14 2016-08-01 2016-08-31 12033407 05884604
15 2016-09-01 2016-09-30 1.001900 35849193
16 2016-10-01 2016-10-31 54855480 60246885
17 2016-11-01 2016-11-30 28672868 30818365
18 2016-12-01 2016-12-31 59765971 94262626
19 2017-01-01 2017-01-31 11357920 20911810
20 2017-02-01 2017-02-28 62857474 16083035
21 2017-03-01 2017-03-31 34419352 70375153
22 2017-04-01 2017-04-30 61174721 10892827
23 2017-05-01 2017-05-31 67878508 93941888
24 2017-06-01 2017-06-30 94663073 10642812
25 2017-07-01 2017-07-31 70470451 49065302
26 2017-08-01 2017-08-31 37340688 40404009
27 2017-09-01 2017-09-30 18761051 71742222
28 2017-10-01 2017-10-31 79369350 96260467
29 2017-11-01 2017-11-30 71482981 77485495
30 2017-12-01 2017-12-31 30204358 23059186
31 2018-01-01 2018-01-31 50507359 89278942
32 2018-02-01 2018-02-28 85796031 35199240
33 2018-03-01 2018-03-31 70171034 53451362
34 2018-04-01 2018-04-30 56365763 22627273
35 2018-05-01 2018-05-30 61703903 55622553
36 2018-06-01 2018-06-30 68747698 32385755
37 2018-07-01 2018-07-31 19301136 96151358
38 2018-08-01 2018-08-31 17822285 88359507
39 2018-09-01 2018-09-30 95392761 34204008
40 2018-10-01 2018-10-31 62474172 88104987
41 2018-11-01 2018-11-30 40321218 86333238
42 2018-12-01 2018-12-31 71079096 63030046
43 2019-01-01 2019-01-30 08696606 275757443
44 2019-02-01 2019-02-28 31158873 20791539
45 2019-03-01 2019-03-31 28869533 88590813
46 2019-05-01 2019-05-31 96589469 46053913
47 2019-06-01 2019-06-30 27818931 25410684
48 2019-07-01 2019-07-31 48687025 06375641

Хэрвээ сайн анзаарвал 2016 оны 9 сарын үндсэн болон 2019 оны 1 сарын супер сугалаа буруу танигдсан байна. Тэд нарыг дараах байдлаар гараар засъя:

sugalaas.loc[15, 'main'] = '11001900'
sugalaas.loc[43, 'super'] = '27575743'

За ингээд бидний шинжилгээнд ашиглах дата маань бэлэн боллоо. Дараагийн хэсэг дээр гаргаж авсан үр дүн дээрээ шинжилгээ хэрхэн хийсэн талаараа бичих болно. Stay tuned!

--

--