关于python:爬虫系列数据标准化

42次阅读

共计 3117 个字符,预计需要花费 8 分钟才能阅读完成。

上一期咱们介绍了应用 Python 数据荡涤的相干办法,本篇文章咱们介绍 数据标准化 的相干办法。

每个人都会遇到一些款式设计不够人性化的网页,比方“请输出你的电话号码,号码格局为 xxx-xxxx-xxxx”。

作为一名优良的程序员,你可能会问:”为什么不主动对输出的数据进行荡涤,去掉非数字内容,而后主动把数据加上分隔符呢?“数据标准化过程要确保荡涤后的数据在语言学上是等价的,比方电话号码尽管显示成”134-1234-5678“和”134-12345678“两种模式,然而理论号码是一样的。

还是用上一期的 n-gram 示例,让咱们在下面减少一些数据标准化的特色。

上期文章内容的显著问题,就是输入后果中蕴含太多反复的 2-gram 序列。程序把每个 2-gram 都退出了列表,没有统计过序列的频率。把握 2-gram 序列的频率,而不只是晓得某个序列是否存在,这有助于比照不同的数据荡涤和数据标准化算法的成果。如果数据标准化胜利了,那么惟一的 n-gram 序列数量就会缩小,而 n-gram 序列的总数(任何一个 n-gram 序列和与之反复的序列都被看成一个 n-gram 序列)不变,也就是说,同样数量的 n-gram 序列,通过去重之后“容量(bucket)”会缩小。

不过 Python 的字典是无序的,不能像数组一样间接对 n-gram 序列频率进行排序。字典外部元素的地位是不固定的,排序之后再次应用时还是发生变化,除非你把排序过的字典里的值复制到其余类型中进行排序。在 Python 中 collections 库外面有一个 OrderedDict 能够解决这个问题:

import re
import string
from collections import OrderedDict

from utils import connection_util


class DataCleaning(object):
    def __init__(self):
        self._target_url = 'https://en.wikipedia.org/wiki/python_(programming_language)'
        self._init_connection = connection_util.ProcessConnection()

    def getNgrams(self, input, n):
        input = self.clean_input(input)
        output = dict()
        for i in range(len(input) - n + 1):
            newNGram = " ".join(input[i:i + n])
            if newNGram in output:
                output[newNGram] += 1
            else:
                output[newNGram] = 1
        return output

    @staticmethod
    def clean_input(input):
        input = re.sub('\n+', " ", input)
        input = re.sub('\[[0-9]*\]', "", input)
        input = re.sub('+', " ", input)
        input = bytes(input, "UTF-8")
        input = input.decode("ascii", "ignore")
        input = input.split(' ')
        clean_input = []
        for item in input:
            # string.punctuation 获取所有的标点符号
            item = item.strip(string.punctuation)
            if len(item) > 1 or (item.lower() == 'a' or item.lower() == 'i'):
                clean_input.append(item)
        return clean_input

    def get_result(self):
        # 连贯指标网站,获取内容
        get_content = self._init_connection.init_connection(self._target_url)
        if get_content:
            content = get_content.find("div", {"id": "mw-content-text"}).get_text()
            ngrams = self.getNgrams(content, 2)
            ngrams = OrderedDict(sorted(ngrams.items(), key=lambda t: t[1], reverse=True))
            print(ngrams)
            print("2-grams count is:" + str(len(ngrams)))


if __name__ == '__main__':
    DataCleaning().get_result()

这咱们应用了 Python 的排序函数(https://docs.python.org/zh-cn/3/howto/sorting.html)把序列频率转换成 OrderedDict 对象,并依照频率值排序。后果如下:

('Python Software', 37), ('2021 Retrieved', 36), ('Foundation Archived', 35), ('on June', 34), ('of Python', 28), ('in the', 25), ('such as', 23)

去掉语气词,以及连接词之后频率最高的是“Software Foundation”和“Python Software”。然而仔细观察后果会发现会有大小写字母的影响,“Python Software”有三次是“Python software”的模式,同样,“Van Rossum”和“van Rossum”也是作为两个序列来统计的。

因而,咱们减少一行代码:

    input = input.upper()

clean_input() 函数里,这样就解决了下面的问题,同时缩小了反复的 2-gram 序列。

除了这些,还须要在考虑一下,本人打算为数据标准化的进一步深刻再投入多少计算力。很多单词在不同的环境里会应用不同的拼写模式,其实都是等价的,然而为了解决这种等价关系,你须要对每个单词进行查看,判断是否和其余单词有等价关系。

比方,“Python 1st”和“Python first”都呈现在 2-gram 序列外面。然而,如果减少一条规定:“让所有‘first’、‘secode’、‘third’……与 1st、2nd、3rd……等价”,那么每个单词就须要额定减少十几次查看。

同理,连字符应用不统一(像“co-ordinated”和“coordinated”)、单词拼写错误以及其余语病(incongruities), 都可能对 n-gram 序列的分组后果造成影响,如果语病很重大的话,很可能彻底打乱输入后果。

对连字符单词的一个解决办法是,首先把连字符去掉,而后把单词当作一个字符串,这可能须要在程序中减少一步操作。然而,这样做也可能把带连字符的短语(这种很常见,比方:“just-in-time”、“object-oriented”等)解决成一个字符串。要是换一种做法,把连字符换成空格可能会更好一些。然而就得筹备见到“co ordinated”和“ordinated attack”之类的 2-gram 序列了!

总结

这篇文章次要解说了在英文中对于数据标准化的相干内容,首先是对单词呈现的频率进行排序,之后对一些大小写进行转换,放大 2-gram 序列的反复内容,之后对一些连字符以及一些语法上的习惯进行解决。

解决实现后的内容咱们能够制作一个 词云,如下:

以上就是这篇文章的全部内容。

源代码曾经托管于 Github 当中,地址:https://github.com/sycct/Scra…

如果有任何问题,欢送大家 issue。

正文完
 0