반응형
XGBoost

XGBoost

eXtreme Gradient Boosting

  • 병렬 처리로 학습, 분류 속도가 빠르다.
  • 다양한 옵션. Customizing 용이
  • Greedy 알고리즘을 사용한 자동 가지치기로 오버피팅 방지가 된다.
  • 다른 알고리즘과 연계에도 성능이 좋다. 뒷단에 다른 레이어 추가.

XGBoost는 딥러닝이 아니다. 여러가지 조건문들이 들어가는 가지치기로 보면 된다. Decision Tree라고 하고 이것들이 다 모이면 최종적으로 forest라고 한다
데이터에 따라 딥러닝보다 성능이 좋은 경우가 많다.

XGBoost는 CART(Classification and regression tree) 앙상블 모델을 사용한다. 모델끼리의 우의 비교를 통해 최종 결정을 내림.

파라미터

  • 일반 파라미터 ; 어떤 모델을 쓸 것인가?
    • gbtree, gblinear, dart
    • nthread ; 쓰레드 수. 디폴트는 max
    • num_feature ; 입력 차원. 디폴트는 max
  • 부스터 파라미터 ; 트리마다 가지치기 옵션
    • eta ; learning rate. 트리에 가지가 많을수록 과적합 발생.
    • gamma ; 정보획득에서 -r. 값이 클수록 트리 depth가 줄어든다. 디폴트는 0
    • max_depth ; 한 트리의 최대 깊이. 클수록 복잡도가 커짐. 즉, 과적합. 디폴트는 6으로 리프노드의 최대개수는 64가 된다.
    • lambda ; L2 Regularization. 클수록 보수적.
    • alpha ; L1 Regularization
  • 학습 과정 파라미터 ; 최적화
    • objective ; 목적함수. reg:linear, binary:logistic, count:poisson 등
    • num_rounds : 라운드 epoch 같은 개념. 너무 커도 좋지 않다.

파라미터를 알아야 모델을 구축할 수 있다.
binary classification 문제에 linear-regression을 적용하면 아무리해도 답이 안나온다.

  • 민감한 정도로 먼저 조정해야 될 것들
    • booster 모양
    • eval_metric(평가함수)/ objective(목적함수)
    • eta (epoch)
    • L1
    • L2

Sample1. XGBClassifier

from numpy import loadtxt
from xgboost import XGBClassifier
from xgboost import plot_importance
from matplotlib import pyplot

dataset = loadtxt('pima-indians-diabetes.csv', delimiter=',')
x=dataset[:,0:8]
y=dataset[:,8]

# fit model no training data
model = XGBClassifier()
model.fit(x,y)

plot_importance(model)
pyplot.show()
  • fitting후 plot_importance로 어떤 피쳐들의 중요도를 높게 보고있는지 막대그래프로 확인할 수 있다.
  • 중요도가 크게 떨어지는 피쳐들은 삭제하는 것이 성능에 좋은 영향을 주는 경우가 많다.

Sample2. XGBRegressor

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import Imputer

# 데이터를 읽고, null 레코드 삭제
data = pd.read_csv('../input/train.csv')
data.dropna(axis=0, subset=['SalePrice'], inplace=True)
# 출력값은 집값
y = data.SalePrice
# 훈련데이터에서 집값제거하고 수치가 아닌 데이터 삭제.
X = data.drop(['SalePrice'], axis=1).select_dtypes(exclude=['object'])
# 데이터 분리. train, validation data. 
train_X, test_X, train_y, test_y = train_test_split(X.as_matrix(), y.as_matrix(), test_size=0.25)

# 데이터 전처리
my_imputer = Imputer()
train_X = my_imputer.fit_transform(train_X)
test_X = my_imputer.transform(test_X)

  • sklearn의 preprocessing에 Imputer로 데이터를 전처리 하였다.
  • Imputer?
    • 누락 NA 데이터에 대한 전처리가 가능하다.
    • 데이터 파일에서 ‘na’ 스트링을 na로 인식하여 로딩하여도록 하려면 pd.read_csv(‘test.csv’, na_values=‘na’)
  • SimpleImputrer
    -누락된 데이터의 값을 특정 값으로 지정하거나 통계값으로 설정할 수 있다.
    • imp = SimpleImputer(missing_values=np.nan, strategy=‘mean’)
    • imp.fit( data ) ; fitting하여 통계 정보를 구한다.
    • X = imp.transform( data ) ; 위 통계 정보를 사용하여 np.nan값을 컬럼마다 평균값으로 채움.
    • missing_values=-1 로 하면 -1값을 누락값으로 인식.
    • strategy의 종류 ; mean, most_frequent (최고빈도로 스트링 컬럼(category)도 처리가 됨.)
  • Imputer
    • Imputer(missing_vaues=‘NaN’, strategy=‘mean’ , axis=0, verbose=0, copy=True) ; 기본값 확인. (여기는 특이하게 axis=0이 컬럼방향이다.)
from xgboost import XGBRegressor

my_model = XGBRegressor()
# Add silent=True to avoid printing out updates with each cycle
my_model.fit(train_X, train_y, verbose=False)

# make predictions
predictions = my_model.predict(test_X)

from sklearn.metrics import mean_absolute_error
print("Mean Absolute Error : " + str(mean_absolute_error(predictions, test_y)))
  • 학습은 위와 같이 매우 간단하다.

모델 튜닝

  • 성능을 올리기 위한 필수 과정.
  • n_estimators ; 학습 횟수
  • early_stopping_rounds ; n연속으로 발전(기존 max 갱신)이 없으면 강제 중지
my_model = XGBRegressor(n_estimators=1000)
my_model.fit(train_X, train_y, early_stopping_rounds=5, 
             eval_set=[(test_X, test_y)], verbose=False)
  • learning_rate ; 학습률
my_model = XGBRegressor(n_estimators=1000, learning_rate=0.05)
my_model.fit(train_X, train_y, early_stopping_rounds=5, 
             eval_set=[(test_X, test_y)], verbose=False)
  • n_jobs ; 병렬처리로 보통 cpu core 수로 정하는 것이 좋다.

Author: crazyj7@gmail.com

'AI(DeepLearning)' 카테고리의 다른 글

[ChatGPT] 글쓰기  (0) 2023.02.09
[ChatGPT] 글쓰기 테스트  (1) 2023.02.09
처음해본 kaggle 도전기  (1) 2019.11.27
Custom EarlyStopping  (0) 2019.11.11
타이타닉 kaggle 자료 분석  (0) 2019.08.23
반응형
solidity03_data_var

Solidity 03. Variables/Datatypes

변수를 어떻게 사용하는가?

  • 멤버 변수들은 Storage 변수. 상태 변수이다.
  • 파라미터들은 Memory 변수. 함수 리턴시 날라간다.
  • 파라미터에 Storage를 지정하면? 참조가 된다?

integer와 string을 get/set 하는 예제

pragma solidity >=0.4.0 <0.6.0;

contract SimpleStorage {
    uint storedData;
    string storedNm;

    function set(uint x) public {
        storedData = x;
    }

    function setNm(string memory x) public {
        storedNm = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }

    function getNm() public view returns (string memory ) {
        return storedNm;
    }
}
  • 기본 자료형이 아닌 것은 저장소를 명시해 주어야 한다. string을 사용하는 부분에 memory 타입으로 명시함.

datatype

  • 기본형
    uint/int ; uint, int는 뒤에 256이 생략되어 있다. (u는 unsigned 의미)
    uint8~uint256 ; 여기서 숫자는 비트수를 의미. 1바이트부터 32바이트까지 있다.
    bool : true or false
    byte : uint8과 같다고 생각하면 된다.
    address : 20바이트 주소값
    address payable : address타입인데 멤버함수가 있다. transfer, send.
    address payable x = address(uint160(to));

enum State { Created, Locked, Inactive } ;
산술/비교/비트/논리 연산자는 C 와 같음. enum도 같다.

  • 참조형
    배열 : [] array
    구조체: struct
0xffff ; int16(-1)
0x42 ; bytes1(0x42)
0x0003 ; uint16(0x03)
0x48656c6c6f2c20776f726c6421 ; string("Hello, world!") (without null)

address의 멤버

  • balance ; 계정 주소에 있는 이더를 wei로 반환
  • transfer(uint amount) ; 계정 주소(받는 사람 주소)에 있는 amount 금액을 송금. to.transfer(_amount)
  • send(uint amount) returns (bool) ; 상동. 실패시 false 리턴. to_send(_amount)
  • call(…) returns (bool) : 상동, 실패시 false 리턴. 가스량 조절 가능. to.call.value(_amount).gas(1000000)() . 리턴값을 확인하여 false이면 revert()로 롤백한다.
  • delegatecall(…) returns (bool) : 다른 계약의 함수를 호출.
address x=0x123 ;
address myAddress = this ;
if (x.balance<10 && myAddress.balance>=10) x.transfer(10) ;
  • send : low-level의 transfer임. (실패시 롤백없음). 리턴값(true/false)을 반드시 확인.

고정크기 바이트 배열

bytes1/bytes2/bytes3/… bytes32 : bytes뒤에 숫자를 붙인다. 바이트수를 의미.
byte : bytes1과 같다.
멤버
length : 고정된 길이를 반환. 읽기 전용.
bytes32는 32바이트까지만 담을 수 있다.
ex)
bytes2 b = “bac”

동적 크기 바이트 배열

bytes : 임의 길이의 원시데이터.
string : UTF-8 인코딩 문자열. 임의의 길이. 거의 무제한.(2^256 * 256 비트)

  • 멤버로 length, push()가 있다.
  • 작은 따옴표나 큰 따옴표 상관없다.
    ex) bytes memory a = ‘aaaaaaaaaa’;
    a.length ;
    a.push(‘c’) ;
    a.push(“C”) ;
    a.push(“AB”) ; // error. byte[]라서 byte 하나만 push 가능.

문자열 리터럴

작은 따옴표, 큰 따옴표 둘 다 가능.
C랑 다르게 null terminated가 아니다. 보이는 문자 개수만큼만 메모리를 차지함.
\n, \xNN (16진수), \uNNNN (유니코드) 도 지원.

16진수 리터럴

hex"001122FF"
앞에 hex를 지정.

이중배열

uint [][5] : 주의할 점은 행과 열이 다른 언어와 반대임.
이것을 C로 보면 uint [5][] 이 된다.

  • 웃긴건 접근할 때는 C처럼 행, 열 순으로 접근한다.
  • 선언할 때랑 사용할 때랑 다르다니 문화충격이다.
uint[3][2] dArray ;
// row index는 0,1까지 가능. column index는 0,1,2까지 가능.
// C나 java로 치면 uint dArray[2][3] 으로 생각해야 함.
dArray[1][2] = 100 ;  // last element.

dArray[2][2] = 100 ; // error. 
dArray[0][3] = 100 ; // error. 
function f(uint len) public pure {
	uint[] memory a = new uint[](7) ;
	bytes memory b = new bytes(len) ;
	// a.length==7, b.length=len
	a[6]=8 ;
}
function f() public pure {
	g([uint(1), 2, 3]) ;
}
function g(uint[3] _data) pubilc pure {
}

[1,2,3] 은 uint8[3] memory 타입이다. array에 첫 번째 요소에 타입을 명시해 줄 수 있다.

  • 고정 크기 배열을 동적크기 배열에 할당할 수 없다.!
uint8[] memory x = [uint8(1),2,3] ;	// 에러
uint8[3] memory x = [uint8(1),2,3] ;	// 가능.

uint[] dArray ;
dArray.push(2) ;
dArray.push(3) ;
  • 삭제는 delete로 배열을 삭제한다.
  • 일반 변수에 delete를 하면 초기값(0)으로 할당된다.

자료구조

struct 지원

struct Voter {
uint w ;
bool v ;
address dele ;
uint vote ;
}

Enum Types

enum State { Created, Locked, Inactive }

Type Conversion

  • uint를 스트링으로 변환. 하나씩 바이트 단위로 ascii char로 변환한다.
function uintToString(uint v) constant returns (string str) {
        uint maxlength = 100;
        bytes memory reversed = new bytes(maxlength);
        uint i = 0;
        while (v != 0) {
            uint remainder = v % 10;
            v = v / 10;
            reversed[i++] = byte(48 + remainder);
        }
        bytes memory s = new bytes(i + 1);
        for (uint j = 0; j <= i; j++) {
            s[j] = reversed[i - j];
        }
        str = string(s);
}

function uint2str(uint i) internal pure returns (string)
{ 
	if (i == 0) return "0"; 
	uint j = i; 
	uint length; 
	while (j != 0){ length++; j /= 10; } 
	bytes memory bstr = new bytes(length); 
	uint k = length - 1; 
	while (i != 0){ bstr[k--] = byte(48 + i % 10); 
	i /= 10; 
	} 
	return string(bstr); 
}
  • 타입 캐스팅은 타입을 함수처럼 사용하여 파라미터로 받는다.
  • 32비트를 16비트로 타입 캐스팅시 하위 바이트(낮은 자리 값)만 가져온다.
  • 예를 들면. uint32 a= 0x12345678 ; 이것을 uint16 b = uint16(a) ; 이렇게 하면 하위 바이트인 0x5678을 가져온다.

Mapping

contract Mappings {
 struct User {
   string name ;
   string email ;
 }
 mapping(address => User) users ;
 function addUser(string memory _name, string memory _email) public {
   users[msg.sender].name = _name ;
   users[msg.sender].email = _email ;
 }
 function getUser() public returns (string memory, string memory) {
   return (users[msg.sender].name, users[msg.sender].email) ;
 }
}

이더리움 단위

wei ; 가장 작은 단위
1000 배씩 올라간다.
kwei, mwei, gwei, micro, milli, ether
kether, mether, gether, tether
위 단위를 코드에 그대로 사용한다.
즉, 1 이더는 10**18 wei

시간 단위

second, minute, hour, day, week, year

블록 및 거래 속성

  • block.blockhash(uint blockNumber) returns (bytes32) : 지정한 블록의 해시값을 리턴. (최근 256개 블록만 사용 가능)
  • block.coinbase ; address 채굴자 계정 주소
  • block.difficulty ; uint 현재 블록 난이도
  • block.gaslimit ; uint 현재 블록의 가스 제한량
  • block.number ; uint 현재 블록 번호
  • block.timestamp ; uint 현재 블록의 타임스탬프
  • msg.data ; bytes 호출 데이터
  • msg.gas ; 남은 가스양
  • msg.sender ; address 메시지를 보낸사람
  • msg.sig ; bytes4 calldata의 첫 4바이트로 함수 식별자
  • msg.value ; uint 메시지와 같이 보낸 wei
  • now ; block.timestamp와 같다. (현재 시간을 의미하는 값은 아니다. 현재시간과 대략 비슷)
  • tx.gasprice ; uint 거래의 가스가격
  • tx.origin ; 거래 발신자 주소. (sender.address와 같을 수도 다를 수도 있다.)
  • this ; 현재 계약
  • selfdestruct(address) ; 현재 계약을 파기해 지정한 주소로 금액을 보냄
  • suicide(address) ; 상동

예외 처리

  • assert(bool condition) ; 조건이 실패하면 에러를 발생시킨다. (보통 내부에러)
  • require(bool condition) ; 위와 같다. 입력값 체크시 사용. (보통 외부에러)
  • revert() ; 에러가 발생하면 롤백을 시킨다.

기타 연산

  • addmod(uint x, uint y, uint k) returns (uint) : (x+y)%k
  • mulmod(uint x, uint y, uint k) returns (uint) : (x*y)%k
  • keccak256( data ) returns (bytes32) : 이더리움 sha3 (KECCAK256) 해시
  • sha256
  • sha3 ; keccak256과 동일
  • ripecmd160(data) returns (bytes20)
  • ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) return (address) : 타원곡선암호서명에서 공개키와 연결된 주소를 리턴

할당

  • 복수 데이터를 할당 할 수 있다. 리턴도 복수개가 가능
    • (x,y) = f() ;
  • swap
    • (x,y) = (y,x) ;
  • 함수 파라미터를 이름대로 지정할 수 있다.
    • f(3, 2) 대신 f({value:2, key:3}) 이렇게 사용. (파라미터 이름)
    • new로 다른 계약을 만들 수 있다.

Author: crazyj7@gmail.com

'BlockChain' 카테고리의 다른 글

Solidity#2 HelloWorld  (0) 2019.12.06
Solidity 0.4 vs 0.5  (0) 2019.12.06
Windows Ethereum python module install error  (0) 2019.12.04
[ether02] 코인만들기  (0) 2019.11.10
[ether01] solidity 맛보기  (0) 2019.11.10
반응형
solidity02_helloworld

Solidity 02

  • solidity 버전 표시
pragma solidity ^0.4.25;    // 정확히 이 버전만 지원
pragma solidity >=0.4.0 <0.6.0;  // 지원 범위

  • 파일 import
import "filename";
import "filename" as symbolName ;
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;

github에 있는 소스도 사용할 수 있다.

  • 주석은 c 형식 사용. /**/ // 등
  • public 함수나 변수는 외부에 노출
  • 반대는 internal로 표시한다. 내부에서만 호출 가능.
  • 파리미터에 memory는 라이프사이클이 함수내.
  • 파리미터에 storage로 주면 참조 형식으로 값이 변할 수 있다.
  • 함수에 view를 주면 storage 변수에 읽기 접근만 가능하다. 이벤트 발생 안된다.
  • 함수에 pure를 주면 storage 변수에 접근이 안된다.
  • view, pure를 귀찮게 왜 쓰나? gas 비용 절감과 보안측면 이다.

구버전

pragma solidity ^0.4.25 ;
contract HelloWorld {
	string public greeting ;
	function HelloWorld(string _g) public {
		greeting = _g ;
	}
	function setGreeting(string _g) public {
		greeting = _g ;
	}
	function say() public constant returns (string) {
		return greeting ;
	}
}

위는 0.4대 버전, 아래는 0.5대 버전이다. 문법이 약간 달라졌다.
- constructor가 클래스명에서 명시적으로 constructor로 변경.
- 파라미터, 리턴 변수앞에 저장소 지정을 명시적으로. (엄격해짐)
- constant가 없어짐. view로 대체.
  • public/internal 의 위치가 타입 뒤에 가는 것이 특징. (cpp, java와 다르다.)
  • 함수 리턴 타입을 지정하는 부분이 마지막에 들어간다.

신버전

pragma solidity >0.5.0;

contract HelloWorld {
	string public greeting ;
	
	constructor(string memory g) public {
		greeting = g;
	}
	
	function setGreeting(string memory g) public {
		greeting = g;
	}
	function say() public view returns (string memory) {
		return greeting ;
	}
}

image

  • deploy시 remix에서 펼쳐서 이름을 입력해줘야 인코딩에러가 안난다.
  • setGreeting시도에 펼쳐서 값을 넣어줘야 작동되었다.

Author: crazyj7@gmail.com

'BlockChain' 카테고리의 다른 글

Solidity#3 변수와 타입  (0) 2019.12.06
Solidity 0.4 vs 0.5  (0) 2019.12.06
Windows Ethereum python module install error  (0) 2019.12.04
[ether02] 코인만들기  (0) 2019.11.10
[ether01] solidity 맛보기  (0) 2019.11.10

+ Recent posts