從零開始用Python搭建超級簡單的點選率預估模型

點選率預估模型
0.前言
本篇是一個基礎機器學習入門篇文章,幫助我們熟悉機器學習中的神經網路結構與使用。
日常中習慣於使用Python各種成熟的機器學習工具包,例如sklearn、TensorFlow等等,來快速搭建各種各樣的機器學習模型來解決各種業務問題。
本文將從零開始,僅僅利用基礎的numpy庫,使用Python實現一個最簡單的神經網路(或者說是簡易的LR,因為LR就是一個單層的神經網路),解決一個點選率預估的問題。
1.假設一個業務場景
宣告:為了簡單起見,下面的一切設定從簡….
定義需要解決的問題:
老闆:小李,這臺機器上有一批微博的點選日誌資料,你拿去分析一下,然後搞點選率預測啥的…
是的,就是預測一篇微博是否會被使用者點選(被點選的概率)…..預測未來,貌似很神奇的樣子!

熱門微博
簡單的介紹一下加深的業務資料
每一條微博資料有由三部分構成: {微博id, 微博特徵X, 微博點選標誌Y}
微博特徵X有三個維度:
X={x0="該微博有娛樂明星”,x1="該微博有圖”,x2="該微博有表情”}
微博是否被點選過的標誌Y:
Y={y0=“點選”, y1=“未點選”}
資料有了,接下來需要設計一個模型,把資料輸入進去進行訓練之後,在預測階段,只需要輸入{微博id,微博特徵X},模型就會輸出每一個微博id會被點選的概率。
2.任務分析:
這是一個有監督的機器學習任務
對於有監督的機器學習任務,可以簡單的分為分類與迴歸問題,這裡我們簡單的想實現預測一條微博是否會被使用者點選,預測目標是一個二值類別:點選,或者不點選,顯然可以當做一個分類問題。
所以,我們需要搭建一個分類模型(點選率預測模型),這也就決定我們需要構建一個有監督學習的訓練資料集。
模型的選擇
選擇最簡單神經網路模型,人工神經網路有幾種不同型別的神經網路,比如前饋神經網路、卷積神經網路及遞迴神經網路等。本文將以簡單的前饋或感知神經網路為例,這種型別的人工神經網路是直接從前到後傳遞資料的,簡稱前向傳播過程。
3.資料準備:
整體的流程:
資料預處理(數值化編碼)——>特徵篩選——>選擇模型(前饋神經網路)——>訓練模型——>模型預測
假設,對4條微博的資料進行數值化編碼,可以表示為如下的矩陣格式:

訓練資料XY
第一條樣本資料為:X0=[0 0 1],分別對應著三維的特徵,最後4x1的矩陣是Y,0表示無,1表示有,可知該特徵對應的Y0是未點選。
所以,這條樣本可以翻譯為:[該微博沒娛樂明星,沒有圖片,有表情],最終y=0,代表該條微博沒有被點選。
業務以及資料特徵是不是很簡單….簡單有點看起來編的不太合理 - !
4.神經網路基本結構:
1.輸入層:輸入的業務特徵資料
2.隱藏層:初始化權重引數
3.啟用函式:選擇啟用函式
4.輸出層:預測的目標,定義損失函式
我們即將使用的機器學習模型:

超級簡單的前饋神經網路
機器學習模型類似一個黑盒子,輸入歷史點選的資料,進行訓練,然後就可以對未來的額資料進行預測….我們上面設計的是一個超級簡單的前饋神經網路,但是可以實現我們上面的目的。
關於啟用函式:
通過引入啟用函式,實現了非線性變換,增強了模型的擬合效果。
關乎啟用函式,請看之前的文章 ofollow,noindex">吾愛NLP(2)--解析深度學習中的啟用函式
在本文教程中,使用的是簡單的Sigmoid啟用函式,但注意一點,在深層神經網路模型中, sigmoid啟用函式一般不作為首選,原因是其易發生梯度彌散現象。

sigmoid公式
此函式可以將任何值對映到0到1之間,並能幫助我們規範化輸入的加權和。

sigmoid影象
對sigmoid啟用函式求偏導:

該偏導函式嗎,等下寫程式會用到,所以先放在這裡!
模型的訓練
訓練階段,模型的輸入X已經確定,輸出層的Y確定,機器學習模型確定,唯一需要求解的就是模型中的權重W,這就是訓練階段的目標。
主要由三個核心的流程構成:
前向計算—>計算損失函式—>反向傳播
本文使用的模型是最簡單的前饋神經網路,起始就是一個LR而已….所以整個過程這裡就不繼續介紹了,因為之前已經寫過一篇關於LR的文章--- 邏輯迴歸(LR)個人學習總結篇 ,如果對其中的細節以及公式的推導有疑問,可以去LR文章裡面去尋找答案。
這裡再提一下權重引數W更新的公式:

至此,所有的寫程式碼需要的細節都已經交代結束了,剩下的就是程式碼了。
5.使用Python程式碼構建網路
# coding:utf-8 import numpy as np class NeuralNetwork(): # 隨機初始化權重 def __init__(self): np.random.seed(1) self.synaptic_weights = 2 * np.random.random((3, 1)) - 1 # 定義啟用函式:這裡使用sigmoid def sigmoid(self, x): return 1 / (1 + np.exp(-x)) #計算Sigmoid函式的偏導數 def sigmoid_derivative(self, x): return x * (1 - x) # 訓練模型 def train(self, training_inputs, training_outputs,learn_rate, training_iterations): # 迭代訓練 for iteration in range(training_iterations): #前向計算 output = self.think(training_inputs) # 計算誤差 error = training_outputs - output # 反向傳播-BP-微調權重 adjustments = np.dot(training_inputs.T, error * self.sigmoid_derivative(output)) self.synaptic_weights += learn_rate*adjustments def think(self, inputs): # 輸入通過網路得到輸出 # 轉化為浮點型資料型別 inputs = inputs.astype(float) output = self.sigmoid(np.dot(inputs, self.synaptic_weights)) return output if __name__ == "__main__": # 初始化前饋神經網路類 neural_network = NeuralNetwork() print "隨機初始化的權重矩陣W" print neural_network.synaptic_weights # 模擬訓練資料X train_data=[[0,0,1], [1,1,1], [1,0,1], [0,1,1]] training_inputs = np.array(train_data) # 模擬訓練資料Y training_outputs = np.array([[0,1,1,0]]).T # 定義模型的引數: # 引數學習率 learn_rate=0.1 # 模型迭代的次數 epoch=150000 neural_network.train(training_inputs, training_outputs, learn_rate, epoch) print "迭代計算之後權重矩陣W: " print neural_network.synaptic_weights # 模擬需要預測的資料X pre_data=[0,0,1] # 使用訓練的模型預測該微博被點選的概率 print "該微博被點選的概率:" print neural_network.think(np.array(pre_data)) """ 終端輸出的結果: 隨機初始化的權重矩陣W [[-0.16595599] [ 0.44064899] [-0.99977125]] 迭代計算之後權重矩陣W: [[12.41691302] [-0.20410552] [-6.00463275]] 該微博被點選的概率: [0.00246122] [Finished in 20.2s] """
6.總結:
根據終端輸出的模型訓練以及預測的結果,針對預測資料pre_data=[0,0,1],模型輸出該微博被點選的概率為0.00246,很顯然被點選的概率比較小,可以認為簡單認為該微博不會被點選!
是的,我們的業務目標初步實現了----輸入任意一條微博的樣本資料到我們的機器學習模型中,既可以輸出該樣本被點選的概率。
上面的就是我們設計的一個超級簡單的模型,假設了一個超級簡單的業務場景,並隨機設定了超簡單的訓練資料,如果有 編 的不合理地方多多包涵!!!該例子雖然可能並不能幫你解決實際的業務問題,但是對於機器學習的新手理解神經網路,或許會有一點點幫助吧!