深入解析 markov 算法:原理、分解示例与应用

一、马尔科夫链:让文字随风起舞的魔法棒

马尔科夫链,其名仿佛源自神秘魔法院。实则,它并非晦涩数学理论,而是一项赋予文字生机的简便工具。设想输入一串文字,这部精巧的链条便活跃起来,切割、重组文字碎片,重塑为全新篇章。这不就像拼砌文字乐高般有趣吗?

此流程本质上简便,涉及将文本分解为众多短句,随后基于短句出现频率随机挑选一句。由此,所产文字既具独特性,又保持原有风格,恰似以同一食材烹制各式佳肴。

二、前缀和后缀:文字的DNA片段

在马尔科夫链模型中,每个文字序列均包含特定的前缀与后缀。前缀如同文字的遗传信息,决定了后缀的选取方向。以“一息若存,希望不灭”为例,“一息”构成了该序列的前缀,与之对应的“若”则是其相应后缀。

此类前缀与后缀的关联,恰似文字的遗传序列,界定着文字的形成途径。通过调节前缀的长度,可操控文字的生成风格。前缀越长,其生成文字愈发贴近原始文本;相对地,前缀缩短,则生成的文字愈发无序。

三、滑动窗口:文字的探险之旅

在本文本生成器中,滑动窗口作用如同一位探险者,逐段审视文辞,依此指引后续探索方向。窗口大小可自由调整,能聚焦于数字至更多字符的阅读范围。

在滑动窗口每次前进一格时,系统记录当前窗口中的文本片段,并据此挑选下一片段。此流程类似探险者绘制地图上的路径,随后依据这些标志确定行进路线。

马尔科夫链以此法捕捉文内微妙变迁,创造出既规则又富创意的文字。

四、统计特性:文字的频率密码

马尔科夫链的核心是文本片段的统计频率,包括其出现频次。每个前缀之后可能有多个后缀,后缀的频率影响着它们被选取的可能性。

图片[1]-深入解析 markov 算法:原理、分解示例与应用-东山笔记

譬如,“一息”随“若”共同出现频率最高,创作文本时,“一息”后接“若”的概率亦较高。此频率导向的选词策略,保证了文本遵循语言规则,并增添了随机性。

五、语言模型:文字的校验师

为确保生成文本的语言规范性,语言模型扮演关键角色。此模型被视为文本的规范性审查者,依据语言规律对文本进行评分。评分越高,表明文本越符合规范要求;评分越低,表明文本与规范相去较远。

经语言模型验证的文字,兼具趣味性与可读性,从而使我们的文字生成器成为一项实用工具,而非单纯胡乱生成的装置。

六、实战演练:打造你的专属句子生成器

现在,我们将通过实际操作演示如何运用马尔科夫链技术构建一个定制的句子生成器。初始步骤是收集多样化的语料文本,它们可涵盖任何你感兴趣的领域,例如小说、诗词、新闻报道等。

您可参照既述流程,调整滑动窗口规模并记载前后缀关联,继之以马尔科夫链技术创制新颖文本。可反复调整参数,观察文本生成的变化。

#!/usr/bin/env python3
# coding=utf-8
import urllib
import re
import random
import string
import operator
'''
马尔科夫链,生产句子:
    尝试将使用不同句子进行训练,生成句子。
'''
class MarkovLinked:
    __dic = dict()
    __keyStart = "#start#"
    __keyEnd = "#end#"
    __maxLoop = 30
    __topicMaxLenth = 1000 #句子长度
    def __init__(self):
        self.__dic[self.__keyStart] = []
    def printMarkovLinked(self):
        for key in self.__dic.keys():
            print('%st%s'%(key,self.__dic[key]))
    def append(self,content):
        '''
        训练文本加入到 markov 连中
        :param content: 
        :return: 
        '''
        #clear
        content = re.sub('s|n|t','',content)
        ie = self.getIterator(content)
        i = 0
        for x in ie:
            key = '%s%s'%(x[0],x[1])
            val = x[2]
            if key not in self.__dic.keys():
                self.__dic[key] = []
            self.__dic[key].append(val)
            #记录开始 key
            if i == 0:
                self.__dic[self.__keyStart].append(key)
            i += 1
        pass
    def getIterator(self,txt):
        '''
        :param txt: 一段话或一个句子
        :return: 返回迭代器,item 为 tuple,每项 3 个值
        '''
        ct = len(txt)
        if ct<3:
            return
        for i in range(ct-2+1):
            w1 = txt[i]
            w2 = txt[i+1]
            w3 = txt[i+2] if i+2 < ct else self.__keyEnd
            yield (w1,w2,w3)
    def topicBuilder(self, topicMax=0):
        #随机选择一个开始词
        startKeyArr = self.__dic[self.__keyStart]
        j = random.randint(0,len(startKeyArr)-1)
        key = startKeyArr[j] # tuple 类型
        #待返回的句子
        topic = key
        i=0
        if topicMax<=0 :
            topicMax = self.__topicMaxLenth
        while i< self.__maxLoop:
            i+=1
            if key not in self.__dic.keys():
                break
            arr = self.__dic[key]
            if not arr:
                break
            j = random.randint(0,len(arr)-1)
            if j= topicMax:
                break
            nextKey = '%s%s'%(key[1],sufix)
            #markovLinked.append(nextKey)
            #无
            if nextKey not in self.__dic.keys():
                break
            key = nextKey
        #print('markovLinked ',markovLinked)
        return topic
def fileReader():
    path = "../NLP/test_markov_data_v2.txt"
    with open(path,'r',encoding='utf-8') as f:
        rows = 0
        # 按行统计
        while True:
            rows += 1
            line = f.readline()
            if not line:
                print('读取结束 %s'%path)
                return
            print('content rows=%s len=%s type=%s'%(rows,len(line),type(line)))
            yield line
    pass
def main():
    markov = MarkovLinked()
    reader = fileReader()
    for row in reader:
        print(row)
        markov.append(row)
    #markov.printMarkovLinked()
    #生成句子
    for i in range(20):
        topic = markov.topicBuilder(topicMax=300)
        print('%st%s'%(i,topic))
    pass
# main()
if __name__ == '__main__':
    main()
    pass

七、结语:让文字跳起舞来

马尔科夫链不仅是一项算法,更似令文字焕发生机的神奇道具。凭借它,将乏味的文字转化为富有创意的语句,使文字在你的操控下栩栩如生。

对有些人来说,困难是放弃的借口,而对另外一部分人来说,困难是成长壮大的机遇。
你从不担心自己配不上优秀的人,你只会担心自己配不上喜欢的人。
一息若存,希望不灭。
来属于那些坚信自己梦想之美的家伙。
心是一个人的翅膀,心有多大,世界就有多大。很多时候,限制我们的,不是周遭的环境,也不是他人的言行,而是我们自己:看不开,忘不了,放不下,把自己囚禁在灰暗的记忆里;不敢想,不自信,不行动,把自己局限在固定的空间里。
找不到坚持下去的理由,那就找一个重新开始的理由,生活本来就这么简单。
一条路,人烟稀少,孤独难行。却不得不坚持前行。因为它的尽头,种着“梦想”。
生活的有趣还在于,你昨日的最大痛楚,极可能会造就你明日的最大力量。
如果没有那些愚蠢的想法, 我们也压根不可能有什么有趣的想法。
世上有很多不可能,不过不要在你未尽全力之前下结论。
希望每天醒来,都是不一样的人生色彩。
思念无声无息,弥漫你的心里。当夜深人静的时候,是不是又感到了寂寞,感到了心烦?那就送你一个好梦吧,愿你梦里能回到你媳妇的娘家……高老庄!
暮春之夜,微风渐暖,睡意缱绻,移身临窗,近看柳枝月色下翩舞摇曳,遥听池塘绵绵蛙鸣。携一份恬淡,悍然入梦。晚安。
睡一睡,精神好,烦恼消,快乐长;睡一睡,心情好,做美梦,甜蜜蜜;睡一睡,身体健,头脑清,眼睛明。愿你酣然入梦,晚安!
思念不因劳累而改变,问候不因疲惫而变懒,祝福不因休息而变缓,关怀随星星眨眼,牵挂在深夜依然,轻轻道声:祝你晚安!
如隔三秋,是因为有人在思念;长夜漫漫,是因为有人在想念;展转反侧,是因为有人在品味孤独;孤枕难眠,是因为有人在数绵羊,爱就两个字:晚安。

此刻,请考虑此问:您是否考虑过,借助马尔科夫链来创作何种风格文字?或许是诗篇、歌词,抑或小说节选?敬请于评论区留下您的见解,以期共同挖掘文字的潜能。

© 版权声明
THE END
喜欢就支持一下吧
分享