HTML 문서 본문 가져오기
04 Nov 2017 | PythonPython 3.x 기반의 코드입니다. 웹페이지의 HTML 본문을 가져오는 코드입니다.
예제 코드
import urllib.request url = "http://snowdeer.github.io/" res = urllib.request.urlopen(url) data = res.read() text = data.decode("UTF-8") print(text)
Python 3.x 기반의 코드입니다. 웹페이지의 HTML 본문을 가져오는 코드입니다.
import urllib.request url = "http://snowdeer.github.io/" res = urllib.request.urlopen(url) data = res.read() text = data.decode("UTF-8") print(text)
Python 3.x 기반의 코드입니다. 인터넷 등 네트워크 상에 있는 파일을 다운로드하는 샘플 코드입니다.
import urllib.request url = "http://snowdeer.github.io/public/img/hello_page.jpg" filename = "snowdeer.jpg" urllib.request.urlretrieve(url, filename) print("Saving image is successful.")
import urllib.request url = "http://snowdeer.github.io/public/img/hello_page.jpg" filename = "snowdeer.jpg" image = urllib.request.urlopen(url).read() with open(filename, mode="wb") as f: f.write(image) print("Saving image is successful.")
강화 학습(Reinforcement Learning)은 일련의 행동 후에 보상이나 평가가 주어질 때 사용할 수 있는 학습 방법입니다.
여기서는 강화 학습 중 Q-Learning
방법에 대해서 C++ 예제를 살펴보도록 하겠습니다.
Q Value
는 어떤 상태에서 취해야 할 각각의 행동들에 대한 지표가 되는 수치입니다.
무작위 행동을 하면서 특정 보상에 도달한 행동에 대해서는 적절한 보상을 해주고 보상에 따라 Q Value
를 업데이트 해주면서 결국 정답에 가까운 행동을 할 수 있도록 자연스럽게 유도하는 학습 방법입니다.
여기서는 Q-Learning 방법을 이용하여 미로 찾기를 하는 강화 학습 코드를 살펴보도록 하겠습니다.
위 그림과 같은 미로가 있으며, 가장 마지막 노드인 s14
에 도착하면 보상을 주도록 했습니다.
#include <stdio.h> #include <stdlib.h> #include <time.h> static const int NODE_COUNT = 15; static const double EPSILON = 0.3f; static const int LEARNING_COUNT = 1000; // 학습 횟수 static const double GAMMA = 0.9f; // 할인율 static const double ALPHA = 0.1; // 학습 계수 int getRandom(int max) { return rand() % (max + 1); } double getRandom() { return (double)rand() / RAND_MAX; } void printQTable(int qtable[NODE_COUNT]) { for (int i = 1; i < NODE_COUNT; i++) { printf("%d\t", qtable[i]); } printf("\n"); } void initQTable(int qtable[NODE_COUNT]) { for (int i = 0; i < NODE_COUNT; i++) { qtable[i] = getRandom(100); } printQTable(qtable); } int getNextNode(int pos, int qtable[NODE_COUNT]) { int left = 2 * pos + 1; int right = 2 * (pos + 1); int nextNode; if (getRandom() < EPSILON) { if (getRandom(1) == 0) { nextNode = left; } else { nextNode = right; } } else { if (qtable[left] > qtable[right]) { nextNode = left; } else { nextNode = right; } } return nextNode; } int updateQTable(int pos, int qtable[NODE_COUNT]) { int left = 2 * pos + 1; int right = 2 * (pos + 1); int qvalue = 0; int qmax; if (pos > 6) { if (pos == 14) { qvalue = qtable[pos] + ALPHA * (1000 - qtable[pos]); } else { qvalue = qtable[pos]; } } else { if (qtable[left] > qtable[right]) { qmax = qtable[left]; } else { qmax = qtable[right]; } qvalue = qtable[pos] + ALPHA * (GAMMA * qmax - qtable[pos]); } return qvalue; } int main() { srand(time(NULL)); int nodeId; int qtable[NODE_COUNT]; initQTable(qtable); for (int i = 0; i < LEARNING_COUNT; i++) { nodeId = 0; for (int j = 0; j < 3; j++) { nodeId = getNextNode(nodeId, qtable); qtable[nodeId] = updateQTable(nodeId, qtable); } printQTable(qtable); } return 0; }
귀납적 학습(Inductive Learning)은 구체적인 데이터 값들을 기반으로 특정 규칙이나 지식을 학습하는 것을 말합니다.
간단한 예제를 살펴보도록 하겠습니다. 다음과 같은 데이터가 있다고 가정합시다.
A | B | C | D | E | F | G | H | I | J | Value |
---|---|---|---|---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 |
0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 |
0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 |
1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 1 |
1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
A부터 J까지의 값의 패턴에 따라 Value
값이 결정이 된다고 할 때, 과거 기록들을 학습하면 향후 A부터 J까지의 값이 주어지면 Value
값을 추측할 수 있습니다.
다음 코드는 Value
값을 예측할 수 있는 A부터 J까지의 값들의 패턴을 추출하는 예제입니다.
#include <stdio.h> #include <stdlib.h> #include <time.h> static const int DATA_COUNT = 30; static const int COMPANY_COUNT = 10; // File에서 데이터를 읽어들임 void loadData(int data[DATA_COUNT][COMPANY_COUNT], int value[DATA_COUNT]) { freopen("data.txt", "r", stdin); setbuf(stdout, NULL); for (int i = 0; i < DATA_COUNT; i++) { for (int j = 0; j < COMPANY_COUNT; j++) { scanf("%d", &data[i][j]); } scanf("%d", &value[i]); } } // 초기 AnswerSheet는 랜덤값으로 설정 void createRandomAnswerSheet(int answer[COMPANY_COUNT]) { for (int i = 0; i < COMPANY_COUNT; i++) { answer[i] = (rand() % 3); } } // 점수 계산 int getScore(int data[DATA_COUNT][COMPANY_COUNT], int value[DATA_COUNT], int answer[COMPANY_COUNT]) { int score = 0; for (int i = 0; i < DATA_COUNT; i++) { int point = 0; for (int j = 0; j < COMPANY_COUNT; j++) { if (answer[j] == 2) { point++; } else if (answer[j] == data[i][j]) { point++; } if ((point == COMPANY_COUNT) && (value[i] == 1)) { score++; } else if ((point != COMPANY_COUNT) && (value[i] == 0)) { score++; } } } return score; } int main() { srand(time(NULL)); int score; int data[DATA_COUNT][COMPANY_COUNT]; int value[DATA_COUNT]; int answer[COMPANY_COUNT]; int bestScore = 0; int bestAnswer[COMPANY_COUNT]; loadData(data, value); for (int i = 0; i < 100000; i++) { createRandomAnswerSheet(answer); score = getScore(data, value, answer); if (score > bestScore) { for (int j = 0; j < COMPANY_COUNT; j++) { bestAnswer[j] = answer[j]; } bestScore = score; for (int j = 0; j < COMPANY_COUNT; j++) { printf("%1d ", bestAnswer[j]); } printf(" --> score: %d\n", bestScore); } } printf("\n\n"); for (int j = 0; j < COMPANY_COUNT; j++) { printf("%1d ", bestAnswer[j]); } printf(" --> score: %d\n", bestScore); return 0; } </pre> 코드를 간략하게 설명하면, 1. 무작위로 랜덤 패턴을 생성(createRandomAnswerSheet) 이 때 패턴은 숫자 0, 1, 2를 사용(2는 와일드 카드) 2. 생성된 랜덤 패턴과 과거 데이터 기록과 유사성 비교 유사성이 있으면 score + 1 3. 가장 높은 score를 획득한 AnswerSheet 추출 과 같습니다. 과거 데이터 기록의 패턴은 0 또는 1의 값을 가지지만 항상 일정한 규칙을 갖고 있는 것은 아니기 때문에 와일드카드(Wildcard)인 2라는 값을 사용합니다. 랜덤 패턴과 과거 데이터 기록 유사성은 A부터 J까지 각 값들을 비교해서 유사성이 있으면 `point` 변수를 1 씩 증가시킵니다. 그리고 해당 패턴과 일치하면서 `Value` 값이 `1`이 되거나, 해당 패턴과 일치하지 않으면서 `Value` 값이 `0`이 되는 경우에 `score` 값을 1 증가시켜줍니다.
디렉토리 | 설명 |
---|---|
/bin | 리눅스의 기본 유틸리티들이 위치함 |
/sbin | 리눅스의 시스템 유틸리티들이 위치함 |
/dev | 시스템에 연결되어 있는 디바이스 파일들이 위치하는 디렉토리 |
/lib | 공유 라이브러리(Shared Library)들이 위치함 |
/boot | 시스템 부팅과 관련된 파일들(ex. 리눅스 커널 이미지 등) |
/home | 일반 사용자의 홈 디렉토리 |
/root | 슈퍼 유저(root)를 위한 디렉토리. 일반 사용자들은 접근 못 함 |
/etc | 시스템 설정과 관련된 파일들이 위치함 |
/proc | 프로세스와 커널의 상태를 제공하는 가상 파일 시스템 |
/usr | 서드 파티 유틸리티나 프로그래밍과 관련된 파일들이 위치함 |
/usr/include | 프로그래밍과 관련된 헤더 파일이 위치함 |
/usr/lib | 프로그래밍과 관련된 정적/공유 라이브러리들이 위치함 |
/usr/bin, /usr/sbin | 서드 파티나 확장 유틸리티를 위한 디렉토리 |
/usr/local | 시스템 관리자가 시스템을 위해 설치하는 유틸리티나 헤더 파일, 라이브러리 등이 위치함 |
/usr/share | 시스템에서 사용하는 공유 파일들을 위한 디렉토리 |
/var | 가변적으로 변하는 log나 메일 등의 파일이 위치함 |
/mnt | 시스템에 마운트되는 장치들을 위한 디렉토리 |
/opt | 기본적으로 설치된 프로그램들을 제외한 나머지 프로그램들 및 애드온 패키지를 위한 디렉토리 |
/selinux | SELinux(Security Enhanced) 파일 시스템으로 보다 향상된 보안을 위한 파일 시스템이 존재 |