提取词性和词边界信息
word_bounds = ['M' for item in tag_list] # 和tag list长度一样的 全部都是M构成的
word_flags = []
for text in texts: # 遍历里面每一句话
for word, flag in psg.cut(text): # 对每一句话进行切词
if len(word) == 1:
start = len(word_flages) # B 开头 E 结束 S 是单独的词
word_bounds[start] = 'S' M是中间的
word_flags.append(flag)
else:
start = len(word_flags)
word_bounds[start] = 'B'
word_flags += [flag] * len(word)
end = len(word_flags) - 1
word_bounds[end] = 'E'
# -------------------统一截断---------------------------------------
tags = []
bounds = []
flags = []
start = 0
end = 0
for s in texts:
l = len(s)
end += 1
bounds.append(word_bounds[start:end])
flags.append(word_flags[start:end])
start += 1
data['bound'] = bounds
data['flag'] = flags
data['label'] = tags
这样就得到分词标记(B M E S) 和词性 (ns, n, eng....)
然后再获取拼音特征
我们要安装一个包
from cnradical import?
pip install cnradical? 写一个test 熟悉一下这个库
from cnradical import Radical, RunOption
radical = Radical(RunOption.Radical) #获取偏旁部首
pinyin = Radical(RunOption.Pinyin) # 获取拼音
input = '大撒大青蛙大全'
radical_out = [radical.trans_ch(ele) for ele in input] # 对每一个字进行处理
pinyin_out = [pinyin.trans_ch(ele) for ele in input]
print(radical_out)
print(pinyin_out)
radical_out = radical.trans_str(input)
pinyin_out = pinyin.trans_str(input)
输出结果为
————————————————获取拼音特征————————————————————
radical = Radical(RunOption.Radical) # 提取偏旁部首
pinyin = Radical(RunOption.Pinyin) # 提取拼音
data['radical'] = [[radical.trans_ch(x) if radical.trans_ch(x) is not None else 'PAD' for x in s] for s in texts] # 如果不是空 把None 改成PAD PAD后续自己再设置
data['pinyin'] = [[pinyin.trans_str(x) if pinyin.trans_ch(x) is not None else 'PAD'for x in s] for s in texts]
# 这里就有一个问题 None 我们要用一个特殊的符号代替
return texts[0] , tags[0],bounds[0], flags[0], data['radical'][0], data['pinyin'][0]
输出 第一句话的texts tags:标签 O B-Disease。。??I-。。? bounds:第一句话的分词边界 B E M S
flags:第一句话的词性? data[’radical‘]:第一句话的偏旁部首 data['pinyin']:第一句话的拼音
然后我们要把数据存起来 后面统一的做数据读取
num_samples=len(texts) # 统计有多少个样本
num_col = len(data.keys) # 统计有多少列 要写成每一行一个字 字 标记 等等特征
dataset = []
for i in range(num_samples): # 用zip压缩
records = list(zip(*[list(v[i] for v in data.value()]))
dataset += records + [['sep'] * num_col] # 加个*解压 第一句话存完之后 要和第二句话隔开
dataset = dataset[:-1] # 不要最后一组隔开符 sep
# 然后再把这个列表变成 dataframe
dataset = pd.DataFrame(dataset, columns=data.keys())
save_path = f'data/prepare/{split_name}/{idx}.csv' #
def clean_word(w):
if w == '\n':
return 'LB'
if w in [' ', '\t', '\u2003']: # '\u2003中文的空格'
return 'SPACE'
if w.isdigit(): # 将所有的数字都变成一种符号 #这样可以提高泛化能力
return 'num'
return w
dataset['word'] = dataset['word'].apply(clean_word) # 对dataset 应用clean_word这个函数
dataset.to_csv(save_path, index=False, encoding='utf-8')
然后将所有的数据全部处理掉? 获取训练集和测试集的下标
train_dir = 'ruijin_round1_train2_20181022'
def multi_process(split_method=None, train_ratio=0.8):
if os.path.exists('data/prepare/'):
shutil.rmtree('data/prepare/') # 如果这个目录存在就删掉
if not os.path.exists('data/prepare/train/'):
os.mkdirs('data/prepare/train'): #如果这个文件夹不存在就创建一个文件夹
os.mkdirs('data/prepare/test'): # 注意 这里是mkdirs 因为创建的多层文件夹
idxs = list(set([file.split('.')[0] for file in os.listdir('datas/') + train_dir])) # 获取所有文件的名字 (下标)
shuffle(idxs) # 打乱下标
index = int(len(idxs) * train_ratio) # 这个就是训练集的下标
# 取 训练集和测试集的下标
train_ids = idxs[:index]
test_ids = idxs[index:]
如果一个文件一个文件处理的话会很慢 所以这里引入多进程
import multiprocessing as mp
num_cpus = mp.cpu_count() # 获取机器cpu的个数
# 线程池
pool = mp.Pool(num_cpus)
train_results = []
test_results = []
for idx in train_ids:
result = pool.apply_async(process_text(), args=(idx, split_method,'train'))
#apply_async 不用等待当前进程执行完毕
#apply 就是需要等待当前进程执行完毕
results.append(result)
for idx in test_ids:
result = pool.apply_async(process_text(), args=(idx, split_method,'test'))
results.append(result)
pool.close() # 进程池关掉
pool.join()
[r.get() for r in results]
到此数据集和测试集就做好了 在开始构建模型之前 我们还需要做一个映射字典(embedding)然后做一个数据增强 下章讲!
|