zoukankan      html  css  js  c++  java
  • Datawhale-新闻文本分类-task4-基于深度学习的文本分类2-word2vec-textcnn-textrnn

    # 在上一次中10fold代码不知道怎么写![](https://img2020.cnblogs.com/blog/1358638/202007/1358638-20200731212605021-1488696390.png) , 之后看了论坛大哥代码,有点理解了。
    
    # 10_kfold fucntion
    import logging
    import random
    fold_num = 10
    data_file = './train_set.csv'
    import pandas as pd
    import numpy as np
    
    logging.basicConfig(level=logging.INFO, format='%(asctime)-15s %(levelname)s: %(message)s')
    
    def all_data2fold(fold_num, num=10000):
        # 
        fold_data = []
        f = pd.read_csv(data_file, sep='	', encoding='utf-8')
        texts = f['text'].tolist()[:num]  # 得到所有text
        labels = f['label'].tolist()[:num] # 得到所有text对应的Label
        
        
        total = len(labels)  # 得到样本总数量
        
        index = list(range(total))  # 制造所有样本对应的index
    #     print(index[:100])
        np.random.shuffle(index) # 打乱所有index顺序
    #     print(index[:100])    
        
        all_texts = []  # 存放所有texts
        all_labels = [] # 存放所有labels
        for i in index: # 将打乱顺序的样本和label全部放入刚建的all_text List 和 all_labels List
            all_texts.append(texts[i])  # all_texts 和 texts 都存放了所有的样本, 但前者是无序,后者是有序
            all_labels.append(labels[i])  # all_labels 和 labels 都存放了所有的label, 但前者是无序,后者是有序
        
        # 这小段代码将得到每个标签对应的样本所在的index。  存放在label2id中, 
        label2id = {}
        for i in range(total):
            label = str(all_labels[i])
            if label not in label2id:
                label2id[label] = [i]
            else:
                label2id[label].append(i)
    #     print(label2id.get('10'))
        
        
        all_index = [[] for _ in range(fold_num)] # 生成一个二维的10个空list。 [[],[],[],[],[],[],[]……]
    #     print(all_index)
        
        for label, data in label2id.items(): # label:样本标签, data: label对应的样本list
            # print(label, len(data))
            batch_size = int(len(data) / fold_num)  # 求得每类label对应的所有样本 / 10 得平均数
            other = len(data) - batch_size * fold_num # 求得多出得样本数量 (求未整除10时,剩余样本数量) 就是按除以10得平均数分完10份后,还剩余得样本数
            
            # 这小段代码时切分十折样本得逻辑: 将多出的样本随机分给10份中某些部分
            for i in range(fold_num):
                cur_batch_size = batch_size + 1 if i < other else batch_size  # 将多出的样本随机分给10份中某些部分
                # i * batch_size:表示在10轮顺序中所处取号排名;b代表在当前每个fold对应应取数目中的排名。
                #因此 i * batch_size + b表示:在label所有对应样本中应取排名
                batch_data = [data[i * batch_size + b] for b in range(cur_batch_size)]  # 拿着上一步分得的应取样本数目到label对应存放样本的data中取
                # 将每个fold取到的样本对应index存到all_index中
                all_index[i].extend(batch_data)  # 注意此处是extend,而不是append,因此一个[]就包含该fold所有类别label对应的样本index
                # 当这小段代码运行结束,所有样本的十折分区就已经分好了。
                # all_index是这样得: [[所有被分到label对应样本的index], [], ……共10个]
        
        # 之前得代码是划分10fold中没fold应取样本得index
        # 这段代码是:取出每个fold对应得样本,label
        batch_size = int(total / fold_num)  # 表示10fold中,每个fold应取得总样本数目为多少。(所有label)
        other_texts = []
        other_labels = []
        other_num = 0
        start = 0
        
        # 
        print(total)
        for fold in range(fold_num):
            count = 0
            num = len(all_index[fold]) # 该fold取得的样本总数量
            texts = [all_texts[i] for i in all_index[fold]] # 取出该fold对应得样本
            fold_labels = [all_labels[i] for i in all_index[fold]]  # 取出该fold对应得label
    #         print(batch_size == len(fold_labels), end='')
            
            
            # 这段代码逻辑则是让每个fold对应的样本和label数量与  总样本数量/fold_num  尽可能相等(至少保证前面几个fold)
            # 但是我不明白这样做有什么意义:因为这样可能导致有样本没有分到10fold中。
            # 举例总样本26,两类。第一类12,第二类14个
            # 按分法,10fold。[[2,2,1,1,1,1,1,1,1,1], [2,2,2,2,1,1,1,1,1,1]] 
            # 那么---> 每个fold对应样本数量[[4],[4],[3],[3],[2],[2],[2],[2],[2],[2]]
            # 总样本数量 / 10fold = 26 /10 = 2.6, 再int 得 avg = 2 ; 将avg与之前folf对应样本数量比较,再划分得到新的每folf对应样本数量
            # ---> [[2],[2],[2],[2],[2],[2],[2],[2],[2],[2]]   , 那么还有6个样本呢? 不在10fold中了? 
            ######  从测试得结果看,我的猜想是错误得, 这段代码没有问题, 并且降低了最大与最小fold样本差
            if num > batch_size:
                fold_texts = texts[:batch_size]
                other_texts.extend(texts[batch_size:])
                fold_labels= labels[:batch_size]
                other_labels.extend(labels[batch_size:])
                other_num += num - batch_size
            elif num < batch_size:
                end = start + batch_size - num
                fold_texts = texts + other_texts[start: end]
                fold_labels = labels + other_labels[start: end]
                start = end
            else:
                fold_texts = texts
                fold_labels = labels
            count += len(fold_labels)
    #         print(count)
    #         print(batch_size == len(fold_labels))
    #         assert  batch_size == len(fold_labels)
    
            # shuffle
            # 再次打乱顺序是此时, 每个label样本是没有被分开得,label对应样本都聚在一起了
            index = list(range(batch_size)) 
            np.random.shuffle(index)
            
            shuffle_fold_texts = []
            shuffle_fold_labels =[]
            
            for i in index:
                shuffle_fold_texts.append(fold_texts[i])
                shuffle_fold_labels.append(fold_labels[i])
            data = {'label': shuffle_fold_labels, 'text': shuffle_fold_texts}
            fold_data.append(data)
            
        logging.info('Fold lens %s', str([len(data['label']) for data in fold_data]))
        
        return fold_data
    

    fold_data = all_data2fold(10)

    word2vec 得到词向量。 我觉得word2vec牛皮得地方在于它得思想,联系上下文,计算得到相似度。那么按这个原理,就可以在其它地方得到应用了。我想到了推荐(商品、视频、好友、文章等)
    为了验证自己得猜想,搜了“word2vec可以做推荐吗?” 果然有很多文章在介绍word2vec在推荐上得应用。
    但是目前自己还是太菜了。所以并不知道,拿到词向量后怎么样在其它算法中使用?

    下面继续摘抄论坛大哥得代码完成打卡。
    但是textcnn、textrnn。 代码PyTorch写的,在注释得情况下,还是看不懂。 所以暂时先提交到word2vec。其它的后面搞懂了再补上

    #####
    # # build train data for word2vec
    fold_id = 9
    
    # 按k fold 取出data作为train_texts
    train_texts = []
    for i in range(0, fold_id):
        data = fold_data[i]
        train_texts.extend(data['text'])
        
    logging.info('Total %d docs.'% len(train_texts))
    
    logging.info('Start trainig……')
    from gensim.models.word2vec import Word2Vec
    
    num_features = 100
    num_workers = 8
    
    # train_texts 是个二维list,使用map
    train_texts = list(map(lambda x: list(x.split()), train_texts))
    
    model = Word2Vec(train_texts, workers=num_workers, size=num_features)
    model.init_sims(replace=True)  # 锁定模型,可以提高后续模型和任务速度。但是模型也不能再训练了。
    
    # save model
    model.save('./word2vec.bin')
    
    # load model
    model = Word2Vec.load('./word2vec.bin')
    
    # convert format
    model.wv.save_word2vec_format('./word2vec.txt', binary=False)
    
  • 相关阅读:
    【UVa 1592】Database
    【UVa 400】Unix ls
    【UVa 136】Ugly Numbers
    【UVa 540】Team Queue
    【Uva 12096】The SetStack Computer
    【POJ 1050】To the Max
    【UVa 156】Ananagrams
    【UVa 10815】Andy's First Dictionary
    [HNOI/AHOI2018]转盘
    CF46F Hercule Poirot Problem
  • 原文地址:https://www.cnblogs.com/Alexisbusyblog/p/13412304.html
Copyright © 2011-2022 走看看