feature가 가질 수 있는 값의 종류.

 

예를 들어 성별은 남자/여자 둘중의 하나이므로 카디널리티가 2이다.

카테고리의 경우 가구/가전/의류 등 세가지 범주를 갖는다면 카디널리티가 3이다.

방의 개수는 대략 1에서 10사이이므로, 이 경우 카디널리티가 10이다.

고객ID/제품SKU등의 경우 매우 높은 카디널리티를 갖는다.

 

위내용까지는 이해가 쉬운데, 연속형 수치를 갖는 feature의 카디널리티는 판단하기 까다로울 수 있다.

예를 들어 일별수익률, 집의 면적, 제품의 가격등이다.

 

수치형 데이터의 카디널리티 판단:

  • 소수점 2자리에서 끊던지 하는 방법으로 어느정도 양자화하고
  • SQL쿼리에서 COUNT(DISTINCT colume)으로 카니널리티 측정

예를 들어 온도보다는 인구수가 카니널리티가 높을것이다.

 

 

반응형

여기 참조

 

개요

일별수익률등 거의 0이 나타나지 않는 feature를 dense feature라고 한다.

원핫 인코딩을 거친 범주형 데이터처럼 0이 매우 많이 나타나고 드물게 0이 아닌 1등이 나타나는 feature를 sparse feature라고 한다.

(원핫 인코딩 여부가 판가름하는 지표가 되기도 한다)

 

한가지 주의할것은 업데이트 주기로 판단하지는 않는 다는 것이다.

예를 들어 GDP값이라는 feature가 있을때, 값은 1년내 거의 고정이지만 이를 sparse feature라고 하지는 않는다. (값의 대부분이 0이진 않기 때문에)

 

모델

XGBoost: 주로 연속적인 수치형 feature(dense feature)에 강점을 가지며, 트리 기반 모델은 feature의 분할을 통해 비선형 관계를 잘 포착함. sparse feature를 사용할때는 카디널리티(cardinality, 고유값의 수)가 높지 않고 연속성이 어느정도 의미가 있는 경우에 효과적.

 

딥러닝모델: dense feature와 sparse feature모두를 효과적으로 처리. sparse feature는 임베딩을 통해 dense vector로 변환되어 처리함.(특히 NLP등에서 중요)

 

즉, 카디널리티가 높지 않은 경우는 XGBoost도 어느정도 sparse feature를 처리할 수 있지만, 카디널리티가 높은 경우는 딥러닝이 임베딩을 통한 기술이 있어서 더 유리하다고 하는 것.

 

 

반응형

'AI, ML > ML' 카테고리의 다른 글

문자열을 벡터로 바꾸는 방법1 - CountVectorizer  (0) 2024.03.12
cardinality  (1) 2024.01.07
binning  (0) 2023.12.28
디시전트리기반 코드 실습  (0) 2023.10.16
그레디언트 부스팅 (Gradient Boosting)  (0) 2023.10.15

다음 코드를 보자(주석을 주의깊게 볼 것)

package org.example;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers;
public class Main {
	public static void main(String[] args) {
		Flux.just("a", "b", "c", "d")  // 1,2,3,4 네개의 아이템을 순차적으로 방출하는 단일 스트림 생성
			.map(s -> {  // 스레드 분기 없이 호출 스레드에서 해당 스트림 아이템에 대해서 대문자변환 연산수행(아래 .subscribe를 만나기 전까지 지연됨!)
				System.out.println("Map 1 - Thread: " + Thread.currentThread().getName());
				return s.toUpperCase();
			})
			.publishOn(Schedulers.boundedElastic())  //이후 작업은 boundedElastic이라는 사전정의된 별도 스레드에서 하도록 지정함!
			.map(s -> {
				System.out.println("Map 2 - Thread: " + Thread.currentThread().getName());
				return s + "!";
			})
			.subscribe(  // 지연 실행을 시작하는 시점이며, 마지막 스케줄러 지정이 boundedElastic이라 boundedElastic 스레드를 통해 수행됨
				s -> System.out.println("Received " + s + " on Thread: " + Thread.currentThread().getName()));
	}
}

실행결과

> Task :Main.main()
Map 1 - Thread: main
Map 1 - Thread: main
Map 1 - Thread: main
Map 1 - Thread: main
Map 2 - Thread: boundedElastic-1
Received A! on Thread: boundedElastic-1
Map 2 - Thread: boundedElastic-1
Received B! on Thread: boundedElastic-1
Map 2 - Thread: boundedElastic-1
Received C! on Thread: boundedElastic-1
Map 2 - Thread: boundedElastic-1
Received D! on Thread: boundedElastic-1

 

 

예제를 조금 수정한 코드를 보자.

package org.example;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Schedulers;
public class Main {
	public static void main(String[] args) {
		Flux.just(1, 2, 0, 4)  // 1,2,0,4 네개의 아이템을 순차적으로 방출하는 단일 스트림 생성
			.map(n -> {  // 스레드 분기 없이 호출 스레드에서 해당 스트림 아이템에 대해서 나누기변환 연산수행(아래 .subscribe를 만나기 전까지 지연됨!)
				System.out.println("Map 1 - Thread: " + Thread.currentThread().getName());
				return 10 / n;
			})
			.publishOn(Schedulers.boundedElastic())  //이후 작업은 boundedElastic이라는 사전정의된 별도 스레드에서 하도록 지정함!
			.map(s -> {
				System.out.println("Map 2 - Thread: " + Thread.currentThread().getName());
				return s + "!";
			})
			.doOnNext(s -> {  // 스트림에 영향을 주지 않으면 로깅등 부가작업을 할때 사용
				System.out.println("doOnNext - Thread: " + Thread.currentThread().getName() + " with value: " + s);
			})
			.doOnError(error -> {  // Exception이 발생한 경우만 여기로 떨어진다.
				System.out.println("Error occurred - Thread: " + Thread.currentThread().getName() + " with error: " + error.getMessage());
			})
			.subscribe(  // 지연 실행을 시작하는 시점이며, 마지막 스케줄러 지정이 boundedElastic이라 boundedElastic 스레드를 통해 수행됨
				s -> System.out.println("Received " + s + " on Thread: " + Thread.currentThread().getName()));
		// boundElastic스레드로 중간에 분기되기 때문에 이 출력이 마지막 줄이 아닐 수 있다!
		// 자바에서는 main함수가 종료되더라도 다른 스레드가 강제종료되지 않는다!
		System.out.println("main end");
	}
}

실행결과

> Task :Main.main()
Map 1 - Thread: main
Map 1 - Thread: main
Map 1 - Thread: main
Map 2 - Thread: boundedElastic-1
doOnNext - Thread: boundedElastic-1 with value: 10!
Received 10! on Thread: boundedElastic-1
Map 2 - Thread: boundedElastic-1
doOnNext - Thread: boundedElastic-1 with value: 5!
Received 5! on Thread: boundedElastic-1
main end
Error occurred - Thread: boundedElastic-1 with error: / by zero

이 예시에서는 onDoNext, onDoError, main end시 스레드 종료 개념을 추가적으로 배울 수 있다.

주석을 주의깊에 보면 되기 때문에 따로 설명은 안하겠다.

반응형

'Programming > JAVA' 카테고리의 다른 글

BiFunction, Function을 사용한 함수형 프로그래밍  (0) 2024.01.01
java Optional  (1) 2023.11.04
java enum  (0) 2023.11.03
IntelliJ 팁  (0) 2023.11.03
java공부  (0) 2023.08.12

다음 코드를 보자.

public class SimpleFunctionExample {

    public static void main(String[] args) {
        double powResult = power(2, 3);
        String result = formatResult(powResult);

        System.out.println(result);
    }

    private static double power(int a, int b) {
        return Math.pow(a, b);
    }

    private static String formatResult(double number) {
        return "Result: " + number;
    }
}

실행결과 Result: 8

 

power함수와 formatResult함수를 만들고 farmatResult(power(2,3)) 이렇게 중첩함수를 사용했다.

반면 BiFunction, Function을 사용하면 다음처럼 andThen, apply를 통해 함수형 프로그래밍으로 체이닝을 할 수 있다.

코드출처: https://codechacha.com/ko/java8-bifunction-example/

import java.util.function.BiFunction;
import java.util.function.Function;

public class BiFunctionExample2 {

    public static void main(String[] args) {

        BiFunction<Integer, Integer, Double> func1 = (a1, a2) -> Math.pow(a1, a2);
        Function<Double, String> func2 = (a1) -> "Result: " + a1;

        String result = func1.andThen(func2).apply(2, 3);

        System.out.println(result);
    }
}

실행결과는 동일하다.

 

반응형

'Programming > JAVA' 카테고리의 다른 글

reactor #1  (1) 2024.01.01
java Optional  (1) 2023.11.04
java enum  (0) 2023.11.03
IntelliJ 팁  (0) 2023.11.03
java공부  (0) 2023.08.12

Binning: 데이터를 구간으로 나누는 기법

예를들어 나이라는 컬럼을 binning하게 되면 10대, 20대, 30대 등으로 범주화 된다.

 

Binning 사용의 장점:

이상치 감소: Binning은 데이터의 이상치나 노이즈에 덜 민감하게 만들 수 있습니다.
비선형 관계 포착: 특히, 특정 범위 내의 데이터가 결과에 다르게 영향을 미칠 때 유용합니다.
해석 용이성: 데이터를 더 쉽게 이해하고 해석할 수 있게 만듭니다.


Binning 사용의 단점:
정보 손실: 데이터를 구간으로 나누면 원래 데이터의 상세한 정보가 일부 손실될 수 있습니다.
임의성: Binning 과정에서 구간을 어떻게 설정하느냐에 따라 결과가 크게 달라질 수 있으며, 이는 때로 분석의 임의성을 증가시킵니다.


Binning은 특정 상황과 데이터 유형에 매우 유용할 수 있지만, 항상 최선의 방법은 아닙니다. 데이터의 복잡성과 모델의 정교함이 증가함에 따라, 머신 러닝 모델은 종종 binning 없이도 원 데이터에서 복잡한 패턴을 학습할 수 있습니다. 

 

---

 

Binning(데이터 구간화) 후에 데이터를 모델에 입력하기 위해 사용하는 인코딩 방식은 주로 두 가지 중 하나입니다:

레이블 인코딩(Label Encoding) 또는 원핫 인코딩(One-Hot Encoding)

레이블 인코딩
방식: 각 구간에 고유한 정수 값을 할당합니다.
적용: 레이블 인코딩은 구간이 순서를 가지고 있을 때 유용합니다. 예를 들어, '낮음', '중간', '높음'과 같은 순서가 의미를 가질 때 적합합니다.
장단점: 레이블 인코딩은 구간 간의 순서 관계를 유지하지만, 모델이 숫자의 크기나 순서에 의미를 부여할 위험이 있습니다.


원핫 인코딩
방식: 각 구간을 독립된 열로 변환하고, 해당 구간에 속하는 데이터에는 1을, 그렇지 않은 데이터에는 0을 할당합니다.
적용: 구간 간에 순서가 중요하지 않거나, 모델이 구간 간의 순서를 고려하지 않게 하고 싶을 때 적합합니다.
장단점: 원핫 인코딩은 구간 간의 순서나 중요도를 부여하지 않지만, 차원의 증가와 데이터의 희소성 문제를 야기할 수 있습니다.
결론
데이터의 성격과 모델의 종류에 따라 선택: 데이터에서 구간의 순서가 중요하고, 순서대로의 관계가 모델에 반영되어야 한다면 레이블 인코딩이 적합할 수 있습니다. 반면, 구간 간의 순서가 중요하지 않거나 모델이 순서를 고려하지 않아야 할 때는 원핫 인코딩이 더 적합할 수 있습니다.
모델의 요구사항 고려: 일부 모델들은 원핫 인코딩된 데이터에 대해 더 잘 작동할 수 있으며, 다른 모델들은 레이블 인코딩된 데이터에서 더 나은 성능을 보일 수 있습니다.
따라서, binning 후에 어떤 인코딩 방식을 사용할지 결정하기 위해서는 데이터의 특성과 분석 목적을 명확히 이해하는 것이 중요합니다.

반응형

'AI, ML > ML' 카테고리의 다른 글

cardinality  (1) 2024.01.07
dense feature vs sparse feature  (0) 2024.01.07
디시전트리기반 코드 실습  (0) 2023.10.16
그레디언트 부스팅 (Gradient Boosting)  (0) 2023.10.15
랜덤 포레스트(random forest)  (1) 2023.10.15

mac에서 brew install python@3.6 등의 명령으로 여러버전의 python을 설치할 수 있으나, 과거 버전은 지원하지 않는다.

이때 pyenv를 통해서 여러버전의 python을 동시에 운용할 수 있다.

먼저 brew install pyenv를 통해서 pyenv를 설치한다음

pyenv install 3.6 등의 명령어를 통해 필요한 버전을 설치하면 된다.

해당 버전으로 전환하기 위해서는 먼저 .zshrc또는 .bashrc파일에 다음 내용을 추가해야한다.

(참고로 macOS의 경우 요즘엔 zsh이 기본이다)

export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"

그다음 source ~/.zshrc 또는 source ~/.bashrc로 적용하고

 

pyenv global 3.6 등의 명령어를 통해 버전을 전환하면 된다.

global은 시스템 전체에서 기본적으로 사용할 Python 버전을 설정하라는 명령어이다.

local을 대신 쓰면  그 프로젝트의 디렉터리 내에서만 사용할 Python 버전을 따로 설정할 수 있다.

pyenv versions 를 통해서 현재 시스템에 설치된 버전들을 볼 수도 있다.

pyenv global system을 하면 원래 시스템의 python으로 돌아갈 수도 있다.

 

virtualenv와의 관계

pyenv
역할: pyenv는 여러 버전의 Python을 설치하고 관리하는 데 사용됩니다. pyenv를 사용하면 시스템 전체에 걸쳐 여러 Python 버전을 설치하고, 각각을 필요에 따라 선택하여 사용할 수 있습니다. 이를 통해 서로 다른 프로젝트에서 다른 Python 버전을 쉽게 사용할 수 있습니다.

activate 명령어: pyenv는 환경을 활성화하기 위해 activate 명령어를 직접 사용하지 않습니다. 대신, pyenv local, pyenv global, pyenv shell 같은 명령어를 통해 Python 버전을 설정합니다. 이러한 설정을 통해 특정 디렉터리나 세션에서 사용할 Python 버전을 자동으로 활성화하게 됩니다.

많은 사용자들은 pyenv 를 사용하여 여러 Python 버전을 관리하고,
virtualenv (또는 pyenv 의 플러그인인 pyenv-virtualenv )를 사용하여 특정 버전에 대한 독립적인 개발 환경을 생성합니다. 이렇게 하면 Python 버전 관리와 프로젝트 의존성 관리를 모두 효과적으로 할 수 있습니다.

 

반응형

'Programming > Python' 카테고리의 다른 글

venv  (0) 2023.12.17
mypy / pytype  (1) 2023.10.07
python 스트링 인코딩 핸들링  (0) 2021.11.30
Python GUI Programming(Tkinter)  (0) 2021.01.02
파이선환경 그리고 requirements.txt  (0) 2020.09.20

 

venv는 virtualenv와 비슷하며 특징을 정리하면 다음과 같음

 

venv

  • venv는 python개발진에 의해 개발되었으며, python3.3부터 등장과 동시에 표준라이브러리로 공식 지원됨.
  • 공식 지원되므로 별도의 설치과정이 필요 없음

 

virtualenv

  • virtualenv는 python 2버전 시절 부터 널리 사용되었으며, 따라서 지금도 python2버전을 지원함
  • virtualenv가 표준으로 채택되지 않은 이유는 더 간단하고 일관된 환경을 만들기 위한 판단이었던것으로 보임
  • virtualenv는 venv보다 더 많은 기능을 제공. 예를 들어, 특정 버전의 Python을 지정하여 가상 환경을 생성할 수 있음
  •  Python 표준 라이브러리에 포함되어 있지 않기 때문에 별도로 설치해야 함
반응형

'Programming > Python' 카테고리의 다른 글

pyenv를 통한 python버전 변경  (0) 2023.12.17
mypy / pytype  (1) 2023.10.07
python 스트링 인코딩 핸들링  (0) 2021.11.30
Python GUI Programming(Tkinter)  (0) 2021.01.02
파이선환경 그리고 requirements.txt  (0) 2020.09.20

비동기 함수를 콜하고 그 결과를 가져와서 사용하는 코딩을 할때 유용.

Executor를 통한 스레드풀 생성을 하고 해당 executor에 submit하는 방식이다.

멀티스레딩인 만큼 동시성 제어관련 코드가 필요할 수 있다.

 

간단한 예시는 아래와 같다.

https://github.com/sevity/problem_solving/blob/main/java/FutureExample.java

 

추가 업데이트 예정.

반응형

 

null처리를 하다보면 코드가 지저분해지고, 실수하기가 쉬우며, 실수했을때는 NullPointException이 발생하게 된다. 

java8부터는 이것을 개선하기위해 null이 될 수 있는 객체를 Optional에 넣어서 명시적으로 메소드를 통해 다룰수 있도록 만들었다. 이를 통해 체이닝이 가능해지며 코딩오류 가능성이 줄게 되었다.

(단 람다함수 및 method reference등으로 인해 다소 이해하기 복잡해보일 순 있다)

 

코드예시는 여기 참조

내가 만든 코드 예시는 아래 참조

https://github.com/sevity/problem_solving/blob/main/java/OptionalExample.java

반응형

'Programming > JAVA' 카테고리의 다른 글

reactor #1  (1) 2024.01.01
BiFunction, Function을 사용한 함수형 프로그래밍  (0) 2024.01.01
java enum  (0) 2023.11.03
IntelliJ 팁  (0) 2023.11.03
java공부  (0) 2023.08.12

c++ enum과 다르게 java의 enum은 좀 더 발전된 형태로 상수의 집합이 아닌 타입 자체가 객체이다.

따라서 enum type 마다 속성과 메서드를 가질 수 있으며 생성자로 초기화 한다.

public enum CoffeeSize {
    SMALL(200, 3000),
    MEDIUM(400, 5000),
    LARGE(600, 7000),
    XLARGE(1000, 9000);

    private final int volumeInMl;
    private final long priceInWon;

    CoffeeSize(int volumeInMl, long priceInWon) {
        this.volumeInMl = volumeInMl;
        this.priceInWon = priceInWon;
    }
}

위 예시를 보면 커피 사이즈를 enum으로 SMAL, MEDIUM, LARGE, XLARGE로 나누는데, 각각 볼륨과 가격의 속성을 추가로 가진다.

반응형

'Programming > JAVA' 카테고리의 다른 글

BiFunction, Function을 사용한 함수형 프로그래밍  (0) 2024.01.01
java Optional  (1) 2023.11.04
IntelliJ 팁  (0) 2023.11.03
java공부  (0) 2023.08.12
react/next.js로 만드는 online-judge 사이트 #4 문제관리 프론트엔드  (0) 2023.08.05

+ Recent posts