1.2-自然语言的分布式表示-基于计数的方法

  • 本篇笔记对应的视频链接为:
    • 3-基于计数的方法表示单词-将文字转换成编号的预处理工作_哔哩哔哩_bilibili;
    • 4-基于计数的方法表示单词-使用共现矩阵进行单词的分布式表示_哔哩哔哩_bilibili;
    • 5-基于计数的方法表示单词-单词之间相似度计算_哔哩哔哩_bilibili;
    • 6-基于计数的方法表示单词-计算点互信息_哔哩哔哩_bilibili;
    • 7-基于计数的方法表示单词-降维_哔哩哔哩_bilibili;
    • 8-基于计数的方法表示单词-在PTB数据集上对单词进行评价_哔哩哔哩_bilibili;

0比较

同义词词典是人为构建了一个词典,然后我们基于这个词典进行一些查询,相似度的计算等操作

这里基于计数的方法开始,纯粹是使用语料库,即一些自然语言,无需手动构建词典, 采用统计的方法,对语料库中的单词进行相关统计。

1语料库的预处理

  • 自然语言的分布式表示之前说到它是要将单词进行向量化,在实际进行向量化之前,需要对自然语言的语料库进行一些处理,主要包括:

    • 分词
    • 构建单词与单词索引的映射
  • 这里就和书上保持一致, 仅仅使用一条句子作为语料库:

    • text="you say goodbye and I say hello."
      

1.1分词

  1. 单词的大小写不影响单词本身的含义,因此这里首先将语料库中的单词全部小写化。
  2. 在真实的语料库中肯定不只有一个句子,因此每一个句子的句号不能省略。为了将句号也进行分割,这里首先在句号和最后一个单词中间插入一个空格,以保证句号能够被分词。
  3. 然后使用非常直接的方式,即直接以空格进行划分。将一个句子拆分成一个一个单词。
text = text.lower()
print('text.lower():', text)
text = text.replace('.', ' .')
print('text.replace.:', text)
words = text.split()  # 直接按照空格进行分隔
print('words:', words)

1.2构建单词及其编号之间的映射

  1. 用字典来完成

  2. # 构建单词及其编号之间的映射
    word_to_id = {}  # word是关键字
    id_to_word = {}  # id是关键字
    for word in words:if word not in word_to_id.keys():new_id = len(word_to_id.keys())word_to_id[word] = new_idid_to_word[new_id] = wordprint('word_to_id:', word_to_id)
    print('id_to_word:', id_to_word)
    
  3. 封装成预处理函数

2分布式表示的概念

  1. 将单词转换成一个向量,这个向量是固定长度的,这个向量能够一定程度上反映单词的含义
  2. 一个例子就是颜色的例子,使用RGB三种颜色来表示各种各样的颜色组合,因此在向量化之后,只需要一个三维的向量,通过改变每一个维度的元素值来反映不同的颜色

3分布式假设

  1. 一个单词的含义,由他周围的单词形成;即 如果一个单词是孤零零的,他就不存在有含义这么一说

  2. 上下文: 表示单词周围的一些单词

  3. 上下文的大小称为窗口大小,如果上下文的大小为1,说明,我们只需要去关注这个单词前面和后面的一个单词,以此类推【本书中是左右两边相同数量的单词作为上下文】

    1. 例如如果只看单词之后的一个单词,I drink milk和we drink water,milk和water都是日常喝的东西,那么如果将drink替换成一个我们不认识的单词,那么我们也能够大致猜出来这个单词是什么意思; 因此,我们进行单词的分布式表示也是想要计算机理解这样一个过程

    2. 下图是书上关于上下文的例子

      在这里插入图片描述

4使用共现矩阵对单词进行分布式表示

基于计数的方法:根据指定的上下文的大小,直接对当前单词周围出现了多少次什么样子的单词进行计数;将结果存放到共现矩阵中

  1. 以上面的text="you say goodbye and I say hello."为例构建共现矩阵

  2. 总共包含7个单词,上下文大小设置为1, 计算每个单词的上下文所包含的单词的频数

  3. 例如you和say的上下文单词的频数可以用一个向量表示:

    在这里插入图片描述

    在这里插入图片描述

  4. 共现矩阵的代码实现

  5. def create_co_matrix(corpus, vocab_size, window_size=1):corpus_size = len(corpus)co_matrix = np.zeros((vocab_size, vocab_size), dtype=np.int32)for idx, word_id in enumerate(corpus):# 获取了当前单词for i in range(1, window_size + 1):left_idx = idx - iright_idx = idx + iif left_idx >= 0:left_word_id = corpus[left_idx]co_matrix[word_id, left_word_id] += 1if right_idx < corpus_size:right_word_id = corpus[right_idx]co_matrix[word_id, right_word_id] += 1return co_matrix
    

5基于共现矩阵计算单词相似度

  1. 每一个单词现在都可以用共现矩阵中的一个行向量来表示

  2. 计算向量之间的相似度来表示单词之间的相似度现在成为可能;使用常见的余弦相似度

    在这里插入图片描述

  3. 可能存在某一个单词对应的向量全部为0,此时模长为0,无法计算除法,因此还需要在模长上加一个很小的数(如1e-8);

  4. 向量的模长即为向量的2范数, 当向量的2范数不为零时,这个很小的数会被范数给吸收掉,简单理解就是这个微小的数可以忽略不计

  5. 涉及到的函数

    1. np.sum()
      np.dot()
      np.sqrt()
      
  6. 实际在计算相似度时,是先对每个向量进行规范化(即除以它的2范数);无论是按照公式来计算还是使用这个方式来算,结果都是一样的

    1. 向量的规范化是一种将向量缩放到单位长度的过程;因此将上面相似度公式的x和y拆开看,就是先对x和y进行规范化(如下图所示,除以模长之后的向量变成了单位长度),然后再执行向量点积的操作

      在这里插入图片描述

def cos_similarity(x:np.ndarray, y:np.ndarray, eps=1e-8):nx = x / (np.sqrt(np.sum(x ** 2)) + eps) # 规范化之后的xny = y / (np.sqrt(np.sum(y ** 2)) + eps)return np.dot(nx, ny)def cos_similarity2(x, y, eps=1e-8):ret = np.dot(x, y)return ret / ((np.sqrt(np.sum(x ** 2)) + eps) * (np.sqrt(np.sum(y ** 2)) + eps))

6给单词相似度排序

给定一个单词,计算其他单词与这个单词的相似度,然后输出与这个单词最相似的前几个单词及其相似度

  1. 实现思路
    1. 取出查询词的单词向量
    2. 分别求得查询词的单词向量和其他所有单词向量的余弦相似度
    3. 基于余弦相似度的结果,按降序显示它们的值
  2. 取出查询词的单词向量时,需要先判断这个单词是否存在
  3. 排序时书上用到了argsort()函数:对numpy数组升序排序,且返回的是升序排序的索引,不是数组的元素
    1. argsort()函数不改变数组本身的值,只是返回一个排序后的下标的数组

7改进之点互信息

7.1基于计数方法的问题分析

  • 计数方法基于共现矩阵,每个元素表示一个单词出现在了另一个单词的上下文中
  • 对于冠词the,他会经常出现在car前面;而drive car是一个比较固定搭配的短语,但是drive不一定要drive car,所以drive和car共现的次数会比the、car共现的次数低,就造成the和car对应的单词向量更相似,即模型会判断出the和car的相关性更强,这显然是不太符合直觉的

7.2点互信息

  1. 点互信息:pointwise mutual information,简称PMI,公式如下:

    在这里插入图片描述

    1. 其中, x x x y y y表示随机变量, P ( x ) P(x) P(x) P ( y ) P(y) P(y)表示 x x x y y y单独出现的概率; P ( x , y ) P(x,y) P(x,y)表示 x x x y y y​共现的概率
    2. PMI值越大,说明越相关
  2. 使用共现矩阵来重写点互信息,公式如下图所示:

    在这里插入图片描述

    1. 其中,共现矩阵表示为 C C C,将单词 x x x y y y的共现次数表示为 C ( x , y ) C(x,y) C(x,y),将单词 x x x y y y的出现次数分别表示为 C ( x ) C(x) C(x) C ( y ) C(y) C(y),将语料库的单词数量记为 N N N
    2. 关于 C ( x ) C(x) C(x) C ( y ) C(y) C(y)的计算方法
      1. C ( x ) = ∑ i C ( i , x ) \boldsymbol{C}(x)=\sum_i\boldsymbol{C}(i,x) C(x)=iC(i,x) C ( y ) = ∑ i C ( i , y ) \boldsymbol{C}(y)=\sum_i\boldsymbol{C}(i,y) C(y)=iC(i,y)​;
      2. 即共现矩阵对应的单词所在列的次数和(不是行是因为行表示某个单词上下文中出现的其他单词,不能用来表示这个单词出现的次数,可结合共现矩阵的示例来看)
    3. 关于单词数量记为 N N N:统计时应该是不去重的,毕竟之后要统计 C ( x ) C(x) C(x)​;
      1. 本书中 N = ∑ i ∑ j C ( i , j ) N=\sum_i\sum_j\boldsymbol{C}(i,j) N=ijC(i,j)​;即共现矩阵中所有元素的和;
      2. 因为共现矩阵对应的单词所在列的次数和表示这个单词出现的次数,因此把所有的列的和加在一起就得到总的单词数量
    4. 以上 N N N C ( x ) C(x) C(x) C ( y ) C(y) C(y)的计算方法都是近似
      1. 因为按列来计算单词单独出现的次数,如果c这个单词夹在a和b之间,上下文大小为1,则计算a和b的单词向量时会两次检测到c,则按列计算c出现的次数时会认为是出现了2次,而实际上在句子中c只出现了1次
      2. 本书这么做,是为了仅从共现矩阵求 PPMI 矩阵
  3. 以点互信息为依据,计算下面的示例:

    在这里插入图片描述

    1. 虽然the和car共现的次数大,但是the单独出现的次数也多,这样分母同样会变大
    2. 这样就不会因为the和car共现次数多而导致结果过大,因为分母牵制了结果的大小
  4. 正的点互信息PPMI

    1. 原因:当两个单词的共现次数为 0 时 log ⁡ 2 0 = − ∞ \log_20=-\infty log20=

    2. 因此,当PMI值为负数时,将其视为0:这样一来,避免了负无穷的情况,同时,就可以将单词间 的相关性表示为大于等于 0 的实数,也比较符合直觉;
      P P M I ( x , y ) = max ⁡ ( 0 , P M I ( x , y ) ) \mathrm{PPMI}(x,y)=\max(0,\mathrm{PMI}(x,y)) \nonumber PPMI(x,y)=max(0,PMI(x,y))

  5. 代码实现

    1. np.zeros_likenp.sum(co_matrix)
      np.sum(co_matrix, axis=0)np.set_printoptions(precision=3) # 设置np数组打印时的有效位数
      

8改进之降维

8.1问题分析

  1. 上述ppmi的改进方法依然是在共现矩阵的基础上进行计算的,能够缓解高频冠词这些看似贡献频率高实则没有意义的问题的出现

  2. 但是既然是在共现矩阵的基础上进一步计算的,那么最终的结果的维度仍然和共现矩阵一样,那么很多单词之间并没有共现,那么在ppmi矩阵中,依然会出现很多0元素,即太稀疏了;如下图所示:

    在这里插入图片描述

  3. 那么随着语料库的增加,这个矩阵的维度会非常大,非常不利于计算机的处理;

  4. 而这矩阵里面很多0元素,表明很多的向量(比如行向量)没有多大意义(因为一行里面含有的非0元素太少了,而且就算有,可能这个非0元素又很小);另外,这样的向量也容易受到噪声影响,稳健性差,具体可以表现为:

    1. 例如,受到噪声的影响,原先 C ( x , y ) = 0 C(x,y)=0 C(x,y)=0的现在大于0了,那么分子 C ( x , y ) ∗ N C(x,y)*N C(x,y)N就不再是0,而且还突然变得挺大的,根据对数函数曲线,对数值会有一定的增长;并且,看上图中ppmi矩阵中的值,如果因为噪声导致原先元素值从0变突然变成2.807355,这个变动还是比较大的;

      在这里插入图片描述

  5. 因此,面对如此多的0元素,就有了接下来的降维

8.2基于奇异值分解对向量进行降维

8.2.1降维的理解

  1. 从字面意思来说,降维就是减少向量维度,但又不是直接减少一些列(因为对于某一列,他不是全为0,他对有的单词有作用,对有些单词没有作用)

  2. 降维的准则是保留重要信息的基础上使维度减少

  3. 以书上二维的数据为例,这些数据可视化之后其实都是分布在一个新的轴上的,因此将这些数据投影到一个新的轴上之后,维度从2变为1,但是仍然可以用一个轴来表示这些数据的分布差异

    在这里插入图片描述

  4. 多维数据也是基于这样的思想,只是随着维度的增加,我们无法像二维三维这样直观的进行展现。

8.2.2奇异值分解的简单理解

  1. 详细的理解需要深入学习奇异值分解;这里只是在书中解释的基础上稍微进一步解释了一下
  1. 对于矩阵A,经过奇异值分解,得到

    在这里插入图片描述

    1. U可以作为词的密集表示;U是正交矩阵,每个列向量都是正交的,即互不相干,可以用作基向量,来表示其他的向量;可以将U理解为词在奇异值分解后的新空间中的坐标,即U的每一行表示一个单词在每个列(轴)上的坐标;
    2. 对角阵的对角元素(奇异值)可以作为不同成分(或者说不同轴、不同列向量)的权重;
    3. 一般用U乘上对角阵来表示词的密集向量表示;而且是选择前k个较大的奇异值以及U中对应的前k个列向量,这样就起到了维度降低的效果;本书上应该是为了简单分析而直接用U来代表词;
  2. 代码实现就很简单了,直接调用对应的奇异值分解函数,然后直接选择U作为词的表示;

    1. # 计算svd
      U,S,V=np.linalg.svd(ppmi)# 在对应坐标位置上标注单词文本
      plt.annotate(word,(U[word_id,0],U[word_id,1]))
      # 画散点图
      plt.scatter(U[:,0],U[:,1],alpha=0.5) # alpha表示透明度
      
    2. 计算完之后进行可视化,如下图所示;可以看到密集向量表示减少了维度,但同时还是可以反映单词分布的差异:goodbyehello位置较近,youi位置更近;

      在这里插入图片描述

9在PTB数据集中进行上述过程

代码详见:pycharmProject/nlp/3-使用PTB数据集计算单词的密集表示.py

9.1 PTB数据集准备

  1. 主要包括数据集的下载、单词ID列表的构建、词汇表(单词与ID之间的映射字典)的构建
  2. 这里只对训练数据部分进行上述几个内容的构建
  1. 一些值得记录的知识

    dataset_dir = os.path.dirname(os.path.abspath(__file__)) # 获取当前文件所在目录
    if os.path.exists(file_path): # 判断文件是否存在# 从指定的 URL 下载文件并保存到本地路径;如果文件不存在则创建;
    # 注意这里会自动创建文件,但是文件之前的目录必须都是存在的
    urllib.request.urlretrieve(url_base + file_name, file_path)# open方法直接读取文本文件全部内容
    words = open(file_path).read().replace('\n', '<eos>').strip().split()  # words就是单词列表# numpy存储和读取数组
    corpus = np.array([word_to_id[w] for w in words])
    np.save(save_path, corpus)
    corpus = np.load(save_path)# pickle包进行文件的写和读
    with open(vocab_path, 'rb') as f:# 二进制读模式word_to_id, id_to_word = pickle.load(f)
    # 以二进制写的方式写入到本地文件
    with open(vocab_path, 'wb') as f:# 将数据序列化并保存到文件中pickle.dump((word_to_id, id_to_word), f)
    
  2. 关于pickle的一个简单介绍:

    在这里插入图片描述

9.2基于PTB数据集的评价

包括构建共现矩阵、ppmi矩阵、SVD降维得到单词的密集向量表示、基于向量表示计算单词间相似度

  1. 共现矩阵、 ppmi矩阵、相似度计算的代码都来自前面的叙述;

  2. 这里只是将SVD计算方法换成了更快地randomized_svd

    1. 该方法通过使用了随机数的 Truncated SVD,仅对奇异值较大的部分进行 计算,计算速度比常规的 SVD 快;
    2. 需要安装sklearn机器学习包
    3. 关于该函数的参数的简单介绍详见代码中
  3. 计算出单词的密集向量表示后,遵照书上的过程,计算了几个单词最相似的单词列表,如下图所示:

    1. 与书上结果不完全相同,因为SVD分解时random_state=None,所以每次结果不一样
    2. 但是最终的结论还是相似的:
      1. 对于you,i、anybody、we都是与之比较相似的;这符合常理;
      2. 对于year,month、quarter等也比较相似;

    在这里插入图片描述

10总结

  • 以上就是对单词进行密集向量表示,然后计算单词间相似度的主要过程,可以概括为:
    • 首先创建单词的共现矩阵,将其转化为 PPMI 矩阵,再基于 SVD 降 维以提高稳健性,最后获得每个单词的分布式表示。另外,我们已经确认 过,这样的分布式表示具有在含义或语法上相似的单词在向量空间上位置相 近的性质,因为从计算与每个单词最相似的单词有哪些的过程可以证实这一点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/25146.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络 —— 网络层(CIDR)

计算机网络 —— 网络层&#xff08;CIDR&#xff09; CIDR的提出背景什么是CIDR基本概念划分示例应用优势 举个例子路由聚合常用数字 我们今天来看IPv4地址划分的另一种方法 —— CIDR。 CIDR的提出背景 CIDR&#xff08;无类域间路由&#xff0c;Classless Inter-Domain Ro…

大众汽车裁员加速,38万元遣散费起步

导语 大家好&#xff0c;我是社长&#xff0c;老K。专注分享智能制造和智能仓储物流等内容。 新书《智能物流系统构成与技术实践》 几周前&#xff0c;大众汽车宣布了一项新的裁员计划。 一、裁员行动与额外福利并行 大众汽车近期在裁员行动上取得了显著进展&#xff0c;其遣散…

深度解析:AI Prompt 提示词工程的兴起、争议与未来发展

PART1: 提示词工程的兴起 在人工智能领域中&#xff0c;一个新的领域——提示词工程&#xff08;prompt engineering&#xff09;——开始显露头角。 这个领域的核心在于精心设计输入&#xff0c;以引导AI模型产生特定的、期望的输出。 随着AI技术的飞速发展&#xff0c;特别…

无头+单向+非循环链表的实现

这里写目录标题 1. 链表1.1 链表的概念及结构1.2 链表的分类 2. 接口实现3. 链表的实现3.1 打印链表3.2 头插3.3 尾插3.4 头删3.5 尾删3.6 单链表查找3.7 在pos之前插入3.8 在pos之后插入3.9 删除pos位置的值3.10 删除pos位置之后的值3.11 链表的释放3.12 动态申请一个节点 4. …

《精通ChatGPT:从入门到大师的Prompt指南》第11章:Prompt与AI的未来

第11章&#xff1a;Prompt与AI的未来 11.1 技术发展的新方向 在迅速发展的人工智能领域&#xff0c;Prompt工程作为与AI模型交互的核心方式&#xff0c;正处于技术创新的前沿。未来几年&#xff0c;Prompt工程将沿着多个新方向发展&#xff0c;这些方向不仅会改变我们与AI互动…

Transformer学习之SwinTransformer

1.算法简介 本文主要参考自以下链接&#xff0c;整理成线上的形式用于备忘&#xff0c;排版太麻烦了直接贴图&#xff0c;参考的朋友慎重&#xff0c;不如直接看参考链接&#xff0c;后期有了新的理解继续更正。 参考链接1&#xff1a;Swin-Transformer网络结构详解_swin tran…

【文件导出2】导出html文件数据

导出html文件数据 文章目录 导出html文件数据前言一、实现代码1.controller层2.接口层3.接口实现类4.FileUtil 工具类 二、文件导出效果总结 前言 springBoot项目实现在线导出html文件数据的功能。 一、实现代码 1.controller层 GetMapping("/record/_export") Ap…

Flutter中同步与异步

一&#xff0c;同步/异步的理解 1&#xff0c;await&#xff1a;同步机制 同步操作会阻止其他操作执行&#xff0c;直到完成为止。同步就好比打电话一样&#xff0c;打电话时都是一个人在说另一个人听&#xff0c;一个人在说的时候另一个人等待&#xff0c;等另一个人说完后再…

【Git】远程操作 -- 详解

一、理解分布式版本控制系统 我们目前所说的所有内容&#xff08;工作区、暂存区、版本库等等&#xff09;都是在本地&#xff0c;也就是在我们的笔记本或者计算机上。而我们的 Git 其实是分布式版本控制系统。 上面这段话是什么意思呢&#xff1f; 可以简单理解为&#xff1…

USB (2)

USB transaction 以2.0的枚举过程为例。 首先是TOKEN TRANSACTION&#xff0c;其次是DATA TRANSACTION&#xff0c;再次是Handshake Transaction。 上面的SETUP TRANSACTION是TOKEN TRANSACTION的一种。另外三种是OUT, IN, SOF。 在每个TRANSACTION中又包含了3个STAGE&#x…

如何在恢复出厂设置后从 Android 恢复照片

在某些情况下&#xff0c;您可能会考虑将 Android 设备恢复出厂设置。需要注意的是&#xff0c;恢复出厂设置后&#xff0c;所有设置、用户数据甚至应用程序数据都将被清除。因此&#xff0c;如果您将 Android 设备恢复出厂设置&#xff0c;甚至在里面留下了一些珍贵的照片&…

java判断对象是否还在被引用

1、代码取消强引用后&#xff0c;gc回收对象 public static void main(String[] args) {Object obj new Object();WeakReference<Object> weakRef new WeakReference<>(obj);System.out.println(weakRef.get());obj null; // 取消强引用,后续gc会被回收,如果不…

1.基于-LABVIEW的自动售卖机开发(前面板)

1.项目简介 随着科技的进步和人们生活节奏的加快&#xff0c;自动售卖机在日常生活中扮演着越来越重要的角色。它们不仅提高了商品购买的便捷性&#xff0c;还节省了人力成本。为了实现更加智能化和高效的售卖服务&#xff0c;本项目旨在开发一款基于LabVIEW平台的自动售卖机系…

SpringBoot+Vue免税商品优选购物商城(前后端分离)

技术栈 JavaSpringBootMavenMySQLMyBatisVueShiroElement-UI 角色对应功能 用户商家 功能截图

Mysql学习(六)——函数

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 三、函数3.1 字符串函数3.2 数值函数3.3 日期函数3.4 流程函数 三、函数 函数是指一段可以直接被另一段程序调用的程序或代码。 3.1 字符串函数 MySQL中内置了很…

论文浅尝 | THINK-ON-GRAPH:基于知识图谱的深层次且可靠的大语言模型推理方法...

笔记整理&#xff1a;刘佳俊&#xff0c;东南大学硕士&#xff0c;研究方向为知识图谱 链接&#xff1a;https://arxiv.org/pdf/2307.07697.pdf 1. 动机 本文是IDEA研究院的工作&#xff0c;这篇工作将知识图谱的和大语言模型推理进行了结合&#xff0c;在每一步图推理中利用大…

[图解]建模相关的基础知识-06

1 00:00:00,790 --> 00:00:03,480 下一个概念&#xff0c;就是基数的概念 2 00:00:04,390 --> 00:00:11,560 cardinality&#xff0c;表示有限集合中元素的数量 3 00:00:12,200 --> 00:00:14,790 我们可以用一个井号 4 00:00:14,800 --> 00:00:18,320 在前面表示…

数据结构--递归和数组

个人介绍 hello hello~ &#xff0c;这里是 code袁~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的…

10.邮票问题

上海市计算机学会竞赛平台 | YACSYACS 是由上海市计算机学会于2019年发起的活动,旨在激发青少年对学习人工智能与算法设计的热情与兴趣,提升青少年科学素养,引导青少年投身创新发现和科研实践活动。https://www.iai.sh.cn/problem/625 题目描述 有四种面值的邮票,分别是 …

使用 Django 创建 App

文章目录 步骤 1&#xff1a;创建 Django 项目步骤 2&#xff1a;创建 App步骤 3&#xff1a;配置 App步骤 4&#xff1a;编写代码步骤 5&#xff1a;运行服务器 在 Django 中&#xff0c;App 是组织代码的基本单元&#xff0c;它可以包含模型、视图、模板等组件&#xff0c;帮…