파이썬 - 머신러닝 프로젝트 설명
OCR 추출 부터 이어지는 머신러닝을 활용한 프로젝트 세 번 째 포스팅 입니다.
제가 진행하는 프로젝트는 SMS로 수신되는 다양한 이미지 스팸(SPAM) 광고 문자(이미지)를 분석해서
텍스트를 분석 -> 출력 후 -> 데이터 정제 -> 기계학습 -> 데이터 확인(스팸 종류 및 여부) 확인
순서로 진행할 예정입니다.
오늘은 파이썬을 활용해서 기계학습 이전 단계까지의 추출 된 텍스트를 1차 정제 및 가공해서 트레이닝
데이터로 전달하기 위해서 최종적으로 작성하는 프로젝트를 구축할 예정입니다.
5회 정도의 포스팅으로 연재를 이어나갈 예정이며, 하단의 예제를 쉽게 따라하실 수 있게 정리하겠습니다.
이전 포스팅을 차근차근 읽어보시면 더욱 도움이 되실걸로 생각이 됩니다. - 관련 포스팅
파이썬 머신러닝 - OCR 추출 및 텍스트 가공 소스코드
Tessaract의 옵션 값을 조절해서 이미지에서 최적의 텍스트를 추출하는 테스트를 완료 했습니다.
하지만, 추출 된 텍스트는 각 스팸 이미지의 텍스트 형식이 워낙 다양한 형태로 작성되어 있어서 1차 가공하는
코드 작성이 필수라고 생각이 됩니다. (예) 특수문자 제거, 공백 제거, 세로 문자 등
본 설정은 Windows10 (x64)에 아나콘다(Anaconda3), Python 3.6 환경에서 설정했습니다.
프로젝트 진행 전 필수 설치 패키지는 이전 포스팅을 참고해 주세요.
아래 예제 소스는 이미지에서 한글 + 영문, 영문, 한글 등을 추출 후 콘솔에서 출력 후 텍스트 파일에 내용을
파이썬의 정규표현식(Regax)를 활용해서 1차 정제한 후 TXT파일로 저장합니다.
마지막으로 머신러닝 트레이닝 데이터로 활용하기 위해서 각 스팸 카테고리별(대출, 인터넷, 도박, 성인, 기타)
로 분류해서 CSV파일로 저장하는 내용도 추가되어 있습니다.
그럼 소스코드를 살펴볼까요?
ocr_to_string_blog.py
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 from PIL import Image #pip install pillowfrom pytesseract import * #pip install pytesseractimport configparserimport sysimport osimport csvimport refrom pymongo import MongoClient #pip install pymongo, mongodb 설치 #Config Parser 초기화config = configparser.ConfigParser()#Config File 읽기config.read(os.path.dirname(os.path.realpath(__file__)) + os.sep + 'envs' + os.sep + 'property.ini') #이미지 -> 문자열 추출def ocrToStr(fullPath, outTxtPath, fileName, lang='eng'): #디폴트는 영어로 추출 #이미지 경로 img = Image.open(fullPath) txtName = os.path.join(outTxtPath,fileName.split('.')[0]) #추출(이미지파일, 추출언어, 옵션) #preserve_interword_spaces : 단어 간격 옵션을 조절하면서 추출 정확도를 확인한다. #psm(페이지 세그먼트 모드 : 이미지 영역안에서 텍스트 추출 범위 모드) #psm 모드 : https://github.com/tesseract-ocr/tesseract/wiki/Command-Line-Usage outText = image_to_string(img, lang=lang, config='--psm 1 -c preserve_interword_spaces=1') print('+++ OCT Extract Result +++') print('Extract FileName ->>> : ', fileName, ' : <<<-') print('\n\n') #출력 print(outText) #추출 문자 텍스트 파일 쓰기 strToTxt(txtName, outText) #문자열 -> 텍스트파일 개별 저장def strToTxt(txtName, outText): with open(txtName + '.txt', 'w', encoding='utf-8') as f: f.write(outText) #텍스트파일 -> csv 파일 생성def txtToCsv(txtName, cateName, outTxtPath, outCsvPath): #파일 사이즈가 0이면 패스(미추출 파일) if os.path.getsize(os.path.join(outTxtPath,txtName)) != 0: with open(os.path.join(outTxtPath, txtName), 'r', encoding='utf-8') as r: with open(os.path.join(outCsvPath, config['FilneName']['CsvFileName']),'a', encoding='utf-8', newline='') as w: writer = csv.writer(w, delimiter=',') clText = cleanText(r.read()) writer.writerow([cateName, clText]) spamList.append({"category" : cateName, "contents": clText}) #텍스트 정제(전처리)def cleanText(readData): #스팸 메세지에 포함되어 있는 특수 문자 제거 text = re.sub('[-=+,#/\?:^$.@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'…》]', '', readData) #양쪽(위,아래)줄바꿈 제거 text = text.strip('\n') return text #메인 시작if __name__ == "__main__": #텍스트 파일 저장 경로 outTxtPath = os.path.dirname(os.path.realpath(__file__))+ config['Path']['OcrTxtPath'] #CSV 파일 저장 경로 outCsvPath = os.path.dirname(os.path.realpath(__file__))+ config['Path']['TxtCsvPath'] #OCR 추출 작업 메인 for root, dirs, files in os.walk(os.path.dirname(os.path.realpath(__file__)) + config['Path']['OriImgPath']): for fname in files: fullName = os.path.join(root, fname) #한글+영어 추출(kor, eng , kor+eng) ocrToStr(fullName, outTxtPath, fname,'kor+eng') #CSV 변환 작업 메인 for fname in os.listdir(os.path.dirname(os.path.realpath(__file__))+ config['Path']['OcrTxtPath']): cateName = ''.join([i for i in fname if not i.isdigit()]).split('.')[0].strip() txtToCsv(fname, cateName, outTxtPath, outCsvPath) #작업 완료 메시지 print('+++ OCR Image >> Text >> CSV Convert Complete! +++' cs
- 11번 라인 : 다양한 운영체제 및 실행 환경 변경 대비 위한 configParser 임포트
- 13번 라인 : 운영체제에 맞는 패스 접근자를 활용해서 property.ini 파일 로드- 16번 라인 : 가장 중요한 이미지에서 텍스트를 출력하는 부분(주석 확인)- 37번 라인 : 텍스트 추출 후 -> 콘솔 출력 -> 텍스트 파일 저장 처리 함수
- 42번 라인 : 수집한 스팸이미지의 종류를 파일명으로 분류 후 최종적으로 단일 CSV 파일로 저장- 52번 라인 : 텍스트 정제 함수 -> 특수문자 제거, 줄 바꿈 제거- 63번 라인 : 텍스트 파일이 저장 될 경로 로드- 68번 라인 : 현재 실행 파일 기준 하위 폴더에 있는 모든 이미지를 순회하며 추출하는 반복문- 75번 라인 : 저장 된 텍스트 파일을 테스트 가공 처리 후 CSV로 저장 처리를 위한 반복문- 80번 라인 : 최종 작업 완료 텍스트 콘솔 출력
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | from PIL import Image #pip install pillow from pytesseract import * #pip install pytesseract import configparser import sys import os import csv import re from pymongo import MongoClient #pip install pymongo, mongodb 설치 #Config Parser 초기화 config = configparser.ConfigParser() #Config File 읽기 config.read(os.path.dirname(os.path.realpath(__file__)) + os.sep + 'envs' + os.sep + 'property.ini') #이미지 -> 문자열 추출 def ocrToStr(fullPath, outTxtPath, fileName, lang='eng'): #디폴트는 영어로 추출 #이미지 경로 img = Image.open(fullPath) txtName = os.path.join(outTxtPath,fileName.split('.')[0]) #추출(이미지파일, 추출언어, 옵션) #preserve_interword_spaces : 단어 간격 옵션을 조절하면서 추출 정확도를 확인한다. #psm(페이지 세그먼트 모드 : 이미지 영역안에서 텍스트 추출 범위 모드) #psm 모드 : https://github.com/tesseract-ocr/tesseract/wiki/Command-Line-Usage outText = image_to_string(img, lang=lang, config='--psm 1 -c preserve_interword_spaces=1') print('+++ OCT Extract Result +++') print('Extract FileName ->>> : ', fileName, ' : <<<-') print('\n\n') #출력 print(outText) #추출 문자 텍스트 파일 쓰기 strToTxt(txtName, outText) #문자열 -> 텍스트파일 개별 저장 def strToTxt(txtName, outText): with open(txtName + '.txt', 'w', encoding='utf-8') as f: f.write(outText) #텍스트파일 -> csv 파일 생성 def txtToCsv(txtName, cateName, outTxtPath, outCsvPath): #파일 사이즈가 0이면 패스(미추출 파일) if os.path.getsize(os.path.join(outTxtPath,txtName)) != 0: with open(os.path.join(outTxtPath, txtName), 'r', encoding='utf-8') as r: with open(os.path.join(outCsvPath, config['FilneName']['CsvFileName']),'a', encoding='utf-8', newline='') as w: writer = csv.writer(w, delimiter=',') clText = cleanText(r.read()) writer.writerow([cateName, clText]) spamList.append({"category" : cateName, "contents": clText}) #텍스트 정제(전처리) def cleanText(readData): #스팸 메세지에 포함되어 있는 특수 문자 제거 text = re.sub('[-=+,#/\?:^$.@*\"※~&%ㆍ!』\\‘|\(\)\[\]\<\>`\'…》]', '', readData) #양쪽(위,아래)줄바꿈 제거 text = text.strip('\n') return text #메인 시작 if __name__ == "__main__": #텍스트 파일 저장 경로 outTxtPath = os.path.dirname(os.path.realpath(__file__))+ config['Path']['OcrTxtPath'] #CSV 파일 저장 경로 outCsvPath = os.path.dirname(os.path.realpath(__file__))+ config['Path']['TxtCsvPath'] #OCR 추출 작업 메인 for root, dirs, files in os.walk(os.path.dirname(os.path.realpath(__file__)) + config['Path']['OriImgPath']): for fname in files: fullName = os.path.join(root, fname) #한글+영어 추출(kor, eng , kor+eng) ocrToStr(fullName, outTxtPath, fname,'kor+eng') #CSV 변환 작업 메인 for fname in os.listdir(os.path.dirname(os.path.realpath(__file__))+ config['Path']['OcrTxtPath']): cateName = ''.join([i for i in fname if not i.isdigit()]).split('.')[0].strip() txtToCsv(fname, cateName, outTxtPath, outCsvPath) #작업 완료 메시지 print('+++ OCR Image >> Text >> CSV Convert Complete! +++' | cs |
- 11번 라인 : 다양한 운영체제 및 실행 환경 변경 대비 위한 configParser 임포트
- 13번 라인 : 운영체제에 맞는 패스 접근자를 활용해서 property.ini 파일 로드
- 42번 라인 : 수집한 스팸이미지의 종류를 파일명으로 분류 후 최종적으로 단일 CSV 파일로 저장
property.ini
property.ini
12345678910 [Bigdata Ocr Extract]Version= 1.0 [FilneName]CsvFileName= result.csv [Path]OriImgPath= \\resource\\orc_ori_imageOcrTxtPath= \\resource\\ocr_result_txtTxtCsvPath= \\resource\\ocr_result_csv cs
- 1번 라인 : 프로그램 버전 명시- 5번 라인 : 저장 CSV 파일명
- 8번 라인 : 추출 할 원본 이미지 경로- 9번 라인 : 추출 된 텍스트 파일이 저장 될 경로- 10번라인 : 완성 된 CSV 파일이 저장 될 경로
1 2 3 4 5 6 7 8 9 10 | [Bigdata Ocr Extract] Version= 1.0 [FilneName] CsvFileName= result.csv [Path] OriImgPath= \\resource\\orc_ori_image OcrTxtPath= \\resource\\ocr_result_txt TxtCsvPath= \\resource\\ocr_result_csv | cs |
- 1번 라인 : 프로그램 버전 명시
- 8번 라인 : 추출 할 원본 이미지 경로
파이썬 configParser 패키지의 추가적인 상세 설명은 이 곳을 참고해 주세요.
파이썬 configParser 패키지의 추가적인 상세 설명은 이 곳을 참고해 주세요.
파이썬 머신러닝 - 스팸 이미지 OCR 추출 및 텍스트, CSV 저장 실행
실제 소스코드 실행 화면(1) - 콘솔 출력
실제 소스코드 실행 화면(2) - OCR 텍스트 추출 TXT 및 CSV 파일 확인
저번 포스팅에서 설명드린 psm, interword_spaces 등의 옵션 값 조절을 통해서 한글, 영문, 한글+영문
조합으로 구성되어 있는 이미지에 대해서 상당히 만족할 만한 OCR 추출 결과를 보여주고 있습니다.
마무리
오늘 포스팅에서는 머신러닝 기계학습 전까지 프로젝트를 작성하는 코드를 설명드렸습니다.
다음 포스팅에서는 본격적으로 파이썬의 KoNLPy 패키지의 트위터 형태소 분석기 및 Scikit-learn 등을
활용해서 추출 된 스팸이미지의 텍스트를 분석해서 스팸 및 햄 여부, 스팸 형식의 분류 등을
학습하는 코드를 작성해 보겠습니다.
또한, 2차 텍스트를 가공 및 정제해서 학습도, 정확도 향상을 위한 테스트 코드를 기재할 예정입니다.
다음포스팅에서 계속해서 연재를 이어나가도록 하겠습니다. 감사합니다.
소스코드 다운로드 : python_bigdata(2).zip
'빅데이터 & 분석 > Machine Learning' 카테고리의 다른 글
파이썬(Python) - Scikit Learn 의사결정트리(Decision Tree) 시각화 예제 (8) | 2018.12.14 |
---|---|
파이썬(Python) - 머신러닝 프로젝트(최종) - 나이브 베이즈 스팸 필터링 (26) | 2018.09.23 |
파이썬(Python) - 머신러닝 프로젝트(4) - mLab 호스팅 활용 MongoDB 연동 (4) | 2018.09.09 |
파이썬(Python) - 머신러닝 프로젝트(2) - OCR 이미지 문자열 추출(파이썬) (12) | 2018.07.23 |
파이썬(Python) - 머신러닝 프로젝트(1) - OCR 이미지 문자열 추출(Tesseract) (7) | 2018.07.15 |