人工智能自动组方实习笔记8—多字典的最大正向匹配算法及python实现

本文章记录了在人工智能自动租房实习中使用的最大正向匹配算法及python代码实现,如果有哪些小伙伴最近也在做相关工作,可以发邮件与我联系([email protected])互相交流学习。
以下为该项目的系列文章
工作记录
萤火虫算法
FCM模糊C聚类
爬虫及python代码
数据预处理
中医分类及python代码
数据预处理python代码
基于字典的最大正向匹配
基于欧式距离的方剂推荐
基于方剂相似性的方剂推荐
GitHub地址

最大正向匹配

最大正向匹配算法是在基于规则的分词中最常用的算法之一。其内容是基于给定的字典,在句子中正向(从左到右)或者逆向(从右到左)的最大匹配de搜索在字典中出现过的词,及在句子中匹配字典中出现过的最长的词。
具体操作:需要字典(该字典就是在项目中需要被识别出来的全部的词),最大窗口大小(句子中最长的一个字的长度)。最大正向匹配就是从左到右的顺序按照窗口从最大到1的次序以此匹配句子,如果窗口内的词在字典中出现了,则认为窗口内文字是一个词,则将其提取出来,如果窗口内的文字没有在字典中,则认为该段文字不是一个词那么窗口大小就要减一。
对于一个句子ABCDEFGJHIJKLMN…而言,如果最大窗口大小为5,则从左到右的选择窗口大小的文字即ABCDE,如果ABCDE没有在字典中出现,就认为ABCDE不是一个词,那么窗口就要减一到4,窗口内的文字同样要减一变成ABCD;如果ABCDE在字典中,则认为ABCDE是一个词,那么窗口后移到FGJHI上。以此进行这种移动窗口进行判断如果是就提取出来如果不是就缩小窗口大小直到1为止。
最大逆向匹配时按照从右到左的顺序移动窗口,窗口变小时删除最右边的一个字。在中文匹配中最大逆向的正确率要高于最大正向匹配

多字典的最大正向匹配算法

对于经典的最大正向匹配算法而言,每一次移动窗口或者缩小窗口就要对窗口内的那段文字便利整个字典,来查找这段文字是否在字典中出现过。这样一来时间复杂度很高,而且很多查找都是无意义的,例如当窗口是5时,如果窗口内的这5个字是一个词的话那么这个词的长度一定是5;如果这个5个字不是一个词那么在长度是5的字典中查找也肯定查找不到,则只要查询词长度是5的那一部分字典即可,没有必要对整个字典(就是长度是1的词、长度是2的词、。。。长度是N的词组成的完整字典)进行查找,查找的次数降低了时间复杂度也随之降低了。

import re
import pandas as pd

def load_dic(medicine_length):
	'''
	读取药物名称字典
	:param medicine_length: 药物名称的长度
	:return: 长度为 medicine_length 的药物字典
	'''
	with open('长度为%s的药物列表.txt'%(str(medicine_length)), 'r',encoding='utf-8') as f:
		dic = f.read()
		dic = dic.split('\n')
	return dic


def FMM(str,max):
	'''
	正向最大匹配算法
	:param str: 需要进行最大匹配的药物组成字符串
	:param max: 最大窗口大小(本数据集中药物最大长度为11,则设置窗口为11)
	:return: 正向最大匹配之后的药物组成列表
	'''
	str = str
	length = max
	match = []
	if len(str) < max:
		length = len(str)
	while str != '':
		word = str[:length]
		#方剂中的药物长度为1,2,3,4,5,6,7,8,11,则当窗口大小变化时,查找对应长度的药物字典,而不用去遍历整个药物字典
		while 1:
			if len(word) < 11 and len(word)>8:
				dic = load_dic(8)
			elif len(word)<8 :
				dic = load_dic(len(word))
			else:dic = load_dic(11)
			if word in dic:
				match.append(word)
				break
			else:
				if len(word) == 11:
					word = word[:8]
				elif len(word) == 1:break
				else:word = word[:len(word) - 1]
		str = str[len(word):]
	return  match


def create_dic(f_medicine):
	'''
	对于不同长度的药物创建各自的药物字典
	:param f_medicine: 方剂药物与标准药物对应表,第一列为方剂中出现的药物别名
	:return: 创建对应字典
	'''
	medicine_perscription = f_medicine['first_row'].tolist()
	a = []
	for i in medicine_perscription:
		a.append((i, len(i)))
	a = sorted(a, key=lambda x: x[1], reverse=True)
	for i in a:
		with open('长度为%s的药物列表.txt' % i[i], 'a', encoding='utf-8') as f:
			f.writelines([i[0], '\n'])


def RMM(str,max):
	'''
		逆向最大匹配算法
		:param str: 需要进行最大匹配的药物组成字符串
		:param max: 最大窗口大小(本数据集中药物最大长度为11,则设置窗口为11)
		:return: 正向最大匹配之后的药物组成列表
		'''
	str = str
	length = max
	match = []
	if len(str) < max:
		length = len(str)
	while str != '':
		word = str[-length:]
		# 方剂中的药物长度为1,2,3,4,5,6,7,8,11,则当窗口大小变化时,查找对应长度的药物字典,而不用去遍历整个药物字典
		while 1:
			if len(word) < 11 and len(word) > 8:
				dic = load_dic(8)
			elif len(word) < 8:
				dic = load_dic(len(word))
			else:
				dic = load_dic(11)
			if word in dic:
				match.append(word)
				break
			else:
				if len(word) == 11:
					word = word[-8:]
				elif len(word) == 1:
					break
				else:
					word = word[-len(word)+1:]
		str = str[:-len(word)]
	return match


if __name__ == '__main__':
	# 公司提供的方剂数据,其中的‘药物组成’字段是我们需要进行操作的那句话
	f_perscription = pd.read_csv(open('方剂数据.csv','r'))
	# 公司方剂数据中的药物对中华本草进行一一对应,第一列为方剂中的药物别名,第二列为中华本草中的标准名称
	f_medicine = pd.read_csv(open('方剂药物完全映射1.csv','r',encoding='utf-8'),names=['first_row','second_row'])

	# create_dic(f_medicine)
	all_medicine = []
	f_perscription['标准药物名称'] = ''
	for i in range(0,f_perscription.shape[0]):
		medicine_list = f_perscription['药物组成'].iloc[i]
		medicine_list = re.sub(r'(.*?)',string=medicine_list,repl='')
		match = FMM(medicine_list, 11)
		print(match)
		temp = []
		all_medicine.extend(match)
		for j in match:
			temp.extend(f_medicine['second_row'].loc[f_medicine['first_row'] == j].tolist())
		f_perscription['标准药物名称'].iloc[i] = '、'.join(temp)
		print(f_perscription['标准药物名称'].iloc[i])
	f_perscription.to_csv('公司数据_标准药物名称.csv',encoding='utf-8',index=False)

	f = open('全部方剂出现的药物.txt','w',encoding='utf-8')
	for i in all_medicine:
		f.writelines([i,'\n'])

你可能感兴趣的:(人工智能自动组方,python代码)