文章目录

  • 前言
  • 算法
  • KMEANS-家庭消费调查
  • DBSCAN-上网时间分布
  • KMEANS-整图分割
  • 总结



前言

对中国大学MOOC-北京理工大学-“Python机器学习应用”上的实例进行分析和修改:记录一些算法、函数的使用方法;对编程思路进行补充;对代码中存在的问题进行修改。
课程中所用到的数据


算法

1.K-Means

from sklearn.cluster import KMeans
km = KMeans(n_clusters=3)#创建实例。n_clusters聚类数;init初始化方法;max_iter迭代次数
label = km.fit_predict(data)#聚类计算(fit),返回序号(predict)

2.DBSCAN

from sklearn.cluster import DBSCAN
db = DBSCAN(eps=0.01, min_samples=20)#创建实例,无需指定聚类数。eps最大距离;min_samples样本数;metric距离计算方式
label = db.fit_predict(start)#聚类计算(fit),返回序号(predict)

KMEANS-家庭消费调查

1、引入库

import numpy as np#处理数组
from sklearn.cluster import KMeans

2、加载数据

def LoadData( path ):
    f = open(path, 'r+')
    lines = f.readlines()
    data = []#初始标签
    city = []#数据
    for line in lines:
        items = line.strip().split(',')
        expense = []
        for i in range(1, len(items)):
            expense.append(items[i])
        city.append(items[0])
        data.append(expense)
    return city, data

3、训练
(1)np.sum(array, axis=1):对数组元素求和。根据axis的取值,块与块之间从外向内求和,axis=0,对同一列求和,axis=1,对同一行求和。
(2)km.cluster_centers_:K-Means聚类中心。

city, data = LoadData('./database/31省市居民家庭消费水平-city.txt')
km = KMeans(n_clusters=3)
label = km.fit_predict(data)#返回簇序号(0/1/2),位置与数据对应
expenses = np.sum(km.cluster_centers_, axis=1)#对同一簇的各维度聚类中心求和
citycluster = [[], [], []]
for i in range(len(city)):
    citycluster[label[i]].append(city[i])#将标签按簇归类
for i in range(len(citycluster)):#打印不同簇的中心及标签
    print("Expences:{:.2f}".format(expenses[i]))
    print(citycluster[i])

4、运行结果

python 短文本聚类 python 聚类函数_python 短文本聚类

DBSCAN-上网时间分布

1、引入库

import numpy as np
from sklearn.cluster import DBSCAN
from sklearn import metrics#评价指标
import matplotlib.pyplot as plt#数据展示

2、加载数据

def LoadData(path):
    f = open(path, 'r+', encoding = "utf-8")
    lines = f.readlines()
    data = []
    for line in lines:
        items = line.split(',')
        start = int(items[4].split(' ')[1].split(':')[0])#起始时间
        time = int(items[6])#上网时长
        data.append([start, time])
    return np.array(data)#将列表转化为数组
data = LoadData("./database/学生月上网时间分布-TestData.txt")

3、训练
(1)array[i1:j1,i2:j2]:以逗号分隔,对数组两个维度切片。
(2)list.count(a):计算列表中元素a出现的次数。
(3)metrics.silhouette_score(data,label):样本轮廓系数,评价聚类效果,1为最优,-1为最差,0表示重叠,负数表示错配。
(4)array.flatten():降维函数。
(5)plt.hist(x,bins,range):绘制直方图,x数据;bins柱数;range范围。
(6)np.log(array):对数组中各元素取自然对数。
(7)np.mean(array):求数组的均值。
(8)np.std(array):求数组的标准差。

#按起始时间聚类
start = data[:,0:1]#提取数据
db = DBSCAN(eps=0.01, min_samples=20)
label = db.fit_predict(start)
print("Labels")
print(label)
noise = list(label).count(-1)/len(label)#计算噪声点(簇序号为-1)的比例
print("noise ratio:{:.2%}".format(noise))
clusters = len(set(label))#将数组转化为集合,计算簇的数目
if -1 in label:
    clusters -= 1#噪声点不计入
print("Estimated number of clusters:", clusters)
print("Silhouette Coeffcient:{:.3f}".format(metrics.silhouette_score(start,label)))#样本轮廓系数
for i in range(clusters):
    print("Clusters", i, ":")
    print(list(start[label==i].flatten()))#提取第i簇的数据,并转化为一维列表。
    # 对于其他簇的数据,label==i返回False,不进行操作。
plt.hist(start, 24)#绘制直方图
plt.show()#显示图像
#按上网时长聚类
times = data[:, 1:]#提取数据
time = np.log(1+times)#取对数,减小数据波动
db = DBSCAN(eps=0.14, min_samples=10)
label = db.fit_predict(time)
print("labels")
print(label)
noise = len(label[label[:]==-1])/len(label)#计算噪声点(簇序号为-1)的比例。
    # 对于非噪声点,label==-1返回False,不进行统计。
print("noise ratio:{:.2%}".format(noise))
clusters =len(set(label))
if -1 in label:
    clusters -= 1
print("Estimated number of clusters:", clusters)
print("Silhouette Coeffcient:{:.3f}".format(metrics.silhouette_score(time,label)))
for i in range(clusters):
    print("Clusters", i, ":")
    count = len(times[label[:]==i].flatten())#统计第i簇样本数量
    mean = np.mean(times[label[:]==i])#求第i簇样本均值
    std = np.std(times[label[:]==i])#求第i簇样本标准差
    print("number of sample:{}".format(count))
    print("mean of sample:{:.1f}".format(mean))
    print("std of sample:{:.1f}".format(std))

4、运行结果

python 短文本聚类 python 聚类函数_python_02

KMEANS-整图分割

1、引入库

import numpy as np
import PIL.Image as image#图像处理
from sklearn.cluster import KMeans

2、加载数据
(1)image.open(path):打开图片。
(2)image.show(title):展示图片。
(3)image.size:返回图片的长、宽。
(4)image.getpixel((i,j)):获取处于(i,j)位置像素点的rgb值。
(5)np.mat(list):生成数组,mat可以从字符串或列表中生成,array只能从列表中生成。

def LoadData(path):
    f = open(path, 'rb')#二进制读取
    data = []
    img = image.open(f)
    img.show("old")#原始图片
    m, n = img.size#获取图片长宽帧数
    for i in range(m):
        for j in range(n):
            r, g, b = img.getpixel((i,j))#获取像素点的rgb值
            data.append([r/256.0, g/256.0, b/256.0])#归一化
    f.close()
    return np.mat(data), m, n#返回数组,维度

3、训练
(1)array.reshape(i,j):将数组转化为i行j列。
(2)image.new(mode, size, color=0):创建图像,mode模式; size大小; color颜色。
(3)image.putpixel(loc,rgb):设置像素rgb值,loc位置。
(4)img.save(path):保存图像

data, m, n = LoadData("./database/bull.jpg")
km = KMeans(n_clusters=4)
label = km.fit_predict(data)#根据rgb三个维度聚类,返回一维标签序列
label = label.reshape(m, n)#转化为与图片相同大小的数组
img = image.new('L', (m, n))#创建图像,灰度模式,大小与原图像相同
for i in range(m):
    for j in range(n):
        img.putpixel((i,j), int(256/(label[i][j]+1)))#设置像素值,+1避免除0
img.save("./database/cut.jpg","JPEG")#保存图像
img.show("new")

4、运行结果

python 短文本聚类 python 聚类函数_python 短文本聚类_03


总结

K-Means:依靠距离聚类,需要指定聚类数目,对聚类中心初始化敏感。
DBSCAN:依靠密度聚类,无需指定聚类数目,不适合密度变化太大和高维的数据。