[ad_1]
在之前的文章中,我們學習了如何執行由BERT支持的高級, 自動意圖分類 在Python中。
我們還學習了如何自動 填充Google表格 在Python中。
如果我們可以直接在Google表格中執行意圖分類,那會很酷嗎?
這正是我們在這裡要做的!
Google Apps腳本簡介
Google表格中內置功能的局限性之一是它限制了您使用預定義的行為。
好消息是,如果您可以自己編寫代碼,則可以使用新行為定義自定義函數 Google Apps腳本。
Google Apps腳本基於JavaScript,並添加了有助於與表格,文檔和其他Google Apps進行交互的其他功能。
我們將定義一個名為fetchPrediction的新自定義函數,該函數將在Google Sheet單元格中使用關鍵字,並通過BERT支持的預測模型運行它們,以獲取搜索用戶的意圖。
這是我們的行動計劃:
- 通過Apps腳本了解如何查看和更新Google表格中的值。
- 練習從API提取結果,並使用檢索到的值填充工作表。
- 使用Uber的訓練我們的BERT支持的預測模型 路德維希。
- 使用Ludwig增強我們可以從Apps腳本調用的API的功能。
- 了解一些新工具和概念,以幫助我們將兩種服務連接在一起。
讓我們開始吧!
從Google表格檢索關鍵字數據
這是一 空的Google工作表 以及一些我們從SEMrush中提取的與條形碼相關的關鍵字。
在第一個練習中,我們將讀取並列印A列中的前10個關鍵字。
轉到工具>腳本編輯器開始使用。
這是Google表格的內置IDE(集成開發環境)。
我們將編寫一個名為logKeywords的簡單JavaScript函數,該函數將讀取工作表中的所有關鍵字並將它們記錄到控制台中。
請參考官方文檔 這裡。
函數logKeywords(){
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange()。getValues();
for(var i = 0; i
我們首先獲得對活動工作表的引用,在本例中為Sheet1。
如果您將此代碼與 我們用Python寫的,您將看到一些優點。
- 我們不需要進行身份驗證。
- 我們不需要打開電子表格。
轉到查看> Stackdriver日誌記錄。在那裡,您將獲得指向Apps腳本儀錶板的鏈接。單擊該按鈕以查看控制台日誌。
最好將此頁面保留在另一個選項卡中,因為您經常將其稱為代碼,並希望查看所做的更改是否有效。
您將在列表頂部看到最新的日誌條目。單擊它,您將看到上面的屏幕截圖。
現在,我們列印了100多行,這花了一些時間。在編寫和測試代碼時,最好使用較小的列表。
我們可以在循環中進行簡單的更改以解決此問題。
函數logKeywords(){
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange()。getValues();
// for(var i = 0; i
我更喜歡注釋掉代碼更改,而不是刪除它們,因為當我準備發布供生產使用時,它會更容易恢復。
當您運行此命令時,它不僅運行速度更快,而且檢查日誌的速度也快得多。
添加帶有關鍵字ID的列
接下來,讓我們學習將數據添加到表格中。
我們將編寫一個名為addIDtoKeywords的新函數。它創建一個帶有每個關鍵字一個數字ID的列。
這樣做沒有太大的價值,但是它應該可以幫助您以超簡單的方式測試這項技術。
這是執行此操作的代碼。
函數addIDtoKeywords(){
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getRange(「 B1」);
//建立值清單
var值= [];
//關鍵字數
長度= 100;
對於(var i = 1; i <= length + 1; i ++){
values.push([i]);
}
console.log(values.length);
//使用計算值更新工作表列
var column = sheet.getRange(「 B2:B102」);
column.setValues(values);
}
在下拉菜單中選擇此功能,然後單擊播放按鈕以運行。
您應該在工作表中獲得一個新列,其編號按升序排列。
我們還可以使用以下代碼以粗體顯示名為Keyword ID的列標題。
data.setValue(「關鍵字ID」);
data.setFontWeight(「 bold」);
這就是更新後的輸出。
這是一個非常相似的代碼。讓我們回顧一下更改。
我添加了一個名為value的JavaScript數組來保存關鍵字ID。
在循環期間,我添加了一行以將循環內生成的每個ID添加到數組。
values.push([i]);
我在循環末尾列印了值數組的長度,以確保生成了正確數量的ID。
最後,我需要將值保存到工作表中。
var column = sheet.getRange(「 B2:B102」);
此代碼選擇要填充的正確單元格,然後我可以使用生成的列表簡單地設置它們的值。
column.setValues(values);
沒有比這更簡單的了!
從Apps腳本中獲取API結果
在下一個練習中,我們將學習如何從Apps腳本執行API請求。
我建議你跟隨 這個代碼實驗室 從Google那裡來熟悉一些更高級的概念。
我們將改編來自 步驟11 它從Books API中提取數據。
除了獲取圖書,我們還將使用 Google翻譯API。
現在,我們開始編寫更有用的代碼!
這是一個新的名為fetchTranslation的函數,它基於從步驟11改編的代碼。
函數fetchTranslation(TEXT){
API_KEY =「輸入您的API密鑰」;
TEXT = encodeURI(TEXT); //「我的名字叫史蒂夫」->「我的%20name%20is%20Steve」;
var url =`https://translation.googleapis.com/language/translate/v2?target=es&key=$ {API_KEY}&q = $ {TEXT}`;
//console.log(url);
var response = UrlFetchApp.fetch(url,{‘muteHttpExceptions’:true});
var json = response.getContentText();
//console.log(json);
翻譯= JSON.parse(json);
返回翻譯[“data”][“translations”][0][“translatedText”];
}
此函數接受輸入文本,對其進行編碼,然後將其插入API URL中以調用Google翻譯服務。
我們需要獲取一個API密鑰,並且還需要啟用翻譯服務。我還建議將API限制為在開發過程中用於測試的IP。
一旦有了要調用的API URL,就和調用此代碼一樣簡單。
var response = UrlFetchApp.fetch(url,{‘muteHttpExceptions’:true});
接下來的幾行使我們獲得JSON格式的響應,並在JSON樹下進行了一些導航之後,我們獲得了翻譯後的文本。
正如您在我的代碼中看到的那樣,我喜歡將代碼中的幾乎每個步驟都記錄到控制台中,以確認它正在按我的預期進行。
這是一個示例,說明了如何找出正確的JSON路徑序列。
//console.log(翻譯[“data”]);
//console.log(翻譯[“data”][“translations”]);
//console.log(翻譯[“data”][“translations”][0]);
//console.log(翻譯[“data”][“translations”][0][“translatedText”]);
您可以在此處的日誌中查看進度,包括最終輸出。
翻譯關鍵詞
在測試該函數並使其起作用時,我們可以繼續創建另一個函數以從工作表中獲取並翻譯關鍵字。
我們將以到目前為止的經驗為基礎。
我們將這個函數稱為超級原始名稱TranslateKeywords!
函數TranslateKeywords(){
var sheet = SpreadsheetApp.getActiveSheet();
var header = sheet.getRange(「 B1」);
//添加一個名為Translation的新標題列
header.setValue(「 Translation」);
header.setFontWeight(「 bold」);
// var關鍵字=「條形碼生成器」;
var關鍵字= sheet.getRange(「 A2」)。getValue();
console.log(關鍵字);
translation_keyword = fetchTranslation(keyword);
console.log(translated_keyword);
var data = sheet.getRange(「 B2」);
data.setValue(translated_keyword);
}
此功能中的代碼與我們用來設置關鍵字ID的代碼非常相似。
主要區別在於我們將關鍵字傳遞給新的fetchTranslation函數,並使用結果更新單個單元格。
這是示例關鍵字的外觀。
您可能會看到,沒有for循環,因此這隻會更新單個行/關鍵字。第一個。
請完成for循環以完成所有關鍵字的翻譯,作為一項家庭作業。
建立意圖分類模型
讓我們開始構建意圖分類服務,我們將調用該服務來填充關鍵字意圖。
在之前的深度學習文章中,我介紹了 Uber的AI工具箱Ludwig。
我非常喜歡它,因為它使您無需編寫任何代碼即可構建最新的深度學習模型。
在Google Colab中運行也非常方便。
我們將遵循與我在其中描述的相同步驟 本文, 這將為我們提供由BERT支持的強大的意圖預測模型。
這是您需要粘貼到的步驟的快速摘要 Google Colab (確保選擇GPU運行時!)。
請參閱 我的文章 對於上下文:
%tensorflow_version 1.x
將tensorflow導入為tf;列印(tf .__ version__)
!pip安裝路德維希
#upload Question_Classification_Dataset.csv和「問題Report_Page 1_Table.csv」
從google.colab導入文件
files.upload()
將熊貓作為pd導入
df = pd.read_csv(「 Question_Classification_Dataset.csv」,index_col = 0)
!wget https://storage.googleapis.com/bert_models/2018_10_18/uncased_L-12_H-768_A-12.zip
!unzip uncased_L-12_H-768_A-12.zip
#創建用於BERT支持的分類的路德維希配置文件
template =「」「
input_features:
—
名稱:問題
類型:文字
編碼器:伯特
config_path:uncased_L-12_H-768_A-12 / bert_config.json
checkpoint_path:uncased_L-12_H-768_A-12 / bert_model.ckpt
預處理:
word_tokenizer:伯特
word_vocab_file:uncased_L-12_H-768_A-12 / vocab.txt
padding_symbol:「[PAD]’
unknown_symbol:「[UNK]’
output_features:
—
名稱:Category0
類型:類別
—
名稱:Category2
類型:類別
文本:
word_sequence_length_limit:128
訓練:
batch_size:32
學習率:0.00002
「」
使用open(「 model_definition.yaml」,「 w」)為f:
f.write(模板)
!pip安裝bert-tensorflow
!路德維希實驗
–data_csv Question_Classification_Dataset.csv
–model_definition_file model_definition.yaml
在Google Colab中完成這些步驟之後,我們應該獲得用於搜索意圖的高精度預測模型。
我們可以使用此代碼驗證預測。
test_df = pd.read_csv(「問題Report_Page 1_Table.csv」)
#我們將查詢重命名為問題以匹配模型的期望
預測= model.predict(test_df.rename(columns = {‘Query’:’Questions’}))
test_df.join(預測)[[“Query”, “Category2_predictions”]]
我們得到一個像這樣的數據幀。
預測的意圖不是您通常期望的意圖:導航,事務性,信息性,但它們足以說明該概念。
請檢查一篇很棒的文章 克里斯汀·廷斯基 解釋了如何擴展這個概念 獲得真正的搜索意圖。
將模型轉化為API服務
路德維希(Ludwig)具有一項超酷的功能,可讓您直接將模型作為API服務提供。
該命令是 路德維希發球。
我試圖沿著一條超級複雜的道路完成同樣的事情,因為我沒有檢查類似的東西是否已經存在。 ?
默認情況下未安裝它,我們需要使用此命令進行安裝。
!pip安裝路德維希[serve]
我們可以使用以下命令檢查命令行選項:
!ludwig服務-幫助
從我們的模型創建API就像運行此命令一樣簡單。
!ludwig serve -m結果/實驗_運行/模型
INFO:開始的伺服器進程 [5604]
INFO:等待應用程序啟動。
INFO:應用程序啟動完成。
信息:在http://0.0.0.0:8000上運行的Uvicorn(按CTRL + C退出)
INFO:關閉
INFO:伺服器進程完成 [5604]
當我們在筆記本中運行此代碼時,我們需要使用一些技巧將此過程推向後台(一個單獨的線程)。
%% bash –bg
nohup ludwig服務-m結果/實驗運行/模型> debug.log 2>&1
神奇的命令%% bash –bg在單獨的線程中運行shellcode,將控制權返回給筆記本,因此我們可以運行可以與服務交互的代碼。
我發現這是一個非常酷且有價值的技巧。我還將介紹很多年前學到的shell技巧。
的 nohup命令 防止該進程在父母死亡時被殺死。這是可選的。
代碼2>&1重定向 標準誤差 到標準輸入,然後兩者都發送到文件debug.log。您可以在此處了解有關此技術的更多信息。
我們可以使用此命令跟蹤後台進程的進度。
!tail debug.log
看到此消息後,您可以繼續執行下一步。
信息:在http://0.0.0.0:8000上運行的Uvicorn(按CTRL + C退出)
讓我們使用curl發送一個測試API請求,以查看該服務是否有效。
!curl http://0.0.0.0:8000/predict -X POST -F’問題=誰是老闆?’
您應該返回此響應。
{ 「Category0_predictions」: 「人」, 「Category0_probabilities _」:0.00021219381596893072, 「Category0_probabilities_ENTITY」:7.17515722499229e-05, 「Category0_probabilities_HUMAN」:0.9988889098167419 「Category0_probabilities_DESCRIPTION」:0.000423480843892321, 「Category0_probabilities_NUMERIC」:2.7793401386588812e-05, 「Category0_probabilities_LOCATION」:0.0003020864969585091 「Category0_probabilities_ABBREVIATION」:7.374086999334395e-05, 「Category0_probability」:0.9988889098167419, 「Category2_predictions」: 「IND」, 「Category2_probabilities _」:8.839580550557002e-05, 「Category2_probabilities_ind」:0.9759176969528198, 「Category2_probabilities_other」:0.0013697665417566895, 「Category2_probabilities_def」:3.929347076336853 E-05, 「Category2_probabilities_count」:4.732362140202895e-05, 「Category2_probabilities_desc」:0.014149238355457783, 「Category2_probabilities_manner」:7.225596345961094e-05, 「Category2_probabilities_date」:7.537546480307356e-05, 「Category2_probabilities_cremat」:0.00012272763706278056,「Category2_probabilities_reason 「:0.00042629052768461406,」 Category2_probabilities_gr 「:0.0025540771894156933,」 Category2_probabilities_country 「:0.0002626778441481292,」 Category2_probabilities_city 「:0.0004305317997932434,」 Category2_probabilities_animal 「:0.00024954770924523473,」 Category2_probabilities_food 「:8.139225974446163e-05,」 Category2_probabilities_dismed 「:7.852958515286446e-05,」 Category2_probabilities_termeq「: 0.00023714809503871948, 「Category2_probabilities_period」:4.197505040792748e-05, 「Category2_probabilities_money」:3.626687248470262e-05, 「Category2_probabilities_exp」:5.991378566250205e-05, 「Category2_probabilities_state」:0.00010361814202042297, 「Category2_probabilities_sport」:8.741072088014334e-05, 「Category2_probabilities_event」:0.00013374585250858217, 「 Category2_probabilities_product」:5.6306344049517065e-05,「 Category2_probabilities_substance」:0.00016623239207547158,「 Category2_probabilities_color」:1.9601659005274996e-05,「 Category2_probabilities_techmeth」:4.74867774755694ry-2「 3491e-05, 「Category2_probabilities_perc」:3.87108520953916e-05, 「Category2_probabilities_veh」:0.00011915313370991498, 「Category2_probabilities_word」:0.00016430433606728911, 「Category2_probabilities_title」:0.0010781479068100452, 「Category2_probabilities_mount」:0.00024070330255199224, 「Category2_probabilities_body」:0.0001515906333224848, 「Category2_probabilities_abb」:8.521509153069928e- 05, 「Category2_probabilities_lang」:0.00022924368386156857, 「Category2_probabilities_plant」:4.893113509751856e-05, 「Category2_probabilities_volsize」:0.0001462997024646029, 「Category2_probabilities_symbol」:9.98345494735986e-05, 「Category2_probabilities_weight」:8.899033855414018e-05, 「Category2_probabilities_instru」:2.636547105794307e-05, 「 Category2_probabilities_letter」:3.7610192521242425e-05,「 Category2_probabilities_speed」:4.142118996242061e-05,「 Category2_probabilities_code」:5.926147059653886e-05,「 Category2_probabilities_temp」:3.687662319862284e-05,「 Category6.7」「 2ate s_religion」:0.00012743560364469886,「 Category2_probabilities_currency」:5.8569487009663135ee-05,「 Category2_probability」:0.9759176969528198}
使用Ngrok公開我們的服務
因此,我們有一個可以進行意圖預測的新API,但是一個大問題是只能從我們的Colab筆記本中訪問它。
讓我介紹我經常使用的另一項很酷的服務, 恩格羅克。
Ngrok可幫助您創建可公開訪問的URL,這些URL連接到本地服務(例如我們剛剛創建的服務)。
我不建議將其用於生產,但是在開發和測試過程中非常方便。
您不需要創建帳戶,但我個人這樣做是因為我可以設置一個經常使用的自定義子域。
以下是為我們的API提供公共URL以便從App Script調用的步驟。
!wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip &&解壓縮ngrok-stable-linux-amd64.zip
我們首先下載並解壓縮ngrok。
%% bash –bg
./ngrok http -hostname = api.yourdomain.com 8000 2> ngrok.log
上面的代碼告訴ngrok在埠8000上連接到本地服務。這就是我們需要做的。
!curl http://api.yourdomain.com/predict -X POST -F’問題=老闆是誰?’
您可以通過重複curl調用,但調用公共URL來確認它是否有效。您應該得到相同的結果。
如果您不想設置自定義域,則可以改用此代碼。
%% bash –bg
./ngrok http 8000 2> ngrok.log
這將生成一個隨機的公共URL,您可以使用此代碼進行檢索。
!curl -s http:// localhost:4040 / api / tunnels | python3 -c
「 import sys,json; print(json.load(sys.stdin)[‘tunnels’][0][‘public_url’])」
現在,我們回到最後的步驟。
獲取意圖預測
我們將調整用於發出Google Translate API請求的代碼,以便發出意圖預測請求。
兩種API服務之間的一大區別是,我們需要發出HTTP POST請求,而不是簡單的HTTP GET請求。
讓我們看看這如何改變我們的代碼, 在此過程中進一步了解HTTP。
函數fetchPrediction(question =「誰是老闆?」){
TEXT = encodeURI(TEXT);
console.log(TEXT);
var url =「 http://api.yourdomain.com/predict」;
var options = {
「 method」:「 POST」,
「 contentType」:「 application / x-www-form-urlencoded」,
「有效載荷」:TEXT,
‘muteHttpExceptions’:是
};
var response = UrlFetchApp.fetch(url,options);
var json = response.getContentText();
//console.log(json);
預測= JSON.parse(json);
//console.log(預測);
console.log(預測[“Category0_predictions”]);
回報預測[“Category0_predictions”];
}
函數fetchPrediction調用我們創建的API服務,並返回預測的意圖。基本上,它重現了與我們進行Colab的curl調用等效的操作,但使用的是Apps Script。
我強調了代碼中的一些關鍵更改。讓我們回顧一下。
GET和POST請求之間的主要區別在於,在GET請求中,數據作為參數在URL中傳遞。
在POST請求中,數據在請求主體內傳遞。
我們需要先對數據進行格式化,然後再將其傳遞到正文中,並且需要設置正確的內容類型,以便伺服器知道如何對其進行解碼。
該行編碼了我們正在傳遞的問題。
TEXT = encodeURI(TEXT);
這是編碼後的TEXT外觀的一個示例。
Questions = label%20generator
此編碼的正確內容類型是application / x-www-form-urlencoded。建議對HTML表單數據進行編碼。
我們創建一個options數據結構,在其中指定這些設置和正確的請求類型,然後開始運行。
從下拉菜單中選擇函數fetchPrediction,然後單擊運行按鈕。
您應該在日誌中看到編碼的輸入和預測的意圖。
我們如何獲得工作表中所有關鍵字的意圖?
您可能以為我們將創建另一個函數,該函數將循環讀取關鍵字並填充意圖。一點也不!
我們可以直接從工作表中直接按名稱調用此函數!多麼酷啊?
了解更多的資源
將簡單的App Script函數與功能強大的API後端結合在一起,您可以使用任何語言進行編碼,這為無限的生產力黑客打開了大門。
這是我在整理這些內容時閱讀的一些資源。
最後,讓我強調一個非常重要和有價值的項目, JR橡樹 開始。
它是一個 很棒的倉庫 用於來自SEO社區的編碼人員的Python和JavaScript項目。我計劃抽出時間上傳我的代碼段,請確保 貢獻你的。
由於某種原因,這個非問題會在我的Twitter feed中不斷彈出。我將在這裡留下此推文,以提醒您。 ✌️
只是一個善意的提醒。 #SEO 該代碼絕非非編碼器「更好」。最聰明 #SEO 我知道??與編碼人員進行了出色的合作。有效的溝通是非常寶貴的,並且很難獲得技能。我們應該歡迎社區中的各種技能。 ?? https://t.co/wvYqxc2sNI
-哈姆雷特(@hamletbatista) 2020年3月10日
圖片積分
由作者拍攝的所有屏幕截圖,2020年3月