golang实现k-modes和k-prototypes聚类算法插件库go-cluster的使用

Golang实现k-modes和k-prototypes聚类算法插件库go-cluster的使用

go-cluster是一个Golang实现的聚类算法库,主要包含k-modes和k-prototypes两种聚类算法。

安装

go get github.com/e-XpertSolutions/go-cluster/v2

算法简介

k-modes算法与著名的k-means聚类算法非常相似,主要区别在于距离计算方式。k-means通常使用欧几里得距离计算两个向量之间的距离,适用于数值型连续数据,但不适合处理分类数据。k-modes使用汉明距离计算向量之间的距离,表示两个向量有多少元素不同。

k-prototypes算法用于混合数据(包含分类和数值型数据)的聚类。

使用示例

KModes算法示例

package main

import (
    "fmt"
    "github.com/e-XpertSolutions/go-cluster/cluster"
)

func main() {
    // 输入的分类数据必须先进行字典编码转换为数字
    // 例如"blue","red","green"可以编码为1,2,3
    
    // 创建数据矩阵
    data := cluster.NewDenseMatrix(lineNumber, columnNumber, rawData)
    newData := cluster.NewDenseMatrix(newLineNumber, newColumnNumber, newRawData)

    // 算法参数配置
    distanceFunction := cluster.WeightedHammingDistance // 距离计算函数
    initializationFunction := cluster.InitCao           // 初始化函数
    clustersNumber := 5                                 // 聚类数量
    maxIteration := 20                                 // 最大迭代次数
    
    // 权重向量 - 用于设置特征重要性
    weights := []float64{1,1,2}
    wvec := [][]float64{weights}
    
    // 模型保存路径
    path := "km.txt"

    // 初始化KModes算法
    km := cluster.NewKModes(distanceFunction, initializationFunction, 
        clustersNumber, 1, maxIteration, wvec, path)

    // 训练模型
    err := km.FitModel(data)
    if err != nil {
        fmt.Println(err)
    }

    // 预测新数据标签
    newLabels, err := km.Predict(newData)
    if err != nil {
        fmt.Println(err)
    }
}

KPrototypes算法示例

// KPrototypes算法需要比k-modes多两个参数:
// categorical - 指示分类特征列的向量
// gamma - 数值型数据成本贡献的重要性

categorical := []int{1} // 表示只有第1列包含分类数据
gamma := 0.2            // 数值型数据的距离函数成本将乘以0.2

// 初始化KPrototypes算法
kp := cluster.NewKPrototypes(distanceFunction, initializationFunction, 
    categorical, clustersNumber, 1, maxIteration, wvec, gamma, "km.txt")

// 训练模型
err := kp.FitModel(data)
if err != nil {
    fmt.Println(err)
}

// 预测新数据标签
newLabelsP, err := kp.Predict(newData)
if err != nil {
    fmt.Println(err)
}

注意事项

  1. 输入的分类数据必须先进行字典编码转换为数字
  2. 可以选择包中提供的距离和初始化函数,也可以使用具有适当参数的自定义函数
  3. 权重向量是可选的,如果为nil则所有特征被视为同等重要(权重=1)
  4. 模型保存路径是可选的,如果不需要保存或加载模型,可以设置为空字符串

参考文献

[HUANG97]: Huang, Z.: Clustering large data sets with mixed numeric and categorical values, Proceedings of the First Pacific Asia Knowledge Discovery and Data Mining Conference, Singapore, pp. 21-34, 1997.

[HUANG98] Huang, Z.: Extensions to the k-modes algorithm for clustering large data sets with categorical values, Data Mining and Knowledge Discovery 2(3), pp. 283-304, 1998.

[CAO09] Cao, F., Liang, J, Bai, L.: A new initialization method for categorical data clustering, Expert Systems with Applications 36(7), pp. 10223-10228., 2009.


更多关于golang实现k-modes和k-prototypes聚类算法插件库go-cluster的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现k-modes和k-prototypes聚类算法插件库go-cluster的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用go-cluster库实现K-Modes和K-Prototypes聚类

K-Modes和K-Prototypes是处理分类数据的聚类算法,是K-Means的变种。下面介绍如何使用go-cluster库实现这两种算法。

安装go-cluster库

首先安装go-cluster库:

go get github.com/e-XpertSolutions/go-cluster/v2

K-Modes聚类实现

K-Modes适用于纯分类数据:

package main

import (
	"fmt"
	"github.com/e-XpertSolutions/go-cluster/v2"
)

func main() {
	// 示例分类数据
	data := [][]interface{}{
		{"红色", "大", "中国"},
		{"蓝色", "中", "美国"},
		{"绿色", "小", "日本"},
		{"红色", "中", "中国"},
		{"蓝色", "大", "美国"},
		{"绿色", "中", "日本"},
	}

	// 初始化K-Modes
	km, err := cluster.NewKModes(2, 10) // 2个簇,最大迭代10次
	if err != nil {
		panic(err)
	}

	// 执行聚类
	clusters, err := km.Cluster(data)
	if err != nil {
		panic(err)
	}

	// 输出结果
	for i, c := range clusters {
		fmt.Printf("数据点 %d 属于簇 %d\n", i, c)
	}

	// 获取簇中心点
	modes := km.Modes()
	fmt.Println("\n簇中心点:")
	for i, mode := range modes {
		fmt.Printf("簇 %d: %v\n", i, mode)
	}
}

K-Prototypes聚类实现

K-Prototypes可以同时处理数值型和分类型数据:

package main

import (
	"fmt"
	"github.com/e-XpertSolutions/go-cluster/v2"
)

func main() {
	// 示例混合数据(数值+分类)
	data := [][]interface{}{
		{25, 30000, "单身", "是"},
		{35, 45000, "已婚", "否"},
		{30, 50000, "单身", "是"},
		{40, 60000, "已婚", "否"},
		{28, 35000, "单身", "是"},
		{45, 70000, "已婚", "否"},
	}

	// 指定哪些列是分类变量(索引从0开始)
	categoricalIndices := []int{2, 3}

	// 初始化K-Prototypes
	// 参数:簇数2,分类变量权重1.0,最大迭代10次
	kp, err := cluster.NewKPrototypes(2, 1.0, 10, categoricalIndices...)
	if err != nil {
		panic(err)
	}

	// 执行聚类
	clusters, err := kp.Cluster(data)
	if err != nil {
		panic(err)
	}

	// 输出结果
	for i, c := range clusters {
		fmt.Printf("数据点 %d 属于簇 %d\n", i, c)
	}

	// 获取簇中心点
	prototypes := kp.Prototypes()
	fmt.Println("\n簇中心点:")
	for i, proto := range prototypes {
		fmt.Printf("簇 %d: %v\n", i, proto)
	}
}

关键参数说明

  1. K-Modes参数:

    • 簇数量(k): 需要预先指定的簇数目
    • 最大迭代次数: 防止算法不收敛时无限循环
  2. K-Prototypes参数:

    • 簇数量(k)
    • 分类变量权重(γ): 控制分类变量对距离计算的相对重要性
    • 最大迭代次数
    • 分类变量索引: 指定哪些列是分类变量

距离度量

在go-cluster中:

  • K-Modes使用简单的匹配不相似度(Simple Matching Dissimilarity)
  • K-Prototypes对数值变量使用欧氏距离,对分类变量使用匹配不相似度

实际应用建议

  1. 数据预处理:

    • 确保分类变量用字符串表示
    • 数值变量应该标准化(0-1或z-score)
  2. 确定最佳簇数:

    • 可以使用肘部法则或轮廓系数
    • 示例代码计算轮廓系数:
func calculateSilhouette(data [][]interface{}, clusters []int) float64 {
    // 实现轮廓系数计算
    // ...
    return silhouetteScore
}
  1. 处理缺失值:
    • go-cluster不直接处理缺失值,需要预先处理
    • 可以考虑用众数填充分类变量,中位数填充数值变量

go-cluster库提供了简单易用的API来实现K-Modes和K-Prototypes聚类,适合处理混合数据类型。对于大型数据集,可能需要考虑性能优化或分布式实现。

回到顶部