精华内容
下载资源
问答
  • 话不多说,自己上篇爬虫博客写的还行,10000的阅读量以及360多的收藏和100多的点赞评论,自己一个一个发送代码发了一个多月,现在正式开源! 写在前面: 自己已经创建公众号啦~ AI算法交流+开源数据汇总+私房数据及...


    话不多说,自己上篇爬虫博客写的还行,10000的阅读量以及360多的收藏和100多的点赞评论,自己一个一个发送代码发了一个多月,现在正式开源!
    附上原文传送门https://blog.csdn.net/qq_46098574/article/details/106048756

    写在前面:

    自己已经创建公众号啦~

    AI算法交流+开源数据汇总+私房数据及标注数据共享+自己实践项目开源

    欢迎大家关注:DeepAI 视界

    在这里插入图片描述

    展示一下:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    爬虫:链接网二手房(以贵阳市为例)

    """
    爬虫
    """
    import requests
    from lxml import etree
    import xlwt
    import xlrd
    import csv
    import pandas as pd
    import time
    import re
    class LanjiaSpider:
        def __init__(self):
            self.url = 'https://wh.lianjia.com/ershoufang/ronganxian/pg{}/'
            self.headers = {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"}
    
        def get_response_spider(self, url_str):  # 发送请求
            get_response = requests.get(url_str, headers=self.headers)
            time.sleep(2)
            response = get_response.content.decode()
            html = etree.HTML(response)
            return html
        def get_content_html(self, html):  # 使xpath获取数据
            self.houseInfo = html.xpath('//div[@class="houseInfo"]/text()')
            self.title = html.xpath('//div[@class="title"]/a/text()')
            self.positionInfo = html.xpath('//div[@class="positionInfo"]/a/text()')
            self.totalPrice = html.xpath('//div[@class="totalPrice"]/span/text()')
            self.unitPrice = html.xpath('//div[@class="unitPrice"]/span/text()')
            self.followInfo = html.xpath('//div[@class="followInfo"]/text()')
            self.tag = html.xpath('//div[@class="tag"]/span/text()')
            # print(title)
            # return houseInfo,title,positionInfo,totalPrice,unitPrice,followInfo,tag
    
        def xpath_houseInfo(self):
            #print(self.houseInfo)
            #print(type(self.houseInfo))
            # df = pd.DataFrame({"houseInfo": self.houseInfo,"tite":self.title,"positionInfo":self.positionInfo,"totaPrice":self.totalPrice,"unitPrice":self.unitPrice,"followInfo":self.followInfo,"tag":self.tag})
            # df=pd.DataFrame({"houseInfo": self.houseInfo,"tite":self.title})
            # df.to_excel(r'C:\Users\wy\Desktop\sublime\链家\pand3.xlsx')
            # a=len(self.houseInfo)
            for i in range(len(self.houseInfo)):
                # print(i)
                # yield i
                # print(type(self.houseInfo))
                yield self.houseInfo[i]
    
        def qingxi_data_houseInfo(self):  # 清洗数据
    
            self.xpath_houseInfo()
            self.xpath_title()
            self.xpath_positionInfo()
            self.xpath_totalPrice()
            self.xpath_unitPrice()
            self.xpath_followInfo()
            self.xpath_tag()
            get_houseInfo = self.xpath_houseInfo()
            get_title = self.xpath_title()
            get_positionInfo=self.xpath_positionInfo()
            get_totalPrice = self.xpath_totalPrice()
            get_unitPrice = self.xpath_unitPrice()
            get_followInfo=self.xpath_followInfo()
            get_tag=self.xpath_tag()
            i = 1
    
            while True:
                data_houseInfo= next(get_houseInfo)
                data_title=next(get_title)
                data_positionInfo=next(get_positionInfo)
                data_totalPrice=next(get_totalPrice)
                data_unitPrice=next(get_unitPrice)
                data_followInfo=next(get_followInfo)
                data_tag=next(get_tag)
    
                with open("a.csv", "a", newline="", encoding="utf-8-sig") as f:
                    # fieldnames = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
                    # writer = csv.DictWriter(f, fieldnames=fieldnames)  # 写入表头
                    # writer.writeheader()
                    writer = csv.DictWriter(f, fieldnames=fieldnames)  # 写入表头
    
                    list_1 = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
                    list_2 = [data_houseInfo,data_title,data_positionInfo,data_totalPrice,data_unitPrice,data_followInfo,data_tag]
                    list_3 = dict(zip(list_1, list_2))
                    writer.writerow(list_3)
                    print("写入第"+str(i)+"行数据")
                i += 1
                if i > len(self.houseInfo):
                    break
    
        def xpath_title(self):
            for i in range(len(self.title)):
                yield self.title[i]
    
        def xpath_positionInfo(self):
            for i in range(len(self.positionInfo)):
                yield self.positionInfo[i]
    
        def xpath_totalPrice(self):
            for i in range(len(self.totalPrice)):
                yield self.totalPrice[i]
        def xpath_unitPrice(self):
            for i in range(len(self.unitPrice)):
                yield self.unitPrice[i]
        def xpath_followInfo(self):
            for i in range(len(self.followInfo)):
                yield self.followInfo[i]
        def xpath_tag(self):
            for i in range(len(self.tag)):
                yield self.tag[i]
        def run(self):
            i = 1
            while True:
                url_str = self.url.format(i)  # 构造请求url
                html = self.get_response_spider(url_str)
                self.get_content_html(html)
                self.qingxi_data_houseInfo()
    
                i += 1
                if i == 1:  # 不包括57页
                    break
    
    
    if __name__ == "__main__":
        with open("a.csv", "a", newline="", encoding="utf-8-sig") as f:
            fieldnames = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
            writer = csv.DictWriter(f, fieldnames=fieldnames)  # 写入表头
            writer.writeheader()
        lanjia = LanjiaSpider()
        lanjia.run()
    
    

    对应的数据可视化:

    """
    数据分析及可视化
    """
    import pandas as pd
    from pyecharts.charts import Line, Bar
    import numpy as np
    from pyecharts.globals import ThemeType
    from pyecharts.charts import Pie
    from pyecharts import options as opts
    
    
    places = ['lianjia_BaiYunQu', 'lianjia_GuanShanHuQu', 'lianjia_HuaXiQu', 'lianjia_NanMingQu', 'lianjia_WuDangQu', 'lianjia_YunYanQu']
    place = ['白云区', '观山湖区', '花溪区', '南明区', '乌当区', '云岩区']
    avgs = []  # 房价均值
    median = []  # 房价中位数
    favourate_avg = []  # 房价收藏人数均值
    favourate_median = []  # 房价收藏人数中位数
    houseidfo = ['2室1厅', '3室1厅', '2室2厅', '3室2厅', '其他']  # 房型定义
    houseidfos = ['2.1', '3.1', '2.2', '3.2']
    sum_house = [0,  0, 0, 0, 0]  # 各房型数量
    price = []  # 房价
    fav = []  # 收藏人数
    type = []
    area = []  # 房间面积
    def avg(name):
        df = pd.read_csv(str(name)+'.csv', encoding='utf-8')
        pattern = '\d+'
        df['totalPrice/万元'] = df['totalPrice/万元'].str.findall(pattern)
        df['followInfo'] = df['followInfo'].str.findall(pattern)
        df['houseInfo'] = df['houseInfo'].str.findall(pattern)
        sum_houses = [0, 0, 0, 0, 0]
        # print(sum_house)
        avg_work_year = []
        medians = []
        favourates = []
        k = 0
        k1 = 0
        k3 = 0
        k4 = 0
    
        for i in range(len(df)):
            if (i + 1) % 2 == 0:
                continue
            else:
                if len(df['totalPrice/万元'][i]) == 2:
                    avg_work_year.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
                    medians.append(float(','.join(df['totalPrice/万元'][i]).replace(',', '.')))
                    price.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
                if len(df['followInfo'][i]) ==2:
                    favourates.append(int(','.join(df['followInfo'][i][:1])))
                    fav.append(int(','.join(df['followInfo'][i][:1])))
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.1:
                    k +=1
                    sum_houses[0] =k
                    type.append(2.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.1:
                    k1 +=1
                    sum_houses[1] =k1
                    type.append(3.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.2:
                    k3 +=1
                    sum_houses[2] =k3
                    type.append(2.2)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.2:
                    k4 +=1
                    sum_houses[3] =k4
                    type.append(3.2)
                else:
                    k4 +=1
                    sum_houses[4] = k4
                    type.append('other')
                area.append(float(','.join(df['houseInfo'][i][2:4]).replace(',', '.')))
        sum_house[0] =sum_houses[0]
        sum_house[1] = sum_houses[1]
        sum_house[2] = sum_houses[2]
        sum_house[3] = sum_houses[3]
        sum_house[4] = sum_houses[4]
    
        favourates.sort()
        favourate_median.append(int(np.median(favourates)))
        medians.sort()
        median.append(np.median(medians))
        # price = avg_work_year
        b = len(avg_work_year)
        b1= len(favourates)
    
        sum = 0
        sum1 = 0
        for i in avg_work_year:
            sum = sum+float(i)
        avgs.append(round(sum/b, 2))
        for i in favourates:
            sum1 = sum1+float(i)
        favourate_avg.append(round(int(sum1/b1), 2))
    
    for i in places:
        avg(i)
    
    print("各区平均房价", avgs)
    print('各房型的出售总数:', sum_house)
    print("房间面积", area)
    """
    [280, 56, 504, 1676, 1680]
    [392, 112, 448, 1679, 1680]
    [224, 0, 616, 3359, 3360]
    [448, 112, 280, 1679, 1680]
    [504, 0, 336, 1680, 1679]
    [224, 56, 168, 1680, 1670]
    
    
    [66.17, 65.6, 76.04, 78.94, 62.06, 74.37] 
    [68.8, 67.8, 79.8, 70.8, 57.6, 78.8]
    [6, 6, 9, 4, 4, 4] [5, 4, 3, 2, 3, 2]
    """
    # print(median)
    # print(favourate_avg,favourate_median)
    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("贵阳各地房价平均值(万元)", avgs)
    line.add_yaxis("贵阳各地房价中位数值(万元)", median)
    # line.render("predict_line.html")
    
    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(place)
                .add_yaxis("平均值", avgs)
                .add_yaxis("中位数", median)
                .set_global_opts(
                title_opts={"text": "贵阳各地房价(万元)"}
            )
        )
        return c
    bar().render("predict_bar.html")
    # print(sum_house)
    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(houseidfo)
                .add_yaxis(place[0], [280, 56, 504, 1676, 1680])
                .add_yaxis(place[1], [392, 112, 448, 1679, 1680])
                .add_yaxis(place[2], [224, 0, 616, 3359, 3360])
                .add_yaxis(place[3], [448, 112, 280, 1679, 1680])
                .add_yaxis(place[4], [504, 0, 336, 1680, 1679])
                .add_yaxis(place[-1], sum_house)
                # .add_yaxis("中位数", favourate_median)
                .set_global_opts(
                title_opts={"text": "贵阳各地房型\n数量"}
            )
        )
        return c
    # bar().render("house_bar.html")
    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("贵阳各地房子平均面积\n(平米)", area)
    line.render("Area_line.html")
    
    
    
    list_num = favourate_avg
    attr = place
    # print(zip(attr, list_num))
    s = [list(z) for z in zip(attr, list_num)]
    c = (Pie().add("", s).set_global_opts(title_opts=opts.TitleOpts(title="贵阳市各区楼房\n平均收藏人数"))
         .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
         )
    c.render("pie_avg.html")
    
    list_num = favourate_median
    attr = place
    # print(zip(attr, list_num))
    s = [list(z) for z in zip(attr, list_num)]
    c = (Pie().add("", s).set_global_opts(title_opts=opts.TitleOpts(title="贵阳市各区楼房\n收藏人数中位数"))
         .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
         )
    c.render("pie_median.html")
    
    from pyecharts import options as  opts
    from pyecharts.charts import Scatter3D
    from pyecharts.faker import Faker
    
    
    price=[float(i)/1 for i in price]
    # print(price)
    # types=list(map(mapfunc,df.house_type.values))
    # type = [224, 56, 168, 1680, 1670]
    data = []
    # print(fav,type)
    # for j in range(len(type)):
    #     for k in range(len(fav)):
    for j in range(100):
        for k in range(100):
            for i in range(500):
                try:
                    data.append([type[j], favourate_avg[k],price[i]])
                except:
                    continue
    # print(data)
    scatter = (
         Scatter3D(init_opts=opts.InitOpts(width='900px', height='600px'))  # 初始化
              .add("", data,
                   grid3d_opts=opts.Grid3DOpts(
                        width=300, depth=300, rotate_speed=300, is_rotate=True,
                   ),)
    
              # 设置全局配置项
              .set_global_opts(
              title_opts=opts.TitleOpts(title="房型——关注度——价格\n三维关系图"),  # 添加标题
              visualmap_opts=opts.VisualMapOpts(
                   max_=100,  # 最大值
                   pos_top=200,  # visualMap 组件离容器上侧的距离
                   range_color=Faker.visual_color  # 颜色映射
              )
         )
              # .render("3D散点图.html")
    )
    print('数据分析和可视化结束,左边点开~')
    

    同时赠送给大家另一个版本的:

    爬虫:链家网:柳州市

    # -*- coding: utf-8 -*-
    import scrapy
    
    
    import requests
    from lxml import etree
    import xlwt
    import xlrd
    import csv
    import pandas as pd
    import time
    
    class LanjiaSpider:
        def __init__(self):
            self.url = 'https://liuzhou.lianjia.com/ershoufang/yufengqu/pg{}/'
            self.headers = {
                "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"}
    
        def get_response_spider(self, url_str):  # 发送请求
            get_response = requests.get(self.url, headers=self.headers)
            time.sleep(2)
            response = get_response.content.decode()
            html = etree.HTML(response)
            return html
        def get_content_html(self, html):  # 使xpath获取数据
            self.houseInfo = html.xpath('//div[@class="houseInfo"]/text()')
            self.title = html.xpath('//div[@class="title"]/a/text()')
            self.positionInfo = html.xpath('//div[@class="positionInfo"]/a/text()')
            self.totalPrice = html.xpath('//div[@class="totalPrice"]/span/text()')
            self.unitPrice = html.xpath('//div[@class="unitPrice"]/span/text()')
            self.followInfo = html.xpath('//div[@class="followInfo"]/text()')
            self.tag = html.xpath('//div[@class="tag"]/span/text()')
            # print(title)
            # return houseInfo,title,positionInfo,totalPrice,unitPrice,followInfo,tag
    
        def xpath_houseInfo(self):
            #print(self.houseInfo)
            #print(type(self.houseInfo))
            # df = pd.DataFrame({"houseInfo": self.houseInfo,"tite":self.title,"positionInfo":self.positionInfo,"totaPrice":self.totalPrice,"unitPrice":self.unitPrice,"followInfo":self.followInfo,"tag":self.tag})
            # df=pd.DataFrame({"houseInfo": self.houseInfo,"tite":self.title})
            # df.to_excel(r'C:\Users\wy\Desktop\sublime\链家\pand3.xlsx')
            # a=len(self.houseInfo)
            for i in range(len(self.houseInfo)):
                # print(i)
                # yield i
                # print(type(self.houseInfo))
                yield self.houseInfo[i]
    
        def qingxi_data_houseInfo(self):  # 清洗数据
    
            self.xpath_houseInfo()
            self.xpath_title()
            self.xpath_positionInfo()
            self.xpath_totalPrice()
            self.xpath_unitPrice()
            self.xpath_followInfo()
            self.xpath_tag()
            get_houseInfo = self.xpath_houseInfo()
            get_title = self.xpath_title()
            get_positionInfo=self.xpath_positionInfo()
            get_totalPrice = self.xpath_totalPrice()
            get_unitPrice = self.xpath_unitPrice()
            get_followInfo=self.xpath_followInfo()
            get_tag=self.xpath_tag()
            i = 1
            while True:
                data_houseInfo= next(get_houseInfo)
                data_title=next(get_title)
                data_positionInfo=next(get_positionInfo)
                data_totalPrice=next(get_totalPrice)
                data_unitPrice=next(get_unitPrice)
                data_followInfo=next(get_followInfo)
                data_tag=next(get_tag)
    
                with open("yufengqu.csv", "a", newline="", encoding="utf-8-sig") as f:
                    fieldnames = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
                    writer = csv.DictWriter(f, fieldnames=fieldnames)  # 写入表头
                    writer.writeheader()
                    list_1 = ['houseInfo', 'title', 'positionInfo', 'totalPrice/万元', 'unitPrice', 'followInfo', 'tag']
                    list_2 = [data_houseInfo,data_title,data_positionInfo,data_totalPrice,data_unitPrice,data_followInfo,data_tag]
                    list_3 = dict(zip(list_1, list_2))
                    writer.writerow(list_3)
                    print("写入第"+str(i)+"行数据")
                i += 1
                if i > len(self.houseInfo):
                    break
    
        def xpath_title(self):
            for i in range(len(self.title)):
                yield self.title[i]
    
        def xpath_positionInfo(self):
            for i in range(len(self.positionInfo)):
                yield self.positionInfo[i]
    
        def xpath_totalPrice(self):
            for i in range(len(self.totalPrice)):
                yield self.totalPrice[i]
        def xpath_unitPrice(self):
            for i in range(len(self.unitPrice)):
                yield self.unitPrice[i]
        def xpath_followInfo(self):
            for i in range(len(self.followInfo)):
                yield self.followInfo[i]
        def xpath_tag(self):
            for i in range(len(self.tag)):
                yield self.tag[i]
        def run(self):
            i = 1
            while True:
                url_str = self.url.format(i)  # 构造请求url
                html = self.get_response_spider(url_str)
                self.get_content_html(html)
                self.qingxi_data_houseInfo()
    
                i += 1
                if i == 100:  # 不包括100页
                    break
    
    
    # if __name__ == "__main__":
    #     lanjia = LanjiaSpider()
    #     lanjia.run()
    
    class MyspiderSpider(scrapy.Spider):
        name = 'myspider'
        allowed_domains = ['https://wh.lianjia.com/ershoufang/jianghan/']
        start_urls = ['https://wh.lianjia.com/ershoufang/jianghan//']
    
        def parse(self, response):
            print('爬取ing....')
            lanjia = LanjiaSpider()
            lanjia.run()
    
    
    
    

    数据可视化:(优化版)

    """
    数据分析及可视化
    auuthor: 周小夏
    """
    import pandas as pd
    from pyecharts.charts import Line, Bar
    import numpy as np
    from pyecharts.globals import ThemeType
    from pyecharts.charts import Pie
    from pyecharts import options as opts
    
    
    places = ['chengzhongqu', 'liubeiqu', 'liuchengxian', 'liujiangqu', 'liunanqu', 'yufengqu']
    place = ['城中区', '柳北区', '柳城县', '柳江区', '柳南区', '鱼峰区']
    avgs = []  # 房价均值
    median = []  # 房价中位数
    favourate_avg = []  # 房价收藏人数均值
    favourate_median = []  # 房价收藏人数中位数
    houseidfo = ['2室1厅', '3室1厅', '2室2厅', '3室2厅', '其他']  # 房型定义
    houseidfos = ['2.1', '3.1', '2.2', '3.2']
    sum_house = [0,  0, 0, 0, 0]  # 各房型数量
    sum_houses = []
    price = []  # 房价均值
    unitprice = []  # 单价
    fav = []  # 收藏人数
    type = []
    area = []  # 房间
    
    
    def avg(name):
        df = pd.read_csv('./spiders/' + str(name)+'.csv', encoding='utf-8')
        pattern = '\d+'
        df['totalPrice/万元'] = df['totalPrice/万元'].str.findall(pattern)
        df['followInfo'] = df['followInfo'].str.findall(pattern)
        df['houseInfo'] = df['houseInfo'].str.findall(pattern)
        df['unitPrice'] = df['unitPrice'].str.findall(pattern)
    
        sum_houses = [0, 0, 0, 0, 0]
        # print(sum_house)
        avg_work_year = []
        areas = []
        unit_avg = []
        medians = []
        favourates = []
        k = 0
        k1 = 0
        k3 = 0
        k4 = 0
    
        for i in range(len(df)):
            if (i + 1) % 2 == 0:
                continue
            else:
                if len(df['unitPrice'][i]) >= 0:
                    unit_avg.append(','.join(df['unitPrice'][i]).replace(',', '.'))
                if len(df['totalPrice/万元'][i]) >= 0:
                    avg_work_year.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
                    medians.append(float(','.join(df['totalPrice/万元'][i]).replace(',', '.'))*100)
                    price.append(','.join(df['totalPrice/万元'][i]).replace(',', '.'))
                if len(df['followInfo'][i]) ==2:
                    favourates.append(int(','.join(df['followInfo'][i][:1])))
                    fav.append(int(','.join(df['followInfo'][i][:1])))
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.1:
                    k +=1
                    sum_houses[0] =k
                    type.append(2.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.1:
                    k1 +=1
                    sum_houses[1] =k1
                    type.append(3.1)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 2.2:
                    k3 +=1
                    sum_houses[2] =k3
                    type.append(2.2)
                if float(','.join(df['houseInfo'][i][:2]).replace(',', '.')) == 3.2:
                    k4 +=1
                    sum_houses[3] =k4
                    type.append(3.2)
                else:
                    k4 +=1
                    sum_houses[4] = k4
                    type.append('other')
                areas.append(float(','.join(df['houseInfo'][i][2:4]).replace(',', '.')))
        sum_house[0] =sum_houses[0]
        sum_house[1] = sum_houses[1]
        sum_house[2] = sum_houses[2]
        sum_house[3] = sum_houses[3]
        sum_house[4] = sum_houses[4]
        sum_house.append(sum_house[0])
        sum_house.append(sum_house[1])
        sum_house.append(sum_house[2])
        sum_house.append(sum_house[3])
        sum_house.append(sum_house[4])
        # print(sum_houses)
        favourates.sort()
        favourate_median.append(int(np.median(favourates)))
        medians.sort()
        median.append(np.median(medians))
        # price = avg_work_year
        b = len(avg_work_year)*100
        b1= len(favourates)
        b2 = len(unit_avg)
        b4 = len(areas)*100
        sum = 0
        sum1 = 0
        for i in unit_avg:
            sum = sum+float(i)
        unitprice.append(round(sum/b2, 2))
        for i in areas:
            sum = sum+float(i)
        area.append(round(sum/b4, 2))
        for i in avg_work_year:
            sum = sum+float(i)
        avgs.append(round(sum/b, 2))
        for i in favourates:
            sum1 = sum1+float(i)
        favourate_avg.append(round(int(sum1/b1), 2))
    
    for i in places:
        avg(i)
    
    print("各区平均房价", avgs)
    print('各房型的出售总数:', sum_house)
    print("房间面积", area)
    print("房价单价", unitprice)
    
    a = []
    for i in median:
        a.append(i/100)
    # print(median)
    # print(favourate_avg,favourate_median)
    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("柳州市各地房价平均值(万元)", avgs)
    line.add_yaxis("柳州市各地房价中位数值(万元)", a)
    line.render("predict_line.html")
    
    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(place)
                .add_yaxis("平均值", unitprice)
                .set_global_opts(
                title_opts={"text": "柳州市各地房价单价(元)"}
            )
        )
        return c
    
    bar().render("unit_prices.html")
    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(place)
                .add_yaxis("平均值", avgs)
                .add_yaxis("中位数", a)
                .set_global_opts(
                title_opts={"text": "柳州市各地房价(万元)"}
            )
        )
        return c
    bar().render("predict_bar.html")
    # print(sum_house)
    def bar() -> Bar:
        c = (
            Bar({"theme": ThemeType.MACARONS})
                .add_xaxis(houseidfo)
                .add_yaxis(place[0], sum_house[0:5])
                .add_yaxis(place[1], sum_house[5:10])
                .add_yaxis(place[2], sum_house[10:15])
                .add_yaxis(place[3], sum_house[15:20])
                .add_yaxis(place[4], sum_house[20:25])
                .add_yaxis(place[-1], sum_house[25:30])
                # .add_yaxis("中位数", favourate_median)
                .set_global_opts(
                title_opts={"text": "柳州市各地房型\n数量"}
            )
        )
        return c
    bar().render("house_bar.html")
    
    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("柳州市各地房子平均面积\n(平米)", area)
    line.render("Area_line.html")
    
    
    
    list_num = favourate_avg
    attr = place
    # print(zip(attr, list_num))
    s = [list(z) for z in zip(attr, list_num)]
    c = (Pie().add("", s).set_global_opts(title_opts=opts.TitleOpts(title="柳州市各区楼房\n平均收藏人数"))
         .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
         )
    c.render("pie_avg.html")
    
    list_num = favourate_median
    attr = place
    # print(zip(attr, list_num))
    s = [list(z) for z in zip(attr, list_num)]
    c = (Pie().add("", s).set_global_opts(title_opts=opts.TitleOpts(title="柳州市各区楼房\n收藏人数中位数"))
         .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
         )
    c.render("pie_median.html")
    
    from pyecharts import options as  opts
    from pyecharts.charts import Scatter3D
    from pyecharts.faker import Faker
    
    
    line = Line()
    line.add_xaxis(place)
    line.add_yaxis("房间面积\n(平米)", area)
    line.add_yaxis("房价\n(/万元)", avgs)
    line.render("price1_line.html")
    
    
    price=[float(i)/1 for i in price]
    # print(price)
    # types=list(map(mapfunc,df.house_type.values))
    # type = [224, 56, 168, 1680, 1670]
    data = []
    # print(fav,type)
    # for j in range(len(type)):
    #     for k in range(len(fav)):
    for j in range(100):
        for k in range(100):
            for i in range(500):
                try:
                    data.append([type[j], favourate_avg[k],price[i]])
                except:
                    continue
    # print(data)
    scatter = (
         Scatter3D(init_opts=opts.InitOpts(width='900px', height='600px'))  # 初始化
              .add("", data,
                   grid3d_opts=opts.Grid3DOpts(
                        width=300, depth=300, rotate_speed=300, is_rotate=True,
                   ),)
    
              # 设置全局配置项
              .set_global_opts(
              title_opts=opts.TitleOpts(title="房型——关注度——价格\n三维关系图"),  # 添加标题
              visualmap_opts=opts.VisualMapOpts(
                   max_=300,  # 最大值
                   pos_top=200,  # visualMap 组件离容器上侧的距离
                   range_color=Faker.visual_color  # 颜色映射
              )
         )
              .render("3D散点图.html")
    )
    print('数据分析和可视化结束,左边点开~')
    

    最后,别忘记了关注公众号~

    分享最新算法!

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CiQYvfTG-1594979733395)(D:\CSDN\pic\WeChat Image_20200716151357.jpg)]

    展开全文
  • 人脸数据清洗方法+代码汇总

    千次阅读 2019-01-27 17:21:42
     这里对目前为止接触到的人脸数据集的清洗进行一个汇总。  此文中把人脸数据集分为三种类型(本分类仅在此文中有效): 1. 野数据集  这里的野数据集指的是从互联网上爬取出的原始人脸数据集,它的特点是:脏、乱...
    • 说明:

            这里对目前为止接触到的人脸数据集的清洗进行一个汇总。
            此文中把人脸数据集分为三种类型(本分类仅在此文中有效):
    1.   野数据集
           这里的野数据集指的是从互联网上爬取出的原始人脸数据集,它的特点是:脏、乱、杂 。数据分布不均匀、尺寸不一、存在年龄跨度较大现象,图像格式命名错误且存在较多的冗余、杂质,但优点是类别数目大。使用前需要做深度清洗的工作。
           野数据集诸如目前收集的:Chinese-Face, Japanese-Face, Korean-Face数据集。
    2.  常用开源数据集
           这里的常用开源数据集指的是业内公开常用的数据集,这种数据集由于其尺寸统一和pose较全的特点,可以直接作为训练集或者测试集来使用,但也存在较少的杂质与冗余人脸图像,需要做中度清洗。常用开源数据集有:CASIAWeb-Face, VGG2, MS1M, Asian-celeb等数据集。
    3. 二次清洗数据集
          这里是指在常用开源数据集的基础上又进行了一次处理。主要是为了保证开源数据集的多样性与类别均衡性。但此类数据集仍然存在小部分的异类人脸图像以及类别分布不均的情况,需要稍作冗余与异类清洗即可。
          二次清洗数据集有:DeepGlint的两个数据集train-celebrity和train-msra。

            清洗原因

            数据清洗是数据准备的第一步,数据准备是人脸识别模型训练的首要步骤,也是给卷积神经网络提供比较干净的人脸图像数据进行学习并训练以便得到可用的、符合特定应用场景的、识别精度较高的人脸识别模型。
           由于爬取得到的人脸数据图像中都会存在噪声图像与无关图像,无论前期从互联网上爬取时工作做的如何疏而不漏,都不能保证最终获取的人脸数据一定符合训练的要求,而掺杂的‘脏’数据往往是影响人脸识别模型训练最终结果的关键。这就需要人工在得到原始数据后对数据完成清洗、增广、提高数据质量等工作。但随着数据量的增加,人工无法满足当下数据清洗的工作提供给后续的开发人员,为了节省时间和提高处理精度,于是编写了清洗工具便于更高效的处理。以下是对清洗过程的介绍。

            清洗思路:

          主要是通过人脸检测和识别算法检测并清洗同一个类别下的人脸照片中掺杂的噪声图像与无关图像,并在同一类别下的人脸图像中计算两两之间的人脸特征余弦距离,再根据余弦距离求其相似度去除冗余图像,即筛掉异类与冗余,同时保证数据的均衡性与多样性。

         各类数据集清洗方法介绍:

         在做人脸数据清洗之前需要对将要清洗的数据集进行评估,根据评估结果了解该数据集。包括其数据分布可视化以及数据质量评估两个步骤。根据数据分布可视化可以了解数据的分布情况,便于设置数据均衡阈值。根据数据质量评估结果,便于设置人脸质量清洗阈值。

          数据分布可视化采用Matplotlib来实现,在可视化之前,需要得到数据类别数目以及人脸图像数据量的csv文件,可以使用shell得到csv文件。

          csv文件生成代码:

    #!/bin/bash
    find ./ -type d |while read line
    do
    pwd=${PWD}
    cd $line
    echo -e "${line#*/},`ls | wc -l`"
    cd $pwd
    done

         数据分布可视化python代码:

    asian_log = pd.read_csv("list2.csv")
    plt.figure()
    ax = plt.subplot(2,2,1)
    ax.set_title("Distribution Curve")
    Num = range(len(asian_log['name']))
    ax.scatter(Num,asian_log['count'])
    ax.set_xlabel('class')
    ax.set_ylabel('class count')
    #plt.legend(loc='upper left')
    plt.legend(loc='upper right')
    plt.show()

         野数据集的清洗方法:

        >>   针对于该类数据集建立便于处理的数据分布形式。 如下图所示,箭头表示包含关系,数据集下包含类别文件夹,每个类别下包括该类别的人脸图像。

                                                                                                             

     

    整理函数如下:

    def fileset(path):
        if os.path.isdir(path):
        lists = os.listdir(path)
        #print(lists)
        for i in lists:
            #print(i)
            path = path + '/' + i
            if os.path.isfile(image_path):
                save_name = image_path.split('/')[7]
                save_path = image_file_dir + '/' + save_name
                print(image_path)
                #print(image_path == save_path)
                save_image = save_path + '/' + i
                print(save_image)
                if image_path != save_image :
                    shutil.move(image_path, save_path)
                if image_path == save_image:
                    print('This image already exists!')

    >>   删除空文件夹以及将图像信息为空的进行删除

    def delete_empty_dir(path):
        if os.path.isdir(path):
        lists = os.listdir(path)
        for item in lists:
           if item!='System Volume Information':
               delete_empty_dir(os.path.join(path, item))
           if not os.listdir(path):
               os.rmdir(path)
               print('移除空目录:' + path)
    def delete_empty_image(path):
        if os.path.isdir(path):
            lists1 = os.listdir(path)
            for i in lists1:
                image_path = path + '/' + i
                print(image_path)
                save_name = image_path.split('/')[7]
                print(save_name)
                save_path = image_file_dir + '/' + save_name + '/'
                #print(save_path)
                if os.path.isdir(image_path):
                    lists2 = os.listdir(image_path)
                    L1 = len(lists2)
                    print(L1)
                    for j in range(L1):
                        print(j)
                        img_name = lists2[j]
                        print(img_name)
                        with open(save_path + '{}'.format(str(img_name)),'rb') as fp:
                            data = fp.read()
                        if(len(data) != 0):
                            pass
                        else:
                            os.remove(save_path + '{}'.format(str(img_name)))

    >>   图片格式校验,是将非法命名格式的图像进行纠正。

    def format_convert(path):
        if os.path.isdir(path):
           file_lists = os.listdir(path)
           print('file_lists:',file_lists)
           for i in file_lists:
               print('i:',i)
               image_path = path + '/' + i
               print('file_path:',image_path)
               if os.path.isdir(image_path):
                  print('pass')
                      pass
               elif os.path.isfile(image_path):
                   print('Judging image format type:')
                   true_type = imghdr.what(image_path)
                   print(true_type,image_path)
                   image_type = image_path.split('.')[1]
                   image_name = image_path.split('.')[0]
                   print('image_type:',image_type)
                   if image_type == true_type:
                       print('The image format type is right!\n',image_path)
                       pass
                   elif true_type == None:
                       print('This is not a image!\n','Delete:',image_path)
                       os.remove(image_path)
                   else:
                       print('The image format type is wrong!\n','Do:')
                       old_image_name = image_path
                       new_image_name = image_name + '.' + true_type
                       newName = image_path.replace(old_image_name,new_image_name)
                       print(image_path,'---->',newName)
                       os.rename(os.path.join(i, image_path),os.path.join(i,newName))
                       print('Done.')
    

     

     数量均衡化处理

    说明:
        清洗工作基于caffe平台使用了人脸检测模型MTCNN以及a、b、c三种人脸识别模型,人脸识别模型的选取可以根据训练或测试所使用的图像尺寸大小来选择。
        a) caffe face          图像尺寸为:112*96
        b) face net             图像尺寸为:160*160
        c) insight face       图像尺寸为:112*112


     以上步骤主要针对于野数据集清洗的第一步,下面是所有类型的数据集需要操作的步骤。

    >>   删除异类人脸图像,洗掉脏数据:

    def List_ordering(distances,class_face_num):
        ordering_lists=[]
        k=range(len(distances))
        for i in k:
            if distances[i][0]<0.5:
            ordering_lists+=[distances[i]]
        return ordering_lists
    
    if __name__ == "__main__":
        # face_model = './facenet_model/myfacenet.prototxt' ####160*160    ###几个人脸识别模型的切换
        # face_weights = './facenet_model/myfacenet.caffemodel'
        # face_model = './caffe_caffemodel/face_deploy.prototxt'###112*96
        # face_weights = './caffe_caffemodel/face_model.caffemodel'
        face_model = './insight_caffemodel/model.prototxt' ###112*112
        face_weights = './insight_caffemodel/face_model.caffemodel'
        net = caffe.Net(face_model, face_weights, caffe.TEST)
        transformer = caffe.io.Transformer({'data': net.blobs['data'].data.shape})
        transformer.set_transpose('data', (2, 0, 1))
        file_lists = os.listdir(image_file_dir)
        class_num_lists = []
        for dir in file_lists:
            path = image_file_dir + '/' + dir
            class_face_num, faces_lists, image_name_lists, names_lists, image_files_lists,class_features_lists=Get_faces(path,net)
            print('image_name_lists:', image_name_lists)
            distances=Distance_calculation(class_features_lists)
            orig_mean_num = pd.DataFrame(columns=None, data=distances)
            orig_mean_num.to_csv(path_or_buf=path + '/orig_test10.csv', encoding='gbk')
            # print('len(distances:)',len(distances))
            ordering_lists=List_ordering(distances,class_face_num)
            # print('ordering_lists:', ordering_lists)
            mean_num = pd.DataFrame(columns=None, data=ordering_lists)
            mean_num.to_csv(path_or_buf=path + '/test10.csv', encoding='gbk')
    

    >>   保证数据均衡性,这里有两种数据均衡的方法:

    1.  先设置图像数量阈值进行数据划分,再裁出满足人脸质量阈值的人脸。
    2.  直接使用人脸检测算法和人脸识别算法并设置均衡阈值,得到最终均衡后的人脸数据集。

    第一种方法比较容易处理,方便调试,但操作流程较为麻烦,第二种方法速度太慢,但流程简单,是直接出结果。

    第一种方法介绍:

    >>   按图像数量阈值进行数据划分:

    if DB_FLAG == 'Celebrity':
       file_lists=os.listdir(image_file_dir)
       class_num_lists = []
       total_class_num=len(file_lists)
       for dir in file_lists:
           path=image_file_dir+'/'+dir
           class_count+=1
           progress = (class_count / total_class_num) * 100
           print('This DS has been processed by %.2f%%' % progress)
           class_face_num,faces_lists,image_name_lists,names_lists,image_files_lists=Get_faces(path)
           print('class_face_num1:', class_face_num)
           print('class_count:', class_count)
           #print('faces_lists:',faces_lists)
           class_num_lists += [class_face_num]
           if class_face_num >= 10:  ##设置图像数量阈值进行选取类别,并另存为
              print('Save this file directly!')
              for i in range(class_face_num):
                  image_file_path = image_files_lists[i]
                  name = image_file_path.split('/')[8]
                  names = image_file_path.split('/')[9]
                  save_to_file = './celebrity10++_aligned_112*112/' + name + '/'  ##新建文件夹将选取出的类别图像得以保存
                  print(save_to_file)
                  mkdir(save_to_file)
                  # for j in range(len(faces_lists)):
                  cv2.imwrite(save_to_file + '%s' % names, faces_lists[i])
              del i
           elif class_face_num==0:
               print('This file has no faces!')
           else:
               pass
       #print('class_num_lists:', class_num_lists)
       del dir,total_class_num,file_lists
    

    >>   设置人脸图像质量阈值和图像尺寸,裁出符合条件的人脸

    def generate_celebrity_db_aligned():
        mtcnn_model_path = "./mtcnn/model"
        detect_threshhold = 0.90
        quality = 0
        multi_faces = False
        caffe.set_mode_gpu()
        image_files = []
        names = []
        image_files, names = utility.get_imagefiles_from_dir(db_image_file_dir,True)
        print(len(image_files))
        print(image_files[0:10])
        facedetector = utility.initFaceDetector(mtcnn_model_path)
        minsize = facedetector[0]
        PNet = facedetector[1]
        RNet = facedetector[2]
        ONet = facedetector[3]
        threshold = facedetector[4]
        factor = facedetector[5]
        faces = []
        for j in range(len(image_files)):
        im_file = image_files[j]
        im = cv2.imread(im_file)
        faces = utility.crop_and_align(im, minsize, PNet, RNet, ONet, threshold, factor, detect_threshhold, quality, multi_faces) 
        if len(faces) == 1:
            save_to_file = './db_aligned_test/' + names[j] + '/'
            utility.mkdir(save_to_file)
            save_branch2 = im_file.split('_')[1]
            cv2.imwrite(save_to_file + names[j] + save_branch2, faces[0])
        elif len(faces) == 0:
            print('cannot found face in file %s' % im_file)
        elif len(faces) > 1:
            print('too many faces in file %s' % im_file)
        if j % 50 == 0:
            print('processed %d pics' % j)

    第二种方法介绍:

    >>   直接输出处理结果

    if DB_FLAG == 'Celebrity':
       file_lists=os.listdir(image_file_dir)
       class_num_lists = []
       total_class_num=len(file_lists)
       for dir in file_lists:
           path=image_file_dir+'/'+dir
           class_count+=1
           progress = (class_count / total_class_num) * 100
           print('This DS has been processed by %.2f%%' % progress)
           class_face_num,faces_lists,image_name_lists,names_lists,image_files_lists=Get_faces(path)
           print('class_face_num1:', class_face_num)
           print('class_count:', class_count)
           #print('faces_lists:',faces_lists)
           class_num_lists += [class_face_num]
           if class_face_num >= 10:
               pass
           elif class_face_num ==0:
               print('This file has no faces!')
           elif class_face_num < 10:
               print('Save this file directly!')
               print('class_face_num:',class_face_num)
               for i in range(class_face_num):
               # print('####################################################################')
               image_file_path = image_files_lists[i]
               name = image_file_path.split('/')[8]
               names = image_file_path.split('/')[9]
               save_to_file = './celebrity_val_aligned_112*112/' + name + '/'
               print('save_to_file:',save_to_file)
               mkdir(save_to_file)
               # for j in range(len(faces_lists)):
               cv2.imwrite(save_to_file + '%s' % names, faces_lists[i])
               # del i
               save_class_count1+=1
               print('save_class_count1:',save_class_count1)
           if save_class_count1==7500:
               print('full!')
               break
               # print('class_num_lists:', class_num_lists)
       del dir,total_class_num,file_lists

     

    保证数据多样性

    如果不单为了保证数据的均衡性,还保留其数据的多样性,那么还需做以下操作:

    注:保留其多样性的代码只完成了一部分,思路连同代码一并给出。

    思路: 利用神经网络的全连接层FC输出得到的人脸特征feature,通过计算单个类别下的人脸图像两两之间的余弦距离,在保证相同类别的前提下判断其距离大小,距离越大,认为其人脸差异性越大,距离越小,则相反,此种方法不仅可以保留其数据的多样性,同时还过滤掉了冗余的图像,且方法得以验证。

    余弦距离计算的代码实现:

    def dist(a,b):
        score = np.dot(a,b)/(np.linalg.norm(a)*np.linalg.norm(b))
        distance = 1 - score
        return distance
    

    人脸特征提取的代码实现:

    def extract_feature_512(net,transformer,img):
         # img read from cv2.imread
         img = (img - 127.5) / 128
         net.blobs['data'].data[...] = transformer.preprocess('data',img) #将图片载入到blob中
         net.forward()
         feature = np.float64(net.blobs['fc5'].data[0])
         return feature

    同一类别下,计算两两距离的代码实现:

    def Distance_calculation(class_features_lists):
        distances=[]
        k = range(len(class_features_lists))
        for i in k:
            # print('i:',i)
            K = range(i + 1, len(class_features_lists))
            for j in K:
            # print('j:',j)
            distance=dist(class_features_lists[i],class_features_lists[j])
            # print('distance:',distance)
            if distance:
                distances += [[distance,[i,j]]]
        orig_mean_num = pd.DataFrame(columns=None, data=distances)
        orig_mean_num.to_csv('./orig_test10.csv', encoding='gbk')
        return distances
    展开全文
  • 基于yolo的口罩识别(开源代码数据集)

    万次阅读 多人点赞 2020-02-17 19:08:19
    数据的清洗 这里笔者采用的数据清洗就比较的笨了,就是人为一个一个的筛选,整理了一个晚上,请原谅笔者的愚蠢。 4. 标注数据集 标注数据集同数据的清洗而言就比较简单了,比较的机械化。这里笔者使用labelImg这个...

    2020年开头真的很人意外,开年爆发了疫情。此次疫情牵动了各行各业,在这里衷心的感谢奋斗在一线的医疗工作者:您们辛苦了。作为一名非医专业的学生,在这样情况下,除了不乱跑以外,我也想以另一种方式去致敬那些保护着全国人民安全的工作人员。接下来就来介绍本项目的开发过程。

    1. 开发环境

    笔者的开发环境如下:
    ubuntu16.04
    PyTorch 1.1.0
    anaconda
    opencv-python
    tqdm
    matplotlib
    pycocotools

    2. 收集数据集

    本项目的数据集是笔者花了一个晚上通过网络爬虫的方式收集的(ps:没有违反爬虫协定)。笔者通过使用python写了一个小爬虫,爬虫的代码如下:

    
    import re
    import requests
    from urllib import error
    from bs4 import BeautifulSoup
    import os
    
    num = 0
    numPicture = 0
    file = ''
    List = []
    
    
    def Find(url):
        global List
        print('正在检测图片总数,请稍等.....')
        t = 0
        i = 1
        s = 0
        while t < 1000:
            Url = url + str(t)
            try:
                Result = requests.get(Url, timeout=7)
            except BaseException:
                t = t + 60
                continue
            else:
                result = Result.text
                pic_url = re.findall('"objURL":"(.*?)",', result, re.S)  # 先利用正则表达式找到图片url
                s += len(pic_url)
                if len(pic_url) == 0:
                    break
                else:
                    List.append(pic_url)
                    t = t + 60
        return s
    
    
    def recommend(url):
        Re = []
        try:
            html = requests.get(url)
        except error.HTTPError as e:
            return
        else:
            html.encoding = 'utf-8'
            bsObj = BeautifulSoup(html.text, 'html.parser')
            div = bsObj.find('div', id='topRS')
            if div is not None:
                listA = div.findAll('a')
                for i in listA:
                    if i is not None:
                        Re.append(i.get_text())
            return Re
    
    
    def dowmloadPicture(html, keyword):
        global num
        # t =0
        pic_url = re.findall('"objURL":"(.*?)",', html, re.S)  # 先利用正则表达式找到图片url
        print('找到关键词:' + keyword + '的图片,即将开始下载图片...')
        for each in pic_url:
            print('正在下载第' + str(num + 1) + '张图片,图片地址:' + str(each))
            try:
                if each is not None:
                    pic = requests.get(each, timeout=7)
                else:
                    continue
            except BaseException:
                print('错误,当前图片无法下载')
                continue
            else:
                string = file + r'\\' + keyword + '_' + str(num) + '.jpg'
                fp = open(string, 'wb')
                fp.write(pic.content)
                fp.close()
                num += 1
            if num >= numPicture:
                return
    
    
    if __name__ == '__main__':  # 主函数入口
        tm = int(input('请输入每类图片的下载数量 '))
        numPicture = tm
        line_list = []
        with open('./name.txt', encoding='utf-8') as file:
            line_list = [k.strip() for k in file.readlines()]  # 用 strip()移除末尾的空格
    
        for word in line_list:
            url = 'http://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=' + word + '&pn='
            tot = Find(url)
            Recommend = recommend(url)  # 记录相关推荐
            print('经过检测%s类图片共有%d张' % (word, tot))
            file = word
            y = os.path.exists(file)
            if y == 1:
                print('该文件已存在,请重新输入')
                file = word
                os.mkdir(file)
            else:
                os.mkdir(file)
            t = 0
            tmp = url
            while t < numPicture:
                try:
                    url = tmp + str(t)
                    result = requests.get(url, timeout=10)
                    print(url)
                except error.HTTPError as e:
                    print('网络错误,请调整网络后重试')
                    t = t + 60
                else:
                    dowmloadPicture(result.text, word)
                    t = t + 60
            numPicture = numPicture + tm
    
        print('任务完成')
    

    运行此爬虫需要配以一个name.txt,在其中写下所需要爬取的信息即可。,rename.py是对获取的数据进行命名整理的。代码如下:

    import os
    
    path_name='./JPEGImages'
    #path_name :表示你需要批量改的文件夹
    i=0
    for item in os.listdir(path_name):#进入到文件夹内,对每个文件进行循环遍历
        os.rename(os.path.join(path_name,item),os.path.join(path_name,('masks_'+'00'+str(i)+'.jpg')))#os.path.join(path_name,item)表示找到每个文件的绝对路径并进行拼接操作
        i+=1
    

    文件结构如下:
    在这里插入图片描述

    3.数据的清洗

    这里笔者采用的数据清洗就比较的笨了,就是人为一个一个的筛选,整理了一个晚上,请原谅笔者的愚蠢。
    在这里插入图片描述

    4. 标注数据集

    标注数据集同数据的清洗而言就比较简单了,比较的机械化。这里笔者使用labelImg这个标注工具进行标注。这里做的是简单的二分类任务,即:Mask和unMasked.标注比数据清洗要快一点。
    在这里插入图片描述

    5. 相关准备

    准备工作的话就是使用一个版本的大体框架,这里使用的是yolov3,yolov3框架。下载后可以重新命名,当然也可不命名,这个随性就可以了。

    6. 数据装载

    申明一下最后会将数据集提供给大家。
    我们需要将数据集Annotations、JPEGImages复制到YOLOV3工程目录下的data文件下;同时新建两个文件夹,分别命名为ImageSets和labels,最后我们将JPEGImages文件夹复制粘贴一下,并将文件夹重命名为images
    在这里插入图片描述

    7. 代码的构建

    这里需要在项目的根目录下新建连个python文件:makeTxt.py和voc_label.py 其中makeTxt.py是用于生成data/ImageSets下的test.txt、train.txt、trainval.txt以及val.txt的;而voc_label.py是将Annotations里数据集的标注文件转为data/label下txt格式的。
    makeTxt.py的代码如下:

    import os
    import random
     
    trainval_percent = 0.1
    train_percent = 0.9
    xmlfilepath = 'data/Annotations'
    txtsavepath = 'data/ImageSets'
    total_xml = os.listdir(xmlfilepath)
     
    num = len(total_xml)
    list = range(num)
    tv = int(num * trainval_percent)
    tr = int(tv * train_percent)
    trainval = random.sample(list, tv)
    train = random.sample(trainval, tr)
     
    ftrainval = open('data/ImageSets/trainval.txt', 'w')
    ftest = open('data/ImageSets/test.txt', 'w')
    ftrain = open('data/ImageSets/train.txt', 'w')
    fval = open('data/ImageSets/val.txt', 'w')
     
    for i in list:
        name = total_xml[i][:-4] + '\n'
        if i in trainval:
            ftrainval.write(name)
            if i in train:
                ftest.write(name)
            else:
                fval.write(name)
        else:
            ftrain.write(name)
     
    ftrainval.close()
    ftrain.close()
    fval.close()
    ftest.close()
    

    voc_label.py的代码如下:

    import xml.etree.ElementTree as ET
    import pickle
    import os
    from os import listdir, getcwd
    from os.path import join
     
    sets = ['train', 'test','val']
     
    classes = ["mask","unmask"]   #我们只是检测细胞,因此只有一个类别
     
     
    def convert(size, box):
        dw = 1. / size[0]
        dh = 1. / size[1]
        x = (box[0] + box[1]) / 2.0
        y = (box[2] + box[3]) / 2.0
        w = box[1] - box[0]
        h = box[3] - box[2]
        x = x * dw
        w = w * dw
        y = y * dh
        h = h * dh
        return (x, y, w, h)
     
     
    def convert_annotation(image_id):
        in_file = open('data/Annotations/%s.xml' % (image_id))
        out_file = open('data/labels/%s.txt' % (image_id), 'w')
        tree = ET.parse(in_file)
        root = tree.getroot()
        size = root.find('size')
        w = int(size.find('width').text)
        h = int(size.find('height').text)
     
        for obj in root.iter('object'):
            difficult = obj.find('difficult').text
            cls = obj.find('name').text
            if cls not in classes or int(difficult) == 1:
                continue
            cls_id = classes.index(cls)
            xmlbox = obj.find('bndbox')
            b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
                 float(xmlbox.find('ymax').text))
            bb = convert((w, h), b)
            out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
     
     
    wd = getcwd()
    print(wd)
    for image_set in sets:
        if not os.path.exists('data/labels/'):
            os.makedirs('data/labels/')
        image_ids = open('data/ImageSets/%s.txt' % (image_set)).read().strip().split()
        list_file = open('data/%s.txt' % (image_set), 'w')
        for image_id in image_ids:
            list_file.write('data/images/%s.jpg\n' % (image_id))
            convert_annotation(image_id)
        list_file.close()
    

    分别运行makeTxt.py和voc_label.py会在data/ImageSets的四个文件中出现如下变化
    在这里插入图片描述
    再运行voc_label.py会在label文件夹下产生如下的变化。
    在这里插入图片描述
    接着还要配置两个文件
    在data文件下新建rbc.data,配置内容如下:

    classes=2
    train=data/train.txt
    valid=data/test.txt
    names=data/rbc.names
    backup=backup/
    eval=coco
    

    值得注意的是这里是对人是否佩戴口罩进行识别的,即分为两类佩戴口罩和为佩戴口罩。所以这里需要将classes设置为2.
    再在data文件下新建rbc.names,配置内容如下:

    Masking
    unMasked
    

    8. 修改配置文件

    这里需要将cfg下的yolov3-tiny.cfg文件进行修改,修改内容如下:

    [net]
    # Testing
    batch=1
    subdivisions=1
    # Training
    # batch=64
    # subdivisions=2
    width=416
    height=416
    channels=3
    momentum=0.9
    decay=0.005
    angle=0
    saturation = 1.5
    exposure = 1.5
    hue=.1
    
    learning_rate=0.005
    burn_in=1000
    max_batches = 500200
    policy=steps
    steps=400000,450000
    scales=.1,.1
    
    [convolutional]
    batch_normalize=1
    filters=16
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    batch_normalize=1
    filters=32
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    batch_normalize=1
    filters=64
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    batch_normalize=1
    filters=128
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    batch_normalize=1
    filters=256
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=2
    
    [convolutional]
    batch_normalize=1
    filters=512
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [maxpool]
    size=2
    stride=1
    
    [convolutional]
    batch_normalize=1
    filters=1024
    size=3
    stride=1
    pad=1
    activation=leaky
    
    ###########
    
    [convolutional]
    batch_normalize=1
    filters=256
    size=1
    stride=1
    pad=1
    activation=leaky
    
    [convolutional]
    batch_normalize=1
    filters=512
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [convolutional]
    size=1
    stride=1
    pad=1
    filters=21   ####因为这里是二分类,根据论文中的介绍这里需要根据3*(5+classnum),应此为21
    activation=linear
    
    
    
    [yolo]
    mask = 3,4,5
    anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
    classes=2    ### 这里因为是二分类,所以改为2
    num=6
    jitter=.3
    ignore_thresh = .7
    truth_thresh = 1
    random=1
    
    [route]
    layers = -4
    
    [convolutional]
    batch_normalize=1
    filters=128
    size=1
    stride=1
    pad=1
    activation=leaky
    
    [upsample]
    stride=2
    
    [route]
    layers = -1, 8
    
    [convolutional]
    batch_normalize=1
    filters=256
    size=3
    stride=1
    pad=1
    activation=leaky
    
    [convolutional]
    size=1
    stride=1
    pad=1
    filters=21   ### 因为这里是二分类,根据论文中的介绍这里需要根据3*(5+classnum),应此为21
    activation=linear
    
    [yolo]
    mask = 0,1,2
    anchors = 10,14,  23,27,  37,58,  81,82,  135,169,  344,319
    classes=2    ### 这里因为是二分类,所以改为2
    num=10
    jitter=.3
    ignore_thresh = .7
    truth_thresh = 1
    random=1
    

    9. 训练数据集

    完成了上述操作后,即可进行数据集的训练操作了。
    在根目录下打开命令行,输入如下命令:

    python train.py --data-cfg data/rbc.data --cfg cfg/yolov3-tiny.cfg --epochs 100
    

    参数说明:
    rbc.data 是data文件夹下
    yolov3-tiny.cfg 是cfg中的yolov3的预训练参数
    epochs 100 迭代训练数据集的次数
    在这里插入图片描述
    在这里插入图片描述
    训练完成后会在weights文件夹下产生训练的模型,包括最好的训练模型和最后一次训练得到的模型还有每个每10次迭代产生的模型。这里我只保留了最好的以及最后一次的训练模型。
    在这里插入图片描述

    10. 测试模型

    在完成了训练后,即可对训练的模型进行测试了,看一下这个其对佩戴口罩和未佩戴口罩者的预测效果
    将要预测的实际照片放在data/sample文件夹下
    在根目录下打开命令行,在其中输入如下命令:

    python detect.py --data-cfg data/rbc.data --cfg cfg/yolov3-tiny.cfg --weights weights/best.pt
    

    预测的结果如下:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    如果需要对视频进行检测的话,则可以输入如下命令:

    python detect.py --source file.mp4
    

    11. 可能出现的bug

    在操作的过程中难免会出现一些小毛病,这里呢,笔者已经为这个项目总结了几个容易出现的问题,请参考笔者的另一篇博客:项目可能出现的问题及其解决方法

    项目源码和数据集

    这里笔者将本项目的源代码和数据集都已经上传到github上,欢迎大家扩展,为保护我们的工作者减少工作压力。
    链接: 源码和数据集

    总结:

    由于笔者知识能力有限,在描述上可能存在不准确的地方,还请谅解。
    如遇到什么问题欢迎添加笔者qq:1017190168
    进行讨论。
    最后对一线的工作者们说一声你们辛苦了!!!!
    祝愿疫情早日结束,祝祖国繁荣富强。

    申明近期笔者接计算机视觉方面的毕业设计、比赛,有需要的欢迎联系!!!

    展开全文
  • 数据预处理——数据清洗

    万次阅读 2018-05-10 20:46:04
    在数据挖掘中,海量的原始数据中存在着大量不完整、不一致、有异常的数据,严重影响到数据挖掘建模的执行效率,甚至可能导致挖掘结果的偏差,所以进行数据清洗就显得尤为重要,数据清洗完成后接着进行或者同时进行...

    在数据挖掘中,海量的原始数据中存在着大量不完整、不一致、有异常的数据,严重影响到数据挖掘建模的执行效率,甚至可能导致挖掘结果的偏差,所以进行数据清洗就显得尤为重要,数据清洗完成后接着进行或者同时进行数据集成、变换、规约等一系列的处理,该过程就是数据预处理。

    数据预处理一方面是要提高数据的质量,另一方面是要让数据更好地适应特定的挖掘技术或工具。

    数据预处理的主要内容包括数据清洗、数据集成、数据变换和数据规约。处理过程如下图所示:

    数据清洗主要是删除原始数据集中的无关数据、重复数据,平滑噪声数据,筛选掉与挖掘主题无关的数据,处理缺失值、异常值。

    缺失值处理

    从统计上说,缺失的数据可能会产生有偏估计,从而使样本数据不能很好地代表总体,而现实中绝大部分数据都包含缺失值,因此如何缺失值很重要。

    一般说来,缺失值的处理包括两个步骤,即缺失数据的识别和缺失值处理。R语言中缺失值通常以NA表示,可以使用函数is.na()判断缺失值是否存在,另外函数complete.cases()可识别样本数据是否完整从而判断确实情况。在对是否存在缺失值进行判断之后需要进行缺失值处理,常用的方法有删除法、替换法、插补法等。

    (1)删除法

    删除法是最简单的缺失值处理方法,根据数据处理的不同角度可分为删除观测样本、删除变量两种。在R中可通过na.omit()函数移除所有含有缺失数据的行,这属于以减少样本量来换取信息完整性的方法,适用于缺失值所占比例较小的情况;删除变量适用于变量有较大缺失且对研究目标影响不大的情况,意味着要删除整个变量,这在R中可通过data[, -p]来实现,p表示缺失变量所在的列。

    (2)替换法

    变量按属性可分为数值型和非数值型,二者的处理办法不同:如果缺失值所在变量为数值型,一般用该变量在其他所有对象的取值的均值来替换变量的缺失值;如果为非数值型变量,则使用该变量其他全部有效观测值的中位数或者众数进行替换。

    (3)插补法

    删除法虽然简单易行,但会存在信息浪费的问题且数据结构会发生变动,以致最后得到有偏的统计结果,替换法也有类似的问题。在面对缺失值问题,常用的插补法有回归插补、多重插补等。回归插补法利用回归模型,将需要插值补缺的变量作为因变量,其他相关变量作为自变量,通过回归函数lm()预测出因变量的值来对缺失值进行补缺;多重插补法的原理是从一个包含缺失值的数据集中生成一组完整的数据,如此进行多次,从而产生缺失值的一个随机样本,R语言中mice()函数包可以进行多重插补。

    下面结合具体案例介绍缺失值的识别和处理。

    餐饮系统中的销量数据可能会出现缺失值,销量数据的下载地址为:

    https://github.com/windform/R/blob/master/R%E8%AF%AD%E8%A8%80%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98/%E6%95%B0%E6%8D%AE%E8%B4%A8%E9%87%8F%E5%88%86%E6%9E%90/chapter4/data/catering_sale.csv

    下面代码将演示均值替换、回归插补、多重插补进行缺失数据插补:

    > # 读取销售数据文件,提取标题行

    > inputfile <- read.csv('./data/catering_sale.csv', header = TRUE)

    > # 变换变量名

    > inputfile <- data.frame(sales = inputfile$'销量', date = inputfile$'日期')

    > # 数据截取

    > inputfile <- inputfile[5:16, ]

    > # 缺失数据的识别

    > is.na(inputfile) # 判断是否存在缺失

    sales date

    5 FALSE FALSE

    6 FALSE FALSE

    7 FALSE FALSE

    8 FALSE FALSE

    9 FALSE FALSE

    10 FALSE FALSE

    11 FALSE FALSE

    12 FALSE FALSE

    13 FALSE FALSE

    14 FALSE FALSE

    15 TRUE FALSE

    16 FALSE FALSE

    > n <- sum(is.na(inputfile)) # 输出缺失值个数

    > # 异常值识别

    > par(mfrow = c(1, 2)) # 将绘图窗口划为1行两列,同时显示两图

    > dotchart(inputfile$sales) # 绘制单变量散点图

    > boxplot(inputfile$sales, horizontal = TRUE) # 绘制水平箱形图

    > # 异常数据处理

    > inputfile$sales[5] = NA # 将异常值处理成缺失值

    > fix(inputfile) # 表格形式呈现数据

    > # 缺失值的处理

    > inputfile$date <- as.numeric(inputfile$date) # 将日期转换成数值型变量

    > sub <- which(is.na(inputfile$sales)) # 识别缺失值所在行数

    > inputfile1 <- inputfile[-sub, ] # 将数据集分成完整数据和缺失数据两部分

    > inputfile2 <- inputfile[sub, ]

    > # 行删除法处理缺失,结果转存

    > result1 <- inputfile1

    > # 均值替换法处理缺失,结果转存

    > avg_sales <- mean(inputfile1$sales) # 求变量未缺失部分的均值

    > inputfile2$sales <- rep(avg_sales,n) # 用均值替换缺失

    > result2 <- rbind(inputfile1, inputfile2) # 并入完成插补的数据

    > # 回归插补法处理缺失,结果转存

    > model <- lm(sales ~ date, data = inputfile1) # 回归模型拟合

    > inputfile2$sales <- predict(model, inputfile2) # 模型预测

    > result3 <- rbind(inputfile1, inputfile2)

    > # 多重插补法处理缺失,结果转存

    > library(lattice) # 调入函数包

    > library(MASS)

    > library(nnet)

    > library(mice) # 前三个包是mice的基础

    > imp <- mice(inputfile, m = 4) # 4重插补,即生成4个无缺失数据集

    iter imp variable

    1 1 sales

    1 2 sales

    1 3 sales

    1 4 sales

    2 1 sales

    2 2 sales

    2 3 sales

    2 4 sales

    3 1 sales

    3 2 sales

    3 3 sales

    3 4 sales

    4 1 sales

    4 2 sales

    4 3 sales

    4 4 sales

    5 1 sales

    5 2 sales

    5 3 sales

    5 4 sales

    > fit <- with(imp,lm(sales ~ date, data = inputfile)) # 选择插补模型

    > pooled <- pool(fit)

    > summary(pooled)

    est se t df Pr(>|t|) lo 95 hi 95 nmis fmi lambda

    (Intercept) -8127.53603 6907.61505 -1.176605 6.5448 0.2803675 -24694.59377 8439.5217 NA 0.2095382 0

    date 61.87193 37.47189 1.651156 6.5448 0.1456650 -27.99975 151.7436 0 0.2095382 0

    > result4 <- complete(imp, action = 3) # 选择第三个插补数据集作为结果

    异常值处理

    在异常值处理之前需要对异常值进行识别,一般多采用单变量散点图或是箱线图来达到目的。在R语言中,使用函数dotchart()、boxplot()实现绘制单变量散点图与箱线图,远离正常值范围的点即视为异常值。异常值产生最常见的原因是人为输入的错误。

    在数据预处理时,异常值是否剔除,需视具体情况而定,因为有些异常值可能包含有用的信息,异常值的常用处理方法有:

    将含有异常值的记录直接删除这种方法简单易行,但缺点也很明显,在观测值很少的情况下,这种删除会造成样本量不足,可能会改变变量的原有分布,从而造成分析结果的不准确。视为缺失值处理的好处是可以利用现有变量的信息,对异常值进行填补。

    很多情况下,要先分析异常值出现的可能原因,再判断异常值是否应该舍弃,如果是正确的数据,可以直接在具有异常值的数据集上进行挖掘建模。

    展开全文
  • etlpy是python编写的网页数据抓取和清洗工具,...内置正则解析,html转义,json转换等数据清洗功能,直接输出可用文件 插件式设计,能够非常方便地增加其他文件和数据库格式 能够支持几乎一切网站,能自动填入cooki...
  • 简单数据清洗

    2018-11-27 20:51:24
    数据清洗代码清理或者使用OpenRefine开源软件 代码清理 转义字符\n Unicode字符 剔除单字符单词 引用标记 标点符号 input = re.sub('\n+', " ", input) input = re.sub('\[[0-9]*\]', "", ...
  • 数据清洗工具kettle

    万次阅读 2015-05-26 09:47:58
    kettle简介:  kettle是pentho的一...kettle是开源工具,有源代码可以下载,ant管理编译,流程比较清楚,如果满足不了自己的需求可以去开发,也可以嵌入使用java代码以及javascript代码,来进行数据清洗。下面我来简
  • 关于NLP数据收集、数据增强、数据清洗、预处理的一些整理收集
  • 数据清洗工具 OpenRefine简介

    千次阅读 2020-03-31 13:50:48
    目前有三款免费的数据清洗工具:OpenRefine,Weka,Data Wrangler。下面主要介绍OpenRefine。 ● OpenRefine前身是谷歌公司(Google) 开发的数据清洗工具GoogleRefine, 随后于2012年开放源代码,改为现在的OpenRefine...
  • Hadoop离线项目之数据清洗 1.背景 1.1 企业级大数据项目开发流程 项目调研:技术?业务? ​ 以业务为导向的项目调研,根据不同的行业对项目进行调研,主要以 产品经理、非常熟悉业务的、项目经理等人员进行项目调研...
  • 最近一直在实习,好长时间没更新博客了。哎,懒惰之心不可有啊!...2.数据获取:根据数据挖掘任务的具体要求,从相关数据源中抽取相关数据集。(以前在实验室的时候用到的都是现成的数据,直接拿过来用就行了
  • 一:数据挖掘 我选用了链家网做数据爬取场所(不得不唠叨一句,这个网站真是为了爬虫而生的,对爬虫特别友好哈哈哈,反扒措施比较少) 比如我们爬取贵阳市乌当区的所有房子的房价及其他信息: 比如我们爬取第一...
  • 数据科学家们会花费大量的时间来清理数据集,毫不夸张地说,数据清洗会占据他们80%的工作时间,而真正用来分析数据的时间只占到20%左右。 所以,数据清洗到底是在清洗些什么? 通常来说,你所获取到的原始数据...
  • ​点击关注 异步图书,置顶公众号每天与你分享 IT好书 技术干货 ...在对数据进行分析之前,数据科学家首先要做的是从这些数据源获取各种格式的数据,并对这些数据进行清洗,去除其中的噪声。今天推荐的图书是《J...
  • 目录 推荐 一、前言 1、数据清洗的方法 2、数据清洗的工具 二、准备工作 2.1 官网安装Anaconda(推荐) 2.2 Anaconda历史版本合集(学长自己的下载方式) 2.3 下载建议 2.4 如何在Jupyter Notebook新建文件 三、数据...
  • 一、数据清洗的那些事 构建业务模型,在确定特征向量以后,都需要准备特征数据在线下进行训练、验证和测试。同样,部署发布离线场景模型,也需要每天定时跑P加工模型特征表。 而这一切要做的事,都离不...
  • python 数据清洗用到两个包 numpy和pandas Pandas的名称来自于Panel data和Python数据分析data analysis,是Python的一个数据分析包,最初由AQR Capital Management于2008年4月开发,被作为金融数据分析工具,为时间...
  • 原文来自Python实用宝典:Python七月超有用的十大开源代码(2019) Mybridge AI 将github上的每个Python项目根据分享总数,读取的分钟数等特征,并用他们的算法计算出了以下2019年7月的十大开源项目。这些项目可能对...
  • 构建在开源核心上,开发人员可以轻松构建批处理和流式数据流,而且代码少,而运营商使用云本地产品将数十或数百个数据流聚合到拓扑中,并通过实时可见性和性能控制集中管理。2、其官网地址:https://streamsets.com3...
  • 环境 hadoop-2.6.5  首先要知道为什么要做数据清洗...具体要做的工作可以参考文章:数据清洗的一些梳理 当了解ETL之后,有一些工具,比如开源kettle可以做这个工作。但是也可以完全自己开发,ETL无非就是三个阶...
  • 1.概要1.1 比赛相关本博文为分析学习github上的美年健康ai大赛的开源代码。1.1.1大赛地址:https://tianchi.aliyun.com/competition/introduction.htm?spm=5176.11409106.5678.1.1c9a560c15bKhJ&amp;raceId=...
  • Kafka Stream 数据清洗

    千次阅读 2019-01-25 12:48:47
    Kafka Streams 是 Apache Kafka 开源项目的一个组成部分。 是一个功能强大,易于使用的库。用于在 Kafka 上构建高可分布式、拓展性,容错的应用程序。 1.1 Kafka Stream 特点 功能强大 高扩展性,弹性,容错 ...
  • 2.第二步数据清洗:解析第一步清洗后的数据, 处理时间,提出URL中的产品编号、得到产品类型, 由IP得到城市信息(用到开源社区的解析代码,该部分具体介绍:ipdatabase解析出IP地址所属城市) ,按照天分区进行存储...
  • 点上方计算机视觉联盟获取更多干货仅作学术分享,不代表本公众号立场,侵权联系删除转载于:新智元AI博士笔记系列推荐周志华《机器学习》手推笔记正式开源!可打印版本附pdf下载链接数据可以说是所...
  • python数据清理开源 在本版开源新闻摘要中,我们将介绍开源仿生腿,新的开源医学影像组织,麦肯锡的第一个开源发行版以及更多内容! 使用开源推进仿生学 一代人从电视剧“六百万美元的男人”和“仿生女人”中...
  • Ensemble Generative Cleaning With Feedback Loops for Defending Adversarial Attacks 《带有反馈回路的集成生成式清洗,以防御对抗攻击》 在本文中,作者提出了一种新的方法,该方法称为带反馈回路的集成生成...
  • 51job pandas数据清洗与pycharts画图分析

    千次阅读 2019-06-13 16:12:01
    上一篇想要的数据已经基本都爬到了,下一步就是数据清洗了。 仔细观察了数据的特征,发现数据中存在太多的脏数据了,就例如很多搞房地产的,销售的,等等很多其他的一些无关职业,并且还包含很多重复项。我就把...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,673
精华内容 3,869
关键字:

数据清洗开源代码