自己動手寫word2vec (二):統計詞頻


系列所有帖子
自己動手寫word2vec (一):主要概念和流程
自己動手寫word2vec (二):統計詞頻
自己動手寫word2vec (三):構建Huffman樹
自己動手寫word2vec (四):CBOW和skip-gram模型


在我之前寫的word2vec的大概流程中,第一步的分詞使用jieba來實現,感覺效果還不錯。

第二步. 統計詞頻

統計詞頻,相對來講比較簡單一些,主要在Python自帶的Counter類基礎上稍作改進。值得注意的是需要去掉停用詞。所謂停用詞,就是出現頻率太高的詞,如逗號,句號等等,以至於沒有區分度。停用詞可以在網上很輕易找到,我事先已經轉化成二進制的格式存儲下來了。這一部分的代碼放在WordCount.py文件中

2.1 MulCounter

MulCounter完成的是根據單詞數組來完成統計詞頻的工作。
這是一個繼承自Counter的類。之所以不直接用Counter是因爲它雖然能夠統計詞頻,但是無法完成過濾功能。而MulCounter可以通過larger_than和less_than這兩個方法過濾掉出現頻率過少和過多的詞。

class MulCounter(Counter):
    # a class extends from collections.Counter
    # add some methods, larger_than and less_than
    def __init__(self,element_list):
        super().__init__(element_list)

    def larger_than(self,minvalue,ret='list'):
        temp = sorted(self.items(),key=_itemgetter(1),reverse=True)
        low = 0
        high = temp.__len__()
        while(high - low > 1):
            mid = (low+high) >> 1
            if temp[mid][1] >= minvalue:
                low = mid
            else:
                high = mid
        if temp[low][1]<minvalue:
            if ret=='dict':
                return {}
            else:
                return []
        if ret=='dict':
            ret_data = {}
            for ele,count in temp[:high]:
                ret_data[ele]=count
            return ret_data
        else:
            return temp[:high]

    def less_than(self,maxvalue,ret='list'):
        temp = sorted(self.items(),key=_itemgetter(1))
        low = 0
        high = temp.__len__()
        while ((high-low) > 1):
            mid = (low+high) >> 1
            if temp[mid][1] <= maxvalue:
                low = mid
            else:
                high = mid
        if temp[low][1]>maxvalue:
            if ret=='dict':
                return {}
            else:
                return []
        if ret=='dict':
            ret_data = {}
            for ele,count in temp[:high]:
                ret_data[ele]=count
            return ret_data
        else:
            return temp[:high]

2.2 WordCounter

WordCounter完成的是根據文本來統計詞頻的工作。確切的來說,對完整的文本進行分詞,過濾掉停用詞,然後將預處理好的單詞數組交給MulCounter去統計

class WordCounter():
    # can calculate the freq of words in a text list

    # for example
    # >>> data = ['Merge multiple sorted inputs into a single sorted output',
    #           'The API below differs from textbook heap algorithms in two aspects']
    # >>> wc = WordCounter(data)
    # >>> print(wc.count_res)

    # >>> MulCounter({' ': 18, 'sorted': 2, 'single': 1, 'below': 1, 'inputs': 1, 'The': 1, 'into': 1, 'textbook': 1,
    #                'API': 1, 'algorithms': 1, 'in': 1, 'output': 1, 'heap': 1, 'differs': 1, 'two': 1, 'from': 1,
    #                'aspects': 1, 'multiple': 1, 'a': 1, 'Merge': 1})

    def __init__(self, text_list):
        self.text_list = text_list
        self.stop_word = self.Get_Stop_Words()
        self.count_res = None

        self.Word_Count(self.text_list)

    def Get_Stop_Words(self):
        ret = []
        ret = FI.load_pickle('./static/stop_words.pkl')
        return ret

    def Word_Count(self,text_list,cut_all=False):

        filtered_word_list = []
        count = 0
        for line in text_list:
            res = jieba.cut(line,cut_all=cut_all)
            res = list(res)
            text_list[count] = res
            count += 1
            filtered_word_list += res

        self.count_res = MulCounter(filtered_word_list)
        for word in self.stop_word:
            try:
                self.count_res.pop(word)
            except:
                pass
發佈了88 篇原創文章 · 獲贊 591 · 訪問量 147萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章