当前位置:   article > 正文

最详细NER实战讲解-bilstm+crf(4)提取词边界和词性特征_ner实现名词提取

ner实现名词提取

提取词性和词边界信息

  1. word_bounds = ['M' for item in tag_list] # 和tag list长度一样的 全部都是M构成的
  2. word_flags = []
  3. for text in texts: # 遍历里面每一句话
  4. for word, flag in psg.cut(text): # 对每一句话进行切词
  5. if len(word) == 1:
  6. start = len(word_flages) # B 开头 E 结束 S 是单独的词
  7. word_bounds[start] = 'S' M是中间的
  8. word_flags.append(flag)
  9. else:
  10. start = len(word_flags)
  11. word_bounds[start] = 'B'
  12. word_flags += [flag] * len(word)
  13. end = len(word_flags) - 1
  14. word_bounds[end] = 'E'
  15. # -------------------统一截断---------------------------------------
  16. tags = []
  17. bounds = []
  18. flags = []
  19. start = 0
  20. end = 0
  21. for s in texts:
  22. l = len(s)
  23. end += 1
  24. bounds.append(word_bounds[start:end])
  25. flags.append(word_flags[start:end])
  26. start += 1
  27. data['bound'] = bounds
  28. data['flag'] = flags
  29. data['label'] = tags

这样就得到分词标记(B M E S) 和词性 (ns, n, eng....)

然后再获取拼音特征

我们要安装一个包

from cnradical import 

pip install cnradical  写一个test 熟悉一下这个库

  1. from cnradical import Radical, RunOption
  2. radical = Radical(RunOption.Radical) #获取偏旁部首
  3. pinyin = Radical(RunOption.Pinyin) # 获取拼音
  4. input = '大撒大青蛙大全'
  5. radical_out = [radical.trans_ch(ele) for ele in input] # 对每一个字进行处理
  6. pinyin_out = [pinyin.trans_ch(ele) for ele in input]
  7. print(radical_out)
  8. print(pinyin_out)
  9. radical_out = radical.trans_str(input)
  10. pinyin_out = pinyin.trans_str(input)

输出结果为

————————————————获取拼音特征————————————————————

  1. radical = Radical(RunOption.Radical) # 提取偏旁部首
  2. pinyin = Radical(RunOption.Pinyin) # 提取拼音
  3. 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后续自己再设置
  4. data['pinyin'] = [[pinyin.trans_str(x) if pinyin.trans_ch(x) is not None else 'PAD'for x in s] for s in texts]
  5. # 这里就有一个问题 None 我们要用一个特殊的符号代替
  6. 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']:第一句话的拼音

然后我们要把数据存起来 后面统一的做数据读取

  1. num_samples=len(texts) # 统计有多少个样本
  2. num_col = len(data.keys) # 统计有多少列 要写成每一行一个字 字 标记 等等特征
  3. dataset = []
  4. for i in range(num_samples): # 用zip压缩
  5. records = list(zip(*[list(v[i] for v in data.value()]))
  6. dataset += records + [['sep'] * num_col] # 加个*解压 第一句话存完之后 要和第二句话隔开
  7. dataset = dataset[:-1] # 不要最后一组隔开符 sep
  8. # 然后再把这个列表变成 dataframe
  9. dataset = pd.DataFrame(dataset, columns=data.keys())
  10. save_path = f'data/prepare/{split_name}/{idx}.csv' #
  11. def clean_word(w):
  12. if w == '\n':
  13. return 'LB'
  14. if w in [' ', '\t', '\u2003']: # '\u2003中文的空格'
  15. return 'SPACE'
  16. if w.isdigit(): # 将所有的数字都变成一种符号 #这样可以提高泛化能力
  17. return 'num'
  18. return w
  19. dataset['word'] = dataset['word'].apply(clean_word) # 对dataset 应用clean_word这个函数
  20. dataset.to_csv(save_path, index=False, encoding='utf-8')

然后将所有的数据全部处理掉  获取训练集和测试集的下标

  1. train_dir = 'ruijin_round1_train2_20181022'
  2. def multi_process(split_method=None, train_ratio=0.8):
  3. if os.path.exists('data/prepare/'):
  4. shutil.rmtree('data/prepare/') # 如果这个目录存在就删掉
  5. if not os.path.exists('data/prepare/train/'):
  6. os.mkdirs('data/prepare/train'): #如果这个文件夹不存在就创建一个文件夹
  7. os.mkdirs('data/prepare/test'): # 注意 这里是mkdirs 因为创建的多层文件夹
  8. idxs = list(set([file.split('.')[0] for file in os.listdir('datas/') + train_dir])) # 获取所有文件的名字 (下标)
  9. shuffle(idxs) # 打乱下标
  10. index = int(len(idxs) * train_ratio) # 这个就是训练集的下标
  11. # 取 训练集和测试集的下标
  12. train_ids = idxs[:index]
  13. test_ids = idxs[index:]

如果一个文件一个文件处理的话会很慢 所以这里引入多进程

  1. import multiprocessing as mp
  2. num_cpus = mp.cpu_count() # 获取机器cpu的个数
  3. # 线程池
  4. pool = mp.Pool(num_cpus)
  5. train_results = []
  6. test_results = []
  7. for idx in train_ids:
  8. result = pool.apply_async(process_text(), args=(idx, split_method,'train'))
  9. #apply_async 不用等待当前进程执行完毕
  10. #apply 就是需要等待当前进程执行完毕
  11. results.append(result)
  12. for idx in test_ids:
  13. result = pool.apply_async(process_text(), args=(idx, split_method,'test'))
  14. results.append(result)
  15. pool.close() # 进程池关掉
  16. pool.join()
  17. [r.get() for r in results]

到此数据集和测试集就做好了 在开始构建模型之前 我们还需要做一个映射字典(embedding)然后做一个数据增强 下章讲!

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号