对于千万行级别的数据,处理起来非常麻烦,例如有一个文件a.txt,大小超过2GB,共2000多万行,每行是一个新闻的相关信息,其中有一列为新闻标题,字符串型,新闻标题较长,现需要对新闻标题进行聚类,将类似标题的新闻归为一类,并将其中代表性的标题作为这一组新闻的标题。
例如"海量数据处理经验交流会今天召开-第一部分","海量数据处理经验交流会今天召开-第二部分","海量数据处理经验交流会今天召开-第三部分",将这三个标题归类为"海量数据处理经验交流会今天召开"。
如何实现?
我的思路是:
首先,从2GB的a.txt文件中,提取出新闻标题这一列,然后将其存入到另一个文件b.txt,这样,就得到一个只包含新闻标题这一列的b.txt文件,文件大小仅为500多MB。
第二步,将其导入到MySQL数据库,具体采用load data infile 'D:/test/news.txt' into table news(newsid,newstitle)这一方法导入。
第三步,由于同时处理上千万条数据,很有可能发生内存不足而发生异常,因此分批从MySQL读取一部分数据(例如一百万条),再利用Levenshtein距离,计算新闻标题(字符串类型)之间的相似性,距离小于等于2的归为一类,并将这一类的第一个新闻标题,截取前面的公共部分作为这一类新闻的标题。
需要注意的是,导入大批量数据到MySQL时,可以采用Python的cursor.executemany()方法,也可以采用Java的PreparedStatement.executeBatch()方法,或者采用MySQL数据库自带的load data infile命令(详见:http://blog.csdn.net/north_easter/article/details/8333137),
我在进行第二步的时候,采用了MySQL自带的命令,第一次执行报错:
The MySQL server is running with the --secure-file-priv so it cannot execute this statement
Google之后才知道,不是随便一个地方的文件都能导入到MySQL数据库,出于MySQL的安全机制,secure_file_priv指定的文件夹里面的文件才能作为数据源导入,因此首先需要使用SHOW VARIABLES LIKE "secure_file_priv"命令找出该文件夹,例如C:ProgramDataMySQLMySQL Server 5.7Uploads
然后需要把作为数据源的txt文件放在该文件夹下,才能导入,如果txt数据源中如果存在中文字符,则可能会报其他的错误。
数据处理经验尚浅,只能想出这种方法,网上查资料,发现对于海量数据处理,大量采用分治法和Hash(例如SimHash)等方法。
参考: