def feature_to_vector(self): """ 创建并初始化ont-hot向量:从csv中读取药物数据,然后将功效特征转换为one-hot向量 :return: """ self.data, self.series = get_data(medicine_path) # print("data:", self.data) # print("series:", self.series) root_2_word = root_to_word(thesaurus_path) # 获取同义词根到词的映射字典 # print("root_2_word", len(root_2_word), root_2_word) word_2_root = word_to_root(thesaurus_path) # 获取词到同义词根的映射字典 # print("word_2_root", len(word_2_root), word_2_root) # 创建并初始化一个DataFrame存储one-hot向量,第一行的列索引为词根 self.df = pd.DataFrame(np.zeros((len(self.series), len(root_2_word))), columns=root_2_word.keys()) for indexs in self.series.index: # series去掉了nan值,index是不连贯的,所以用这种方法遍历 item_str = self.series[indexs] if item_str == '': continue # item_list = item_str.strip().split() # 针对以空格作为分隔符的症状数据 item_list = re.split("、|;", item_str) # 针对以“、”作为分隔符的功效数据 for item in item_list: if item in word_2_root: # 找到每个功效特征词的词根,然后在one-hot向量的相应索引处进行激活 self.df[word_2_root[item]].loc[indexs] = 1 else: print(item) # 输出没有匹配的词,进行人工处理 # 删除没有任何匹配的词根 max_value = self.df.max() # 返回df中每一列的最大值 # print("max_value:", max_value) drop_list = list(max_value[max_value == 0].index) # 找到最大值为0的列的索引(即没有出现过的词根) # print("drop_list:", len(drop_list)) self.df = self.df.drop(drop_list, axis=1) # 删除未出现过的词根
def search_relatives(function_to_medicine, medicine_index, medicines_to_taste_label): """ 基于聚类结果寻找药物的相似药物 :param function_to_medicine:基于功效团的聚类结果 :param medicine_index:需要寻找相似药物的目标药物所在索引 :param medicines_to_taste_label:药物到性味归经标签的映射字典 :return:relatives_list目标药物的相似药物列表 """ relatives_list = [] # 用于保存相似药物的列表 data, series = get_data(medicine_path) # data为完整药物数据,series为功效数据 medicine_label = data["Label"].loc[medicine_index] # 获取目标药物在性味归经聚类结果中的标签 function_list = re.split( "、|;", data["Function"].loc[medicine_index]) # 获取目标药物的功效列表 function_set = set(function_list) print("function_set:", function_set) for group in function_to_medicine.keys(): # 遍历字典中的功效团 # 若功效团是目标药物功效的子集或者目标药物功效是功效团的子集,则认为该药物属于该功效团,与该功效图案中的药物有相似的可能性 if set(group).issubset(function_set) or function_set.issubset( set(group)): # 若功效团是目标药物功效的子集,则认为该药物属于该功效团,与该功效图案中的药物有相似的可能性 # if set(group).issubset(function_set): medicine_list = function_to_medicine[tuple(group)] # 获取属于该功效团的药物列表 # print("medicine_list:", medicine_list) # 遍历属于功效团的药物列表,若基于性味归经的聚类结果的标签相同,则认为目标药物和该药物相似 for i in medicine_list: if medicines_to_taste_label[ i] == medicine_label and medicines_to_taste_label[ i] != medicine_index: relatives_list.append(i) # 添加相似药物的名称 relatives_list = set(relatives_list) # 去除重复项 print("relatives_list:", relatives_list) return relatives_list
def word_to_index(word): """ 根据药物名称获取其在药物数据中的索引 :param word:药物名称 :return: """ data, series = get_data(medicine_path) # data为完整药物数据 index = data.loc[data["名称"] == word].index[0] return index
def main(is_cluster=False, search_all=False): """ 主函数,根据is_cluster进行聚类或者相似药物的寻找 :param is_cluster: 决定是进行聚类,还是根据聚类结果搜索目标药物的相似药物 :param search_all: 决定是否输出所有药物的相似药物到文件中 :return: """ if is_cluster: # 若需要进行聚类 cluster() else: # 若需要进行相似药物寻找 with open(function_to_medicine_path, 'rb') as f: function_to_medicine_dict = pickle.load(f) # 加载聚类结果 print("function_to_medicine:", function_to_medicine_dict) with open(all_medicines_cluster_path, "rb") as f: all_medicines_cluster = pickle.load(f) # 加载所有被聚类的药物 with open(medicines_to_taste_label_path, "rb") as f: medicines_to_taste_label = pickle.load(f) all_medicines_cluster = set(all_medicines_cluster) if search_all: data, _ = get_data(medicine_path) length = data.shape[0] # all_relatives = pd.DataFrame(np.zeros((length, 2)), columns=["药物名称", "相似药物"]) all_medicine_word_list = [] all_relatives_list = [] for i in range(length): medicine_word = data["名称"].loc[i] all_medicine_word_list.append(medicine_word) if medicine_word not in all_medicines_cluster: all_relatives_list.append("无相似药物") else: medicine = word_to_index(medicine_word) # 获取目标药物在总药物数据中的索引 relatives_list = search_relatives( function_to_medicine_dict, medicine, medicines_to_taste_label) # 获得药物的相似药物的索引列表 all_relatives_list.append("、".join(relatives_list)) # all_relatives["药物名称"].loc[i] = medicine_word # all_relatives["相似药物"].loc[i] = "、".join(relatives_list) # all_relatives.to_csv(all_relatives_path, encoding="utf-8") all_medicine_word_series = pd.Series(all_medicine_word_list, name="药物名称") all_relatives_series = pd.Series(all_relatives_list, name="相似药物") series_list = [all_medicine_word_series, all_relatives_series] all_relatives_data = pd.concat(series_list, axis=1) all_relatives_data.to_csv(all_relatives_path, index=False, encoding="utf-8") else: medicine_word = "川贝母" # 目标药物 medicine = word_to_index(medicine_word) # 获取目标药物在总药物数据中的索引 relatives_list = search_relatives( function_to_medicine_dict, medicine, medicines_to_taste_label) # 获得药物的相似药物的索引列表 return relatives_list