Flutter聚类分析插件kmeans的使用

发布于 1周前 作者 zlyuanteng 来自 Flutter

Flutter聚类分析插件kmeans的使用

package:kmeans

package:kmeans 是一个用于Dart语言的实现K均值聚类算法的包。K均值聚类倾向于产生大小相等的簇,具体细节可以参考维基百科的相关文章。

在该实现中,数据点在每个维度上进行平移和缩放,以尝试给每个参数相同的权重。默认情况下,簇初始化使用K-means++方法。然而,仍然建议进行多次试验以避免局部最小值。用户也可以提供一组初始均值。

为了评估聚类的好坏,并在不知道k值的情况下找到合适的k值,该库包含计算聚类的轮廓系数,并在bestFit()方法中使用它。

使用示例

以下是一个简单的使用示例:

import 'package:kmeans/kmeans.dart';

main() {
  // 初始化数据点
  var kmeans = KMeans([
    [0.0, 0.0], // 数据点1
    [1.1, 1.1], // 数据点2
    [-5.0, -0.50], // 数据点3
    // 添加更多数据点...
  ]);

  // 设置簇的数量
  var k = 3;

  // 计算聚类
  var clusters = kmeans.compute(k);

  // 获取轮廓系数
  var silhouette = clusters.silhouette;
  print('The clusters have silhouette $silhouette');

  // 输出每个数据点所属的簇及其均值
  for (int i = 0; i < kmeans.points.length; i++) {
    var point = kmeans.points[i];
    var cluster = kmeans.clusters[i];
    var mean = kmeans.means[cluster];
    print('$point is in cluster $cluster with mean $mean.');
  }

  // 寻找最佳的k值范围
  var bestCluster = kmeans.computeBest(
    minK: 3,
    maxK: 10,
  );
}

完整示例Demo

以下是完整的示例代码,展示了如何使用kmeans包进行聚类分析:

// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:io';
import 'package:kmeans/kmeans.dart';

// 假设有一个ARFF文件读取工具
import '../test/utils/arff.dart';

Future<void> main() async {
  // 读取ARFF文件中的数据
  final ArffReader reader = ArffReader.fromFile(File('example/letter.arff'));
  await reader.parse();

  const int labelIndex = 16; // 标签索引
  final int trainingSetSize = reader.data.length ~/ 2; // 训练集大小

  // 使用前半部分数据进行训练
  final List<List<double>> trainingData =
      reader.data.sublist(0, trainingSetSize);
  final KMeans trainingKMeans = KMeans(trainingData, labelDim: labelIndex);
  
  // 找到最佳的k值
  final Clusters trainingClusters = trainingKMeans.bestFit(
    minK: 26,
    maxK: 26,
  );

  // 统计训练错误
  int trainingErrors = 0;
  for (int i = 0; i < trainingClusters.clusterPoints.length; i++) {
    // 统计每个标签出现的次数
    final List<int> counts = List<int>.filled(trainingClusters.k, 0);
    for (int j = 0; j < trainingClusters.clusterPoints[i].length; j++) {
      counts[trainingClusters.clusterPoints[i][j][labelIndex].toInt()]++;
    }

    // 找到出现次数最多的标签
    int maxIdx = -1;
    int maxCount = 0;
    for (int j = 0; j < trainingClusters.k; j++) {
      if (counts[j] > maxCount) {
        maxCount = counts[j];
        maxIdx = j;
      }
    }

    // 如果一个点不在出现次数最多的簇中,则认为是错误
    for (int j = 0; j < trainingClusters.clusterPoints[i].length; j++) {
      if (trainingClusters.clusterPoints[i][j][labelIndex].toInt() != maxIdx) {
        trainingErrors++;
      }
    }
  }
  // 这个值应该为零
  print('trainingErrors: $trainingErrors');

  // 忽略标签的聚类副本
  final Clusters ignoreLabel = Clusters(
    trainingClusters.points,
    <int>[labelIndex],
    trainingClusters.clusters,
    trainingClusters.means,
  );

  // 预测后半部分数据的簇
  final List<List<double>> data = reader.data.sublist(trainingSetSize);
  final List<int> predictions = data.map((List<double> point) {
    return ignoreLabel.kNearestNeighbors(point, 5);
  }).toList();

  // 统计预测不匹配标签的点数
  int errors = 0;
  for (int i = 0; i < predictions.length; i++) {
    final List<double> rep = ignoreLabel.clusterPoints[predictions[i]][0];
    final int repClass = rep[labelIndex].toInt();
    final int dataClass = data[i][labelIndex].toInt();
    if (dataClass != repClass) {
      errors++;
    }
  }

  // 希望这些值很小
  final int testSetSize = reader.data.length - trainingSetSize;
  final double errorRate = errors.toDouble() / testSetSize.toDouble();
  print('classification errors: $errors / $testSetSize');
  print('error rate: $errorRate');
}

更多关于Flutter聚类分析插件kmeans的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter聚类分析插件kmeans的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter应用中使用KMeans聚类分析插件的示例代码。为了简洁起见,我将假设你已经有一个Flutter项目,并且你希望在其中集成KMeans聚类分析。

首先,你需要在pubspec.yaml文件中添加KMeans插件的依赖项。虽然Flutter本身没有官方的KMeans插件,但你可以使用Dart编写的KMeans实现,或者通过平台通道调用原生代码。这里,我们假设你找到一个合适的Dart实现的KMeans库,比如kmeans_dart(注意:实际库名可能不同,你需要根据具体可用的库进行调整)。

dependencies:
  flutter:
    sdk: flutter
  kmeans_dart: ^x.y.z  # 替换为实际版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Dart代码中,你可以按照以下方式使用KMeans进行聚类分析。假设你有一组二维数据点,并希望使用KMeans进行聚类:

import 'package:flutter/material.dart';
import 'package:kmeans_dart/kmeans.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('KMeans Clustering Example'),
        ),
        body: Center(
          child: ClusteringExample(),
        ),
      ),
    );
  }
}

class ClusteringExample extends StatefulWidget {
  @override
  _ClusteringExampleState createState() => _ClusteringExampleState();
}

class _ClusteringExampleState extends State<ClusteringExample> {
  List<List<double>> dataPoints = [
    [1.0, 2.0],
    [1.5, 1.8],
    [5.0, 8.0],
    [8.0, 8.0],
    [1.0, 0.6],
    [9.0, 11.0],
    [8.0, 2.0],
    [10.0, 2.0],
    [9.0, 3.0],
  ];

  List<List<List<double>>> clusters;

  @override
  void initState() {
    super.initState();
    performKMeansClustering();
  }

  void performKMeansClustering() async {
    int k = 3; // 聚类数量
    KMeans kmeans = KMeans(dataPoints, k);
    kmeans.train();
    clusters = kmeans.getClusters();

    // 更新UI
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('KMeans Clustering Result'),
        SizedBox(height: 20),
        if (clusters != null) {
          for (int i = 0; i < clusters.length; i++) {
            Text('Cluster ${i + 1}:'),
            Wrap(
              spacing: 10,
              runSpacing: 10,
              children: clusters[i].map((point) => Chip(
                label: Text('(${point[0]}, ${point[1]})'),
                backgroundColor: Color((i + 1) * 0x1000000), // 简单的颜色区分
              )).toList(),
            ),
            SizedBox(height: 20),
          }
        } else {
          Text('Loading...'),
        }
      ],
    );
  }
}

注意:

  1. 上面的代码假设kmeans_dart库提供了一个KMeans类,该类有traingetClusters方法。实际使用时,你需要根据所选库的API进行调整。
  2. Color((i + 1) * 0x1000000)仅用于简单地为每个聚类分配不同的颜色,实际应用中你可能需要更复杂的颜色管理。
  3. 初始化KMeans时,k表示你希望聚类的数量。

由于实际可用的KMeans库可能与假设的kmeans_dart不同,因此请查阅你选择的库的文档以获取正确的用法。如果你找不到合适的Dart库,你也可以考虑通过平台通道调用原生平台(如iOS和Android)上的KMeans实现。

回到顶部