# !pip install scikit-learn
# !pip install scipy
from sklearn import svm
# 1. XOR의 계산 결과 데이터
xor_data = [
[0,0,0],
[0,1,1],
[1,0,1],
[1,1,0]
]
# 2. 학습을 위해 데이터와 레이블 분리하기
# 학습시키기 fit() 매개변수에 필요
data = [] # 훈련데이터
label = [] # 답
for row in xor_data:
p = row[0]
q = row[1]
r = row[2]
data.append([p, q])
label.append(r)
# input 데이터 확인
print(data)
# 답 확인
print(label)
# 3. 데이터 학습시키기 : fit()
# SVM 알고리즘 사용
clf = svm.SVC()
# 모델 훈련
clf.fit(data, label)
# 4. 데이터 예측하기 : predict()
pre = clf.predict(data)
print('예측결과 : ', pre)
# 5. 결과 확인 하기
ok = 0
total = 0
# enumerate : 반복문 사용시 몇 번째 반복문인지 확인할 수 있음
for idx, answer in enumerate(label):
p = pre[idx]
if p == answer:
ok += 1
total += 1
print('정답률 : ', ok, '/', total, '=', ok/total)
data
label
pre
import pandas as pd
from sklearn import svm, metrics
# 데이터 복사
xor_input = xor_data[:]
xor_input
# 1. 입력을 학습 전용 데이터와 테스트 전용 데이터로 분류하기
xor_df = pd.DataFrame(xor_input)
xor_data = xor_df.loc[:,0:1] # 데이터
xor_label = xor_df.loc[:,2] # 레이블
# 2. 데이터 학습과 예측하기
clf = svm.SVC()
clf.fit(xor_data, xor_label)
pre = clf.predict(xor_data)
# 3. 정답률 구하기
ac_score = metrics.accuracy_score(xor_label, pre)
print('정답률 = ', ac_score)
xor_label
pre
from sklearn import svm, metrics
import random, re
# re 정규표현식 사용하도록
# 1. 붓꽃의 csv 데이터 읽어들이기
csv = []
with open('pyml_rev_examples_20191204/ch4/iris.csv', 'r', encoding='utf-8') as fp:
for line in fp:
line = line.strip() # 줄바꿈 없애기
cols = line.split(',') # 콤마로 구분
# 문자열 데이터를 숫자로 변환하기
fn = lambda n : float(n) if re.match(r'^[0-9\.]+$', n) else n # n이 숫자가 아니면 숫자로 바꿔
cols = list(map(fn, cols))
csv.append(cols)
# 가장 앞 줄의 헤더 제거
del csv[0]
csv[:3]
data = pd.read_csv('pyml_rev_examples_20191204/ch4/iris.csv')
data.head()
# 2. 데이터 셔플하기(섞기)
random.shuffle(csv)
# 3. 학습 전용 데이터와 테스트 전용 데이터 분할하기 (2:1 비율)
total_len = len(csv) # 150개
train_len = int(total_len * 2 / 3) # 2:1 비율로 분할할거니까 # 100개
# 학습용
train_data = []
train_label = []
# 테스트용
test_data = []
test_label = []
for i in range(total_len):
data = csv[i][0:4] # i번째 행의 0~4번째 인덱스 열 앞 까지(SepalLength/SepalWidth/PetalLength/PetalWidth)
label = csv[i][4] # i번째 행의 4 번째 인덱스 열 (Name)
# 100번째 이하면 - 학습용 데이터로 분류
if i < train_len:
train_data.append(data)
train_label.append(label)
# 100번째 이상이면 - 테스트 데이터로 분류
else:
test_data.append(data)
test_label.append(label)
train_data[:3]
train_label[:3]
test_data[:3]
test_label[:3]
# 4. 데이터를 학습시키고 예측하기
clf = svm.SVC()
clf.fit(train_data, train_label)
pre = clf.predict(test_data)
# 5. 정답률 구하기
ac_score = metrics.accuracy_score(test_label, pre)
print('정답률 = ', ac_score)
import pandas as pd
from sklearn import svm, metrics
from sklearn.model_selection import train_test_split
# 1. 붓꽃의 CSV 데이터 읽어들이기
csv = pd.read_csv('pyml_rev_examples_20191204/ch4/iris.csv')
# 2. 컬럼명으로 필요한 열 추출하기
csv_data = csv[["SepalLength","SepalWidth","PetalLength","PetalWidth"]]
csv_label = csv["Name"]
# 3. 학습 전용 데이터와 테스트 전용 데이터로 나누기
train_data, test_data, train_label, test_label = train_test_split(csv_data, csv_label)
train_data[:3]
len(train_data)
test_data[:3]
len(test_data)
train_label[:3]
# 셔플이라 순서가 잘 섞여있음
test_label[:3]
# 4. 데이터 학습시키고 예측하기
clf = svm.SVC()
clf.fit(train_data, train_label)
pre = clf.predict(test_data)
# 5. 정답률 구하기
ac_score = metrics.accuracy_score(test_label, pre)
print('정답률 = ', ac_score)
# binary 파일 변환을 위한 모듈 import
import struct
def to_csv(name, maxdata):
# 레이블 파일과 이미지 파일 열기 (파일 경로)
lbl_f = open('MNIST/'+name+'-labels.idx1-ubyte', 'rb') # 읽기모드
img_f = open('MNIST/'+name+'-images.idx3-ubyte', 'rb')
csv_f = open('MNIST/'+name+'.csv', 'w', encoding='utf-8') # 쓰기모드(저장)
# 1. 헤더 정보 읽기
# unpack() : 지정된 Format에 따라 String을 Unpack, 결과는 Tuple로 리턴 (원하는 바이너리 수만큼 읽고 변환)
# > Little-endian
# II 4byte 4byte
# https://suspected.tistory.com/155
# PGM : 글자파일로 이미지 생성 가능
mag, lbl_count = struct.unpack('>II', lbl_f.read(8))
mag, img_count = struct.unpack('>II', img_f.read(8))
rows, cols = struct.unpack('>II', img_f.read(8))
pixels = rows * cols
# 2. 이미지 데이터를 읽고 csv로 저장하기
res = []
for idx in range(lbl_count):
if idx > maxdata: break
label = struct.unpack('B', lbl_f.read(1))[0]
bdata = img_f.read(pixels)
sdata = list(map(lambda n: str(n), bdata))
csv_f.write(str(label) + ',')
csv_f.write(','.join(sdata) + '\r\n')
# 3. 잘 저장됐는지 이미지 파일로 저장해서 테스트하기
if idx < 10:
s = 'P2 28 28 255\n' # 28*28 사이즈 이미지에서 흰색칸은 0, 검은칸은 255이 있다
s += ' '.join(sdata)
iname = './MNIST/{0}-{1}-{2}.pgm'.format(name,idx,label)
with open(iname, 'w', encoding='utf-8') as f:
f.write(s)
csv_f.close()
lbl_f.close()
img_f.close()
# 4. 결과를 파일로 출력하기
# 6만개 처리 시간이 많이 걸려 학습 1000개 / 테스트 500개
to_csv("train", 1000)
to_csv("t10k", 500)
from sklearn import model_selection, svm, metrics
# 1. CSV 파일 읽어들이고 가공하기
def load_csv(fname):
labels = []
images = []
with open(fname, 'r') as f:
for line in f:
cols = line.split(',')
if len(cols) < 2:
continue
labels.append(int(cols.pop(0)))
# 0 <= vals < 1
vals = list(map(lambda n: int(n) / 256, cols))
images.append(vals)
return {'labels':labels, 'images':images}
data = load_csv('MNIST/train.csv')
test = load_csv('MNIST/t10k.csv')
# 2. 학습하기
clf = svm.SVC()
clf.fit(data['images'], data['labels'])
# 3. 예측하기
predict = clf.predict(test['images'])
# 4. 결과 확인하기
ac_score = metrics.accuracy_score(test['labels'], predict)
cl_report = metrics.classification_report(test['labels'], predict)
print('정답률 = ', ac_score)
print('리포트 = ')
print(cl_report)
from sklearn import svm, metrics
import glob, os.path, re, json
# 1. 텍스트를 읽어들이고 출현 빈도 조사하기
def check_freq(fname):
name = os.path.basename(fname)
# 파일명 앞의 두 문자가 언어코드
lang = re.match(r'^[a-z]{2,}', name).group()
# print(name)
# print(lang)
with open(fname, 'r', encoding='utf-8') as f:
text = f.read()
text = text.lower() # 소문자 변환
# 숫자 세기 변수(cnt) 초기화하기
cnt = [0 for n in range(0, 26)] # 알파벳 26자
# ord() 함수 : 특정한 한 문자를 아스키 코드 값으로 변환해주는 함수
code_a = ord('a')
code_z = ord('z')
# print(code_a)
# 2. 알파벳 출현 횟수 구하기
for ch in text:
n = ord(ch)
# print(n)
if code_a <= n <= code_z: # a~z 사이에 있을 때, 알파벳만 처리
cnt[n - code_a] += 1
# 3. 정규화하기 (각 텍스트파일의 글자수가 다르므로 정규화 필요)
total = sum(cnt)
freq = list(map(lambda n: n / total, cnt))
return(freq, lang)
# 각 파일 처리하기
def load_files(path):
freqs = []
labels = []
# glob() : 특정 파일만 출력하기
# https://wikidocs.net/3746
file_list = glob.glob(path)
for fname in file_list:
r = check_freq(fname)
freqs.append(r[0])
labels.append(r[1])
return {'freqs':freqs, 'labels':labels}
data = load_files('pyml_rev_examples_20191204/ch4/lang/train/*.txt')
test = load_files('pyml_rev_examples_20191204/ch4/lang/test/*.txt')
# 위 데이터 JSON으로 결과 저장해두기 - 이미지 출력용
with open('pyml_rev_examples_20191204/ch4/lang/freq.json', 'w', encoding='utf-8') as fp:
json.dump([data, test], fp)
# 4. 학습하기
clf = svm.SVC()
clf.fit(data['freqs'], data['labels'])
# 5. 예측하기
predict = clf.predict(test['freqs'])
# 6. 결과 테스트하기
ac_score = metrics.accuracy_score(test['labels'], predict)
cl_report = metrics.classification_report(test['labels'], predict)
print('정답률 = ', ac_score)
print('리포트 = ')
print(cl_report)
import matplotlib.pyplot as plt
import pandas as pd
import json
# 1. 알파벳 출현 빈도 데이터 읽어들이기
with open('pyml_rev_examples_20191204/ch4/lang/freq.json', 'r', encoding='utf-8') as fp:
freq = json.load(fp)
# 2. 언어마다 계산하기
lang_dic = {}
for i, lbl in enumerate(freq[0]['labels']):
fq = freq[0]['freqs'][i]
if not (lbl in lang_dic):
lang_dic[lbl] = fq
continue
for idx, v in enumerate(fq):
lang_dic[lbl][idx] = (lang_dic[lbl][idx] + v) / 2
# 3. Pandas의 DataFrame에 데이터 넣기
asclist = [[chr(n) for n in range(97,97+26)]]
df = pd.DataFrame(lang_dic, index=asclist)
df.head()
# 4. 그래프 그리기
df.plot(kind='bar', subplots=True, ylim=(0,0.15)) # subplots=True 그래프 각각 그려
plt.savefig('lang-plot.png')
# 다른 그래프로 확인
df.plot(kind='line')
# pip install joblib
# 언어를 판정할때마다 데이터학습할 필요 없으니 학습 모델 저장
from sklearn import svm
# from sklearn.externals import joblib
import joblib
# 각 언어의 출현 빈도 데이터(JSON) 읽어들이기
with open('pyml_rev_examples_20191204/ch4/lang/freq.json','r', encoding='utf-8') as fp:
d = json.load(fp)
data = d[0]
# 데이터 학습하기
clf = svm.SVC()
clf.fit(data['freqs'], data['labels'])
# 학습 데이터 저장하기(pickle로)
# 학습한 모델을 저장할 수 있는 sklearn의 joblib
# https://minwook-shin.github.io/python-disk-caching-parallel-computing-using-joblib/
joblib.dump(clf, 'pyml_rev_examples_20191204/ch4/lang/freq.pkl')
print('ok')
#!/usr/bin/env python3
import cgi, os.path
from sklearn.externals import joblib
# 학습 데이터 읽어 들이기
pklfile = os.path.dirname(__file__) + "/freq.pkl"
clf = joblib.load(pklfile)
# 텍스트 입력 양식 출력하기
def show_form(text, msg=""):
print("Content-Type: text/html; charset=utf-8")
print("")
print("""
<html><body><form>
<textarea name="text" rows="8" cols="40">{0}</textarea>
<p><input type="submit" value="판정"></p>
<p>{1}</p>
</form></body></html>
""".format(cgi.escape(text), msg))
# 판정하기
def detect_lang(text):
# 알파벳 출현 빈도 구하기
text = text.lower()
code_a, code_z = (ord("a"), ord("z"))
cnt = [0 for i in range(26)]
for ch in text:
n = ord(ch) - code_a
if 0 <= n < 26: cnt[n] += 1
total = sum(cnt)
if total == 0: return "입력이 없습니다"
freq = list(map(lambda n: n/total, cnt))
# 언어 예측하기
res = clf.predict([freq])
# 언어 코드를 한국어로 변환하기
lang_dic = {"en":"영어","fr":"프랑스어",
"id":"인도네시아어", "tl":"타갈로그어"}
return lang_dic[res[0]]
# 입력 양식의 값 읽어 들이기
form = cgi.FieldStorage()
text = form.getvalue("text", default="")
msg = ""
if text != "":
lang = detect_lang(text)
msg = "판정 결과:" + lang
# 입력 양식 출력
show_form(text, msg)
# 위 코드를 메모장 등의 파일로 저장한 뒤, Anaconda prompt를 이용,
# python -m http.server --cgi 명령어로 웹으로 연결
# http://localhost:8080/cgi-bin/lang-Webapp.py (혹은 지정한 포트로) 웹 프로그램 실행