花书解读与实现——第一章(1-19页)

花书即Deep-Learning,我的代码都是半吊子学的,准备靠它系统的整理我的知识点,第一章属于引言部分,但还有一些有用的知识点,我整理出来。(所有标题均为书籍上对应标题)

书中内容用黑字标识自己理解与解读用红字标识

1.2机器学习中的关键组件

 书中原话是:核心组件有可以用于学习的数据;如何转换数据的模型;一个目标函数,用来量化模型的有效性;调整模型参数以优化目标函数的算法

 我自己的理解是:核心组件:数据,模型(算法),算力。   我认为模型就是算法,在机器学习中通过生成预估器使用数据和算法加载模型,算力不光是我们所说的显卡性能,还有廉价的传感器,包括不同算法里对DRAM和SRAM的运算分配;同时与传统机器学习相比,深度学习的一个主要优势是可以处理不同长度的数据

1.3各种机器学习的问题

1.3.1监督学习 

 监督学习擅长在“给定输入特征”的情况下预测标签。每个”特征标签“对应一个样本,给定一组特定的可用数据的情况下,估计未知事物的概率

1.3.1.3标注问题

 学习预测不相互排斥的类别的问题成为多标签分类,比如一篇文章可能会有多个标签,他们彼此之间互不排斥,例如计算机,机器学习,深度学习

1.3.1.4搜索

以网络搜索为例,目标不是简单的”查询“——”网页“分类,而是在海里搜索结果中找到用户最需要的那部分,搜索结果的排序也十分重要,学习算法需要输出有序的元素子集,结果集的顺序也很重要。

该问题的一种解决方案:首先为集合中的每个元素分配对应的相关性评分,然后检索评分最高的元素。PageRank----谷歌搜索引擎背后的最初秘密武器。

PageRank解读

(来自CSDN作者十二月的猫居多,以及其他掘金,youtobe博主)原文链接:https://blog.csdn.net/m0_67656158/article/details/138189702

中心思想 

如何确定网站的重要性,有了重要性就可以根据重要性进行排名。

 PR算法核心就在于:一、量化重要性;二、实际应用简化为理论模型

 一、量化重要性

我们不可能让机器阅读网页的内容,也不可能自己阅读所有网页告诉机器它重不重要

所有网页本身没有重要性,网页重要性靠其他网页提供,所有指向该网页的其他网页,反映该网页的重要性(避开对网页内容的衡量)

 根据三个指标对网页的重要性进行量化

1.数量指标

 当在网页模型图中,一个网页接受到的其他网页指向的入链(in-links)越多,说明该网页越重要。换句话说,越多的网页引用了该网页,那么该网页就越重要(因为它影响力越大)

 2.质量指标

 当一个质量高的网页指向(out-links)一个网页,说明这个被指的网页重要。例如:一个诺贝尔奖的得主说你的网页好,和一个普通人说你的网页好所提供的影响力是不一样的。

3. 稀释指标

假如一个质量很高的网页指向你的网页,但是同时也指向了很多其他的网页,那么此时这个网页能够给你的网页提供的重要性增幅也是有限的,重要性会被稀释掉。因为用户会有百分之十五的概率进入其他网站,用户在浏览时有很大概率会通过这个高质量网站“冲浪”到其他它所指向的网站,而不是你的网站

 二.实际应用简化为理论模型

 

(这部分都引入的原作者的,讲的非常清楚,参考作者十二月的猫居多) 

 PageRank公式

 

  • PR(a):a节点(a网站)的重要性
  • i+1:第i+1次迭代,算法循环次数
  • PR(Ti):指向a节点的其他节点的PR值
  • L(Ti):指向a节点的其他节点的总出链数

1、PR(Ti)就体现了质量指标

2、\sum就体现了数量指标

3、除L(Ti)就体现了稀释指标

  

 具体计算过程(拿一个例子):

 

关键点:

1、一开始要给每个节点初始重要值:1/N(N为节点总数)

2、每一轮都是按顺序给所有节点更新重要值,更新是拿前一轮的值

3、直到所有节点重要值不变为止 

        按照公式定义来计算PR值存在一个问题,就是我们需要一步步自己去迭代实现。拉里佩奇便要思考一个可以实现让计算机自己去一步步计算,最终输出结果的智能算法 

马尔可夫矩阵预测网站的重要度

                      

矩阵关键点:

1、列表示出链:例如第一列就表示A出链到ABCD各个点的概率值

2、行表示入链:例如第一行就表示ABCD入链到A的概率值

 

 

理解关键点:

1、矩阵*向量=矩阵行 *向量 作为结果向量的行

2、联系三个含义:矩阵行的含义,向量的含义,结果向量的含义

PageRank算法存在的问题
PageRank算法主要存在两个问题:一、Dead Ends问题;二、Spider Traps问题。这两个问题都是在特殊情况才会出现,但是一出现便会让我们的佩奇排序算法无法执行

Spider traps问题和Dead ends问题是PageRank算法中两种不同的情况,它们都会影响链接结构的平衡性。具体来说:

Dead ends问题:指的是某些节点没有任何出边,即它们不会将PageRank值传递给其他页面。这会导致这些页面积累较高的PageRank值,因为它们只接收来自其他页面的值而不向外传递。
Spider traps问题:是指一些网页故意设计成只有入链而几乎没有或没有出链,有时还包含指向自己的链接,即自环。这种结构会导致PageRank值在这些“陷阱”网页上积累,使得它们获得异常高的排名,从而影响整个网络的链接结构。

一、Dead Ends问题

问题描述

在多次迭代后,所有网站的重要性都转变为0

 

 

出现原因及解释
原因:由于网络中某些节点没有指向其他节点的出链,导致链接结构中断

解释:

        1、利用佩奇算法确定网站的重要性可以理解为:让一个小虫子在网站间不停且随机地爬,它爬到哪个网站的次数最多,则这个网站的重要性就越高

        2、此时假如其中一个网站没有出链,那么当小虫子爬到该网站时便无法离开,此时其他网站就无法被小虫子爬到,因此重要性都会迭代为0。最后由于该网站本身也是依靠其他网站的重要性来确定自身重要性的,所以该网站的重要性也将变为0,即虫子无法运动导致爬虫死亡

 使用马尔科夫矩阵快速计算PR值

 

解决方法:Teleport

        既然问题出现的原因是存在一个没有出链的网站,那么我们在PageRank算法执行前对有向图矩阵进行检查。如果存在这种不合要求的有向图矩阵,那么我们便执行下面的操作:

 

 

关键点:

1、 引入了“传送”(teleport)机制。当冲浪者遇到一个没有出链的页面时,1/n的概率随机跳转到任意一个页面(假设总共能跳转的页面有n个)(其实相当于加了一个阻尼,百分之十五的概率让他跳转出下一个,异曲同工)

二、Spider Traps问题

 Spider traps问题是PageRank算法中的一种现象,它指的是某些网页故意设计成只有入链以及指向自己的出链,即自环,以此来提升网页的重要性

出现原因及解释
原因:网页只有入链以及指向自己的出链

解释:

        1、利用佩奇算法确定网站的重要性可以理解为:让一个小虫子在网站间不停且随机地爬,它爬到哪个网站的次数最多,则这个网站的重要性就越高

        2、当出现这种问题,小虫子走到Traps节点时,由于该节点没有出链只有自环。所有小虫子会在这个节点不停的循环走,这就会导致该节点的重要性不停提高直到1,而其他节点的重要性降低到0

图解示例

 解决方法

 

 

1、选择概率\beta为跟随出链,正确打开网页的概率。1- \beta为随机打开网页的概率 

2、按照概率\beta加权分配这个概率矩阵

PageRank算法问题解决总结

1、两个问题的解决都利用:修正M矩阵

2、前者直接加上修正矩阵,使得不存在全为0的列即可

3、后者需要对M矩阵进行等比例缩小,再加上加权处理后的修正矩阵。如此,才能让矩阵中不再存在为1的值

4、Spider Traps的解决方法不可以用于Dead ends。原因如下:

5、 Dead ends的解决方法不能用于Spider Traps,原因是直接加上一个矩阵,Spider Traps为1的值仍然无法解决

6、两个方法的限制点:a. 列之和为1;b. 不能存在为1的值

7、值越大表明按照链接正常跳转的概率越大,这也意味这爬虫的移动会在相邻节点间进行,模型收敛速度变慢;反之值越少,随机链接访问的概率越大,这样意味着模型各网站的重要性相差越近,模型收敛速度越快

 PageRank代码实现

 导包解决法

import matplotlib.pyplot as plt
import networkx as netx  # 网络图库:生成构造网络图,并对网络图进行各类分析
import random
 
random.seed(42)  # 设置随机数种子,让结果可以复现
diGraph = netx.DiGraph()  # 生成有向图
diGraph.add_nodes_from(range(0, 100))  # range生成一个可迭代对象(迭代器:1、访问工具,本身不是具体的数据类型,可以对各种数据类型进行迭代;2、动态生成值,在每一次运行时动态加载到内存)
for i in range(100):
    j = random.randint(0, 100)
    k = random.randint(0, 100)
    diGraph.add_edge(k, j)
 
# 绘图
netx.draw(diGraph, with_labels=True)
plt.show()
 
# 计算并生成PR值
prValue = netx.pagerank(diGraph, max_iter=500, alpha=0.85)  # 生成的对象是一个字典类型
 
# 对PR值进行排序
prValue_list = list(prValue.items())  # 利用items(视图元组,不是实际元组)将字典转为元组,再用list将元组转为列表(可迭代访问对象)
 
# 使用 sorted() 函数对 prValue_list 进行排序,按照值(即 PageRank 值)从大到小排序
sorted_prValue = sorted(prValue_list, key=lambda x: x[1], reverse=True)
 
print(sorted_prValue)
 

 手搓代码版

 一、随机有向图的生成

import networkx as nx
import matplotlib.pyplot as plt
 
def get_init_pr(dg):
    """
    获得每个节点的初始PR值
    :param dg: 有向图
    """
    nodes_num = dg.number_of_nodes()
    for node in dg.nodes:
        pr = 1 / nodes_num
        dg.add_nodes_from([node], pr=pr)
 
 
def create_network():
    """
    创建有向图
    :return dg: 有向图
    """
    dg = nx.DiGraph()  # 创建有向图
    dg.add_nodes_from(['0', '1', '2', '3', '4'])  # 添加节点
    dg.add_edges_from([('1', '0'), ('2', '1'), ('3', '4'), ('4', '1'), ('3', '1')])  # 添加边
 
    get_init_pr(dg)
 
    return dg
 
 
def draw_network(dg):
    """
    可视化有向图
    :param dg: 有向图
    """
    fig, ax = plt.subplots()
    nx.draw(dg, ax=ax, with_labels=True)
    plt.show()
 

 二、根据有向图生成马尔科夫矩阵

import numpy as np
 
def solve_ranking_leaked(adj_matrix):
    """
    解决Dead Ends问题(也称为排名泄露问题)
    :param adj_matrix: 邻接矩阵
    """
    col_num = np.size(adj_matrix, 1)  # 获得邻接矩阵列数
 
    row_num = 0  # 用来统计矩阵的行数(只有通过出度的问题检查才算)
    for row in adj_matrix:
        # 如果排名泄露,那么修改这个节点对每个节点都有出链
        if sum(row) == 0:  # 这个节点出度为0,表明它存在排名泄露问题
            for col in range(col_num):
                adj_matrix[row_num][col] = 1
        row_num += 1
 
 
def calc_out_degree_ratio(adj_matrix):
    """
    计算每个节点影响力传播的比率,即该节点有多大的概率把影响力传递给下一个节点
    公式:
        out_edge / n
        out_edge: 出边,即这个节点可以把影响力传递给下一个节点
        n: 这个节点共有多少个出度
    :param adj_matrix: 邻接矩阵
    """
    row_num = 0
    for row in adj_matrix:  # 每次都拿出一个行列表
        n = sum(row)  # 求该节点的所有出度
        col_num = 0
        for col in row:
            adj_matrix[row_num][col_num] = col / n  # out_edge / n
            col_num += 1
 
        row_num += 1
 
 
def create_matrix(dg):
    """
    通过有向图生成邻接矩阵
    :param dg: 有向图
    :return adj_matrix: 邻接矩阵
    """
    node_num = dg.number_of_nodes()
 
    adj_matrix = np.zeros((node_num, node_num))
 
    for edge in dg.edges:
        adj_matrix[int(edge[0])][int(edge[1])] = 1
 
    solve_ranking_leaked(adj_matrix)
    calc_out_degree_ratio(adj_matrix)
    # print(adj_matrix)
    return adj_matrix
 
 
def create_pr_vector(dg):
    """
    创建初始PR值的向量
    :param dg: 有向图
    :return pr_vec: 初始PR值向量
    """
    pr_list = []
    nodes = dg.nodes
 
    # 将初始PR值存入列表
    for node in nodes:
        pr_list.append(nodes[node]['pr'])
 
    pr_vec = np.array(pr_list)  # 将列表转换为ndarray对象
 
    return pr_vec

 三、 利用马尔科夫矩阵计算PR值

import numpy as np
import matplotlib.pyplot as plt
 
# 设置阻尼因子(跳转因子)防止Spider traps问题
alpha = 0.85  # 跳转因子
 
 
def draw(iter_list, pr_list):
    """
    绘制收敛图
    :param iter_list: 迭代次数列表
    :param pr_list: 每一个向量的值
    :return:
    """
    plt.plot(iter_list, pr_list)
    plt.show()
 
 
def pagerank(adj_matrix, pr_vec):
    """
    pagerank算法:
        V_{i+1} = alpha * V_i * adj + (1 - alpha) * E/ N
        (这个公式和上文介绍的略有不同,但是这两个是等价的)
         按照上文解决Spider Traps的方法,公式应该为:
                V_{i+1} = (alpha  * adj + ((1 - alpha) / N) * E)* V_i
    收敛条件:
        1. V_{i+1} == V_i
        2. 迭代次数200次
    就是说如果PR向量并没有发生改变,那么收敛结束,得到的PR值就是最终的PR值
    但是假设迭代次数过高后且未发生收敛,那么就会陷入死循环等,根据前人总结的经验,设置为迭代20次
    :param adj_matrix: 邻接矩阵
    :param pr_vec: 每个节点PR值的初始向量
    :return:
    """
    num_nodes = np.size(adj_matrix, 1)  # 获得矩阵列数(ie. 节点数)
    jump_value = (1 - alpha) / num_nodes  # 从其他页面跳转入所在页面的概率(标量)
    jump_vec = jump_value * np.ones(num_nodes)  # 向量化
 
    # iter_list = []
    # pr_list = []
 
    for n_iter in range(1, 201):
        pr_new = alpha * np.dot(pr_vec, adj_matrix) + jump_vec
 
        print("第{0}次迭代的PR值:{1}".format(n_iter, pr_new))
 
        # iter_list.append(n_iter)
        # pr_list.append(tuple(pr_new))
 
        if (pr_new == pr_vec).all():
            break
        # else:
        #     # 调试用
        #     test = pr_new - pr_vec
 
        pr_vec = pr_new
 
    # draw(iter_list, pr_list)
 
    print("迭代完成!")
    print("收敛值为:", pr_vec)

总结
        PageRank 算法是现代数据科学中用于图链接分析的经典方法,最初由LarryPage 和Sergey Brin 在1996年提出。两位斯坦福大学研究生认为互联网上的链接结构能够反映页面的重要性,与当时基于关键词的搜索方法形成对比。这一独特观点不仅赢得了学术界的认可,也为后来创建的Google搜索引擎奠定了基础。

   PageRank的核心思想基于有向图上的随机游走模型,即一阶马尔可夫链。描述了随机游走者如何沿着图的边随机移动,最终收敛到一个平稳分布。在这分布中,每个节点被访问的概率即为其PageRank值,代表节点的重要性。 PageRank是递归定义的,计算需要迭代方法,因为一个页面的值部分取决于链接到它的其他页面的值。尽管最初设计用于互联网页面,但PageRank已广泛应用于社会影响力、文本摘要等多个领域,展示了其在图数据上的强大实用性

 1.3.1.5推荐系统

 推荐系统目标是像用户进行个性化推荐

在某些应用中,用户会明确反馈表达他们对特定产品的喜爱程度,例如评论等等,在其他情况下,用户会提供隐性反馈,比如跳过,不停留,推荐系统会为”给定用户和产品的匹配性打分“,这个分数可能是估计的评级和购买的概率。

尽管推荐系统具有巨大的应用价值,但单纯用它作为预测模型还存在一些缺陷:审查,激励和反馈循环,审查激励:用户给自己感兴趣的数据打分,例如一分,五分较多,三分不打,反馈循环,推荐系统往往会推送一个较好的物品,用户依据算法继续循环,那么会越来越推荐

1.3.1.6聚类问题

 如果输入的样本之间没有任何关系,以上模型完美无缺,但如果输入是连续的,模型可能就需要具有”记忆“功能,语言也是如此,机器翻译的输入输出都是文字序列

(1)标记与解析

一个很简单的示例,它使用”标记“来注释一个句子,该标记指示哪些单词引用命名实体,标记为Ent,是实体(entity)的简写

Tom has dinner in Washington with Sally

Ent -- -- -- Ent -- Ent 

 1.3.2无监督学习

老板可能会给我们一大堆数据,然后要求用它做一些数据科学研究,却对结果没有什么要求

聚类问题:在没有标签的情况下,我们是否能给数据分类呢?比如,给定一组照片,我们能把它们分成风景,狗,婴儿,猫,山峰的照片

主成分分析问题:我们能否找到少量的参数来准确地捕捉数据的线性相关属性

因果关系与概率图模型问题:我们能够简单的地根据经验数据发现它们之间的关系

生成对抗网络:为我们提供一种合成数据的方法,甚至对像图像和音频这样复杂的非结构化数据

1.3.3和环境互动 

不管是监督学习还是无监督学习,我们都会预先获取大量数据,然后启动模型,不在与环境交互,这里的所有学习都是在算法与环境断开后进行的,被称为离线学习

人工智能是”智能代理“,而不仅是”预测模型“

1.3.4 强化学习

如果你对机器学习开发并与环境交互产生兴趣,那么最终可能会专注于强化学习,强化学习框架通用性十分强大,强化学习者必须处理学分分配问题:决定哪些动作是值得奖励的,哪些动作是需要惩罚的,就像一个员工晋升一样,这次晋升很可能反应了该员工的前一年的大量动作,想要在未来获得更多的晋升,就必须清楚这一过程中哪些动作导致晋升。

强化学习智能体必须不断做出选择:是应该利用当前最好策略,还是探索新的策略空间(放弃一些短期奖励来换取知识)

 1.7特点

 深度学习的一个关键优势是,它不仅取代了传统学习管道末端的浅层模型,还取代了劳动密集型的特征工程的过程,消除了以前分隔计算机视觉,语音识别,自然语言处理,医学信息学和其他应用领域的许多边界

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值