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

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

+ Recent posts