文档章节

一个根据相似度的去重方法

鼎铭
 鼎铭
发布于 2017/07/19 18:02
字数 561
阅读 143
收藏 0

需求,一个csv文件中有很多行,每行是个id,字符串,每个字符串可能两两相似(是相似,不是相同),怎样去重,保留两两相似度小于0.8的id。

做法,用diff库计算两两相似度,每次计算结果,这里可以用(进程/线程/协程加速),然后将相似度大于0.8的结果放到set中,最后set中取任意一个加非集合中成员,可以返回去重结果。

import sys, os
from HTMLParser import HTMLParser
from multiprocessing import Queue
wait_set=Queue()

class HTMLStripper(HTMLParser):
    def __init__(self):
        self.reset()
        self.fed = []
    def handle_data(self, d):
        self.fed.append(d)
    def get_data(self):
        return ''.join(self.fed)


def strip_tags(html):
    s = HTMLStripper()
    s.feed(html.decode('UTF-8'))
    return s.get_data()


def distance(s1, s2):
    import difflib
    return difflib.SequenceMatcher(None, s1, s2).ratio()


class CSV():
    def __init__(self, csvfile, delimiter=',', quotechar='"'):
        self.csvfile = csvfile
        self.delimiter = delimiter
        self.quotechar = quotechar
        self.items = []

        import csv
        csv.field_size_limit(sys.maxsize)#this line is limited in linux,if run in windows will rasise
        #csv.field_size_limit(131072)
        with open(csvfile, 'rU') as f:
            for item in csv.reader(f, delimiter=delimiter, quotechar=quotechar):
                self.items.append(item)
        f.close()

    def diff(self, threshold=None, strip=None, truncate=None, start=0, end=None):
        i = start
        for item in self.items[start:end]:
            i = i + 1

            id = item[0]
            text = item[1]
            if strip:
                text = strip_tags(text)

            # Skip the items already diffed or itself
            for c_item in self.items[i:]:
                c_id = c_item[0]
                c_text = c_item[1]
                if strip:
                    c_text = strip_tags(c_text)

                if truncate:
                    d = distance(text[0:truncate], c_text[0:truncate])
                else:
                    d = distance(text, c_text)

                if (threshold and d < threshold):
                    continue
                wait_set.put(id)# because the subprocess
		wait_set.put(c_id)

    def output(self, data):
        print ','.join(data)
        sys.stdout.flush()

    def analysis(self):
        print "%s items, %s bytes." % ( len(self.items), os.path.getsize(self.csvfile) )
        print '%6s %32s %32s %32s' % ('No', 'UUID', 'Length(after strip)', 'Length(before strip)')
        i = 0
        for item in self.items:
            print '%6s %32s %32s %32s' % (i, item[0], len(strip_tags(item[1])), len(item[1]))
            i = i + 1;


def wrapper(args):
    CSV.diff(*args)


def main():
    csvfile = sys.argv[1]
    threshold = 0.8
    threads = 4
    strip = True
    truncate = 256
    action = 'diff'

    if len(sys.argv) > 2:
        if sys.argv[2] == '-a':
            action = 'analysis'
        else:
            threshold = float(sys.argv[2])
    if len(sys.argv) > 3:
        threads = int(sys.argv[3])
    if len(sys.argv) > 4:
        strip = bool(int(sys.argv[4]))
    if len(sys.argv) > 5:
        truncate = int(sys.argv[5])

    c = CSV(csvfile)

    if action == 'analysis':
        c.analysis()
    elif action == 'diff':
        if threads > 1:
            batch = len(c.items) / threads
            tail = len(c.items) % threads

            from multiprocessing import Pool
            pool = Pool()
            args = []

            i = 0
            while (i < threads):
                start = batch * i
                end = start + batch
                # Last loop
                if i == (threads - 1):
                    end = end + tail

                args.append( (c, threshold, strip, truncate, start, end) )
                i = i + 1

            pool.map(wrapper, args)
        else:
            c.diff(threshold, strip, truncate)
    wait_list=[x[0] for x in c.items[1:]]

    if wait_set.qsize:
	queue_list=list(set([wait_set.get() for x in range(wait_set.qsize())]))
	for x in range(len(queue_list)-1):#left one element
		ele = queue_list[x]
		if ele in wait_list:
			wait_list.remove(ele)
	print wait_list
    else:
	return wait_list
    sys.stdout.flush()

if __name__ == '__main__':
    main()

 

© 著作权归作者所有

鼎铭
粉丝 51
博文 71
码字总数 45420
作品 0
东城
程序员
私信 提问
粒子滤波目标跟踪原理(不带公式)

参考: http://blog.csdn.net/wenglee918/article/details/34422939 http://www.cnblogs.com/yangyangcv/archive/2010/05/23/1742263.html 1. 基本思想 粒子滤波本质上是一种表示概率分布的方......

yushupan
2017/12/19
0
0
如何在不同摄像头里识别行人?多层相似度感知CNN网络解析 | 技术贴

阿里妹导读:行人重识别是指给定一个摄像头下某个行人的图片,在其他摄像头对应的图片中准确地找到同一个人。行人重识别技术有十分重要的科研和实际应用价值,近来广泛应用到交通、安防等领域...

阿里云科技快讯
2018/08/10
0
0
基于文本相似度算法,分析 Vue 是抄出来的框架吗?

本周一篇指摘 Vue 抄袭 Angular 的文章一石激起千层浪。为此,笔者作为中立吃瓜的 React 用户,分析了 13 个主流前端框架版本上万个变量的命名风格,应用自然语言处理中的文本相似度算法进行...

doodlewind
2017/08/05
0
0
火眼金睛算法,教你海量短文本场景下去重

本文由QQ大数据发表 最朴素的做法 在大多数情况下,大量的重复文本一般不会是什么好事情,比如互相抄袭的新闻,群发的垃圾短信,铺天盖地的广告文案等,这些都会造成网络内容的同质化并加重数...

腾讯云加社区
2018/12/03
58
0
老司机带你检测相似图片

欢迎大家前往腾讯云社区,获取更多腾讯海量技术实践干货哦~ 作者:雷经纬 导语: 本文从从图片的dhash,ahash,phash,颜色分布向量到基于语义的sift,surf,gist特征,构建一套分层相似图片检...

腾讯云社区
2017/11/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

DDD(五)

1、引言 之前学习了解了DDD中实体这一概念,那么接下来需要了解的就是值对象、唯一标识。值对象,值就是数字1、2、3,字符串“1”,“2”,“3”,值时对象的特征,对象是一个事物的具体描述...

MrYuZixian
47分钟前
3
0
数据库中间件MyCat

什么是MyCat? 查看官网的介绍是这样说的 一个彻底开源的,面向企业应用开发的大数据库集群 支持事务、ACID、可以替代MySQL的加强版数据库 一个可以视为MySQL集群的企业级数据库,用来替代昂贵...

沉浮_
今天
4
0
解决Mac下VSCode打开zsh乱码

1.乱码问题 iTerm2终端使用Zsh,并且配置Zsh主题,该主题主题需要安装字体来支持箭头效果,在iTerm2中设置这个字体,但是VSCode里这个箭头还是显示乱码。 iTerm2展示如下: VSCode展示如下: 2...

HelloDeveloper
今天
6
0
常用物流快递单号查询接口种类及对接方法

目前快递查询接口有两种方式可以对接,一是和顺丰、圆通、中通、天天、韵达、德邦这些快递公司一一对接接口,二是和快递鸟这样第三方集成接口一次性对接多家常用快递。第一种耗费时间长,但是...

程序的小猿
今天
5
0
Python机器学习之数据探索可视化库yellowbrick

背景介绍 从学sklearn时,除了算法的坎要过,还得学习matplotlib可视化,对我的实践应用而言,可视化更重要一些,然而matplotlib的易用性和美观性确实不敢恭维。陆续使用过plotly、seaborn,...

yeayee
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部