Re: [問題] OCR實務經驗請益
不好意思,又就同一個主題來討教。
前陣子我已經用規則和正規表達式完成一個版本,
不過過程中也發現一些問題,是在規則下無法一一解決的,
想和板眾請教、盼能得到一點方向。
目前我大致的做法是:
1. 用每個Google Vision辨認出的文字框的x座標,
做k-means clustering輔以Silhouette analysis,
以決定這份拿到的成績單有幾個欄位(columns)。
2. 根據決定出的每個欄位的文字內容,
用正規表達式去做一個voting system,
去對每個欄位表決這應該是個:
a. 科目欄位
b. 成績欄位
c. 分數單位欄位
d. 前標 - 後標參考範圍欄位
四者之中的哪一種。
3. 最後,挑出科目及成績欄位,
依y座標去讓成績欄位中的文字框向科目欄位中的文字框尋求對應。
但是以上的做法有幾個瓶頸:
1. 在上述做法的第一步裡面,最基本的假設是:
成績單總是依直欄排列,不同項目是分佈在不同直欄內。
但其實這假設不為真。
2. 在第二步中,由於是用整個欄位的內容一起表決,
因此會包含許多不需要的文字框,例如我下面引文裡面的第一個例子,
成績欄位就會包含「姓名:王小明」、「考試日期:」、「分數」、「分數」等,
而且「分數」文字框還會對應到「科目」文字框,形成多餘的無意義組合。
這不能用正規表達式挑數字來解決,
因為成績欄位中不一定是數字,還可能是A+、優秀、有待加強、甲上...等文字,
不可能用正規表達式窮盡所有可能。
3. 同種科目可能在各校有不同名稱,且Google Vision回傳的文字不一定是對的。
這會讓日後的資料變得雜亂而無意義。
我需要一個自動校正系統,盡可能基於人類對「成績單」的認知去校正內容,
例如「國文」、「國語」、「中文」、「團文」、「國X」(真的是英文字母X),
全部都應該要是「國文」。
而「90.l」、「90.I」應該是「90.1」,「3A.6」可能是「34.6」。
現在,我的問題可以限縮成幾個也許和ML或DL有關的問題:
1. 中文的自動校正可以怎麼達成?
我有想過用jieba斷詞,去斷已知、正確的科目名稱,再嘗試做模糊搜索,
(雖然實務上要怎麼做模糊搜索也還不清楚),
但是,例如「國文」再斷也就是「國」「文」,
用「文」的話「英文」跟「團文」都變國文,「國語」校正不到;
用「國」的話「團文」就校正不到。
這還沒解決成績中也許「優秀」跟「憂秀」都是「優秀」。
感覺需要一個能自我學習的常用詞系統,但不知道怎麼開始。
2. 要怎麼根據單一個文字框的內容,去判斷它屬於哪一類?
我稍微查過text classification,好像都是對一整篇文章做分類,
例如Stack Overflow的auto-tag,或是垃圾郵件的區辨。
但我今天需要的卻是根據也許十個字元以下的內容,
判斷它是上述步驟2中abcd,還有e(無意義文字框如「分數」)的哪一種。
我初步的想法是把每個文字框內容轉成向量,再做KNN,
但我直覺認為很難分得出來,
尤其裡面有好幾個欄位都可能有文數字摻雜,又或者多個欄位都是數字。
例如:成績中有「優」、「95」這兩個文字框;
同時,前標 - 後標參考範圍中也有「優」、「88-96」這兩個文字框。
直覺上它們的向量都是相近的。
拜託各位高手不吝賜教,謝謝~
※ 引述《parcequetoi (Sky)》之銘言:
: 作業系統: Linux
: 問題類別: OCR
: 使用工具: Python 3, Google Vision API
: 問題內容:
: 最近正在玩Google Vision API,
: 目標是透過OCR辨認出一份報告/成績單的內容(格式不限),
: 並轉存成後續可再利用分析的檔案(e.g. json, csv, txt... 這部分還沒想好)。
: 想像有以下三種成績單:
: --------
: XXX高中
: 姓名:王小明 性別:男
: 考試日期:2018/01/10
: 語文能力
: 科目 分數 班平均
: 國文 70 75
: 英文 86 87
: 自然科學
: 科目 分數 班平均
: 物理 40 30
: 化學 93 60
: --------
: 實事求是 精益求精
: 姓名:李大同 性別:男
: 考試日期:2018-01-09
: 科目 分數 班平均
: 國文
: CHINESE 90 80
: 數學
: MATHEMATICS 89 90
: --------
: 姓名:黃小美
: 性別:女
: 學號:970284
: 試驗日期:2018-01-08
: 考試科目 全班平均 實得分數
: CHINESE 國文 60 84
: MATHEMATICS 數學 90 92
: --------
: 這三種照片如果整理成CSV,大概都會希望長得像:
: 科目,分數,班平均
: 國文,70,75
: 英文,86,87
: 物理,40,30
: 化學,93,60
: 即英文科目名稱忽略不計,留下分數及班平均。
: 至於照片最上面的個人資料都忽略。(如果能留下考試日期當然也不錯)
: 目前我已經做到透過Google Vision API的text detection讀出照片上的文字資訊,
: (document text detection我也試過但效果不好)
: (https://cloud.google.com/vision/docs/ocr)
: 並且把每個文字框內容依像素座標由上到下、由左到右排列。
: 但緊接著碰到兩個問題:
: 1. 成績單上同列資料y座標軸可能不同
: 可能因為成績單紙張不平整或照相時有歪斜,
: 所以由上到下、由左到右排列完後,
: 可能會有「75,國文,70」這樣的順序,而非期待的「國文,70,75」。
: 這部分我想到或許可手動用rule-based的方法,
: 如任兩個文字框y座標不超過n單位就視為同一列之類的,
: 但也想請問有沒有更好的做法?
: 2. 分辨各欄位內容
: 各家的個人資料排列方式與位置均不同(置中置左置右),
: 有些的科目名稱只有中文,有些是中英文對照,
: 中英文對照的又可以有在同一行寫或分兩行寫等變化,
: 有些把班平均擺前面欄位,有些擺後面......
: 我曾經想過初步的想法是把每個文字框的x座標做x-means clustering,
: 再從x座標小的群開始,把每個cluster的內容依y座標排列下來,
: 原本預期可以避開上述問題1,
: 但是這方法卻不能排除無用的文字框
: (e.g. 「姓名」、「語文能力」、多餘的英文科目列),
: 導致每個cluster的元素數量不會一樣多,卻又不是每個元素都需要;
: 另外也不能分辨每一個cluster內表示的究竟是班平均還是個人分數。
: 想請問板上高手,有沒有人有相關的資源或實務經驗可以分享?謝謝!
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 203.74.120.191
※ 文章網址: https://www.ptt.cc/bbs/DataScience/M.1525927544.A.2ED.html
※ 編輯: parcequetoi (203.74.120.191), 05/10/2018 13:07:47
討論串 (同標題文章)
DataScience 近期熱門文章
PTT數位生活區 即時熱門文章