小白入門篇使用Python搭建點(diǎn)擊率預(yù)估模型
點(diǎn)擊率預(yù)估模型
0.前言
本篇是一個(gè)基礎(chǔ)機(jī)器學(xué)習(xí)入門篇文章,幫助我們熟悉機(jī)器學(xué)習(xí)中的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)與使用。
日常中習(xí)慣于使用Python各種成熟的機(jī)器學(xué)習(xí)工具包,例如sklearn、TensorFlow等等,來快速搭建各種各樣的機(jī)器學(xué)習(xí)模型來解決各種業(yè)務(wù)問題。
本文將從零開始,僅僅利用基礎(chǔ)的numpy庫,使用Python實(shí)現(xiàn)一個(gè)最簡單的神經(jīng)網(wǎng)絡(luò)(或者說是簡易的LR,因?yàn)長R就是一個(gè)單層的神經(jīng)網(wǎng)絡(luò)),解決一個(gè)點(diǎn)擊率預(yù)估的問題。
1.假設(shè)一個(gè)業(yè)務(wù)場景
聲明:為了簡單起見,下面的一切設(shè)定從簡….
定義需要解決的問題:
老板:小李,這臺機(jī)器上有一批微博的點(diǎn)擊日志數(shù)據(jù),你拿去分析一下,然后搞點(diǎn)擊率預(yù)測啥的…
是的,就是預(yù)測一篇微博是否會被用戶點(diǎn)擊(被點(diǎn)擊的概率)…..預(yù)測未來,貌似很神奇的樣子!
熱門微博
簡單的介紹一下加深的業(yè)務(wù)數(shù)據(jù)
每一條微博數(shù)據(jù)有由三部分構(gòu)成: {微博id, 微博特征X, 微博點(diǎn)擊標(biāo)志Y}
微博特征X有三個(gè)維度:
X={x0="該微博有娛樂明星”,x1="該微博有圖”,x2="該微博有表情”}
微博是否被點(diǎn)擊過的標(biāo)志Y:
Y={y0=“點(diǎn)擊”, y1=“未點(diǎn)擊”}
數(shù)據(jù)有了,接下來需要設(shè)計(jì)一個(gè)模型,把數(shù)據(jù)輸入進(jìn)去進(jìn)行訓(xùn)練之后,在預(yù)測階段,只需要輸入{微博id,微博特征X},模型就會輸出每一個(gè)微博id會被點(diǎn)擊的概率。
2.任務(wù)分析:
這是一個(gè)有監(jiān)督的機(jī)器學(xué)習(xí)任務(wù)
對于有監(jiān)督的機(jī)器學(xué)習(xí)任務(wù),可以簡單的分為分類與回歸問題,這里我們簡單的想實(shí)現(xiàn)預(yù)測一條微博是否會被用戶點(diǎn)擊,預(yù)測目標(biāo)是一個(gè)二值類別:點(diǎn)擊,或者不點(diǎn)擊,顯然可以當(dāng)做一個(gè)分類問題。
所以,我們需要搭建一個(gè)分類模型(點(diǎn)擊率預(yù)測模型),這也就決定我們需要構(gòu)建一個(gè)有監(jiān)督學(xué)習(xí)的訓(xùn)練數(shù)據(jù)集。
模型的選擇
選擇最簡單神經(jīng)網(wǎng)絡(luò)模型,人工神經(jīng)網(wǎng)絡(luò)有幾種不同類型的神經(jīng)網(wǎng)絡(luò),比如前饋神經(jīng)網(wǎng)絡(luò)、卷積神經(jīng)網(wǎng)絡(luò)及遞歸神經(jīng)網(wǎng)絡(luò)等。本文將以簡單的前饋或感知神經(jīng)網(wǎng)絡(luò)為例,這種類型的人工神經(jīng)網(wǎng)絡(luò)是直接從前到后傳遞數(shù)據(jù)的,簡稱前向傳播過程。
3.數(shù)據(jù)準(zhǔn)備:
整體的流程:
數(shù)據(jù)預(yù)處理(數(shù)值化編碼)——>特征篩選——>選擇模型(前饋神經(jīng)網(wǎng)絡(luò))——>訓(xùn)練模型——>模型預(yù)測
假設(shè),對4條微博的數(shù)據(jù)進(jìn)行數(shù)值化編碼,可以表示為如下的矩陣格式:
訓(xùn)練數(shù)據(jù)XY
解讀一條樣本數(shù)據(jù):
第一條樣本數(shù)據(jù)為:X0=[0 0 1],分別對應(yīng)著三維的特征,最后4x1的矩陣是Y,0表示無,1表示有,可知該特征對應(yīng)的Y0是未點(diǎn)擊。
所以,這條樣本可以翻譯為:[該微博沒娛樂明星,沒有圖片,有表情],最終y=0,代表該條微博沒有被點(diǎn)擊。
業(yè)務(wù)以及數(shù)據(jù)特征是不是很簡單….簡單有點(diǎn)看起來編的不太合理 - !
4.神經(jīng)網(wǎng)絡(luò)基本結(jié)構(gòu):
1.輸入層:輸入的業(yè)務(wù)特征數(shù)據(jù)
2.隱藏層:初始化權(quán)重參數(shù)
3.激活函數(shù):選擇激活函數(shù)
4.輸出層:預(yù)測的目標(biāo),定義損失函數(shù)
我們即將使用的機(jī)器學(xué)習(xí)模型:
超級簡單的前饋神經(jīng)網(wǎng)絡(luò)
機(jī)器學(xué)習(xí)模型類似一個(gè)黑盒子,輸入歷史點(diǎn)擊的數(shù)據(jù),進(jìn)行訓(xùn)練,然后就可以對未來的額數(shù)據(jù)進(jìn)行預(yù)測….我們上面設(shè)計(jì)的是一個(gè)超級簡單的前饋神經(jīng)網(wǎng)絡(luò),但是可以實(shí)現(xiàn)我們上面的目的。
關(guān)于激活函數(shù):
通過引入激活函數(shù),實(shí)現(xiàn)了非線性變換,增強(qiáng)了模型的擬合效果。
關(guān)乎激活函數(shù),請看之前的文章 吾愛NLP(2)--解析深度學(xué)習(xí)中的激活函數(shù)
在本文教程中,使用的是簡單的Sigmoid激活函數(shù),但注意一點(diǎn),在深層神經(jīng)網(wǎng)絡(luò)模型中, sigmoid激活函數(shù)一般不作為首選,原因是其易發(fā)生梯度彌散現(xiàn)象。
sigmoid公式
此函數(shù)可以將任何值映射到0到1之間,并能幫助我們規(guī)范化輸入的加權(quán)和。
sigmoid圖像
對sigmoid激活函數(shù)求偏導(dǎo):
該偏導(dǎo)函數(shù)嗎,等下寫程序會用到,所以先放在這里!
模型的訓(xùn)練
訓(xùn)練階段,模型的輸入X已經(jīng)確定,輸出層的Y確定,機(jī)器學(xué)習(xí)模型確定,唯一需要求解的就是模型中的權(quán)重W,這就是訓(xùn)練階段的目標(biāo)。
主要由三個(gè)核心的流程構(gòu)成:
前向計(jì)算—>計(jì)算損失函數(shù)—>反向傳播
本文使用的模型是最簡單的前饋神經(jīng)網(wǎng)絡(luò),起始就是一個(gè)LR而已….所以整個(gè)過程這里就不繼續(xù)介紹了,因?yàn)橹耙呀?jīng)寫過一篇關(guān)于LR的文章--- 邏輯回歸(LR)個(gè)人學(xué)習(xí)總結(jié)篇 ,如果對其中的細(xì)節(jié)以及公式的推導(dǎo)有疑問,可以去LR文章里面去尋找答案。
這里再提一下權(quán)重參數(shù)W更新的公式:
至此,所有的寫代碼需要的細(xì)節(jié)都已經(jīng)交代結(jié)束了,剩下的就是代碼了。
5.使用Python代碼構(gòu)建網(wǎng)絡(luò)
# coding:utf-8 import numpy as np class NeuralNetwork(): # 隨機(jī)初始化權(quán)重 def __init__(self): np.random.seed(1) self.synaptic_weights = 2 * np.random.random((3, 1)) - 1 # 定義激活函數(shù):這里使用sigmoid def sigmoid(self, x): return 1 / (1 + np.exp(-x)) #計(jì)算Sigmoid函數(shù)的偏導(dǎo)數(shù) def sigmoid_derivative(self, x): return x * (1 - x) # 訓(xùn)練模型 def train(self, training_inputs, training_outputs,learn_rate, training_iterations): # 迭代訓(xùn)練 for iteration in range(training_iterations): #前向計(jì)算 output = self.think(training_inputs) # 計(jì)算誤差 error = training_outputs - output # 反向傳播-BP-微調(diào)權(quán)重 adjustments = np.dot(training_inputs.T, error * self.sigmoid_derivative(output)) self.synaptic_weights += learn_rate*adjustments def think(self, inputs): # 輸入通過網(wǎng)絡(luò)得到輸出 # 轉(zhuǎn)化為浮點(diǎn)型數(shù)據(jù)類型 inputs = inputs.astype(float) output = self.sigmoid(np.dot(inputs, self.synaptic_weights)) return output if __name__ == "__main__": # 初始化前饋神經(jīng)網(wǎng)絡(luò)類 neural_network = NeuralNetwork() print "隨機(jī)初始化的權(quán)重矩陣W" print neural_network.synaptic_weights # 模擬訓(xùn)練數(shù)據(jù)X train_data=[[0,0,1], [1,1,1], [1,0,1], [0,1,1]] training_inputs = np.array(train_data) # 模擬訓(xùn)練數(shù)據(jù)Y training_outputs = np.array([[0,1,1,0]]).T # 定義模型的參數(shù): # 參數(shù)學(xué)習(xí)率 learn_rate=0.1 # 模型迭代的次數(shù) epoch=150000 neural_network.train(training_inputs, training_outputs, learn_rate, epoch) print "迭代計(jì)算之后權(quán)重矩陣W: " print neural_network.synaptic_weights # 模擬需要預(yù)測的數(shù)據(jù)X pre_data=[0,0,1] # 使用訓(xùn)練的模型預(yù)測該微博被點(diǎn)擊的概率 print "該微博被點(diǎn)擊的概率:" print neural_network.think(np.array(pre_data)) """ 終端輸出的結(jié)果: 隨機(jī)初始化的權(quán)重矩陣W [[-0.16595599] [ 0.44064899] [-0.99977125]] 迭代計(jì)算之后權(quán)重矩陣W: [[12.41691302] [-0.20410552] [-6.00463275]] 該微博被點(diǎn)擊的概率: [0.00246122] [Finished in 20.2s] """
6.總結(jié):
根據(jù)終端輸出的模型訓(xùn)練以及預(yù)測的結(jié)果,針對預(yù)測數(shù)據(jù)pre_data=[0,0,1],模型輸出該微博被點(diǎn)擊的概率為0.00246,很顯然被點(diǎn)擊的概率比較小,可以認(rèn)為簡單認(rèn)為該微博不會被點(diǎn)擊!
是的,我們的業(yè)務(wù)目標(biāo)初步實(shí)現(xiàn)了----輸入任意一條微博的樣本數(shù)據(jù)到我們的機(jī)器學(xué)習(xí)模型中,既可以輸出該樣本被點(diǎn)擊的概率。
上面的就是我們設(shè)計(jì)的一個(gè)超級簡單的模型,假設(shè)了一個(gè)超級簡單的業(yè)務(wù)場景,并隨機(jī)設(shè)定了超簡單的訓(xùn)練數(shù)據(jù),如果有 編 的不合理地方多多包涵!??!該例子雖然可能并不能幫你解決實(shí)際的業(yè)務(wù)問題,但是對于機(jī)器學(xué)習(xí)的新手理解神經(jīng)網(wǎng)絡(luò),或許會有一點(diǎn)點(diǎn)幫助吧!
總結(jié)
以上所述是小編給大家介紹的用Python搭建超級簡單的點(diǎn)擊率預(yù)估模型,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
python Web應(yīng)用程序測試selenium庫使用用法詳解
selenium主要是用來做自動化測試,支持多種瀏覽器,爬蟲中主要用來解決JavaScript渲染問題本文詳細(xì)介紹了在python中selenium模塊的使用方法2021-10-10Python利用psutil實(shí)現(xiàn)獲取硬件,網(wǎng)絡(luò)和進(jìn)程信息
Python?有一個(gè)第三方模塊叫?psutil,專門用來獲取操作系統(tǒng)以及硬件相關(guān)的信息,比如:CPU、磁盤、網(wǎng)絡(luò)、內(nèi)存等等。下面來看一下它的用法2022-07-07詳談python read readline readlines的區(qū)別
下面小編就為大家?guī)硪黄斦刾ython read readline readlines的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09Python實(shí)現(xiàn)破解網(wǎng)站登錄密碼(帶token驗(yàn)證)
這篇文章主要為大家介紹一個(gè)Python暴力破解網(wǎng)站登錄密碼腳本(帶token驗(yàn)證),文中的過程講解詳細(xì),對我們學(xué)習(xí)Python有一定的幫助,感興趣的可以學(xué)習(xí)一下2022-02-02pandas 數(shù)據(jù)歸一化以及行刪除例程的方法
今天小編就為大家分享一篇pandas 數(shù)據(jù)歸一化以及行刪除例程的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-11-11python命令行參數(shù)解析OptionParser類用法實(shí)例
這篇文章主要介紹了python命令行參數(shù)解析OptionParser類用法實(shí)例,需要的朋友可以參考下2014-10-10