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='\t', 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)