code: public static List<KmeansPoint> createInitialCentroids(List<KmeansPoint> basePoints,
              int clusterNum)
      {
          Random random = new Random();
          List<KmeansPoint> resultList = Lists.newArrayList();
          // ベースデータリストを更新しないためにコピーを生成して用いる
          List<KmeansPoint> pointList = Lists.newArrayList(basePoints);
          KmeansPoint firstCentroid = pointList.remove(random.nextInt(pointList.size()));
          resultList.add(firstCentroid);
  
          double[] dxs;
          // KMeans++方式による中心点算出をクラスタの数だけ実施する。
          // 最初の1点はランダムで算出しているため、1オリジンで開始している。
          for (int centroidIndex = 1; centroidIndex < clusterNum; centroidIndex++)
          {
              // 各データポイントに対する距離を用いて重みつき確率分布を算出する。
              dxs = computeDxs(pointList, resultList);
  
              // 重みつき確率分布を用いて次の中心点を選出する。
              double r = random.nextDouble() * dxs[dxs.length - 1];
              int next = Arrays.binarySearch(dxs, r);
              int index = 0;
              if (next > 0)
              {
                  index = next - 1;
              }
              else if (next < 0)
              {
                  index = COMPENSATE_INDEX - next;
              }
  
              while (index > 0 && resultList.contains(pointList.get(index)))
              {
                  index = index - 1;
              }
  
              resultList.add(pointList.get(index));
          }
  
          return resultList;
      }
docs: KMeans++アルゴリズムで初期の中心点リストを生成する。
  
  @param basePoints 中心点を生成するベースデータ
  @param clusterNum クラスタ数
  @return 中心点リスト