用Python搭建简单的神经网络预估模型

前言


本篇是一个基础机器学习入门篇文章,帮助我们熟悉机器学习中的神经网络结构与使用。

日常中习惯于使用Python各种成熟的机器学习工具包,例如sklearn、TensorFlow等等,来快速搭建各种各样的机器学习模型来解决各种业务问题。

本文将从零开始,仅仅利用基础的numpy库,使用Python实现一个最简单的神经网络(或者说是简易的LR,因为LR就是一个单层的神经网络),解决一个点击率预估的问题。

假设业务场景


定义需要解决的问题:
老板:X1uq1n9,这台机器上有一批微博的点击日志数据,你拿去分析一下,然后搞点击率预测啥的…

是的,就是预测一篇微博是否会被用户点击(被点击的概率)…..预测未来,貌似很神奇的样子!

简单的介绍一下加深的业务数据
每一条微博数据有由三部分构成:{微博id, 微博特征X, 微博点击标志Y}

微博特征X有三个维度:
X={x0="该微博有娱乐明星”,x1="该微博有图”,x2="该微博有表情”}

微博是否被点击过的标志Y:
Y={y0=“点击”, y1=“未点击”}

数据有了,接下来需要设计一个模型,把数据输入进去进行训练之后,在预测阶段,只需要输入{微博id,微博特征X},模型就会输出每一个微博id会被点击的概率。

任务分析


这是一个有监督的机器学习任务

对于有监督的机器学习任务,可以简单的分为分类与回归问题,这里我们简单的想实现预测一条微博是否会被用户点击,预测目标是一个二值类别:点击,或者不点击,显然可以当做一个分类问题。

所以,我们需要搭建一个分类模型(点击率预测模型),这也就决定我们需要构建一个有监督学习的训练数据集。

模型的选择


选择最简单神经网络模型,人工神经网络有几种不同类型的神经网络,比如前馈神经网络、卷积神经网络及递归神经网络等。本文将以简单的前馈或感知神经网络为例,这种类型的人工神经网络是直接从前到后传递数据的,简称前向传播过程。

数据准备


整体的流程:

数据预处理(数值化编码)——>特征筛选——>选择模型(前馈神经网络)——>训练模型——>模型预测

假设,对4条微博的数据进行数值化编码,可以表示为如下的矩阵格式:

解读一条样本数据:

第一条样本数据为:X0=[0 0 1],分别对应着三维的特征,最后4x1的矩阵是Y,0表示无,1表示有,可知该特征对应的Y0是未点击。

所以,这条样本可以翻译为:[该微博没娱乐明星,没有图片,有表情],最终y=0,代表该条微博没有被点击。

神经网络基本结构


1.输入层:输入的业务特征数据
2.隐藏层:初始化权重参数
3.激活函数:选择激活函数
4.输出层:预测的目标,定义损失函数

我们即将使用的机器学习模型:

机器学习模型类似一个黑盒子,输入历史点击的数据,进行训练,然后就可以对未来的额数据进行预测….我们上面设计的是一个超级简单的前馈神经网络,但是可以实现我们上面的目的。

关于激活函数:

通过引入激活函数,实现了非线性变换,增强了模型的拟合效果。

在本文中,使用的是简单的Sigmoid激活函数,但注意一点,在深层神经网络模型中, sigmoid激活函数一般不作为首选,原因是其易发生梯度弥散现象。

Sigmoid

此函数可以将任何值映射到0到1之间,并能帮助我们规范化输入的加权和。

对sigmoid激活函数求偏导:

该偏导函数吗,等下写程序会用到,所以先放在这里!

模型的训练

训练阶段,模型的输入X已经确定,输出层的Y确定,机器学习模型确定,唯一需要求解的就是模型中的权重W,这就是训练阶段的目标。

主要由三个核心的流程构成:

前向计算—>计算损失函数—>反向传播

这里再提一下权重参数W更新的公式:

至此,所有的写代码需要的细节都已经交代结束了,剩下的就是代码了。

使用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 "Initialized weight matrix 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
    # print training_outputs 
    # 定义模型的参数:
    # 参数学习率
    learn_rate=0.1
    # 模型迭代的次数
    epoch=150000
    neural_network.train(training_inputs, training_outputs, learn_rate, epoch) 
    print "Weight matrix after calculation W: "
    print neural_network.synaptic_weights
    # 模拟需要预测的数据X
    pre_data=[1,0,0]
    # 使用训练的模型预测该微博被点击的概率
    print "Probability: "
    print neural_network.think(np.array(pre_data))

最终输出结果:

Initialized weight matrix W:
[[-0.16595599]
[ 0.44064899]
[-0.99977125]]
Weight matrix after calculation W:
[[10.08717036]
[-0.20694058]
[-4.83746674]]
Probability:
[0.99995839]

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇