1. 应用K-means算法进行图片压缩

读取一张图片

观察图片文件大小,占内存大小,图片数据结构,线性化

用kmeans对图片像素颜色进行聚类

获取每个像素的颜色类别,每个类别的颜色

压缩图片生成:以聚类中收替代原像素颜色,还原为二维

观察压缩图片的文件大小,占内存大小

 首先来看一下完整代码:


from sklearn.datasets import load_sample_image
from matplotlib import pyplot as plt
from sklearn.cluster import KMeans
import numpy as np
import sys

#读取一张sklearn.datasets里的图片china.jpg
china = load_sample_image('china.jpg')
plt.show()

#观察china图片的大小和内存
print("china图片原大小:",china.size)
print("china图片原内存:",sys.getsizeof(china))

#根据图片的分辨率,可适当降低分辨率
img=china[::4,::4]  #降低分辨率
x=img.reshape(-1,3)  #生成行数未知,列数为3

#将图片中所有的颜色值做聚类,然后获取每个像素的颜色类别,每个类别的颜色。
n_colors=64
model=KMeans(n_colors)
labels=model.fit_predict(x) #每个点颜色分类,训练x
colors=model.cluster_centers_#找聚类点
new_img=colors[labels].reshape(img.shape)

#形成新的图片
plt.imshow(new_img.astype(np.uint8))
plt.show()

#观察新图片的大小与所占用内存的大小。
print("压缩后大小:",new_img.size)
print("压缩后内存:",sys.getsizeof(new_img))

   一开始最困难的一件事就是安装图像数据库,尝试了各种办法都安装不了PIL,查了才知道PIL库最多支持到python2的版本,我使用的是python3.7版本所以安装不了PIL。然后查了csdn知道3.7版本可以直接安装Pillow库,这个库里包涵了PIL,所以安装后就解决了。(ps:因为最新的7.1.1版本用不了,所以我安装的是低版本的Pillow库)

 

 

 

原图片: 

 

 

经过k-means聚类后新图片:

 

 

 图片各种信息:

 

 

 

2. 观察学习与生活中可以用K均值解决的问题。

从数据-模型训练-测试-预测完整地完成一个应用案例。

这个案例会作为课程成果之一,单独进行评分。

 

本案例主要是研究汽车价格与已行驶里程数的关系:

详细代码:

# KMeans聚类分析
import numpy as np
import matplotlib.pyplot as plt
def load_dataset(file_name):
    data_mat = []
    with open(file_name) as fr:
        lines = fr.readlines()
    for line in lines:
        cur_line = line.strip().split("\t")
        flt_line = list(map(lambda x:float(x), cur_line))
        data_mat.append(flt_line)
    return np.array(data_mat)
data_set = load_dataset(r"./data/201706120189-翟梓乐.txt") #从文本文件中读入数据到矩阵
print(data_set)


def dist_eclud(vecA, vecB):  #欧几里得距离函数
    vec_square = []
    for element in vecA - vecB:
        element = element ** 2
        vec_square.append(element)
    return sum(vec_square) ** 0.5


def rand_cent(data_set, k): #构建k个随机质心
    n = data_set.shape[1]
    centroids = np.zeros((k, n))
    for j in range(n):
        min_j = float(min(data_set[:,j]))
        range_j = float(max(data_set[:,j])) - min_j
        centroids[:,j] = (min_j + range_j * np.random.rand(k, 1))[:,0]
    return centroids


def Kmeans(data_set, k):    #定义K-means函数实现算法
    m = data_set.shape[0]
    cluster_assment = np.zeros((m, 2))
    centroids = rand_cent(data_set, k)
    cluster_changed = True
    while cluster_changed:
        cluster_changed = False
        for i in range(m):
            min_dist = np.inf; min_index = -1
            for j in range(k):
                dist_ji = dist_eclud(centroids[j,:], data_set[i,:])
                if dist_ji < min_dist:
                    min_dist = dist_ji; min_index = j
            if cluster_assment[i,0] != min_index:
                cluster_changed = True
            cluster_assment[i,:] = min_index, min_dist**2
        for cent in range(k):
            pts_inclust = data_set[np.nonzero(list(map(lambda x:x==cent, cluster_assment[:,0])))]
            centroids[cent,:] = np.mean(pts_inclust, axis=0)
    return centroids, cluster_assment

my_centroids, my_cluster_assment = Kmeans(data_set, 4)
print(my_centroids)


# 建立图形
point_x = data_set[:,0]
point_y = data_set[:,1]
cent_x = my_centroids[:,0]
cent_y = my_centroids[:,1]
fig, ax = plt.subplots(figsize=(10,5))
ax.scatter(point_x, point_y, s=30, c="green", marker="o", label="sample point")
ax.scatter(cent_x, cent_y, s=100, c="black", marker="v", label="centroids")
ax.legend()
ax.set_xlabel("factor1")
ax.set_ylabel("factor2")
plt.title('K-means')
plt.show()
plt.savefig(“julei.png”)

 

从售卖二手车网站爬取的资料(已经过数据处理),分别是同一类车型的价格和已行驶里程数据:

 

 

 用k-means算法来分析他们之间的关系:

 

 

由图可以看出,在二手车交易中汽车价格越低行驶里程数就会越高,也可以说二手车的已行驶里程数会影响车的价格,所以行驶里程与价格有着很大的关系: