파이썬 - 머신러닝 프로젝트 설명
OCR 추출 부터 이어지는 머신러닝을 활용한 스팸 이미지 분류의 마지막 포스팅 입니다.
해당 프로젝트는 SMS로 수신되는 다양한 이미지 스팸(SPAM) 광고 문자(이미지)를 분석해서
텍스트를 분석 -> 출력 -> 데이터 정제 -> 기계학습 -> 스팸 종류 및 카테고리를 분류하는
순서로 개발했습니다.
오늘은 마지막 과정인 파이썬의 Pandas, Scikit-learn과 트위터 형태소 분석기(KoNLPy)를 활용해서
전처리 된 텍스트를 기계학습(지도학습) 후에 스팸 항목별 분류 정확도를 높이는 예제를 작성하도록
하겠습니다.
관련 프로젝트를 진행하실 예정이거나, 관련 주제를 학습하시는 분들을 위해서 하단에 최종 소스파일을
첨부하였으므로, 실습을 해보시면 조금은 도움이 될 것으로 생각됩니다.
아울러, 1화 포스팅 부터 차근차근 읽어보시면 조금이나마 도움이 되실거라 생각이 됩니다. - 관련 포스팅
파이썬 머신러닝 - KoNLPy 및 Naive Bayesian Classification 소스 예제
지난 네 번째 포스팅에서 달라진 점은 가장 중요한 트위터 형태소(KoNLPy)를 활용한 한글 단어 전처리 과정을 추가한 부분입니다.
아울러, 가장 중요한 부분인 단어별 빈도수를 계산 후 해당 텍스트가 스팸이미지일 확률을 나이브베이지안을
직접 클래스로 구성해서 파이썬의 math, random 패키지 등을 활용해서 직접 소스코드로 구현한 부분입니다.
해당 소스 코드는 나이브베이지안 분류(Naive Bayesian Classification) 알고리즘 대한 이해 및 형태소 분석
(한국어 처리)에 대한 선행학습이 있어야 이해가 가능합니다.
물론, 관련 이론을 학습하신분은 바로 소스코드 리뷰가 가능합니다.
관련 지식은 포스팅으로 직접 설명하면 매우 길어지므로, 자세하게 나와 있는 관련 링크를 하단에 참조하오니
꼭 참고해주시기 바랍니다.
해당 링크 내용을 참고하신 소스코드를 살펴보시면 쉽게 이해 하실 수 있습니다.
그럼 소스코드를 살펴볼까요?
main.py
1234567891011121314151617181920212223242526272829 from PIL import Image #pip install pillowfrom pytesseract import * #pip install pytesseractimport configparserimport sysimport ioimport osimport csvimport refrom pymongo import MongoClient #pip install pymongo, mongodb 설치from lib.SpamClsEngine import * #예제파일 참조(지난 포스팅과 소스코드 내용 동일) #텍스트파일 -> 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}) print('clText',clText) #트레이닝 및 스팸 판독 여부, 카테고리 분류 작업 시작 nlpKoSpamStart(clText, config['System']['OperMode']) #예제파일 참조(지난 포스팅과 소스코드 내용 동일) cs
지난 예제와 비교해서 변경 및 추가된 라인은 기계학습 후 스팸 판독 및 분류 작업메소드를 호출하는 부분입니다.
- 10번 라인 : 기계학습 및 스팸 분류를 위해 외부 패키지에 작성한 SpamClsEngine.py 파일을 import
- 27번 라인 : nlpKoSpamStart 메소드에 전처리 된 텍스트 및 모드 플래그를 매개변수 전달 후 호출
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 | from PIL import Image #pip install pillow from pytesseract import * #pip install pytesseract import configparser import sys import io import os import csv import re from pymongo import MongoClient #pip install pymongo, mongodb 설치 from lib.SpamClsEngine import * #예제파일 참조(지난 포스팅과 소스코드 내용 동일) #텍스트파일 -> 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}) print('clText',clText) #트레이닝 및 스팸 판독 여부, 카테고리 분류 작업 시작 nlpKoSpamStart(clText, config['System']['OperMode']) #예제파일 참조(지난 포스팅과 소스코드 내용 동일) | cs |
지난 예제와 비교해서 변경 및 추가된 라인은 기계학습 후 스팸 판독 및 분류 작업메소드를 호출하는 부분입니다.
- 10번 라인 : 기계학습 및 스팸 분류를 위해 외부 패키지에 작성한 SpamClsEngine.py 파일을 import
- 27번 라인 : nlpKoSpamStart 메소드에 전처리 된 텍스트 및 모드 플래그를 매개변수 전달 후 호출
SpamClsEngine.py
SpamClsEngine.py
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 from __future__ import divisionfrom collections import Counter, defaultdictfrom sklearn.model_selection import train_test_splitimport math, random, re, globimport pandas as pdfrom konlpy.tag import Twitter # 단어 단위로 잘라주는 함수 (# konlpy 사용하는 것으로 변경)def tokenize(message): t=Twitter() all_words=t.nouns(message) return set(all_words) # 단어별 빈도수를 세어는 함수 [스팸여부, 메시지 내용] # 1 : adult, 2: ETC, 3 : gambling 4 : internet 5 :loan # 0 : hamsdef count_words(training_set): counts = defaultdict(lambda: [0,0,0,0,0,0]) training_set_arr = training_set.values for is_spam, message in training_set_arr: for word in tokenize(message): counts[word][int(is_spam)]+= 1 return counts #'weekends': [1, 1],[스팸에서 나온 빈도,햄에서 나온빈도] # 빈도수를 통해 확률값 추정() ㅣlist 형식def word_probabilities(counts, total_non_spams, total_adultSpams, total_etcSpams, total_gamblingSpams, total_internetSpams, total_loanSpams, k=0.5): return [(w, (non_spam + k) / (total_non_spams + 2 * k), (adultSpam + k) / (total_adultSpams + 2 * k), (etcSpam + k) / (total_etcSpams + 2 * k), (gamblingSpam + k) / (total_gamblingSpams + 2 * k), (intersSpam + k) / (total_internetSpams + 2 * k), (loanSpam + k) / (total_loanSpams + 2 * k)) for w, (non_spam,adultSpam,etcSpam,gamblingSpam,intersSpam,loanSpam) in counts.items()] ##1 : adult, 2: ETC, 3 : gambling 4 : internet 5 :loan # 0 : hamsdef spam_probability(word_probs, message): message_words = tokenize(message) log_prob_if_adultSpam = log_prob_if_not_spam = 0.0 log_prob_if_etcSpam = log_prob_if_gamblingSpam = log_prob_if_internetSpam = log_prob_if_loanSpam = 0.0 for word, prob_if_not_spam, prob_if_adultSpam, prob_if_etcSpam, prob_if_gamblingSpam, prob_if_internetSpam, prob_if_loanSpam in word_probs: if word in message_words: log_prob_if_adultSpam += math.log(prob_if_adultSpam) log_prob_if_etcSpam += math.log(prob_if_etcSpam) log_prob_if_gamblingSpam += math.log(prob_if_gamblingSpam) log_prob_if_internetSpam += math.log(prob_if_internetSpam) log_prob_if_loanSpam += math.log(prob_if_loanSpam) log_prob_if_not_spam += math.log(prob_if_not_spam) else: log_prob_if_adultSpam += math.log(1.0 - prob_if_adultSpam) log_prob_if_etcSpam += math.log(1.0 - prob_if_etcSpam) log_prob_if_gamblingSpam += math.log(1.0 - prob_if_gamblingSpam) log_prob_if_internetSpam += math.log(1.0 - prob_if_internetSpam) log_prob_if_loanSpam += math.log(1.0 - prob_if_loanSpam) log_prob_if_not_spam += math.log(1.0 - prob_if_not_spam) prob_if_adultSpam = math.exp(log_prob_if_adultSpam) prob_if_etcSpam = math.exp(log_prob_if_etcSpam) prob_if_gamblingSpam = math.exp(log_prob_if_gamblingSpam) prob_if_internetSpam = math.exp(log_prob_if_internetSpam) prob_if_loanSpam = math.exp(log_prob_if_loanSpam) prob_if_not_spam = math.exp(log_prob_if_not_spam) max_Proba = 0 index_Proba = '' if max_Proba < (prob_if_loanSpam / (prob_if_loanSpam + prob_if_not_spam)): max_Proba = prob_if_loanSpam / (prob_if_loanSpam + prob_if_not_spam) index_Proba = 'loan' if max_Proba < (prob_if_adultSpam / (prob_if_adultSpam + prob_if_not_spam)): max_Proba = prob_if_adultSpam / (prob_if_adultSpam + prob_if_not_spam) index_Proba = 'adult' if max_Proba < (prob_if_etcSpam / (prob_if_etcSpam + prob_if_not_spam)): max_Proba = prob_if_etcSpam / (prob_if_etcSpam + prob_if_not_spam) index_Proba = 'etc' if max_Proba < (prob_if_gamblingSpam / (prob_if_gamblingSpam + prob_if_not_spam)): maxProba = prob_if_gamblingSpam / (prob_if_gamblingSpam + prob_if_not_spam) index_Proba = 'gambling' if max_Proba < (prob_if_internetSpam / (prob_if_internetSpam + prob_if_not_spam)): max_Proba = (prob_if_internetSpam / (prob_if_internetSpam + prob_if_not_spam)) index_Proba = 'internet' return max_Proba, index_Proba # 제일 높은 확률과 카테고리 # 나이브 베이지안 클래스에 넣기class NaiveBayesClassifier: def __init__(self, k=0.5): self.k = k self.word_probs = [] def classify(self, message): return spam_probability(self.word_probs, message) def train(self, training_set): num_non_spams = len(training_set[training_set.is_spam == '0']) num_adultSpams = len(training_set[training_set.is_spam == '1']) num_etcSpams = len(training_set[training_set.is_spam == '2']) num_gamblingSpams = len(training_set[training_set.is_spam == '3']) num_internetSpams = len(training_set[training_set.is_spam == '4']) num_loanSpams = len(training_set[training_set.is_spam == '5']) # 학습 데이터 적용하여 모델 만들기 word_counts = count_words(training_set) self.word_probs = word_probabilities(word_counts, num_non_spams, num_adultSpams, num_etcSpams, num_gamblingSpams, num_internetSpams, num_loanSpams, self.k) # print(self.word_probs) def p_spam_given_word(word_prob): word, prob_if_spam, prob_if_not_spam = word_prob return prob_if_spam / (prob_if_spam + prob_if_not_spam) def train_and_test_model(data, sw, predicMess=''): if sw == '0': # 학습 random.seed(0) train_data, test_data = train_test_split(data, test_size=0.25) print("train_data_cnt:", len(train_data)) print("test_data_cnt:", len(test_data)) classifier = NaiveBayesClassifier() classifier.train(train_data) test_data_arr = test_data.values classified = [(is_spam, message, classifier.classify(message)) for is_spam, message in test_data_arr] print(classified) else: # 예측 random.seed(0) train_data, test_data = train_test_split(data, test_size=0) classifier = NaiveBayesClassifier() classifier.train(train_data) spam_probability = classifier.classify(predicMess) print(spam_probability) print(spam_probability[0]) if spam_probability[0] > 0.5: category = '' if spam_probability[1] == "adult": category = '성인물' elif spam_probability[1] == 'etc': category = '기타' elif spam_probability[1] == 'gambling': category = '게임' elif spam_probability[1] == 'internet': category = '인터넷유도' elif spam_probability[1] == 'loan': category = "대출" print(category, " 스팸 메시지 입니다. ", spam_probability[0]) else: print("스팸메시지가 아닙니다 . ", spam_probability[0]) def nlpKoSpamStart(predicMessage, mode): #mode = '1' # 0: modeling 1 : prediction readData = pd.read_csv('전처리 된 csv파일 경로') trainData = readData.loc[:,['is_spam','message']] train_and_test_model(trainData, mode, predicMessage) cs
- 6번 라인 : KoNLPy 패키지에서 Twitter 형태소 분석기 import
- 9번 라인 : 단어 별 슬라이스(Slice) 처리를 위한 함수 선언- 15번 라인 : 단어 출현 별 빈도수를 카운팅해서 리턴하는 함수- 25번 라인 : 분류 결과의 정확도 향상을 위해서 빈도수를 입력받아 확률값을 추정하는 함수
- 85번 라인 : 나이브베이지안(Naive Bayesian Classification) 클래스 생성- 112번 라인 : 가장 중요한 스팸 분류 학습(Mode 0) 또는 예측(Mode 1)하는 함수 작성
- 153번 라인 : main.py에서 호출하는 학습 또는 예측 실행 함수
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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | from __future__ import division from collections import Counter, defaultdict from sklearn.model_selection import train_test_split import math, random, re, glob import pandas as pd from konlpy.tag import Twitter # 단어 단위로 잘라주는 함수 (# konlpy 사용하는 것으로 변경) def tokenize(message): t=Twitter() all_words=t.nouns(message) return set(all_words) # 단어별 빈도수를 세어는 함수 [스팸여부, 메시지 내용] # 1 : adult, 2: ETC, 3 : gambling 4 : internet 5 :loan # 0 : hams def count_words(training_set): counts = defaultdict(lambda: [0,0,0,0,0,0]) training_set_arr = training_set.values for is_spam, message in training_set_arr: for word in tokenize(message): counts[word][int(is_spam)]+= 1 return counts #'weekends': [1, 1],[스팸에서 나온 빈도,햄에서 나온빈도] # 빈도수를 통해 확률값 추정() ㅣlist 형식 def word_probabilities(counts, total_non_spams, total_adultSpams, total_etcSpams, total_gamblingSpams, total_internetSpams, total_loanSpams, k=0.5): return [(w, (non_spam + k) / (total_non_spams + 2 * k), (adultSpam + k) / (total_adultSpams + 2 * k), (etcSpam + k) / (total_etcSpams + 2 * k), (gamblingSpam + k) / (total_gamblingSpams + 2 * k), (intersSpam + k) / (total_internetSpams + 2 * k), (loanSpam + k) / (total_loanSpams + 2 * k)) for w, (non_spam,adultSpam,etcSpam,gamblingSpam,intersSpam,loanSpam) in counts.items()] ##1 : adult, 2: ETC, 3 : gambling 4 : internet 5 :loan # 0 : hams def spam_probability(word_probs, message): message_words = tokenize(message) log_prob_if_adultSpam = log_prob_if_not_spam = 0.0 log_prob_if_etcSpam = log_prob_if_gamblingSpam = log_prob_if_internetSpam = log_prob_if_loanSpam = 0.0 for word, prob_if_not_spam, prob_if_adultSpam, prob_if_etcSpam, prob_if_gamblingSpam, prob_if_internetSpam, prob_if_loanSpam in word_probs: if word in message_words: log_prob_if_adultSpam += math.log(prob_if_adultSpam) log_prob_if_etcSpam += math.log(prob_if_etcSpam) log_prob_if_gamblingSpam += math.log(prob_if_gamblingSpam) log_prob_if_internetSpam += math.log(prob_if_internetSpam) log_prob_if_loanSpam += math.log(prob_if_loanSpam) log_prob_if_not_spam += math.log(prob_if_not_spam) else: log_prob_if_adultSpam += math.log(1.0 - prob_if_adultSpam) log_prob_if_etcSpam += math.log(1.0 - prob_if_etcSpam) log_prob_if_gamblingSpam += math.log(1.0 - prob_if_gamblingSpam) log_prob_if_internetSpam += math.log(1.0 - prob_if_internetSpam) log_prob_if_loanSpam += math.log(1.0 - prob_if_loanSpam) log_prob_if_not_spam += math.log(1.0 - prob_if_not_spam) prob_if_adultSpam = math.exp(log_prob_if_adultSpam) prob_if_etcSpam = math.exp(log_prob_if_etcSpam) prob_if_gamblingSpam = math.exp(log_prob_if_gamblingSpam) prob_if_internetSpam = math.exp(log_prob_if_internetSpam) prob_if_loanSpam = math.exp(log_prob_if_loanSpam) prob_if_not_spam = math.exp(log_prob_if_not_spam) max_Proba = 0 index_Proba = '' if max_Proba < (prob_if_loanSpam / (prob_if_loanSpam + prob_if_not_spam)): max_Proba = prob_if_loanSpam / (prob_if_loanSpam + prob_if_not_spam) index_Proba = 'loan' if max_Proba < (prob_if_adultSpam / (prob_if_adultSpam + prob_if_not_spam)): max_Proba = prob_if_adultSpam / (prob_if_adultSpam + prob_if_not_spam) index_Proba = 'adult' if max_Proba < (prob_if_etcSpam / (prob_if_etcSpam + prob_if_not_spam)): max_Proba = prob_if_etcSpam / (prob_if_etcSpam + prob_if_not_spam) index_Proba = 'etc' if max_Proba < (prob_if_gamblingSpam / (prob_if_gamblingSpam + prob_if_not_spam)): maxProba = prob_if_gamblingSpam / (prob_if_gamblingSpam + prob_if_not_spam) index_Proba = 'gambling' if max_Proba < (prob_if_internetSpam / (prob_if_internetSpam + prob_if_not_spam)): max_Proba = (prob_if_internetSpam / (prob_if_internetSpam + prob_if_not_spam)) index_Proba = 'internet' return max_Proba, index_Proba # 제일 높은 확률과 카테고리 # 나이브 베이지안 클래스에 넣기 class NaiveBayesClassifier: def __init__(self, k=0.5): self.k = k self.word_probs = [] def classify(self, message): return spam_probability(self.word_probs, message) def train(self, training_set): num_non_spams = len(training_set[training_set.is_spam == '0']) num_adultSpams = len(training_set[training_set.is_spam == '1']) num_etcSpams = len(training_set[training_set.is_spam == '2']) num_gamblingSpams = len(training_set[training_set.is_spam == '3']) num_internetSpams = len(training_set[training_set.is_spam == '4']) num_loanSpams = len(training_set[training_set.is_spam == '5']) # 학습 데이터 적용하여 모델 만들기 word_counts = count_words(training_set) self.word_probs = word_probabilities(word_counts, num_non_spams, num_adultSpams, num_etcSpams, num_gamblingSpams, num_internetSpams, num_loanSpams, self.k) # print(self.word_probs) def p_spam_given_word(word_prob): word, prob_if_spam, prob_if_not_spam = word_prob return prob_if_spam / (prob_if_spam + prob_if_not_spam) def train_and_test_model(data, sw, predicMess=''): if sw == '0': # 학습 random.seed(0) train_data, test_data = train_test_split(data, test_size=0.25) print("train_data_cnt:", len(train_data)) print("test_data_cnt:", len(test_data)) classifier = NaiveBayesClassifier() classifier.train(train_data) test_data_arr = test_data.values classified = [(is_spam, message, classifier.classify(message)) for is_spam, message in test_data_arr] print(classified) else: # 예측 random.seed(0) train_data, test_data = train_test_split(data, test_size=0) classifier = NaiveBayesClassifier() classifier.train(train_data) spam_probability = classifier.classify(predicMess) print(spam_probability) print(spam_probability[0]) if spam_probability[0] > 0.5: category = '' if spam_probability[1] == "adult": category = '성인물' elif spam_probability[1] == 'etc': category = '기타' elif spam_probability[1] == 'gambling': category = '게임' elif spam_probability[1] == 'internet': category = '인터넷유도' elif spam_probability[1] == 'loan': category = "대출" print(category, " 스팸 메시지 입니다. ", spam_probability[0]) else: print("스팸메시지가 아닙니다 . ", spam_probability[0]) def nlpKoSpamStart(predicMessage, mode): #mode = '1' # 0: modeling 1 : prediction readData = pd.read_csv('전처리 된 csv파일 경로') trainData = readData.loc[:,['is_spam','message']] train_and_test_model(trainData, mode, predicMessage) | cs |
- 6번 라인 : KoNLPy 패키지에서 Twitter 형태소 분석기 import
- 9번 라인 : 단어 별 슬라이스(Slice) 처리를 위한 함수 선언
- 85번 라인 : 나이브베이지안(Naive Bayesian Classification) 클래스 생성
참고 : 각 운영체제별 KoNLPy 설치 방법 (공식)- 관련 포스팅
파이썬 머신러닝 - 지도학습(Supervised) 후 스팸 별 카테고리 분류 결과
실제 소스코드 실행 화면(1) - OCR 대상 원본 스팸 이미지 확인
실제 소스코드 실행 화면(2) - OCR 추출 후 텍스트 파일 확인
실제 소스코드 실행 화면(3) - 최종 기계학습 후 스팸 분류 결과 및 정확도
실제 결과를 보면 스팸 예측 확률 및 각 스팸별 카테고리를 가장 많이 발생되고 있는 형태의 5가지 분류
(인터넷, 성인, 대출, 도박게임, 기타)로 분류해서 결과 값을 출력하는 것을 확인하실 수 있습니다.
즉, 이미지스팸 확률, 스팸일 경우 카테고리명, 원본 스팸 메시지 등을 일괄 출력해서 전체 과정 결과의
정확도 값을 통해서 프로그램의 완성도를 확인하실 수 있을거라 생각됩니다.
마무리
5회에 걸친 포스팅을 진행하면서 많은 시간을 데이터 전처리 과정 및 기술 학습 습득에 할애하였습니다.
몇 달 전으로 돌아가서 프로젝트의 시작은 한국 데이터베이스 진흥원 빅데이터분석 전문가 과정의 조별
프로젝트로 부터 시작했습니다.
스팸 이미지를 수집(김유미님께 감사)에 많은 어려움이 있었으며, 아직까지는 데이터 분석의 전단계인
데이터수집, 가공 및 전처리 프로세스에 기획당시의 예상보다 훨씬 뛰어넘는 기술 및 시간투자가 이루어
진다는 것을 다시 한 번 느끼게 되었습니다.
초기 프로젝트 기획 단계에서 개발 단계 까지 팀원간에 조속한 의사소통과 개인 스킬에 가장 적합한 업무
분배를 통해서 좋은 결과를 도출했다고 생각합니다. (데이터진흥원 프로젝트 우수상 수상!)
참고로 나이브베이즈(Naive Bayesian) 관련 분류는 박경미님께서 개발해주셨고 해당 내용을 제가 다시
리팩토링 해서 제가 다시 정리했음을 알려드립니다.
마지막으로 관련 포스팅을 통해서 데이터 수집 부터 기계학습 후 결과 도출이라는 머신러닝 프로젝트 관련
지식 습득에 큰 도움이 되셨기를 기대하는 마음입니다.
지금은 실무에서 여러 프로젝트 경험을 통해서 항상 새로운 것을 깨닫는 단계이지만, 이번 프로젝트의 경험은
저에게 큰 자산이 되었다고 생각이 됩니다.
그럼 관련 주제의 포스팅을 마치겠습니다.
소스코드 다운로드 :
python_bigdata(4).zip
'빅데이터 & 분석 > Machine Learning' 카테고리의 다른 글
Flask(플라스크) - 머신러닝, 딥러닝 웹 서비스 예제 소스 및 개념 설명(1) (16) | 2019.06.12 |
---|---|
파이썬(Python) - Scikit Learn 의사결정트리(Decision Tree) 시각화 예제 (8) | 2018.12.14 |
파이썬(Python) - 머신러닝 프로젝트(4) - mLab 호스팅 활용 MongoDB 연동 (4) | 2018.09.09 |
파이썬(Python) - 머신러닝 프로젝트(3) - 문자열 가공 및 TXT 및 CSV 저장 (9) | 2018.07.27 |
파이썬(Python) - 머신러닝 프로젝트(2) - OCR 이미지 문자열 추출(파이썬) (12) | 2018.07.23 |