- 來源 | 愿碼(ChainDesk.CN)內容編輯
- 愿碼Slogan | 連接每個程序員的故事
- 網站 | http://chaindesk.cn
- 愿碼愿景 | 打造全學科IT系統免費課程,助力小白用戶、初級工程師0成本免費系統學習、低成本進階,幫助BAT一線資深工程師成長并利用自身優勢創造睡后收入。
- 官方公眾號 | 愿碼 | 愿碼服務號 | 區塊鏈部落
- 免費加入愿碼全思維工程師社群 | 任一公眾號回復“愿碼”兩個字獲取入群二維碼
本文閱讀時長:12min
要創建自定義新聞Feed模型,我們需要可以訓練的數據。這些培訓數據將被輸入模型,以教它區分我們感興趣的文章和我們不感興趣的文章。
在本文中,我們將學習構建自定義新聞語料庫并分別注釋與興趣相對應的大量文章。
創建受監督的訓練數據集
在我們在新聞文章中創建我們的品味模型之前,我們需要培訓數據。這些培訓數據將被輸入我們的模型,以教它區分我們感興趣的文章和我們不感興趣的文章。要構建此語料庫,我們需要注釋大量符合這些興趣的文章。對于每篇文章,我們將其標記為“y”或“n”。這將表明該文章是否是我們希望在我們的日常摘要中發送給我們的文章。
為簡化此過程,我們將使用Pocket應用程序。Pocket是一個應用程序,允許您保存故事以供稍后閱讀。您只需安裝瀏覽器擴展,然后在希望保存故事時單擊瀏覽器工具欄中的Pocket圖標。該文章將保存到您的個人存儲庫中。Pocket的一個重要功能就是它的用途,能夠使用您選擇的標簽保存文章。我們將使用此功能將有趣的文章標記為“y”,將非有趣的文章標記為“n”。
安裝Pocket Chrome擴展程序
我們在這里使用谷歌瀏覽器,但其他瀏覽器應該類似。對于Chrome,請進入Google App Store并查找“擴展”部分:
點擊藍色的添加到Chrome按鈕。如果您已有帳戶,請登錄,如果您還沒有帳戶,請繼續注冊(免費)。完成后,您應該會在瀏覽器的右上角看到Pocket圖標。它將顯示為灰色,但是一旦有想要保存的文章,您可以單擊它。保存文章后,它將變為紅色,如下圖所示。
右上角可以看到灰色圖標。
單擊圖標時,它會變為紅色,表示文章已保存。
開始保存您遇到的所有文章。用“y”標記有趣的標簽,用“n”標記非有趣的標簽。這將需要一些工作。你的最終結果只會和訓練集一樣好,所以你需要為數百篇文章做這件事。如果您在保存文章時忘記標記文章,則可以隨時訪問該網站http://www.get.pocket.com,在其中標記。
使用Pocket API檢索故事
既然您已經將文章保存到Pocket,那么下一步就是檢索它們。為此,我們將使用Pocket API。您可以通過https:// ge?tpocket.com/developer/apps/new注冊一個帳戶。單擊左上角的“ 創建新應用程序 ”并填寫詳細信息以獲取API密鑰。確保單擊所有權限,以便添加,更改和檢索文章。
填寫完成并提交后,您將收到您的 消費者密鑰 。您可以在“ 我的應用” 下的左上角找到此信息。這將看起來像下面的屏幕,但顯然有一個真正的鍵:
設置完成后,您就可以繼續下一步,即設置授權。它要求您輸入您的使用者密鑰和重定向URL。重定向網址可以是任何內容。在這里,我使用了我的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
您將看到以下輸出:
輸出將包含下一步所需的代碼。將以下內容放在瀏覽器欄中:
https://getpocket.com/auth/au... ect_uri = https% 3A // www.twitter.com / acombs
如果您將重定向網址更改為您自己的網址,請確保對其進行網址編碼。這有很多資源。一種選擇是使用Python庫 urllib ,另一種是使用免費的在線源。
此時,您應該看到授權屏幕。繼續并批準它,我們可以繼續下一步:
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
我們將在此處使用以下輸出代碼繼續檢索故事:
首先,我們檢索標記為“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
上面的代碼生成以下輸出:
請注意,我們在標記為“n”的所有文章上都有一個長JSON字符串。這里有幾個鍵,但我們實際上只對URL感興趣。我們將繼續創建一個包含以下所有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。現在,讓我們把它放在一個
DataFrame對象并將其標記為:
import pandas
no_uf = pd.DataFrame(no_urls, columns=['urls'])
no_uf = no_uf.assign(wanted = lambda x: 'n')
no_uf
上面的代碼生成以下輸出:
現在,我們都準備好了不想要的故事。讓我們對我們感興趣的故事做同樣的事情:
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
上面的代碼生成以下輸出:
現在我們的訓練數據都有兩種類型的故事,讓我們將它們組合成一個DataFrame:
df = pd.concat([yes_uf, no_uf])
df.dropna(inplace=1)
df
上面的代碼生成以下輸出:
現在我們在一個框架中設置了所有URL和相應的標簽,我們將繼續為每篇文章下載HTML。我們將使用另一個名為 embed.ly的 免費服務。
使用embed.ly API下載故事主體
我們將使用embed.ly來執行此操作,但您還可以使用許多其他服務。
第一步是注冊embed.ly API訪問。您可以在https://app.embed.ly/signup上...。這是一個簡單的過程。確認注冊后,您將收到一個API密鑰..您只需在HTTPrequest中使用此密鑰即可。我們現在就這樣做:
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
上面的代碼生成以下輸出:
有了它,我們有每個故事的HTML。由于內容嵌入在HTML標記中,并且我們希望將純文本提供給我們的模型,我們將使用解析器去除標記標記:
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
上面的代碼生成以下輸出:
有了這個,我們就準備好了訓練。我們現在可以繼續討論如何將文本轉換為模型可以使用的內容。
設置每日個人簡報
為了設置帶有新聞故事的個人電子郵件,我們將再次使用IFTTT。構建應用程序以查找廉價機票,我們將使用Maker Channel發送POST請求。
首先,單擊IFTTT主頁上的Create a Recipe。然后,搜索Maker
頻道:
選擇此項,然后選擇接收Web請求:
然后,為請求命名。我正在使用news_event:
單擊“創建觸發器”完成。接下來,單擊它以設置電子郵件。搜索Gmail并單擊如下圖標:
點擊Gmail后,點擊發送電子郵件。從這里,您可以自定義您的電子郵件。
輸入您的電子郵件地址,主題行,最后在電子郵件正文中包含Value1。我們將通過我們的POST請求傳遞我們的故事標題并鏈接到此。單擊“創建”以完成此操作。
現在,我們已準備好生成將按計劃運行的腳本,自動向我們發送感興趣的文章。我們將為此創建一個單獨的腳本,但我們現有代碼中需要做的最后一件事是序列化我們的矢量化器和我們的模型:
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'))
有了這個,我們從模型中保存了所需的一切。在我們的新腳本中,我們將閱讀這些內容以生成新的預測。我們將使用相同的調度庫來運行我們在第3章“構建應用程序以查找廉價機票”中使用的代碼。總而言之,我們有以下腳本:
# 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)
這個腳本將每隔4小時運行一次,從Google表格下載新聞報道,通過模型運行故事,通過向IFTTT發送POST請求以生成預期感興趣的故事,生成電子郵件,最后,它將清除電子表格中的故事,以便在下一封電子郵件中只發送新故事。
恭喜!您現在擁有自己的個性化新聞Feed!
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

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