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)
}
注意事项
- 输入的分类数据必须先进行字典编码转换为数字
- 可以选择包中提供的距离和初始化函数,也可以使用具有适当参数的自定义函数
- 权重向量是可选的,如果为nil则所有特征被视为同等重要(权重=1)
- 模型保存路径是可选的,如果不需要保存或加载模型,可以设置为空字符串
参考文献
[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
更多关于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)
}
}
关键参数说明
-
K-Modes参数:
- 簇数量(k): 需要预先指定的簇数目
- 最大迭代次数: 防止算法不收敛时无限循环
-
K-Prototypes参数:
- 簇数量(k)
- 分类变量权重(γ): 控制分类变量对距离计算的相对重要性
- 最大迭代次数
- 分类变量索引: 指定哪些列是分类变量
距离度量
在go-cluster中:
- K-Modes使用简单的匹配不相似度(Simple Matching Dissimilarity)
- K-Prototypes对数值变量使用欧氏距离,对分类变量使用匹配不相似度
实际应用建议
-
数据预处理:
- 确保分类变量用字符串表示
- 数值变量应该标准化(0-1或z-score)
-
确定最佳簇数:
- 可以使用肘部法则或轮廓系数
- 示例代码计算轮廓系数:
func calculateSilhouette(data [][]interface{}, clusters []int) float64 {
// 实现轮廓系数计算
// ...
return silhouetteScore
}
- 处理缺失值:
- go-cluster不直接处理缺失值,需要预先处理
- 可以考虑用众数填充分类变量,中位数填充数值变量
go-cluster库提供了简单易用的API来实现K-Modes和K-Prototypes聚类,适合处理混合数据类型。对于大型数据集,可能需要考虑性能优化或分布式实现。