作业四——K均值算法--应用

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

(1)读取一张图片(照片来源:微博@喵呜不停)

 

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

 1 from matplotlib import pyplot as plt
 2 from sklearn.cluster import KMeans
 3 import numpy as np
 4 import matplotlib.image as img
 5 
 6 plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
 8 
 9 img1 = img.imread("./img/cat.jpg")
10 
11 # 根据图片的分辨率,可适当降低分辨率
12 img2 = img1[::6, ::6]  # 降低分辨率,训练时减短等待时间
13 X = img1.reshape(-1, 3)  # 生成行数未知,列数为3
14 print(img1.shape, img2.shape, X.shape)

 打印输出:

 

 

 

(3)压缩图片

 · 构造函数方法:

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

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

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

 

 1 # 构建模型 :用k均值聚类算法,将图片中所有的颜色值做聚类。
 2 def cluster(x, n_colors):
 3     model = KMeans(n_clusters=n_colors, n_init=10, max_iter=200)
 4     model.fit(x)
 5     labels = model.predict(x)  # 每个像素颜色类别
 6     colors = model.cluster_centers_  # 聚类中心,每个类别的颜色值
 7     # img = colors[labels]
 8     # 重塑图片:用聚类中心的颜色代替原来的颜色值,还原为二维。
 9     new_img = colors[labels]
10     # new_img = img.astype(np.uint8)
11     return new_img

 

 · 利用函数生成压缩图片

 

1 # 形成新的图片(8,32,64,128)
2 img_8 = cluster(X, 8).reshape(img1.shape).astype(np.uint8)
3 img_32 = cluster(X, 32).reshape(img1.shape).astype(np.uint8)

 

 

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

 1 # 观察原始图片与新图片。
 2 plt.subplot(131)
 3 plt.title("原图")
 4 plt.imshow(img1)
 5 
 6 plt.subplot(132)
 7 plt.title("聚类32种颜色")
 8 plt.imshow(img_32)
 9 
10 plt.subplot(133)
11 plt.title("聚类8种颜色")
12 plt.imshow(img_8)
13 plt.show()

 

 

1 # 将原始图片与新图片保存成文件,观察文件的大小。
2 plt.imsave("./img/img1.jpg", img1)
3 plt.imsave("./img/img_8.jpg", img_8)
4 plt.imsave("./img/img_32.jpg", img_32)
5 import sys  # 查看内存大小
6 
7 sys.getsizeof(img1)
8 sys.getsizeof(img_8)
9 print("原图大小:" + img1.size + "\n 聚类8类图片大小:" + img_8.size)

 

运行结果:

 

 · 对比按比例压缩和K-Means算法压缩

 

 1 plt.subplot(131)
 2 plt.title("原图")
 3 plt.imshow(img1)
 4 
 5 plt.subplot(132)
 6 plt.title("聚类8种颜色")
 7 plt.imshow(img_8)
 8 plt.show()
 9 
10 plt.subplot(133)
11 plt.title("每隔6个像素点压缩")
12 plt.imshow(img2)

  · 经过等比压缩后和K-Means算法联合压缩后图片的大小

 

 

 

参考资料:Kmeans算法原理与应用-RGB图像压缩

 

 

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

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

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

 

 · 分析某淘宝店铺的客户群体划分

以淘宝天池User Behavior Data on Taobao App作为源数据

1)数据处理:

筛选一个星期(2014-11-18至2014-11-24)客户成交订单(behavior_type=4)的数据量

 删除无用列 用户所在地理位置、商品种类、用户行为

日期格式设置为 YY-MM-DD

 

 1 import pandas as pd
 2 import datetime
 3 
 4 data = pd.read_csv("./data/user.csv", encoding="utf-8", low_memory=False)
 5 data = data.drop("user_geohash", axis=1)  # 删除用户地理位置
 6 data = data.drop("item_id", axis=1)  # 删除商品id
 7 # data.keys()
 8 data = data.dropna()
 9 data = data.loc[data["behavior_type"] == 4]  # 筛选用户已支付订单
10 data = data.drop("behavior_type", axis=1)  # 删除用户操作类型
11 # 修改时间格式
12 data['time'] = data['time'].map(lambda x: x.split(" ")[0])
13 data['time'] = data['time'].map(lambda x: datetime.datetime.strptime(x, '%Y-%m-%d'))
14 # 将商品的类别当成商品金额来处理(数据源没有订单金额,将就叭)
15 data.rename(columns={'item_category': 'item_money'}, inplace=True)
16 # 获取每个用户的消费总金额
17 df2 = data.groupby(by=['user_id'])['item_money'].sum()
18 data2 = pd.DataFrame({"user": df2.index, "count": df2})
19 # 获取每个用户距离24号的最新一次消费的日间隔
20 df3 = datetime.datetime.strptime("2014-11-24", '%Y-%m-%d') - data.groupby(by=['user_id'])['time'].max()
21 df3 = df3.map(lambda x: x.days)
22 data3 = pd.DataFrame({"user": df3.index, "recent_consume": df3})
23 data_rfm = pd.merge(data2, data3, how='left', on='user')
24 data_rfm.to_csv("./data/rfm.csv")

 

 2)构建模型

 

1 from matplotlib import pyplot as plt
2 from sklearn.cluster import KMeans
3 import numpy as np
4 X = data_rfm.iloc[:, 1:]
5 est = KMeans(n_clusters=3)
6 est.fit(X)

 

 

 

 3)预测数据

通过直方图可以直观的看出该店铺的活跃客户人数

 

1 y_means = est.predict(X)
2 level, number = np.unique(y_means,return_counts=True)
3 plt.barh(level, number)
4 plt.show()

 

 

 

 

 参考资料:RFM模型淘宝用户行为分析

posted @ 2020-04-16 15:57  酒大暗  阅读(301)  评论(0编辑  收藏  举报