因为大多数通情达理的人都熟悉“哈利波特”这本书,所以书中的内容是建立助记系统的理想材料,特别是助记大系统是用来记忆数字序列的。
为了执行本帖子中概述的步骤,您需要哈利波特书籍(如果您愿意,也可以是其他书籍)的内容。在上一篇帖子中,我向您展示了如何下载奇幻书籍并提取其文本。其中下载的数据包括我将在本帖子中使用的哈利波特书籍。
在助记大调系统中,从0到9的每个数字都与一个或多个辅音相关联。请使用下表作为参考。
Ch(奶酪),j(果汁),g(姜),sh(壳),c(大提琴,特制),cz(捷克语),s(组织,视觉),sc(法西斯主义者),sch(回避),t(定量),tsch(暴击),z(癫痫)。
在英语中,字母的发音根据上下文的不同而不同,这就是为什么有些字母在不同的行中重复的原因。但归根结底,重要的是声音,而不是拼写。
这里有几个单词的例子,它们的IPA表示和它们所编码的数字。
分拣帽:Həm,dɪfəkəlt.。Vɛri dɪfəkəlt.。Plɛntiəv kərɪʤ,aɪsi.。Nɑtəbæd maɪnd,iüər.Finɛrz tælənt,oʊjɛs.əndəθərst tɪpruv jʊrsɛlf.。Bət wɛr tɪpʊt ju?harry:nɑt slɪangərɪN.nɑt slɪərɪn.分类帽:nɑt slɪərɪn,ɛ?ər juʃʊr?Ju kʊd bi greɪt,ju noʊ.。ɪtsɔl hirɪn jʊr hɛd.ənd slɪərɪn wɪl hɛLP juɔn§əweɪtɪgreɪtnəs,Finɛrz noʊdaʊtəba tʊt angəT.noʊ?Harry:pliz,pliz。ɛniθɪŋbət slɪ§ərɪn,ɛniθɪŋbət slɪərɪn.分类帽子:wɛlɪf jʊrʃʊr,bɛtər bi.。GRɪfɪndɔː!
分类帽:3 18751 84 18751 9521 8 746 021 91 321 14 140 1521 021 8401 1948 4058 91 1 91 Harry:21 05142 21 05142分类帽:21 05142 4 64 71 9741 2 10 5 42 4 1 21 05142 5 59 2 1 1 1 74120 140 2 11 91 11 2 Harry:950 950 282 91 05142 282 91 05142分类帽:5 4 64 914 9 74821
我将向您展示如何编写一个培训程序,在步骤4中将声音映射到数字的概念内在化。但首先,您需要具备自动将文本转换为数字的能力。这分两个步骤进行。首先,将文本转换为IPA。然后,将IPA转换为数字。
将IPA转换为数字的过程非常简单。我遍历IPA字符,如果有与该字符相关联的数字,则将该数字附加到结果中。
#从数字映射到发音Num_to_Phones={0:[';s';,';z';],1:[';t';,';d';,';n';],2:[';n';,';ŋ';],3:[';m';],4:[';r';],5:[';l';],6:[';ʤ';,';ʧ';,';ʃ';,';ʒ';],7:[';k';,';g';],8:[';f';,';v';,';θ';],9:[';p';,';b';]}}#从声音到号码Phone_to_Num={x:k for k,v in Num_to_Phones]。V}def MAJOR_DECODE_FROM_IPA(IPA):";";";将IPA转换为数字序列的项目()。";";";结果=[]用于IPA中的字符:IF(num:=phone_to_num。Get(Char))不是NONE:RESULT。追加(Num)返回结果。
例如,MAJOR_DECODE_FROM_IPA(';dɪfəkəlt';)生成[1,8,7,5,1]。
Def numseq_to_str(Numseq):";";";将数字序列转换为字符串。";";";返回';';。JOIN(str(X)for x in numseq)def str_to_numseq(S):";";";将字符串转换为数字序列。";";";如果x,则返回[int(X)for x in s。Isdigit()]。
为了自动将文本转换为IPA(然后转换为数字),您需要使用IPAtionary。
Python的Eng-to-IPA包能够使用卡内基-梅隆大学发音字典将文本转换为IPA。
导入Eng_to_IPA s=';“我会带来一些三明治。”';#句子摘自HP书籍IPA=eng_to_IPA。CONVERT(s,RETRIEVE_ALL=TRUE,KEEP_SPOT=FALSE,STREST_MARKS=FALSE)打印(IPA)
[';“我会*brɪŋəp səm三明治。”*';]。
根据文件,Eng-to-IPA将用星号重新打印CMU词典中找不到的单词。因此,“我要和三明治。”都没有找到。显然,标点符号才是问题所在。我对文本进行预处理以便于转换为IPA。
#标点符号,包括Unicode字符标点符号=';';。JOIN(chr(I)for i in range(sys.。Maxunicode),如果是unicodedata。类别(CHR(I))。以(';P';)开始定义预处理(文本):";";";去掉单词之间的标点符号,规格化空格,小写,替换Unicode撇号。";";";返回';';。加入(x.。去掉(标点符号)。较低()。将文本中的x替换为(';‘';,';\';';)。Split())打印(eng_to_ipa.。CONVERT(预处理,RETRIEVE_ALL=TRUE,KEEP_SPOT=FALSE,STEST_MARKS=FALSE)。
[aɪl brɪŋəp səm s sɪʧɪz';,';aɪl brɪŋəp səm sændwɪʧɪz&39;,';aɪl brɪŋəp səm s sɪʧɪz';]。
如你所见,根据你是喜欢用m、n还是nd发音,这个句子有3种发音方式。为了有效地使用主要系统,您应该使用听起来最自然的版本。
[';wɛlɪf JURʃʊr bɛtər bi Gryffindor*';,';wɛlɪf jʊrʃʊr bɛtər bi Gryffindor*';]。
不出所料,在CMU词典中没有找到格兰芬多这个词。在快速搜索该词的发音后,我找到了YouGLish,它使用YouTube视频来查找IPAs。虽然他们的API不是免费的,但为了我们的目的,可以取消数量有限的IPA。
导入时间、随机、请求、lxml。HTML。Soupparser def ipa_from_youglish(Word):";";";从youglish.com抓取单词。";";url=f';https://youglish.com/pronounce/{Word}/English?';而true:print(f';从youglish抓取单词";{word}&34;from youglish...';,end=';';,Flush=True)响应=请求。如果响应超出了使用限制,则获取(Url)。文本:RAISE EXCEPTION(';YOUGLISH使用限制超出';)root=lxml。HTML。汤解析器。FromString(响应。文本),如果是root。XPath(';//div[@class=";g-reCAPTCHA";]';):打印(';reCAPTCHA';)输入(f';打开{url},提交验证码质询,按Enter键继续。';)否则:休息时间。睡眠(随机。随机()*3)d=根。Xpath(';//div[@id=";phoneticPanel";]/div/ul[@class=";transcript";]';';/li/SPAN[CONTAINS(Text(),";Traditional IPA";)]';';/Follow-Siering::Text()';)如果d:PRINT(';SUCCESS';)返回d[0]。条带(';ˈ';)打印(';失败';)
如您所见,此功能是半交互式的。如果没有用户干预,它将卡在验证码上。即使到那时,您最终也会达到他们的日常使用限制,并且将无法继续使用。不过,就我们的目的而言,这应该足够好了。
我已经说明了许多单词有几种可能的发音,您需要从其中选择您喜欢的发音,并且有些单词不在CMU词典中,需要从其他来源刮取IPA或根本不可用。出于这两个原因,您将需要构建您自己的IPA词典。
我将通过迭代哈利波特书中的单词,并将每个单词和相应的IPA添加到我的词典中,来构建我的IPA词典。
首先,我定义了一些用于管理我的字典的函数(在本例中是一个简单的JSON文件)。
导入os ipa_dict_path=';data/ipa-dic.json';def load_json_file_or_dict(文件名):";";";如果存在则从json文件加载数据,否则如果操作系统存在,则返回空dict。";";";路径。Isfile(Filename):使用open(Filename)作为f:返回json。加载(F)返回dict()def save_to_json_file(data,filename):";";";";将数据保存到json文件。";";";使用open(filename,';w';)作为f:json。Dump(data,f)def load_ipa_dict():";";";从json文件加载ipa dict。";";";return load_json_file_or_dict(Ipa_Dict_Path)def save_ipa_dict(IPA_Dict):";";";将ipa dict保存到json文件。";";
接下来,我遍历书籍中的单词,并将每个单词以及Eng-to-IPA返回的任何内容输入到我的字典中。
Import json,glob def Harry_Potter_text():";";";";";返回单个字符串中的哈利波特图书的全部内容。";";";";data=[]以获取glob中的文件名。Glob(';data/json/Harry Potter*';):使用open(文件名)作为f:data。追加(json.。LOAD(F)[';text';])返回';';。联接(数据)def PUPULATE_IPA_DICT_FROM_TEXT(TEXT):";";";从eng_to_IPA获取所有IPA信息并保存到IPA_dict.";";";ipa_dict=load_ipa_dict()word=preprocess(Text)。Set(Words)-Set(IPA_DIC.。KEYS()):ipa=eng_to_ipa。CONVERT(WORD,RETRIEVE_ALL=TRUE,KEEP_SPORT=FALSE,STREST_MARKS=FALSE)IPA_DICT[WORD]=IPA save_IPA_DICT(IPA_DICT)RESOLE_IPA_FOR_TEXT_STEP_1(Harry_Potter_Text())。
字典中的每个值现在都是一个可能的IPA列表,因为这是eng-to-IPA返回的内容。在使用这本词典之前,我们需要确保每个词恰好有一个词缀。如果一个单词的不同IPA解码成不同的数字,我们需要向用户询问他们更喜欢的发音。否则,这个选择是无关紧要的,我们只是简单地选择第一个。
Def get_IPA_PREF(Word,IPA):";";";让用户为Word选择首选的IPA。";";";";print()print(f';为Word";{Word}";:';)为枚举中的i、w选择IPA(IPA):print(f';{i}:{w}';)option=int(input(&。您的选择:';))print()return IPA[CHOICE]def disampluate_ipas_in_ipa_dict():";";";";";";";IPA_DICT=LOAD_IPA_DICT()try:for Word,IPA in iPA_dict。Items():if isinstance(iPA,list):if len(Ipa)==1\or len(set(tuple(main_decode_from_ipa(X)for x for x in IPA))==1:ipa_dict[word]=IPA[0]Else:ipa_dict[word]=get_ipa_pref(word,IPA)EXCEPT:save_ipa_dict(IPA_Dict)raise save_ipa_dict(IPA_dict。
为Word";三明治";选择国际音标:0:sæmwɪʧ1:sændwɪʧ2:sænwɪʧ您的选择:1。
接下来,我在IPA字典中搜索后跟星号的值(正如您在前面看到的,这表示在CMU字典中没有找到IPA),并尝试从YouGlish中删除它。
导入重新,集合def find_missing_ipas(Text):";";";";尝试从ipa_dict中删除,先删除常用单词。";";";ct=集合。计数器(预处理(文本)。Split()IPA_DICT=LOAD_IPA_DICT()表示word,以ct为单位计数。MOST_COMMON():如果单词不在IPA_DICT中:如果m:=Re,则继续IPA=IPA_DICT[Word]。Match(r';(\S+)\*';,iPA):print(ct[word],end=';\t';)ipa=ipa_from_youglish(m.。GROUP(1))IPA:IPA_DICT[WORD]=IPA ELSE:DEL IPA_DICT[WORD]save_IPA_DICT(IPA_DICT)find_Missing_IPAS(Harry_Potter_Text())。
仅此而已,我的IPA词典已经准备好了!我定义了几个函数来方便地将文本转换为IPA。
类NoIPAFound(异常):";";";";在IPA_DICT中找不到IPA表示形式。";";";DEF WORD_TO_TO_IPA(IPA_DICT,Word):";";";为Word返回IPA。";";";Try:Return IPA_DICT[Word],KeyError:引发NoIPAFound(Word)de.。";返回文本的所有IPA。";";";WORD=预处理(文本)。Split()返回';';。JOIN(word_to_ipa(ipa_dict,x)for x in word)def has_ipa(ipa_dict,text):";";";";测试文本是否有IPA。";";";try:ipa_from_text(ipa_dict,text),NoIPAFound:return false return True。
例如,TEXT_TO_IPA(LOAD_IPA_DICT(),';Well Done,Harry!';)将生成wɛl dən hɛri。
使用上一步中的MAJOR_DECODE_FROM_IPA函数,我现在可以将文本转换为数字。
Def MAJOR_DECODE_FROM_TEXT(IPA_DICT,TEXT,GROUP_BY_WORD=FALSE):";";";解码文本并返回数字序列。";";";为文本中的x返回[MAJOR_DECODE_FROM_IPA(TEXT_TO_IPA(IPA_DICT,x))。SPLIT()]\IF GROUP_BY_WORD ELSE MAJOR_DECODE_FROM_IPA(TEXT_TO_IPA(IPA_DICT,TEXT))。
这个函数还有一个额外的好处,它可以根据源句中的单词对结果进行分组,这在打印较长文本的数字序列时很有用。
>;MAJOR_DECODE_FROM_TEXT(LOAD_IPA_DICT(),';干得好,Harry!';,group_by_word=True)[[5],[1,2],[4]]>;';';。JOIN(number_to_str(X)for x in_)5 12 4。
为了有效地使用主系统,您需要能够在头脑中快速将文本转换为数字。
既然你可以用计算机将文本转换成数字,那么就很容易编写一个简单的训练程序来练习在你脑海中做同样的事情。
导入蜡笔def系列解码():";";";";";";";IPA_DICT_ITEMS=LIST(LOAD_IPA_DICT()。Items()),而True:Word,IPA=Random。CHOICE(IPA_DICT_ITEMS)Numseq=MAJOR_DECODE_FROM_IPA(IPA),而True:Print(';Word是';,蜡笔。Blue(word,粗体=True))user_input=input(';enter number:';)user_numseq=str_to_numseq(User_Input)if numseq==user_numseq:print(f';{word}->;{ipa}->;{numseq}';)print(蜡笔。绿色(正确!\n&39;))中断其他:打印(蜡笔。Red(';重试!\n';))TRING_DECODING()。
单词是必需的输入数字:2127重试!单词是想要的!单词是想要的:212想要->;wɑNTɪŋ->;[2,1,2]正确!单词是必需的!输入数字:020Essence->;ɛsəns->;[0,2,0]正确!单词是紧凑的输入数字:
当你想要用主系统记忆一个数字序列时,你需要为它找一个合适的编码。下面的代码帮助您实践这一概念。
Def系列编码(min_numseq_len=1,max_numseq_len=4):";";";交互式训练数字编码。";";";ipa_dict=load_ipa_dict(),而True:numseq_len=Random。Randint(min_numseq_len,max_numseq_len)numseq=[随机。Randint(0,9)for_in range(Numseq_Len)]numseq_str=numseq_to_str(Numseq)而True:print(';number是';,蜡笔。Magenta(numseq_str,粗体=True))user_input=input(';enter text:';)尝试:user_ipa=text_to_ipa(ipa_dict,user_input。Strie()),NoIPAFound除外,格式为e:print(蜡笔。红色(f';找不到";{e.。Args[0]}";。重试!\n';))如果user_numseq==numseq:Print(蜡笔),则继续user_numseq=MAJOR_DECODE_FROM_IPA(USER_IPA)打印(f';{user_input}->;{user_numseq}->;{user_numseq}';)。绿色(正确!\n&39;))中断其他:打印(蜡笔。红色(';重试!\n';)。
号码是61输入文本:shitNo IPA未找到";狗屎";。重试!号码是61输入文本:Jetjet->;ʤɛt->;[6,1]正确!号码是1982输入文本:风管风扇->;tjub fæn->;[1,9,8,2]正确!
与解码文本相比,为给定的数字序列找到好的(难忘的)编码是一个更有创造性(也更费力)的过程。让我们看看是否可以使用“哈利波特”书中的内容来编码数字序列。
给定一个数字序列,我将在“哈利波特”书中搜索合适的编码。这个过程可能会很慢,因此预先计算所有可能的编码并将其保存到索引文件中是有意义的。
下面是几个方便的函数,允许我从字符串列表创建索引文件,并查询它们的数字序列。
Def load_numseq_index(文件名):";";";load(数字序列->;text)索引。";";";index=load_json_file_or_dict(文件名)返回{k:为索引中的k、v设置(V)。Items()}def save_numseq_index(index,filename):";";";Save(数字序列-&>文本)索引。";";";index={k:索引中k、v的列表(V)。Items()}save_to_json_file(index,filename)def COMANIZE_NUMSEQ_INDEX(INDEX):";";";";将多个(数字序列-&>文本)索引合并为一个。";";";d=dict()表示索引中的索引:对于k,表示索引中的v。Items():对于v:d中的x。Setdefault(k,set())。Add(X)返回d定义BUILD_NUMSEQ_INDEX_FROM_STRINGS(FILENAME,IPA_DICT,STRINGS,EXTEND_INDEX=True):";";";为数字序列到文本的映射创建索引并保存。";";";INDEX=LOAD_NUMSEQ_INDEX(文件名),如果字符串中的字符串为EXTEND_INDEX ELSE DICT():TRY:NUMSEQ=MAJOR_DECODE_FROM_TEXT(IPA_DICT,STRING),NoIPAFound:CONTINUE NUMSEQ_STR=NUMSEQ_TO_STR(NUMSEQ)INDEX。Setdefault(numseq_str,set())。Add(String)save_numseq_index(index,filename)def find_encodings_for_numseq_with_index(numseq,index):";";";";如果找到,则返回编码。";";";numseq_str=numseq_to_str(Numseq)返回列表(index。GET(NUMSEQ_STR,[]))DEF FIND_ENCODINGS_FOR_NUMSEQ_WITH_INDEX_FILE(NUMSEQ,文件名):";";";加载索引文件并传递给find_encodings_for_numseq_with_index.";";";INDEX=LOAD_NUMSEQ_INDEX(文件名)返回FIND_ENCODINGS_FOR_NUMSEQ_WITH_INDEX(NUMSEQ,INDEX)。
接下来,我将为从“哈利波特”系列书籍中摘录的不同类型的文本块创建几个索引。
好吧!所有可以编码的单词都已经存在于我们的IPA词典中,因此查找数字序列的单词非常简单。
Ipa_dict=load_ipa_dict()#只需使用ipa_dict的键,因为它们是单词build_numseq_index_from_string(';data/numseq-word-index.json';,ipa_dict,ipa_dict。密钥()。
名词通常比其他类型的词更容易想象(因此也更容易记住),因此,在试图寻找数字序列的编码时,特别寻找名词是有意义的。
我将使用Python的NLTK包来处理哈利波特文本并识别名词,所需的过程称为词性标记(POS标记)。
下面是一个示例,让您了解POS标记器的作用。
邓布利多说,当我们看到死亡和黑暗时,我们害怕的是未知,仅此而已。>;nltk.>;nltk。POS_TAG(nltk。标记化。Word_tokenize(预处理))[(';it';,';PRP';),(';is';,';VBZ&39;),(';the';,';dt';),(';未知';,';JJ&39;),(';我们;#39;,';PRP&39;),(';恐惧,#39;VBP&39;),(';当#39;,#39;WRB&39;),(';我们,#39;PRP&39;),(';Look';,';VBP&39;),(';在';、';IN';)、(';死亡';、';nn';)、(';和';、';cc';)、(';黑暗';、';nn';)、(';什么也没有';、';nn';)上,(';死亡';,';nn';),(';和';,';nn';)。),(#39;更多,#39;JJR&39;),(';Said';,';VBD&39;),(';邓布利多#39;,';NN&39;)]。
不是的。
.