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)   # 删除未出现过的词根
Example #2
0
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
Example #3
0
def word_to_index(word):
    """
    根据药物名称获取其在药物数据中的索引
    :param word:药物名称
    :return:
    """
    data, series = get_data(medicine_path)  # data为完整药物数据
    index = data.loc[data["名称"] == word].index[0]
    return index
Example #4
0
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