• K均值算法--应用


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

    读取一张图片

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

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

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

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

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

    代码如下:

    from sklearn.datasets import load_sample_image
    from sklearn.cluster import KMeans
    import matplotlib.pyplot as plt
    import numpy as np
    import matplotlib.image as mpimg
    import sys
    
    #加载样本图像
    # image = load_sample_image('china.jpg')
    #加载本地图片
    image = mpimg.imread('image2.jpg')
    #降维(将二维图片变成一维)
    X = image.reshape(-1,3)
    print(image.shape,X.shape)
    
    #进行聚类将255*255*255聚成64类
    n_colors=64
    model=KMeans(n_colors)
    #一维(273280, 3)对每一个像素进行分类
    labels=model.fit_predict(X)
    #将273280分成64类
    colors=model.cluster_centers_
    
    new_image=colors[labels].reshape(image.shape)
    #显示原图片
    plt.imshow(image)
    plt.show()
    #显示压缩后的图片
    new_image=new_image.astype(np.uint8)
    plt.imshow(new_image)
    plt.show()
    #二次压缩(每三个像素取一个)
    new_image=new_image.astype(np.uint8)[::3,::3]
    plt.imshow(new_image)
    plt.show()
    
    print("image Size:",sys.getsizeof(image))
    print("new_image Size:",sys.getsizeof(new_image))
    
    import matplotlib.image as img
    img.imsave('F:\01.jpg',image)
    img.imsave('F:\02.jpg',new_image)

    原图:

     第一次压缩后的图:

     第二次压缩后的图:

     原图和压缩后的图的大小对比:

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

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

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

    将不同工作经验者的工资进行Kmeans算法归类

    • 爬取30000条智联招聘网的招聘信息
    import requests
    import re
    import csv
    # https://www.zhipin.com/c101280100/?query=Java
    # https://jobs.51job.com/guangzhou/p1/
    # <span class="location">10-15万/年</span>
    # <div class="e ">D+</div>
    # <p class="info">(.*?)</p>D+<p class="order">(.*?)</p>
    i=1
    with open('data.csv', 'a+', newline='', encoding='utf8') as f:
        writer = csv.writer(f, dialect="excel")
        writer.writerow(['职位','地址','工资','发布日期','学历要求','工作经验','公司性质','公司规模'])
        while True:
            url = "https://jobs.51job.com/guangzhou/hy01/p"+str(i)+"/"
            int(i)
            i+=1
            print(url)
            response = requests.get(url)
            if response.status_code!=200:
                break
            response.encoding='gbk'
            data_list = re.findall('<p class="info">(.*?)</p>D+<p class="order">(.*?)</p>',response.text)
            datac = {}
            for data in data_list:
                # print(data[0])
                data1 = re.findall('<a.*?target="_blank".*?>(.*?)</a>.*?<span class="location name">(.*?)</span>.*?<span class="location">(.*?)</span>.*?<span class="time">(.*?)</span>',data[0])
                # print(data1)
                datac['职位']=data1[0][0]
                datac['地址']=data1[0][1]
                datac['工资']=data1[0][2]
                datac['发布日期']=data1[0][3]
                # print(data[1])
                data2 = re.findall('学历要求:(.*?)<span>.*?工作经验:(.*?)<span>.*?公司性质:(.*?)<span>.*?公司规模:(.*)',data[1])
                # print(data1)
                datac['学历要求']=data2[0][0]
                datac['工作经验']=data2[0][1]
                datac['公司性质']=data2[0][2]
                datac['公司规模']=data2[0][3]
                if datac:
                    writer.writerow([datac['职位'],datac['地址'],datac['工资'],datac['发布日期'],datac['学历要求'],datac['工作经验'],datac['公司性质'],datac['公司规模']])
    • 处理爬取到的信息
    from pandas import read_csv
    import re
    import csv
    import numpy as np
    
    data=read_csv('data.csv')
    
    # dict={}#字典去重
    # dict2=[]#地址去重后的存放容器
    # #地址去重
    # for i in data['工资']:
    #     i = str(i)#1-1.5万/月
    #     d=re.findall('d+.?d*-d+.?d(.*/.*)', i)
    #     if d:
    #         dict[d[0]]=0
    # for i in dict.keys():
    #     print(i)
    
    # 查询出来的结果
    # 万/月 千/月 万/年
    
    def format(x):
        x = str(x)
        min1=re.findall('(d+.?d*)-(d+.?d*)?(千/月)', x)
        if min1:
            # print(float(min1[0][0])*1000)
            min=str(float(min1[0][0])*1000)
            max=str(float(min1[0][1])*1000)
            return min+"-"+max
        min2 = re.findall('(d+.?d*)-(d+.?d*)?(万/月)', x)
        if min2:
            # print(float(min2[0][0])*10000)
            min=str(float(min2[0][0])*10000)
            max=str(float(min2[0][1])*10000)
            return min+"-"+max
        min3 = re.findall('(d+.?d*)-(d+.?d*)?(万/年)', x)
        if min3:
            # print(float(min2[0][0])*10000)
            min=str(float(min3[0][0])*10000/12)
            max=str(float(min3[0][1])*10000/12)
            return min+"-"+max
    data['工资']=data['工资'].apply(format)
    data[['最低工资','最高工资']]=data['工资'].str.split('-',1,True)
    data=data.drop(['工资'],axis=1)#删除工资列
    print(data)
    
    data=data.dropna()
    
    data['平均工资']=(data.最低工资.astype(float)+data.最高工资.astype(float))/2
    
    with open('mogong.csv', "w", newline='', encoding='utf8') as f:
        writer = csv.writer(f)
        writer.writerow(data.columns)
        writer.writerows(data.values)
    • 用Kmeans算法进行归类
    from sklearn.cluster import KMeans
    import pandas as pd
    import matplotlib.pyplot as plt
    from pylab import mpl
    
    data = pd.read_csv('mogong.csv')
    # 去重后的存放容器
    dict2=[]
    sumSalary={}
    column=['工作经验']
    # 轴坐标存放容器
    X = []
    
    
    #获取样本种类(样本去重)
    def getKind(column):
        for i in data[column]:
            sumSalary[i]=0
        for i in sumSalary.keys():
            dict2.append(i)
    
    def format(x):
        for j in dict2:
            if x == j:
                return dict2.index(j)+1
    
    def relationCoefficient(column1):
        getKind(column1)
        data[column1] = data[column1].apply(format)
    
    for i in column:
        relationCoefficient(i)
        # 备份dict2数据
        X=dict2
        # 初始化容器
        dict2=[]
        sumSalary={}
    
    data = data[['工作经验','平均工资']].astype(int)[0:6000].values
    
    # 构建模型
    model = KMeans(n_clusters=5).fit(data)
    model.labels_
    
    # 查看聚类效果
    mpl.rcParams['font.sans-serif'] = ['SimHei']  # 雅黑字体
    for i in range(5):
        plt.scatter(data[model.labels_ == i, 0], data[model.labels_ == i, 1])
    # 替换坐标
    plt.xticks(range(1,len(X)+1),X,rotation=30)
    # 设置y轴名称
    plt.ylabel("每月工资")
    plt.show()

    结果图如下

  • 相关阅读:
    ThreadPoolExecutor线程池参数设置技巧
    CountDownLatch与join的区别和联系
    数据库的隔离级别
    Spring事务管理的demo
    Java中isAssignableFrom的用法
    Java注解的基本概念和原理及其简单实用
    System.getProperty("line.separator") 是什么意思?
    关于“100g文件全是数组,取最大的100个数”解决方法汇总
    Intellij IDEA 添加jar包的三种方式
    亿级Web系统搭建 Web负载均衡的几种实现方式(阿里)
  • 原文地址:https://www.cnblogs.com/mogong/p/12732820.html
Copyright © 2020-2023  润新知