携帯基地局データを用いたビジネス圏分析

1. 目的

携帯電話ネットワークは、ユーザーのスマートフォンに関する情報を記録します。例えば、どの基地局エリアにいるかや、そのエリアに滞在している時間などです。これらのデータを使用してビジネス圏を分析し、潜在的な顧客の分布を理解することで、適切なビジネス戦略を立案することができます。例えば、商業地域、住宅地域、または業務地域に分類できます。

2. データ

以下のような形式で与えられるデータセットを使います。このデータセットは既に集計、変換、フィルタリングが行われています。

基站编号,工作日上班时间人均停留时间,凌晨人均停留时间,周末人均停留时间,日均人流量
36902,78,521,602,2863
36903,144,600,521,2245
36904,95,457,468,1283
36905,69,596,695,1054

各特徴量は次の通りです:

  • 平日の勤務時間(9:00-18:00)における平均滞在時間
  • 凌晨時間帯(00:00-07:00)における平均滞在時間
  • 週末における平均滞在時間
  • 日平均人流

3. コード

特徴量を抽出・処理し、クラスタリング手法を利用して複数の区域に分類します。それぞれの区域について分析を行います。

public static void analyzeBusinessZones(SparkSession session) {
    String path = PropertiesReader.get("processed_business_zone_data");

    // CSVデータの読み込み
    Dataset<Row> rawDataset = session.read()
            .option("sep", ",")
            .option("header", "true")
            .option("inferSchema", "true")
            .csv(path);

    // 特徴ベクトルへの変換
    Dataset<Row> featureDataset = rawDataset.map((MapFunction<Row, Row>) row -> {
        int stationId = row.getInt(0);
        double weekdayStay = (double) row.getInt(1);
        double nightStay = (double) row.getInt(2);
        double weekendStay = (double) row.getInt(3);
        double dailyTraffic = (double) row.getInt(4);

        return RowFactory.create(stationId, Vectors.dense(new double[] { 
            dailyTraffic, weekendStay, nightStay, weekdayStay 
        }));
    }, RowEncoder.apply(new StructType(new StructField[] {
        new StructField("stationId", DataTypes.IntegerType, false, Metadata.empty()),
        new StructField("features", SQLDataTypes.VectorType(), false, Metadata.empty())
    })));

    // データの正規化
    MinMaxScalerModel scalerModel = new MinMaxScaler()
            .setInputCol("features")
            .setOutputCol("normalizedFeatures")
            .fit(featureDataset);

    Dataset<Row> normalizedDataset = scalerModel.transform(featureDataset);

    // 最適なクラスター数の選定
    int optimalK = determineOptimalClusters(normalizedDataset, 10);

    // クラスタリングモデルの構築
    BisectingKMeans clusteringModel = new BisectingKMeans()
            .setFeaturesCol("normalizedFeatures")
            .setK(optimalK)
            .setSeed(42);

    BisectingKMeansModel model = clusteringModel.fit(normalizedDataset);

    // 結果の予測
    Dataset<Row> predictions = model.transform(normalizedDataset);

    // クラスター中心点の取得
    Vector[] clusterCenters = model.clusterCenters();
    for (Vector center : clusterCenters) {
        System.out.println(center);
    }

    // 上位5件の結果を表示
    predictions.show(5);
}

private static int determineOptimalClusters(Dataset<Row> data, int maxK) {
    double bestSilhouette = -1;
    int optimalK = 2;

    for (int k = 2; k <= maxK; k++) {
        BisectingKMeans tempModel = new BisectingKMeans()
                .setK(k)
                .setSeed(1);

        BisectingKMeansModel tempCluster = tempModel.fit(data);
        double silhouetteScore = Silhouette.silhouette(tempCluster, data);

        if (silhouetteScore > bestSilhouette) {
            bestSilhouette = silhouetteScore;
            optimalK = k;
        }
    }

    return optimalK;
}

タグ: Spark clustering BusinessAnalytics

7月5日 16:51 投稿