[컴퓨터 과학 입문 3회: 기계를 배워보자] 자바로 k평균법~데이터 집합의 중심을 설치하자~

입문


안녕하십니까, 여기는 탄산수입니다.
저번에 했던 거야. 계속해.
[컴퓨터 과학 입문 2회: 기계를 배워보기] 자바로 k평균법~데이터 사이의 거리를 설치해보세요~
처음이라면 시리즈의 처음부터 꼭 보세요.
[컴퓨터 과학 입문 0회: 기계를 배워보자] 자바로 k평균법을 설치해보세요.
이번에는 데이터 집합 센터의 생각을 이야기합시다.

환경

  • IntelliJ IDEA
  • Java12 + SpringBoot 2.1.6
  • JUnit5
  • 이 환경에 대한 준비는 이 문장에 쓰였다.
    IntelliJ+Gradle+SpringBoot+JUnit5(jupiter)에서 새로운 개발을 시작할 때의 비망록

    하고 싶은 일


    "왜 이런 생각이 필요해요?"그렇다면 내가 먼저 어떤 일을 하고 싶은지 말해 볼게요.
    말로 설명하는 것보다 그림을 보는 것이 빠르니 이쪽을 보세요.

    이런 느낌, 파란 점처럼 여러 개의 데이터가 있는데, 이 그룹의 중심은 어디에 있습니까?사용자 정의 모양새를 정의합니다.
    제 0회 하지만 그렇게 말하면 인간이 보면'대충 이 근처에 있겠지'라고 판단할 수 있지만 컴퓨터에 숫자로 계산할 수 있는 정의를 주어야 한다.

    중심 계산 방법


    오랜 시간 의뢰를 내렸지만 일상생활에서도 익숙한 산술평균(가평균)을 사용한다
    '수학의 평균점'따위.전체 인원의 몫을 합쳐서 인원수로 나눈 것이다.
    성함
    수학 점수
    미스터 A
    70점
    미스터 B
    60점
    C씨
    90점
    D씨
    50점
    이런 상황에서 평균점은
    (70+60+90+50)/4 = 67.5
    
    67.5점이라는 얘기다.
    이 생각도 좌표의 수치에도 적용된다.2차원 데이터로 생각하면 그림과 같다.가로와 세로 숫자의 평균값은 중심 좌표입니다.

    시험적으로 실시하다


    나는 이전에 한 클래스에 getCentroid 방법을 추가했다.
    package net.tan3sugarless.clusteringsample.lib.data;
    
    import lombok.EqualsAndHashCode;
    import lombok.Getter;
    import lombok.ToString;
    import lombok.Value;
    import net.tan3sugarless.clusteringsample.exception.DimensionNotUnifiedException;
    import net.tan3sugarless.clusteringsample.exception.NullCoordinateException;
    import net.tan3sugarless.clusteringsample.exception.UnexpectedCentroidException;
    
    import java.util.List;
    import java.util.Objects;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    
    /**
     * ユークリッド距離空間上の座標集合
     */
    @Getter
    @ToString
    @EqualsAndHashCode
    @Value
    public class EuclideanSpace {
    
        private final List<List<Double>> points;
        private final int dimension;
    
        //
        // ~~中略~~
        //
    
        /**
         * インスタンスに所属する各点の中心点となる座標を求める
         * <p>
         * 中心は算術平均とする
         *
         * <pre>
         *     n次元空間において、i番,(x11+x21+....+xm1)/m,目の点のj番目の要素をxijとして、     *
         * [x11, x12,...,x1n],[x21, x22,...,x2n]
         * とm個の点が与えられているとき、中心点の座標は、
         *
         * [(x11+x21+....+xm1)/m,(x12+x22+....+xm2)/m,...,(x1n+x2n+....+xmn)/m]
         * となる。
         *
         * という計算を行う。
         * </pre>
         *
         * @return 中心点の座標
         * @throws UnexpectedCentroidException 基本あり得ない
         */
        public List<Double> getCentroid() {
            return IntStream
                    .range(0, dimension)
                    .boxed()
                    .map(i -> points.stream().mapToDouble(point -> point.get(i)).average().orElseThrow(UnexpectedCentroidException::new))
                    .collect(Collectors.toList());
        }
    }
    
    그리고 테스트
    
        /**
         * points : 0次元/2次元 x 3要素
         */
        static Stream<Arguments> testGetCentroidProvider() {
            return Stream.of(
                    //@formatter:off
                    Arguments.of(Collections.emptyList(), Collections.emptyList()),
                    Arguments.of(asList(Collections.emptyList(), Collections.emptyList(), Collections.emptyList()), Collections.emptyList()),
                    Arguments.of(asList(asList(2.0, -4.0), asList(1.0, 0.0), asList(6.0, 1.0)), asList(3.0, -1.0))
                    //@formatter:on
            );
        }
    
        @ParameterizedTest
        @MethodSource("testGetCentroidProvider")
        @DisplayName("中心算出のテスト")
        void testGetCentroid(List<List<Double>> points, List<Double> centroid) {
            EuclideanSpace space = new EuclideanSpace(points);
    
            Assertions.assertEquals(centroid, space.getCentroid());
        }
    

    다음


    오늘은 여기까지.이렇게 하면 부품이 모두 갖추어져서 다음에 마침내 k-평균법의 주요 논리를 설명할 것이다.
    이번 해설의 버전은 태그에 남겨진 것이니 가능하다면 보십시오.
    https://github.com/tan3nonsugar/clusteringsample/releases/tag/v0.0.3
    '정중간'의 정의는 또 다른 중앙치 등 종류가 있지만 말이 혼란스러워 산수 평균에 말을 고정시킨다. 

    좋은 웹페이지 즐겨찾기