python开发bs程序_python简直无所不能,程序员用python居然开发出这个

u=1335610476,3812761959&fm=173&app=25&f=JPEG?w=550&h=251&s=4558E0339F4845491C7480DE0100C0B1

import urllib.request as urllib2from bs4 import BeautifulSoupimport pandas as pdimport refrom unidecode import unidecodequote_page = 'http://metrolyrics.com/{}-lyrics-drake.html'filename = 'drake-songs.csv'songs = pd.read_csv(filename)for index, row in songs.iterrows(): page = urllib2.urlopen(quote_page.format(row['song'])) soup = BeautifulSoup(page, 'html.parser') verses = soup.find_all('p', attrs={'class': 'verse'}) lyrics = ''for verse in verses: text = verse.text.strip() text = re.sub(r"[.*] ", "", unidecode(text)) if lyrics == '': lyrics = lyrics + text.replace(' ', '|-|') else: lyrics = lyrics + '|-|' + text.replace(' ', '|-|') songs.at[index, 'lyrics'] = lyrics print('saving {}'.format(row['song'])) songs.head()print('writing to .csv')songs.to_csv(filename, sep=',', encoding='utf-8')

u=2317949710,603953371&fm=173&app=25&f=JPEG?w=550&h=144&s=1C087433C578DD200ADDC4DA000080B3

u=2651661830,1629221776&fm=173&app=25&f=JPEG?w=550&h=196&s=8862753297B9702054C914D60100C0B2

用DataFrame存储了所有的歌曲歌词

运行爬虫之后,我就得到了以合适的结构存储歌词的csv文件,下一步开始对数据进行预处理并且搭建模型。

模型介绍

现在我们来看看模型是如何生成文本的,这部分你要着重理解,因为这是真正的干货。我将先从模型设计和生成歌词模型中的关键组成部分讲起,然后,我们就可以直接进入实施阶段。

u=2366357071,1798832080&fm=173&app=25&f=JPEG?w=550&h=221&s=5518E0330F685C011C7500DA0000D0B3

u=3088716844,1773293256&fm=173&app=25&f=JPEG?w=550&h=839&s=8840E81311AFC0EC0EF4E0DF000080B2

u=3083864491,3114924319&fm=173&app=25&f=JPEG?w=550&h=572&s=0010703319BEE4CC18F5E1DB000080B2

图3. 词汇级模型生成词汇的迭代过程

现在在这个模型中,我们以一个词汇为单位向前寻找下一个词汇,而非字符。因此,我们想找到概率P(new_word|seed)的最大值,其中new_word是任一词汇。

这里要注意的是,这里我们搜索的范围比字符级要大得多。字符集模型中,我们只需从字符表中查找大概30个字符,但词汇级中每次迭代搜索的范围远远大于这个数量,因此每次迭代的运行速度更慢,但既然我们生成的是一整个词而不只是一个字符,所以也不算太糟糕。

关于词汇级模型,我最后想说明一点,我们可以通过在数据集中搜索独特的词汇来生成更加多样的词汇(这一步通常在数据预处理阶段进行)。由于词汇量可以无限大,我们其实有很多提高生成词汇性能的算法,比如词嵌入,不过关于这个问题可以再写一篇文章了。

u=2476162612,3334988478&fm=173&app=25&f=JPEG?w=550&h=376&s=04186433150A45494AF501D3000080B1

u=1004913839,1096913657&fm=173&app=25&f=JPEG?w=550&h=471&s=8250E0331BAFF4CE18F1D1DA0100E0B1

图4. 用滑动窗口获得输入/输出

我们通过每次平移一个字符,得到相应长度为20个字符的模型输入和长度为1个字符的模型输出。每次只平移一格的额外好处就是大大扩展了数据集的大小。

4.标注编码训练序列

最后,我们不想直接处理原始字符(尽管理论上讲每个字符都是一个数字,所以你也可以说ASCII码已经帮我们为每个字符完成了编码)。我们要做的是用唯一的数字和每个字符一一对应,这一步就是所谓的标签编码。同时,我们要建立两个非常重要的映射:character-to-index (字符到索引)和index-to-character(索引到字符)。有了这两个映射,我们就能将字母表中任意的字符编码成对应的数字,同理,也能将模型输出的数字索引解码获得相应的字符。

u=2950184275,526799108&fm=173&app=25&f=JPEG?w=550&h=128&s=14107033CD6C4F2012DC45DB0000C0B2

u=2268842844,759806184&fm=173&app=25&f=JPEG?w=550&h=622&s=0C0A5432410FE54D487524DB000050B2

3.建立模型

我们将用循环神经网络(RNN),更具体的说是长短期记忆网络(LSTM),基于前面出现的字符集来预测下一个字符。如果这两个概念都听着陌生的话,我也提供了相关概念的快速复习

RNN快速复习

通常,你看到的网络就是一个网状,从很多点汇聚到一个单点输出。如下图所示:

u=276413996,464076574&fm=173&app=25&f=JPEG?w=491&h=260&s=1E2A74235511D1C61CFD04DA0000C0B1

图5. 神经网络示意图

这里的神经网络是单点输入,单点输出。它适用于输入是不连续的情况,因为输入的顺序不会影响到输出结果。但是在我们的案例中,输入字符的顺序是非常重要的,因为顺序决定了对应的单词。

而RNN可以接收连续的输入,同时将前一个节点的输出作为参数输入下一个节点,从而解决输入顺序的问题。

u=2279329541,3359680630&fm=173&app=25&f=JPEG?w=550&h=243&s=87F0ED361B326803486DD0DB020050B0

图6. 简易RNN示意图

u=403080690,2296657821&fm=173&app=25&f=JPEG?w=550&h=223&s=4550E0338FE84C010A71F8D30100C0B3

u=3146323930,3093831768&fm=173&app=25&f=JPEG?w=550&h=119&s=C410E53BC572CC3042F409DA0100C0B2

图7. LSTM示意图,摘自Andrew Ng的深度学习课程

不仅传递前一个元胞的输出a ,同时包含之前元胞输入信息的c 也作为了下一个元胞的输入的一部分。这使得LSTM能够更好地保留上下文的信息,并适用于语言建模的预测。

编程建模

我之前学过一点Keras,所以这次就以Keras为框架编程搭建模型。其实也可以选择自己搭建模型框架,但这样会花费更多的时间。

# create sequential network, because we are passing activations# down the networkmodel = Sequential()# add LSTM layermodel.add(LSTM(128, input_shape=(maxlen, len(chars))))# add Softmax layer to output one charactermodel.add(Dense(len(chars)))model.add(Activation('softmax'))# compile the model and pick the loss and optimizermodel.compile(loss='categorical_crossentropy', optimizer=RMSprop(lr=0.01))# train the modelmodel.fit(x, y, batch_size=128, epochs=30)

u=4078473720,632020263&fm=173&app=25&f=JPEG?w=550&h=211&s=4450E0338F786C014C7C21DE000010B0

u=451553573,256743967&fm=173&app=25&f=JPEG?w=550&h=698&s=EB84A70E515EC5CC0A69807E03000073

你可能会注意到,生成的单词有的是没有意义的,这是字符级模型的一个常见问题。这是因为输入序列经常在单词的中间被切断,使得神经网络模型学习并生成对其输入而言是有意义,但是我们看来很奇怪的新单词。

这也是在词汇级模型中可以解决的问题,但是对于仅以200行代码建立的模型来说,字符级模型所达到的效果仍然令人印象深刻。

其他应用

在这里演示的字符级模型的歌词预测功能可以被扩展到其他更有用的应用上。

例如,可以利用相同的原理对iPhone键盘上要输入的下一个单词进行预测。

u=1544216238,2147612148&fm=173&app=25&f=JPEG?w=554&h=396&s=80B3CD304912EDC85CF590DA000080B3

图8. 键盘输入预测下一个单词

此文来自第三方转载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值