- 來源 | 愿碼(ChainDesk.CN)內(nèi)容編輯
- 愿碼Slogan | 連接每個(gè)程序員的故事
- 網(wǎng)站 | http://chaindesk.cn
- 愿碼愿景 | 打造全學(xué)科IT系統(tǒng)免費(fèi)課程,助力小白用戶、初級(jí)工程師0成本免費(fèi)系統(tǒng)學(xué)習(xí)、低成本進(jìn)階,幫助BAT一線資深工程師成長(zhǎng)并利用自身優(yōu)勢(shì)創(chuàng)造睡后收入。
- 官方公眾號(hào) | 愿碼 | 愿碼服務(wù)號(hào) | 區(qū)塊鏈部落
- 免費(fèi)加入愿碼全思維工程師社群 | 任一公眾號(hào)回復(fù)“愿碼”兩個(gè)字獲取入群二維碼
本文閱讀時(shí)長(zhǎng):12min
要?jiǎng)?chuàng)建自定義新聞Feed模型,我們需要可以訓(xùn)練的數(shù)據(jù)。這些培訓(xùn)數(shù)據(jù)將被輸入模型,以教它區(qū)分我們感興趣的文章和我們不感興趣的文章。
在本文中,我們將學(xué)習(xí)構(gòu)建自定義新聞?wù)Z料庫(kù)并分別注釋與興趣相對(duì)應(yīng)的大量文章。
創(chuàng)建受監(jiān)督的訓(xùn)練數(shù)據(jù)集
在我們?cè)谛侣勎恼轮袆?chuàng)建我們的品味模型之前,我們需要培訓(xùn)數(shù)據(jù)。這些培訓(xùn)數(shù)據(jù)將被輸入我們的模型,以教它區(qū)分我們感興趣的文章和我們不感興趣的文章。要構(gòu)建此語(yǔ)料庫(kù),我們需要注釋大量符合這些興趣的文章。對(duì)于每篇文章,我們將其標(biāo)記為“y”或“n”。這將表明該文章是否是我們希望在我們的日常摘要中發(fā)送給我們的文章。
為簡(jiǎn)化此過程,我們將使用Pocket應(yīng)用程序。Pocket是一個(gè)應(yīng)用程序,允許您保存故事以供稍后閱讀。您只需安裝瀏覽器擴(kuò)展,然后在希望保存故事時(shí)單擊瀏覽器工具欄中的Pocket圖標(biāo)。該文章將保存到您的個(gè)人存儲(chǔ)庫(kù)中。Pocket的一個(gè)重要功能就是它的用途,能夠使用您選擇的標(biāo)簽保存文章。我們將使用此功能將有趣的文章標(biāo)記為“y”,將非有趣的文章標(biāo)記為“n”。
安裝Pocket Chrome擴(kuò)展程序
我們?cè)谶@里使用谷歌瀏覽器,但其他瀏覽器應(yīng)該類似。對(duì)于Chrome,請(qǐng)進(jìn)入Google App Store并查找“擴(kuò)展”部分:
點(diǎn)擊藍(lán)色的添加到Chrome按鈕。如果您已有帳戶,請(qǐng)登錄,如果您還沒有帳戶,請(qǐng)繼續(xù)注冊(cè)(免費(fèi))。完成后,您應(yīng)該會(huì)在瀏覽器的右上角看到Pocket圖標(biāo)。它將顯示為灰色,但是一旦有想要保存的文章,您可以單擊它。保存文章后,它將變?yōu)榧t色,如下圖所示。
右上角可以看到灰色圖標(biāo)。
單擊圖標(biāo)時(shí),它會(huì)變?yōu)榧t色,表示文章已保存。
開始保存您遇到的所有文章。用“y”標(biāo)記有趣的標(biāo)簽,用“n”標(biāo)記非有趣的標(biāo)簽。這將需要一些工作。你的最終結(jié)果只會(huì)和訓(xùn)練集一樣好,所以你需要為數(shù)百篇文章做這件事。如果您在保存文章時(shí)忘記標(biāo)記文章,則可以隨時(shí)訪問該網(wǎng)站http://www.get.pocket.com,在其中標(biāo)記。
使用Pocket API檢索故事
既然您已經(jīng)將文章保存到Pocket,那么下一步就是檢索它們。為此,我們將使用Pocket API。您可以通過https:// ge?tpocket.com/developer/apps/new注冊(cè)一個(gè)帳戶。單擊左上角的“ 創(chuàng)建新應(yīng)用程序 ”并填寫詳細(xì)信息以獲取API密鑰。確保單擊所有權(quán)限,以便添加,更改和檢索文章。
填寫完成并提交后,您將收到您的 消費(fèi)者密鑰 。您可以在“ 我的應(yīng)用” 下的左上角找到此信息。這將看起來像下面的屏幕,但顯然有一個(gè)真正的鍵:
設(shè)置完成后,您就可以繼續(xù)下一步,即設(shè)置授權(quán)。它要求您輸入您的使用者密鑰和重定向URL。重定向網(wǎng)址可以是任何內(nèi)容。在這里,我使用了我的Twitter帳戶:
import requests
auth_params = {'consumer_key': 'MY_CONSUMER_KEY', 'redirect_uri':
'https://www.twitter.com/acombs'}
tkn = requests.post('https://getpocket.com/v3/oauth/request',
data=auth_params)
tkn.content
您將看到以下輸出:
輸出將包含下一步所需的代碼。將以下內(nèi)容放在瀏覽器欄中:
https://getpocket.com/auth/au... ect_uri = https% 3A // www.twitter.com / acombs
如果您將重定向網(wǎng)址更改為您自己的網(wǎng)址,請(qǐng)確保對(duì)其進(jìn)行網(wǎng)址編碼。這有很多資源。一種選擇是使用Python庫(kù) urllib ,另一種是使用免費(fèi)的在線源。
此時(shí),您應(yīng)該看到授權(quán)屏幕。繼續(xù)并批準(zhǔn)它,我們可以繼續(xù)下一步:
usr_params = {'consumer_key':'my_consumer_key', 'code':
'some_long_code'}
usr = requests.post('https://getpocket.com/v3/oauth/authorize',
data=usr_params)
usr.content
我們將在此處使用以下輸出代碼繼續(xù)檢索故事:
首先,我們檢索標(biāo)記為“n”的故事:
no_params = {'consumer_key':'my_consumer_key', 'access_token':
'some_super_long_code',
'tag': 'n'}
no_result = requests.post('https://getpocket.com/v3/get',
data=no_params)
no_result.text
上面的代碼生成以下輸出:
請(qǐng)注意,我們?cè)跇?biāo)記為“n”的所有文章上都有一個(gè)長(zhǎng)JSON字符串。這里有幾個(gè)鍵,但我們實(shí)際上只對(duì)URL感興趣。我們將繼續(xù)創(chuàng)建一個(gè)包含以下所有URL的列表:
no_jf = json.loads(no_result.text)
no_jd = no_jf['list']
no_urls=[]
for i in no_jd.values():
no_urls.append(i.get('resolved_url'))
no_urls
上面的代碼生成以下輸出:
此列表包含我們不感興趣的故事的所有URL。現(xiàn)在,讓我們把它放在一個(gè)
DataFrame對(duì)象并將其標(biāo)記為:
import pandas
no_uf = pd.DataFrame(no_urls, columns=['urls'])
no_uf = no_uf.assign(wanted = lambda x: 'n')
no_uf
上面的代碼生成以下輸出:
現(xiàn)在,我們都準(zhǔn)備好了不想要的故事。讓我們對(duì)我們感興趣的故事做同樣的事情:
ye_params = {'consumer_key': 'my_consumer_key', 'access_token':
'some_super_long_token',
'tag': 'y'}
yes_result = requests.post('https://getpocket.com/v3/get',
data=yes_params)
yes_jf = json.loads(yes_result.text)
yes_jd = yes_jf['list']
yes_urls=[]
for i in yes_jd.values():
yes_urls.append(i.get('resolved_url'))
yes_uf = pd.DataFrame(yes_urls, columns=['urls'])
yes_uf = yes_uf.assign(wanted = lambda x: 'y')
yes_uf
上面的代碼生成以下輸出:
現(xiàn)在我們的訓(xùn)練數(shù)據(jù)都有兩種類型的故事,讓我們將它們組合成一個(gè)DataFrame:
df = pd.concat([yes_uf, no_uf])
df.dropna(inplace=1)
df
上面的代碼生成以下輸出:
現(xiàn)在我們?cè)谝粋€(gè)框架中設(shè)置了所有URL和相應(yīng)的標(biāo)簽,我們將繼續(xù)為每篇文章下載HTML。我們將使用另一個(gè)名為 embed.ly的 免費(fèi)服務(wù)。
使用embed.ly API下載故事主體
我們將使用embed.ly來執(zhí)行此操作,但您還可以使用許多其他服務(wù)。
第一步是注冊(cè)embed.ly API訪問。您可以在https://app.embed.ly/signup上...。這是一個(gè)簡(jiǎn)單的過程。確認(rèn)注冊(cè)后,您將收到一個(gè)API密鑰..您只需在HTTPrequest中使用此密鑰即可。我們現(xiàn)在就這樣做:
import urllib
def get_html(x):
qurl = urllib.parse.quote(x)
rhtml = requests.get('https://api.embedly.com/1/extract?url=' +
qurl + '&key=some_api_key')
ctnt = json.loads(rhtml.text).get('content')
return ctnt
df.loc[:,'html'] = df['urls'].map(get_html)
df.dropna(inplace=1)
df
上面的代碼生成以下輸出:
有了它,我們有每個(gè)故事的HTML。由于內(nèi)容嵌入在HTML標(biāo)記中,并且我們希望將純文本提供給我們的模型,我們將使用解析器去除標(biāo)記標(biāo)記:
from bs4 import BeautifulSoup def get_text(x):
soup = BeautifulSoup(x, 'lxml')
text = soup.get_text()
return text
df.loc[:,'text'] = df['html'].map(get_text)
df
上面的代碼生成以下輸出:
有了這個(gè),我們就準(zhǔn)備好了訓(xùn)練。我們現(xiàn)在可以繼續(xù)討論如何將文本轉(zhuǎn)換為模型可以使用的內(nèi)容。
設(shè)置每日個(gè)人簡(jiǎn)報(bào)
為了設(shè)置帶有新聞故事的個(gè)人電子郵件,我們將再次使用IFTTT。構(gòu)建應(yīng)用程序以查找廉價(jià)機(jī)票,我們將使用Maker Channel發(fā)送POST請(qǐng)求。
首先,單擊IFTTT主頁(yè)上的Create a Recipe。然后,搜索Maker
頻道:
選擇此項(xiàng),然后選擇接收Web請(qǐng)求:
然后,為請(qǐng)求命名。我正在使用news_event:
單擊“創(chuàng)建觸發(fā)器”完成。接下來,單擊它以設(shè)置電子郵件。搜索Gmail并單擊如下圖標(biāo):
點(diǎn)擊Gmail后,點(diǎn)擊發(fā)送電子郵件。從這里,您可以自定義您的電子郵件。
輸入您的電子郵件地址,主題行,最后在電子郵件正文中包含Value1。我們將通過我們的POST請(qǐng)求傳遞我們的故事標(biāo)題并鏈接到此。單擊“創(chuàng)建”以完成此操作。
現(xiàn)在,我們已準(zhǔn)備好生成將按計(jì)劃運(yùn)行的腳本,自動(dòng)向我們發(fā)送感興趣的文章。我們將為此創(chuàng)建一個(gè)單獨(dú)的腳本,但我們現(xiàn)有代碼中需要做的最后一件事是序列化我們的矢量化器和我們的模型:
import pickle pickle.dump(model, open (r'/Users/alexcombs/Downloads/news_model_pickle.p', 'wb')) pickle.dump(vect, open (r'/Users/alexcombs/Downloads/news_vect_pickle.p', 'wb'))
有了這個(gè),我們從模型中保存了所需的一切。在我們的新腳本中,我們將閱讀這些內(nèi)容以生成新的預(yù)測(cè)。我們將使用相同的調(diào)度庫(kù)來運(yùn)行我們?cè)诘?章“構(gòu)建應(yīng)用程序以查找廉價(jià)機(jī)票”中使用的代碼。總而言之,我們有以下腳本:
# get our imports. import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.svm import LinearSVC
import schedule import time
import pickle import json import gspread import requests
from bs4 import BeautifulSoup
from oauth2client.client import SignedJwtAssertionCredentials
# create our fetching function def fetch_news():
try:
vect =
pickle.load(open(r'/Users/alexcombs/Downloads/news_vect_pickle.p', 'rb'))
model =
pickle.load(open(r'/Users/alexcombs/Downloads/news_model_pickle.p', 'rb'))
json_key =
json.load(open(r'/Users/alexcombs/Downloads/APIKEY.json'))
scope = ['https://spreadsheets.google.com/feeds']
credentials = SignedJwtAssertionCredentials(json_key['client_email'], json_key['private_key'].encode(), scope)
gc = gspread.authorize(credentials)
ws = gc.open("NewStories")
sh = ws.sheet1
zd = list(zip(sh.col_values(2), sh.col_values(3),
sh.col_values(4)))
zf = pd.DataFrame(zd, columns=['title', 'urls', 'html'])
zf.replace('', pd.np.nan, inplace=True)
zf.dropna(inplace=True)
def get_text(x):
soup = BeautifulSoup(x, 'lxml')
text = soup.get_text()
return text
zf.loc[:, 'text'] = zf['html'].map(get_text)
tv = vect.transform(zf['text'])
res = model.predict(tv)
rf = pd.DataFrame(res, columns=['wanted'])
rez = pd.merge(rf, zf, left_index=True, right_index=True)
news_str = ''
for t, u in zip(rez[rez['wanted'] == 'y']['title'],
rez[rez['wanted'] == 'y']['urls']):
news_str = news_str + t + '\n' + u + '\n'
payload = {"value1": news_str}
r =
requests.post('https://maker.ifttt.com/trigger/news_event/with/key/IFTTT_KE
Y', data=payload)
# cleanup worksheet
lenv = len(sh.col_values(1))
cell_list = sh.range('A1:F' + str(lenv))
for cell in cell_list:
cell.value = ""
sh.update_cells(cell_list)
print(r.text)
except:
print('Failed')
schedule.every(480).minutes.do(fetch_news)
while 1: schedule.run_pending() time.sleep(1)
這個(gè)腳本將每隔4小時(shí)運(yùn)行一次,從Google表格下載新聞報(bào)道,通過模型運(yùn)行故事,通過向IFTTT發(fā)送POST請(qǐng)求以生成預(yù)期感興趣的故事,生成電子郵件,最后,它將清除電子表格中的故事,以便在下一封電子郵件中只發(fā)送新故事。
恭喜!您現(xiàn)在擁有自己的個(gè)性化新聞Feed!
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
