protected void initClusters ( ) { log . info ( "Generating initial clusters" ) ; List < Point > points = new ArrayList <> ( initialPoints ) ; //Initialize the ClusterSet with a single cluster center (based on position of one of the points chosen randomly) val random = Nd4j . getRandom ( ) ; Distance distanceFn = clusteringStrategy . getDistanceFunction ( ) ; int initialClusterCount = clusteringStrategy . getInitialClusterCount ( ) ; clusterSet = new ClusterSet ( distanceFn , clusteringStrategy . inverseDistanceCalculation ( ) , new long [ ] { initialClusterCount , points . get ( 0 ) . getArray ( ) . length ( ) } ) ; clusterSet . addNewClusterWithCenter ( points . remove ( random . nextInt ( points . size ( ) ) ) ) ; //dxs: distances between // each point and nearest cluster to that point INDArray dxs = Nd4j . create ( points . size ( ) ) ; dxs . addi ( clusteringStrategy . inverseDistanceCalculation ( ) ? - Double . MAX_VALUE : Double . MAX_VALUE ) ; //Generate the initial cluster centers, by randomly selecting a point between 0 and max distance //Thus, we are more likely to select (as a new cluster center) a point that is far from an existing cluster while ( clusterSet . getClusterCount ( ) < initialClusterCount && ! points . isEmpty ( ) ) { dxs = ClusterUtils . computeSquareDistancesFromNearestCluster ( clusterSet , points , dxs , exec ) ; double r = random . nextFloat ( ) * dxs . maxNumber ( ) . doubleValue ( ) ; for ( int i = 0 ; i < dxs . length ( ) ; i ++ ) { double distance = dxs . getDouble ( i ) ; Preconditions . checkState ( distance >= 0 , "Encountered negative distance: distance function is not valid? Distance " + "function must return values >= 0, got distance %s for function s" , distance , distanceFn ) ; if ( dxs . getDouble ( i ) >= r ) { clusterSet . addNewClusterWithCenter ( points . remove ( i ) ) ; dxs = Nd4j . create ( ArrayUtils . remove ( dxs . data ( ) . asDouble ( ) , i ) ) ; break ; } } } ClusterSetInfo initialClusterSetInfo = ClusterUtils . computeClusterSetInfo ( clusterSet ) ; iterationHistory . getIterationsInfos ( ) . put ( currentIteration , new IterationInfo ( currentIteration , initialClusterSetInfo ) ) ; }
Initialize the cluster centers at random