6集群
一组数据可以组织成一个集群,用于检测和标记这些集群的机器学习技术称为集群技术
有一组已知的特征或属性与尝试预测的标签和编号相匹配。利用这些已经标记的数据将模型拟合到特定行为上 是有监督的
大多数集群技术是无监督的。
6.1集群模型术语
集群或者群组:每一个集群或者群组都是数据点的集合,集群技术是将数据点组织到其中
组内或集群内:从集群过程中产生的集群,可以通过测量集群内数据点与同集群数据点的相似度进行评估。称为组内或集群内相似度评估
组间或集群间:集群过程中产生的簇可以通过测量集群内数据点与不同集群数据点之间的相异度来进行评估/称为组外或集群间相异度评估
内部标准:利用集群内或集群间相似度来衡量集群技术的性能
外部标准:使用外部自定义标准衡量集群技术性能
距离或相似度:衡量两个数据点有多接近的度量标准。例如欧几里得距离
6.2距离或相似的度量
利用某种距离或者相似度以定量得方式衡量数据点之间得接近程度
常用得方式:
欧几里得距离:d = sqrt((x1-x2)+(y1-y2)
曼哈顿距离:用以标明两个点在标准坐标系上的绝对轴距总和 d(i,j)=|X1-X2|+|Y1-Y2|
明氏距离(明可夫斯基距离):被看做是欧氏距离和曼哈顿距离的一种推广 (∑|xi-yi|p)(1/p) (i=1,2,…n) .
汉明距离:两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数,即将一个字符串变换成另外一个字符串所需要替换的字符个数
6.3集群评估技术
6.3.1内部集群评估技术
轮廓系数
s= b-a/max(a,b)
a:一个数据点到同集群中所有其他点之间的平均距离
b:一个数据点到相邻最近集群中所有其他点之间的平均距离
package main
import (
"fmt"
"log"
"os"
"gonum.org/v1/gonum/floats"
"github.com/kniren/gota/dataframe"
)
// 检索浮点数据
func dfFloatRow(df dataframe.DataFrame, names []string, idx int) []float64 {
var row []float64
for _, name := range names {
row = append(row, df.Col(name).Float()[idx])
}
return row
}
func main() {
type centriod []float64
irisfile, err := os.Open("D:/gocode/iris.csv")
if err != nil {
log.Fatal(err)
}
defer irisfile.Close()
irisdara := dataframe.ReadCSV(irisfile)
// 根据花的种类进行分类
speciesName := []string{
"Iris-setosa",
"Iris-versicolor",
"Iris-virginica",
}
// 大循环是计算质心的
centriods := make(map[string]centriod)
clusters := make(map[string]dataframe.DataFrame)
for _, species := range speciesName {
filter := dataframe.F{
Colname: "species",
Comparator: "==",
Comparando: species,
}
filtered := irisdara.Filter(filter)
summarDf := filtered.Describe()
var c centriod
for _, feature := range summarDf.Names() {
if feature == "column" || feature == "species" {
continue
}
c = append(c, summarDf.Col(feature).Float()[0])
}
centriods[species] = c
// 计算轮廓系数新加入的
clusters[species] = filtered
}
for _, species := range speciesName {
fmt.Printf("%s centriod %v\n", species, centriods[species])
}
// 计算轮廓系数
labels := irisdara.Col("species").Records()
floatColumns := []string{
"sepal_length",
"Swidth",
"Plength",
"Pwidth",
}
var silhouette float64
for idx, label := range labels {
var a float64
for i := 0; i < clusters[label].Nrow(); i++ {
current := dfFloatRow(irisdara, floatColumns, idx)
other := dfFloatRow(clusters[label], floatColumns, i)
a += floats.Distance(current, other, 2) / float64(clusters[label].Nrow())
}
var otherClusters string
var distanceToCluster float64
for _, species := range speciesName {
if species == label {
continue
}
distanceForThisCluster := floats.Distance(centriods[label], centriods[species], 2)
if distanceToCluster == 0.0 || distanceForThisCluster < distanceToCluster {
otherClusters = species
distanceToCluster = distanceForThisCluster
}
}
var b float64
for i := 0; i < clusters[otherClusters].Nrow(); i++ {
current := dfFloatRow(irisdara, floatColumns, idx)
other := dfFloatRow(clusters[otherClusters], floatColumns, i)
b += floats.Distance(current, other, 2) / float64(clusters[otherClusters].Nrow())
}
if a > b {
silhouette += ((b - a) / a) / float64(len(labels))
}
silhouette += ((b - a) / b) / float64(len(labels))
}
fmt.Printf("\n 平均轮廓系数:%0.2f\n\n", silhouette)
}
6.3.2外部集群评估:
https://nlp.stanford.edu/IR-book/html/htmlediton/evaluation-of-clustering-1.html
6.4 K 均值群技术
github.com/mash/gokmeans
stanford.edu/class/ee103/visualizations/kmeans有交互动画
陷阱与假设
球形或空间分组的集群:K均值技术适合再球形或者空间上接近的区域绘制集群分布,对其他的空间分布可能不适合
相似的大小:小的外围集群可能会导致奇怪的分组
陷阱:
由于K是我们随机的选的,所以最好使用肘型图来寻找最佳的k
不能保证k均值总是收敛到相同的集群