'scribbling' 카테고리의 다른 글
gradle 과 java 10 이슈 (0) | 2018.06.08 |
---|---|
롤아웃(roll-out) 의미 (0) | 2018.06.04 |
우분투 개발 코드 이름 유래 (0) | 2018.05.31 |
네이버링(Neighbouring) (0) | 2018.05.25 |
[소식] Google cloud에서 Confluent사와 도움으로 kafka를 지원한다. (0) | 2018.05.23 |
gradle 과 java 10 이슈 (0) | 2018.06.08 |
---|---|
롤아웃(roll-out) 의미 (0) | 2018.06.04 |
우분투 개발 코드 이름 유래 (0) | 2018.05.31 |
네이버링(Neighbouring) (0) | 2018.05.25 |
[소식] Google cloud에서 Confluent사와 도움으로 kafka를 지원한다. (0) | 2018.05.23 |
특정 mesos 에만 동작하도록 하는 방법이다.
$ sudo vi /etc/default/mesos-slave
export MESOS_ATTRIBUTES="ip:11.11.11.11;os:Ubuntu;os-version:16;server-type:user;service:google-api"
$ sudo vi /etc/default/mesos-slave
$ sudo service mesos-slave stop
MESOS_ATTRIBUTES를 수정할 때마다 MESOS_WORK_DIR의 모든 메타 파일을 삭제해야 합니다
$ sudo rm -rf $MESOS_WORK_DIR/*
$ sudo service mesos-slave start
확인하는 방법.
curl 'http://슬레이브_ip:5051/slave(1)/state' | jq
...
"attributes": {
"ip": "10.61.106.159",
"os": "Ubuntu",
"os-version": 16,
"server-type": "user",
"service": "google-api"
},
"master_hostname": "11.11.11.11",
"log_dir": "/var/log/mesos",
"flags": {
"appc_simple_discovery_uri_prefix": "http://",
"appc_store_dir": "/tmp/mesos/store/appc",
"attributes": "ip:11.11.11.11;os:Ubuntu;os-version:16;server-type:user;service:google-api",
...
마라톤 앱에 다음 constraints를 추가한다.
"constraints": [
[
"service",
"CLUSTER",
"google-api"
]
],
kubernetes로 가면 저 labeling을 환경 설정(env)로 쉽게 진행할 수 있다. mesos 약간 불편한 점이 있다.
[marathon] 80포트 막고 443 포트만 열기 (0) | 2018.06.12 |
---|---|
[marathon] 80 -> 443 포트 리다이렉트(redirect) (0) | 2018.06.08 |
마라톤(marathon) 앱 포트 지정 (0) | 2018.06.01 |
[marathon] marathon의 상태, waiting, staging 해결하기 (0) | 2018.05.31 |
mesos 설정과 재시작 이슈 관련 (0) | 2018.04.13 |
ubunt 16.04에서 docker 재설치 가이드이다.
기존 환경은 docker 1.11인데, 최신인 docker ce(18.03.1-ce)을 설치한다.
https://docs.docker.com/install/linux/docker-ce/ubuntu/#set-up-the-repository
root 사용자로 진행한다.
$ apt-get remove docker docker-engine docker.io
$ rm /etc/systemd/system/docker.service.d/docker.conf
$ setproxy apt-get update
$ apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
PROXY를 셋팅한다.
$ export ..
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
OK
$ apt-key fingerprint 0EBFCD88
pub 4096R/0EBFCD88 2017-02-22
Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb) <docker@docker.com>
sub 4096R/F273FCD8 2017-02-22
$ sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
$ apt-get update
$ apt-get install docker-ce
$ docker version
Client:
Version: 18.03.1-ce
API version: 1.37
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:17:20 2018
OS/Arch: linux/amd64
Experimental: false
Orchestrator: swarm
Server:
Engine:
Version: 18.03.1-ce
API version: 1.37 (minimum version 1.12)
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:15:30 2018
OS/Arch: linux/amd64
Experimental: false
$ service docker start
만약 proxy 이슈라면 다음을 실행한다.
$ setproxy apt-get update
$ setproxy apt-get install docker-ce
$ service docker start
$ docker version
Client:
Version: 18.03.1-ce
API version: 1.37
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:17:20 2018
OS/Arch: linux/amd64
Experimental: false
Orchestrator: swarm
Server:
Engine:
Version: 18.03.1-ce
API version: 1.37 (minimum version 1.12)
Go version: go1.9.5
Git commit: 9ee9f40
Built: Thu Apr 26 07:15:30 2018
OS/Arch: linux/amd64
Experimental: false
참고
https://docs.docker.com/install/linux/docker-ce/ubuntu/#install-docker-ce-1
[docker] docker 컨테이너 로그 확인하기 (0) | 2018.06.19 |
---|---|
docker 17.07부터 바뀐 proxy 설정 (0) | 2018.06.15 |
[docker] mac docker에서 k8s를 사용할 수 있다고 한다.. - 펌질 (0) | 2018.01.25 |
[docker] ipv6 지원 (0) | 2017.11.24 |
[docker] python flask 앱 실행하기, 간단실행 vs gunicorn (0) | 2017.11.08 |
marathon 앱의 포트를 지정할 때.
servicePort는 앱에서 외부로 노출될 서비스 port를 의미한다.
servicePort: When you create a new application in Marathon (either through the REST API or the front end), you may assign one or more service ports to it. You can specify all valid port numbers as service ports or you can use 0 to indicate that Marathon should allocate free service ports to the app automatically
containerPort는 컨테이너에서 앱이 실행중인 포트를 지정한다.즉 load balancer와 앱 간에 연결되고 있는 port를 의미한다. 이 포트로 health check가 일어난다.
containerPort: A container port specifies a port within a container. This is only necessary as part of a port mapping when using BRIDGE
or USER
mode networking with a Docker container.
아래 예를 보면, 외부에서 8080포트로 접근할 수 있고, LB와 마라톤 앱간에는 18080으로 통신한다라는 뜻이다.
"container": {
"type": "DOCKER",
"volumes": [],
"docker": {
"image": "imageurl",
"network": "BRIDGE",
"portMappings": [
{
"containerPort": 8080,
"hostPort": 0,
"servicePort": 18080,
"protocol": "tcp",
"name": "8080",
"labels": {}
}
],
"privileged": false,
"parameters": [],
"forcePullImage": true
}
},
[marathon] 80 -> 443 포트 리다이렉트(redirect) (0) | 2018.06.08 |
---|---|
특정 mesos 에만 동작하도록 하는 방법 (0) | 2018.06.01 |
[marathon] marathon의 상태, waiting, staging 해결하기 (0) | 2018.05.31 |
mesos 설정과 재시작 이슈 관련 (0) | 2018.04.13 |
[marathon] 마라톤 lb의 포트별 설정 (0) | 2018.04.10 |
spark-shell을 이용해 "랜덤 포레스트를 이용한 MNIST 데이터셋 분류" 예를 공부한다.
이 섹션에서는 랜덤 포레스트를 사용한 분류 예를 소개할 것이다. 코드를 단계별로 분석 해결책을 쉽게 이해할 수 있다.
1단계. LIVSVM 포맷으로 MNIST 데이터셋을 로드하고 파싱한다.
import org.apache.spark.mllib.util.MLUtils
// LIBSVM 포맷의 트레이닝 데이터를 로드한다.
val data = MLUtils.loadLibSVMFile(spark.sparkContext, "data/mnist.bz2")
2단계. 트레이닝과 테스트 셋을 준비한다.
데이터를 트레이닝 셋(75%)과 테스트 셋(25%)으로 나누고 재현하기 위해 다음처럼 시드를 설정한다.
val splits = data.randomSplit(Array(0.75, 0.25), seed = 12345L)
val training = splits(0).cache()
val test = splits(1)
모델을 구축하기 위해 트레이닝 알고리즘을 실행한다.
빈 categoricalFeaturesInfo를 사용해 랜덤 포레스트 모델을 트레이닝시킨다. 모든 피쳐가 데이터셋에서 연속적이기 때문에 관련 작업이 필요하다.
import org.apache.spark.mllib.tree.RandomForest
val numClasses = 10 //MNIST 데이터 셋의 클래스의 개수
val categoricalFeaturesInfo = Map[Int, Int]()
val numTrees = 50 // 실제 상황에서는 더 큰 수를 사용한다. 값이 더 클수록 좋다.
val featureSubsetStrategy = "auto" // 알고리즘을 선택한다.
val impurity = "gini" // 이전에 설명한 랜덤 포레스트를 설명한 노트를 살펴보라.
val maxDepth = 30 // 실제 상황에서는 값이 더 클수록 좋다.
val maxBins = 32 // 실제 상황에서는 값이 더 클수록 좋다.
val model = RandomForest.trainClassifier(training, numClasses, categoricalFeaturesInfo, numTrees, featureSubsetStrategy, impurity, maxDepth, maxBins)
랜덤 포레스트 모델을 트레이닝하는 것은 매우 자원이 소비되는 작업이다. 따라서 더 많은 메모리가 필요하므로 OOM이 발생되지 않도록 주의해야 한다.
이전에 언급한 성능 메트릭을 사용해 다음처럼 모델을 평가할 수 있도록 테스트 셋의 원 점수를 계산한다.
val scoreAndLabels = test.map { point =>
val score = model.predict(point.features)
(score, point.label)
}
평가를 위해 다중 클래스에 대한 메트릭을 초기화한다.
import org.apache.spark.mllib.evaluation.MulticlassMetrics
val metrics = new MulticlassMetrics(scoreAndLabels)
혼동 행렬을 생성한다.
println(metrics.confusionMatrix)
1498.0 0.0 3.0 2.0 0.0 2.0 4.0 0.0 12.0 0.0
0.0 1736.0 8.0 1.0 2.0 1.0 2.0 4.0 0.0 2.0
7.0 0.0 1424.0 2.0 3.0 1.0 5.0 12.0 10.0 4.0
0.0 3.0 20.0 1507.0 0.0 19.0 2.0 13.0 19.0 9.0
3.0 0.0 5.0 0.0 1416.0 0.0 2.0 4.0 4.0 29.0
10.0 2.0 1.0 21.0 4.0 1272.0 14.0 3.0 13.0 1.0
6.0 2.0 0.0 0.0 1.0 9.0 1456.0 0.0 4.0 0.0
2.0 1.0 6.0 0.0 9.0 1.0 0.0 1578.0 8.0 18.0
2.0 6.0 7.0 9.0 5.0 10.0 5.0 2.0 1398.0 10.0
7.0 3.0 0.0 22.0 16.0 4.0 1.0 15.0 13.0 1404.0
이전 코드는 분류를 위해 다음과 같은 혼동 행렬을 출력한다.
이제 모델의 성능을 판단하기 위해 전체 통계를 계산하자.
정확도, 정밀도, 회수율, 참 긍정 비율, 거짓 긍정 비율, F1 점수와 같은 성능 메트릭을 포함하는 다음 출력을 생성한다.
val accuracy = metrics.accuracy
println("Summary Statistics")
println(s"Accuracy = $accuracy")
// 레이블 당 정확도
val labels = metrics.labels
labels.foreach { l =>
println(s"Precision($l) = " + metrics.precision(l))
}
// 레이블 당 회수율
labels.foreach { l =>
println(s"Recall($l) = " + metrics.recall(l))
}
// 레이블 당 거짓 긍정 비율
labels.foreach { l =>
println(s"FPR($l) = " + metrics.falsePositiveRate(l))
}
// 레이블 당 F-측정 값
labels.foreach { l =>
println(s"F1-Score($l) = " + metrics.fMeasure(l))
}
실제 실행 결과는 다음과 같다.
scala> val accuracy = metrics.accuracy
accuracy: Double = 0.967591067782096
scala> println("Summary Statistics")
Summary Statistics
scala> println(s"Accuracy = $accuracy")
Accuracy = 0.967591067782096
scala> // 레이블 당 정확도
scala> val labels = metrics.labels
labels: Array[Double] = Array(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)
scala> labels.foreach { l =>
| println(s"Precision($l) = " + metrics.precision(l))
| }
Precision(0.0) = 0.9758957654723127
Precision(1.0) = 0.9903023388476897
Precision(2.0) = 0.966078697421981
Precision(3.0) = 0.9635549872122762
Precision(4.0) = 0.9725274725274725
Precision(5.0) = 0.9643669446550417
Precision(6.0) = 0.9765258215962441
Precision(7.0) = 0.967504598405886
Precision(8.0) = 0.9439567859554355
Precision(9.0) = 0.950575490859851
scala> // 레이블 당 회수율
scala> labels.foreach { l =>
| println(s"Recall($l) = " + metrics.recall(l))
| }
Recall(0.0) = 0.9848783694937541
Recall(1.0) = 0.9886104783599089
Recall(2.0) = 0.9700272479564033
Recall(3.0) = 0.946608040201005
Recall(4.0) = 0.9678742310321258
Recall(5.0) = 0.9485458612975392
Recall(6.0) = 0.9851150202976996
Recall(7.0) = 0.9722735674676525
Recall(8.0) = 0.9614855570839065
Recall(9.0) = 0.9454545454545454
scala> // 레이블 당 거짓 긍정 비율
scala> labels.foreach { l =>
| println(s"FPR($l) = " + metrics.falsePositiveRate(l))
| }
FPR(0.0) = 0.0027086383601756954
FPR(1.0) = 0.001266294227188082
FPR(2.0) = 0.003646175162254795
FPR(3.0) = 0.004194569136801825
FPR(4.0) = 0.0029158769499927103
FPR(5.0) = 0.0033959537572254336
FPR(6.0) = 0.0025541852149164415
FPR(7.0) = 0.003909131140286178
FPR(8.0) = 0.006046477744590952
FPR(9.0) = 0.005330023364485981
scala> // 레이블 당 F-측정 값
scala> labels.foreach { l =>
| println(s"F1-Score($l) = " + metrics.fMeasure(l))
| }
F1-Score(0.0) = 0.9803664921465969
F1-Score(1.0) = 0.9894556853804503
F1-Score(2.0) = 0.9680489462950375
F1-Score(3.0) = 0.9550063371356146
F1-Score(4.0) = 0.9701952723535457
F1-Score(5.0) = 0.956390977443609
F1-Score(6.0) = 0.9808016167059616
F1-Score(7.0) = 0.9698832206515058
F1-Score(8.0) = 0.952640545144804
F1-Score(9.0) = 0.9480081026333558
scala>
이제 전체 통계를 다음처럼 계산하자.
println(s"Weighted precision: ${metrics.weightedPrecision}")
println(s"Weighted recall: ${metrics.weightedRecall}")
println(s"Weighted F1 score: ${metrics.weightedFMeasure}")
println(s"Weighted false positive rate: ${metrics.weightedFalsePositiveRate}")
val testErr = scoreAndLabels.filter(r => r._1 != r._2).count.toDouble / test.count()
println("Accuracy = " + (1-testErr) * 100 + " %")
이전 코드는 가중치 정밀도, 회수율, F1 점수, 거짓 긍정 비율을 포함하는 다음 출력을 출력한다.
Overall statistics
----------------------------
Weighted precision: 0.9676041167963592
Weighted recall: 0.9675910677820959
Weighted F1 score: 0.9675700010426889
Weighted false positive rate: 0.03240893221790396
Accuracy = 96.7591067782096 %
전체 통계에 따르면 모형의 정확도는 96%이상 로지스틱 회귀 분석보다 우수하다.
그러나 모델을 잘 튜닝하면 더욱 개선될 수 있다.
[spark] - spark streaming의 누산기 예시 (0) | 2018.10.25 |
---|---|
[spark] 기본 파티션 개수 (0) | 2018.10.12 |
[spark] 로지스틱 회귀 분석을 이용한 멀티 클래스 분류 (0) | 2018.05.31 |
[spark] spark-shell 메모리/cpu 설정 (0) | 2018.05.31 |
[spark] 스파크 머신 러닝(ML) api을 사용하여 파이프 라인 개발하기 - 유방암 가능성 예측 (0) | 2018.05.31 |