1、K-means找中心点和数据点分类例子
import numpy as npdef loadDataSet(fileName):dataMat = []fr = open(fileName)for line in fr.readlines():curLine = line.strip().split('\t')fltLine = map(float,curLine)dataMat.append(fltLine)return dataMatdef distEclud(vecA,vecB):return np.sqrt(np.sum(np.power(vecA-vecB,2)))def randCent(dataSet,k):n = np.shape(dataSet)[1]'''centroids是一个3*2的矩阵,用于存储三个中心点的坐标'''centroids = np.mat(np.zeros((k,n))) for j in range(n): #统计每一列的最小值minJ = min(dataSet[:,j]) #每列最大值与最小值的差值rangeJ = float(max(dataSet[:,j]) - minJ)#random.rand(k,1) 产生k*1的数组,里面的数据是0~1的浮点型。array2 = minJ + rangeJ * np.random.rand(k,1)#转换成k*1矩阵 赋值给centroidscentroids[:,j] = np.mat(array2)return centroidsdef kMeans(dataSet, k, distMeas=distEclud, createCent=randCent):m = np.shape(dataSet)[0]
y.mat 将二维数组转换成矩阵clusterAssment = np.mat(np.zeros((m,2)))
createCent找到K个随机中心点坐标centroids = createCent(dataSet, k)
# print centroidsclusterChanged = Truewhile clusterChanged:clusterChanged = False#遍历80个数据到每个中心点的距离for i in range(m): #np.inf float的最大值,无穷大minDist = np.inf#当前点属于的类别号minIndex = -1#每个样本点到三个中心点的距离for j in range(k):
返回两点距离的值distJI = distMeas(centroids[j,:],dataSet[i,:])if distJI < minDist:#当前最小距离的值minDist = distJI#当前最小值属于哪个聚类minIndex = j#有与上次迭代计算的当前点的类别不相同的点if clusterAssment[i,0] != minIndex: clusterChanged = True#将当前点的类别号和最小距离 赋值给clusterAssment的一行clusterAssment[i,:] = minIndex,minDistfor cent in range(k):
ent[:,0].A==censInClust 取出的是对应是当前遍历cent类别的 所有行数据组成的一个矩阵ptsInClust = dataSet[np.nonzero(clusterAssment[:,0].A==cent)[0]]心点坐标的位置centroids[cent,:] = np.mean(ptsInClust, axis=0) #返回 【 当前三个中心点的坐标】 【每个点的类别号,和到当前中心点的最小距离】return centroids, clusterAssmentif __name__ == '__main__': 80*2的矩阵dataMat = np.mat(loadDataSet('./testSet.txt'))k=3
centroids, clusterAssment =
kMeans(dataMat, k, distMeas=distEclud, createCent=randCent)print centroidsprint clusterAssment
2、 使用matplotlib检验分类效果
对于分类结果,可以抽样数据使用matplotlib检验数据的分布情况。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs #建立12*12新的图像
plt.figure(figsize=(12, 12))
n_samples = 1500
random_state = 170
'''make_blobs函数是为聚类产生数据集 , 产生一个数据集和相应的标签 n_samples:表示数据样本点个数,默认值100 n_features:表示数据的维度,特征,默认值是2 centers:产生数据的中心点,默认值3个 shuffle :洗乱,默认值是True random_state:官网解释是随机生成器的种子
'''
#x返回的是向量化的数据点,y返回的是对应数据的类别号
x,y = make_blobs(n_samples=n_samples, random_state=random_state)
#使用KMeans去聚类,返回聚好的类别集合,聚合成几类
y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(x) #subplot 绘制多个子图,221 等价于2,2,1 表示两行两列的子图中的第一个
plt.subplot(221)
#scatter 绘制散点图
plt.scatter(x[:, 0], x[:, 1], c=y_pred)
plt.title("kmeans01") transformation = [[ 0.60834549, -0.63667341], [-0.40887718, 0.85253229]]
#numpy.dot 矩阵相乘
X_aniso = np.dot(x, transformation)
y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_aniso)
plt.subplot(222)
plt.scatter(X_aniso[:, 0], X_aniso[:, 1], c=y_pred)
plt.title("kmeans02") #vstack 是合并矩阵,将y=0类别的取出500行,y=1类别的取出100行,y=2类别的取出10行
X_filtered = np.vstack((x[y == 0][:500], x[y == 1][:100], x[y == 2][:10]))
y_pred = KMeans(n_clusters=3, random_state=random_state).fit_predict(X_filtered)
plt.subplot(223)
plt.scatter(X_filtered[:, 0], X_filtered[:, 1], c=y_pred)
plt.title("kmeans03")dataMat = []
fr = open("testSet.txt","r")
for line in fr.readlines():if line.strip() <> "":curLine = line.strip().split('\t')fltLine = map(float,curLine) dataMat.append(fltLine)
dataMat = np.array(dataMat)
y_pred = KMeans(n_clusters=4, random_state=random_state).fit_predict(dataMat)
plt.subplot(224)
plt.scatter(dataMat[:,0], dataMat[:, 1], c=y_pred)
plt.title("kmeans04")
plt.savefig("./kmeans.png")
plt.show()
3、使用SparkMllib训练K-means模型
object KMeans {def main(args: Array[String]) {//1 构建Spark对象val conf = new SparkConf().setAppName("KMeans").setMaster("local")val sc = new SparkContext(conf)// 读取样本数据1,格式为LIBSVM formatval data = sc.textFile("kmeans_data.txt")
val parsedData = data.map(s => Vectors.dense(s.split(' ')
.map(_.toDouble))).cache()val numClusters = 4val numIterations = 100val model = new KMeans().//设置聚类的类数setK(numClusters).//设置找中心点最大的迭代次数setMaxIterations(numIterations).run(parsedData)//四个中心点的坐标val centers = model.clusterCentersval k = model.kcenters.foreach(println)println(k)//保存模型
// model.save(sc, "./Kmeans_model")//加载模型val sameModel = KMeansModel.load(sc, "./Kmeans_model")println(sameModel.predict(Vectors.dense(1,1,1)))val sqlContext = new SQLContext(sc)sqlContext.read.parquet("./Kmeans_model/data").show()}
}
给Kmeans指定中心点坐标:
object KMeans2 {def main(args: Array[String]) {val conf = new SparkConf().setAppName("KMeans2").setMaster("local")val sc = new SparkContext(conf)val rdd = sc.parallelize(List(Vectors.dense(Array(-0.1, 0.0, 0.0)),Vectors.dense(Array(9.0, 9.0, 9.0)),Vectors.dense(Array(3.0, 2.0, 1.0))))//指定文件 kmeans_data.txt 中的六个点为中心点坐标。val centroids: Array[Vector] = sc.textFile("kmeans_data.txt").map(_.split(" ").map(_.toDouble)).map(Vectors.dense(_)).collect()val model = new KMeansModel(clusterCenters=centroids)println("聚类个数 = "+model.k)//模型中心点model.clusterCenters.foreach { println }//预测指定的三条数据val result = model.predict(rdd)result.collect().foreach(println(_))}
}