python实现排队论模型_python实现TransE模型

一般来说,要想训练一个模型,大致分为四个步骤:数据处理、模型构建、训练模型、测试模型,接下来的内容也会从这四个步骤开始介绍。

数据处理

FB15K数据是从Freebase(http://www.freebase.com)抽取到的一系列三元组(同义词集,关系类型,三元组)。该数据集可以看作是3模张量,描述了同义集之间的三元关系。

总共包含了3种文件:

  • train.txt 36M

  • valid.txt 3.7K

  • test.txt 4.4M

首先我定义了一个config.py文件用来存放一些与数据集相关的路径。

class Config(object):    def __init__(self):        super()        self.train_fb15k = "./datasets/fb15k/train.txt"     # 训练集路径        self.test_fb15k = "./datasets/fb15k/test.txt"       # 测试集路径        self.valid_fb15k = "./datasets/fb15k/valid.txt"     # 验证集路径        self.entity2id_train_file = "./datasets/fb15k/entity2id_train.txt"      # 训练集实体到索引的映射        self.relation2id_train_file = "./datasets/fb15k/relation2id_train.txt"  # 训练集关系到索引的映射        self.entity2id_test_file = "./datasets/fb15k/entity2id_test.txt"        # 测试集实体到索引的映射        self.relation2id_test_file = "./datasets/fb15k/relation2id_test.txt"    # 测试集关系到索引的映射        self.entity2id_valid_file = "./datasets/fb15k/entity2id_valid.txt"      # 验证集实体到索引的映射        self.relation2id_valid_file = "./datasets/fb15k/relation2id_valid.txt"  # 验证集关系到索引的映射        self.entity_50dim_batch400 = "./datasets/fb15k/entity_50dim_batch400"   # 400 batch, 实体embedding向量50维的训练结果        self.relation_50dim_batch400 = "./datasets/fb15k/relation_50dim_batch400"   # 400 batch, 关系embedding向量50维的训练结果

然后定义了一个data_process.py文件来对数据集进行处理,该文件包含一个Datasets类用来处理数据。

import osfrom config import Configclass Datasets(object):    def __init__(self, config):        super()        self.config = config        self.entity2id = {}        self.relation2id = {}    def load_data(self, file_path):        '''        加载数据        :param file_path: 数据的文件路径        :return: 读取的数据, 按行划分构成list        '''        with open(file_path, "r", encoding="utf-8") as f:            lines = f.readlines()        return lines    def build_data2id(self, is_test=False):        '''        将数据从字符串转换为index索引, 并保存到对应的路径        :param is_test: 是否是测试集        :return: null        '''        # load data        lines = []        if not is_test:            lines = self.load_data(self.config.train_fb15k)            print("load train data completely.")        else:            lines = self.load_data(self.config.test_fb15k)            print("load test data completely.")        # process 1 line        idx_e = 0        idx_r = 0        for line in lines:            line = line.strip().split("\t")            self.entity2id.setdefault(line[0], idx_e)            idx_e += 1            self.entity2id.setdefault(line[2], idx_e)            idx_e += 1            self.relation2id.setdefault(line[1], idx_r)            idx_r += 1        # save entity2id        if not os.path.exists(self.config.entity2id_train_file):            with open(self.config.entity2id_train_file, "a+", encoding="utf-8") as f:                for k, v in self.entity2id.items():                    entry = k + " " + str(v) + "\n"                    f.write(entry)        # save relation2id        if not os.path.exists(self.config.relation2id_train_file):            with open(self.config.relation2id_train_file, "a+", encoding="utf-8") as f:                for k, v in self.relation2id.items():                    entry = k + " " + str(v) + "\n"                    f.write(entry)    def build_data(self):        '''        将字符型数据转换为由one-hot编码表示的数据        :return:            entity_set: 实体集            relation_set: 关系集            triple_list: 三元组列表        '''        # save entities        entity_set = set()        # save relations        relation_set = set()        # save triples        triple_list = []        # load data        lines = self.load_data(self.config.train_fb15k)        # build data        for line in lines:            triple = line.strip().split("\t")            # h, r, t of a triple            h_ = self.entity2id[triple[0]]            r_ = self.relation2id[triple[1]]            t_ = self.entity2id[triple[2]]            entity_set.add(h_)            entity_set.add(t_)            relation_set.add(r_)            triple_list.append([h_, r_, t_])        return entity_set, relation_set, triple_list

然后可以在该脚本上看看数据的处理过程。

原数据可以通过load_data方法读取,并将其输出

config = Config()datasets = Datasets(config)lines = datasets.load_data(config.train_fb15k)print(lines[:1])

最后在控制台会得到这样的结果

fde8ee79ebc66ee5ef03b5e043c250da.png

上图中的内容实际上是一个三元组,其格式为(头实体,关系,尾实体),只不过实体和关系之间用/t隔开,因此,标准的格式应该是(/m/027rn,/location/country/form_of_government,/m/06cx9),这是知识图谱的RDF表示形式。知道了读取的数据格式,就可以对其进行处理,首先,计算机是很难处理字符型数据的,此外字符类型数据作为存储的话会占用比较大的内存空间,因此需要将这种字符类型的数据转换为one-hot编码,这里采用索引的方式,通过调用build_data2id方法来完成。

datasets.build_data2id()print("entity to index:")print(list(datasets.entity2id.items())[:1])print("relation to index:")print(list(datasets.relation2id.items())[:1])

上面是输出了构建好的实体到索引映射的第一条和关系到索引映射的第一条,然后在控制台就可以看到输出的结果:

0bea70cc3ed96c689385afb858d94b0c.png

前面说的,计算机不好直接处理字符类型,所以我们需要把输入模型的数据也转换为这种索引类型的,以下面这条三元组为例:

fde8ee79ebc66ee5ef03b5e043c250da.png

转换后的结果就变为,表示索引为0的实体与索引为1的实体存在着索引0的关系。这种原始数据到索引表示的数据的处理是通过build_data方法来实现的。

entity_set, relation_set, triple_list = datasets.build_data()

这样子就构建好了模型需要的数据格式。

模型构建

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以回答你的问题。多观测序列的马尔可夫模型(Hidden Markov Model, HMM)是一种常见的机器学习模型,常用于序列数据的建模,例如语音识别、自然语言处理等。下面是Python实现多观测序列的马尔可夫模型的步骤: 1. 定义状态空间和观测空间。状态空间是指该系统可能的状态集合,观测空间是指该系统可能的观测集合。 ```python states = ['Sunny', 'Rainy'] observations = ['Walk', 'Shop', 'Clean'] ``` 2. 定义初始状态分布。初始状态分布是指在t=0时,系统处于每个状态的概率分布。 ```python start_probability = {'Sunny': 0.6, 'Rainy': 0.4} ``` 3. 定义状态转移概率矩阵。状态转移概率矩阵是指在当前状态下,系统转移到下一个状态的概率分布。 ```python transition_probability = { 'Sunny' : {'Sunny': 0.7, 'Rainy': 0.3}, 'Rainy' : {'Sunny': 0.4, 'Rainy': 0.6}, } ``` 4. 定义观测概率矩阵。观测概率矩阵是指在当前状态下,系统观测到每个观测值的概率分布。 ```python emission_probability = { 'Sunny' : {'Walk': 0.4, 'Shop': 0.4, 'Clean': 0.2}, 'Rainy' : {'Walk': 0.1, 'Shop': 0.3, 'Clean': 0.6}, } ``` 5. 定义前向算法,用于计算观测序列在给定模型下的概率。 ```python def forward(obs, states, start_p, trans_p, emit_p): T = {} for state in states: T[state] = [start_p[state] * emit_p[state][obs[0]]] for t in range(1, len(obs)): for state in states: prob = sum(T[prev_state][t-1] * trans_p[prev_state][state] * emit_p[state][obs[t]] for prev_state in states) T[state].append(prob) return sum(T[state][-1] for state in states) ``` 6. 定义后向算法,用于计算给定观测序列下,系统处于某个状态的概率。 ```python def backward(obs, states, start_p, trans_p, emit_p): T = {} for state in states: T[state] = [1] for t in reversed(range(len(obs)-1)): for state in states: T[state].insert(0, sum(T[next_state][1] * trans_p[state][next_state] * emit_p[next_state][obs[t+1]] for next_state in states)) return sum(start_p[state] * emit_p[state][obs[0]] * T[state][0] for state in states) ``` 7. 定义维特比算法,用于计算最可能的状态序列。 ```python def viterbi(obs, states, start_p, trans_p, emit_p): V = [{}] path = {} for state in states: V[0][state] = start_p[state] * emit_p[state][obs[0]] path[state] = [state] for t in range(1, len(obs)): V.append({}) newpath = {} for state in states: (prob, state_) = max((V[t-1][prev_state] * trans_p[prev_state][state] * emit_p[state][obs[t]], prev_state) for prev_state in states) V[t][state] = prob newpath[state] = path[state_] + [state] path = newpath (prob, state) = max((V[len(obs)-1][state], state) for state in states) return (prob, path[state]) ``` 以上就是Python实现多观测序列的马尔可夫模型的步骤。你可以根据实际情况修改状态空间、观测空间、初始状态分布、状态转移概率矩阵和观测概率矩阵等参数,来适用于不同的场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值