Verified Commit 4960bb3f authored by 施乐存's avatar 施乐存
Browse files

论文:视频创作者分析

Signed-off-by: 施乐存's avatarszdytom <szdytom@qq.com>
parent 56c788b9
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -5,3 +5,6 @@ cookies/
__pycache__
cover/
.env
paper/fonts
paper/build
paper/*.pdf
+22 −10
Original line number Diff line number Diff line
[[fonts]]
url = "https://github.com/dse/dse-typewriter-font/archive/3496d1054e5ec51a0301e16a5962b6466234b80e.zip"
url = "https://github.com/notofonts/noto-cjk/releases/download/Serif2.003/09_NotoSerifCJKsc.zip"
patterns = [".otf"]

[[fonts]]
url = "https://github.com/notofonts/noto-cjk/releases/download/Sans2.004/08_NotoSansCJKsc.zip"
patterns = [".otf"]

[[fonts]]
url = "https://github.com/TrionesType/zhuque/releases/download/v0.212/ZhuqueFangsong-v0.212.zip"
patterns = [".ttf"]

[[fonts]]
url = "https://github.com/tonsky/FiraCode/releases/download/6.2/Fira_Code_v6.2.zip"
patterns = [".ttf"]

[[fonts]]
@@ -7,12 +19,12 @@ url = "https://mirrors.ctan.org/fonts/concmath-otf.zip"
patterns = [".otf"]

[typst]
version = "0.13.1"
aarch64-darwin = "https://github.com/typst/typst/releases/download/v0.13.1/typst-aarch64-apple-darwin.tar.xz"
aarch64-windows = "https://github.com/typst/typst/releases/download/v0.13.1/typst-aarch64-pc-windows-msvc.zip"
aarch64-linux = "https://github.com/typst/typst/releases/download/v0.13.1/typst-aarch64-unknown-linux-musl.tar.xz"
armv7-linux = "https://github.com/typst/typst/releases/download/v0.13.1/typst-armv7-unknown-linux-musleabi.tar.xz"
riscv64-linux = "https://github.com/typst/typst/releases/download/v0.13.1/typst-riscv64gc-unknown-linux-gnu.tar.xz"
x86_64-darwin = "https://github.com/typst/typst/releases/download/v0.13.1/typst-x86_64-apple-darwin.tar.xz"
x86_64-windows = "https://github.com/typst/typst/releases/download/v0.13.1/typst-x86_64-pc-windows-msvc.zip"
x86_64-linux = "https://github.com/typst/typst/releases/download/v0.13.1/typst-x86_64-unknown-linux-musl.tar.xz"
version = "0.14.2"
aarch64-darwin = "https://github.com/typst/typst/releases/download/v0.14.2/typst-aarch64-apple-darwin.tar.xz"
aarch64-windows = "https://github.com/typst/typst/releases/download/v0.14.2/typst-aarch64-pc-windows-msvc.zip"
aarch64-linux = "https://github.com/typst/typst/releases/download/v0.14.2/typst-aarch64-unknown-linux-musl.tar.xz"
armv7-linux = "https://github.com/typst/typst/releases/download/v0.14.2/typst-armv7-unknown-linux-musleabi.tar.xz"
riscv64-linux = "https://github.com/typst/typst/releases/download/v0.14.2/typst-riscv64gc-unknown-linux-gnu.tar.xz"
x86_64-darwin = "https://github.com/typst/typst/releases/download/v0.14.2/typst-x86_64-apple-darwin.tar.xz"
x86_64-windows = "https://github.com/typst/typst/releases/download/v0.14.2/typst-x86_64-pc-windows-msvc.zip"
x86_64-linux = "https://github.com/typst/typst/releases/download/v0.14.2/typst-x86_64-unknown-linux-musl.tar.xz"

paper/main.typ

0 → 100644
+116 −0
Original line number Diff line number Diff line
#import "template.typ": font, project, unset-par-indent

#show: project.with(
  "热门视频是怎样炼成的——基于B站“每周必看”的内容生态历时性分析",
)

#v(4em)
#{
  set align(center)
  block[
    #set text(font: font.sans, weight: "semibold")
    #set align(left)
    #show: unset-par-indent
    #set par(spacing: 0.5em)
    #text(2em)[热门视频是怎样炼成的]

    #text(1.5em)[——基于B站“每周必看”的内容生态历时性分析]
  ]
}

#v(2em)

*摘要*:#lorem(50)

#v(2em)

= 引言

#lorem(50)

= 研究方法

本研究采用定量分析与内容分析相结合的方法,对B站“每周必看”栏目进行历时性研究。研究流程分为数据收集、数据处理和数据分析三个主要阶段。

== 数据收集与数据库构建

数据来源于 Bilibili 官方网页端应用程序所使用的未公开 API,这些 API 由“哔哩哔哩 - API 收集整理”@Bilibili_API_collect 项目通过逆向工程获得。过自主编写的爬虫程序系统收集了自20193月至202511月共348期“每周必看”榜单的全部数据。数据存储采用SQLite关系型数据库,共计收集 12725 条视频记录,涵盖包括视频标识(bvid)、所属分区、时长、各项互动数据(播放量、弹幕、评论、点赞、投币、收藏、分享)等多个维度的信息。

另外,为了进一步理解“每周必看”视频的内容特征,我们通过爬虫程序获取了每个视频的封面图像,并使用多模态大语言模型对这些封面进行识别分析 @Qwen_VL @Qwen3_VL,以提取视频的视觉内容的量化特征。

== 数据处理与分析

// TODO: 介绍数据处理方法

进一步,我们使用 Mathematica 对数据的各项统计指标进行计算,并绘制相关图表,以揭示“每周必看”视频在不同时间段内的表现差异和趋势变化。

= 研究结果

== 创作者分析

基于B"每周必看"榜单的UP主#footnote[UP主:取自英文单词 Uploader,是 B 站社区对视频创作者的称呼。]数据,本研究发现创作者生态呈现出显著的幂律分布特征与特定的内容策略规律,这些规律对理解"热门视频"的形成机制具有重要启示。

=== 创作者分布的幂律特征

B  UP主的上榜表现呈现出典型的长尾分布模式,如@up-distribution-fig 所示。对UP主上榜次数的频率分布进行幂律拟合,得到拟合函数

$ y = 732 x^(-1.53) $

其中 $x$ 表示UP主的上榜次数,$y$ 表示对应的UP主数量。

#figure(
  image("../up-analysis/up_video_distribution.png"),
  caption: [创作者分布的幂律特征],
) <up-distribution-fig>

拟合指数为 $-1.53$  YouTube 等平台通常观察到的 $-1.2$  $-1.4$ 更为陡峭,表明 B 站内容生态的“头部效应”尤为显著。数据显示,约 $0.2%$  UP 主(上榜 20 次以上)占据了约 $20%$ 的上榜次数,而 $75%$ UP主仅上榜 $1$ 次。这种分布模式反映了B站内容生态的“赢家通吃”特性:每增加一倍的上榜次数,对应UP主数量减少约 $2.9$ 倍,意味着从“偶尔上榜”到“经常上榜”存在明显的跃迁门槛。

#figure(
  image("../up-analysis/up_rank_cumulative.png"),
  caption: [创作者上榜次数的累积分布图],
) <up-rank-cumulative-fig>

累计分布分析(@up-rank-cumulative-fig)进一步揭示,仅 $20%$  UP 主贡献了接近 $80%$ 的上榜视频,凸显了核心创作者群体在内容生产中的主导地位。尽管生态中存在 $27$ 位上榜超过 $20$ 次的"常青UP主"(最高达 $161$ 次),但中间层UP主相对薄弱,$2$  $10$次上榜的UP主数量衰减迅速,表明B站创作者生态呈现"两极分化"结构:大量UP主依赖单次爆款,而极少数UP主能够建立稳定的内容输出机制。

对视频创作者而言,数据说明,只有少量创作者真正把握了“热门视频”的生产规律,形成了持续输出高质量内容的能力,而大多数创作者则难以突破偶然性,缺乏稳定的上榜表现。

对平台管理者而言,这种创作者生态结构高度依赖核心创作者群体,平台应重点扶持这些“头部UP主”,同时探索激励中间层创作者的策略,以促进内容生态的多样化和可持续发展。

=== 分区专注度与成功策略

对频繁上榜 UP 主(上榜频次 $>= 10$)的分析(@up-zone-diversity-fig)显示,其分区专注度分布呈现倒 U 型关系,平均涉猎 $5.91$ 个分区,但中位数仅为 $4$ 个分区,表明少数高分区 UP 主拉高了平均值。具体而言,涉猎 $3$ 个分区的UP主数量最多($34$ 人),$2$ 个分区次之($30$ 人),$4$ 个分区第三($21$ 人),形成明显的"适度多元"最优策略。

#figure(
  image("../up-analysis/up_diversity_distribution.png"),
  caption: [创作者分区专注度分布],
) <up-zone-diversity-fig>

这一分布呈现典型的幂律特征:头部($1$  $8$ 个分区)占总数的 $89.8%$($193$ 人),而尾部($>= 9$ 个分区)仅占 $10.2%$($22$人)。数据表明,超过 $8$ 个分区后 UP 主数量锐减,存在明显的“隐形门槛”。值得注意的是,$3$ 个分区构成“甜蜜点”,这样的“适度多元”策略既避免了过度专一导致的内容局限,又防止了过度分散带来的专业度稀释,集中资源打造核心竞争力,是频繁上榜 UP 主最成功的策略组合。

=== UP主的生态流动性

#figure(
  image("../up-analysis/new_up_ratio.png"),
  caption: [每期“每周必看”榜单中新UP主占比时序分析],
  placement: auto,
) <frac-new-up-plot-fig>

我们进一步研究了每一期“每周必看”榜单中新UP主的占比情况,以评估创作者生态的流动性特征(@frac-new-up-plot-fig)。这里的新 UP 主并不是指首次在 B 站上传视频的创作者,而是指首次进入“每周必看”榜单的 UP 主。由于 2019 年初“每周必看”栏目刚刚上线,前几期榜单中新 UP 主比例较高(首期必然是 $100%$)。

UP主占比的时序分析揭示了 B 站“每周必看”内容生态中持续而稳定的流动性特征。数据显示,尽管平台存在显著的头部效应,但每期仍有约三分之一(中位数 $33.33%$)的上榜UP主是首次进入榜单的新面孔,这一比例在300多期的长期运行中保持相对稳定,表明平台在建立了相对稳定但仍有活力的生态结构。

这种持续的流动性与前述幂律分布特征形成看似矛盾却实际互补的关系:一方面,头部UP主凭借稳定产出占据大量曝光机会;另一方面,平台机制持续为新创作者提供展示窗口。值得注意的是,新UP主比例并未随时间推移而显著下降,这表明"每周必看"栏目并未陷入完全封闭的循环,而是保持了对新兴创作者的开放性。这种"头部稳固、中层流动"的结构,既保证了内容质量的稳定性,又维持了生态的创新活力,为理解B站热门视频的持续生产机制提供了关键视角——热门内容的产生不仅依赖于已建立影响力的创作者,也持续受益于新鲜血液的注入。

=== 创作者生态的结构启示

B 站创作者生态呈现出“头部效应显著、中间层薄弱、新入口开放”的三重特征。虽然马太效应明显,成功 UP 主的护城河深厚,但每年仍有大量新 UP 主首次上榜,表明平台仍保持一定的流动性。与国际平台相比,B站更陡峭的幂律分布($-1.53$)可能反映了中国观众口味的相对集中性、B站推荐算法对头部内容的偏好,以及社区文化中“梗”和“潮流”更易形成共识的特点。

这些发现对理解“热门视频”的形成机制提供了重要视角:成功不仅依赖于单次爆款,更需要在 $2$  $4$ 个相关分区建立持续产出能力;同时,创作者需在专业深度与内容多样性之间找到平衡点,避免过度专一或过度分散。这种“适度多元”策略既符合平台算法偏好,又能满足用户多元化需求,成为频繁上榜UP主的共同成功要素。

== 视频时长与互动表现



#pagebreak()

#bibliography("works.bib", style: "gb-7714-2015-numeric")
+4 −3
Original line number Diff line number Diff line
@@ -174,7 +174,9 @@ def invoke_typst(mode="c", mem_mode=False, input="main.typ"):
		print("Typst executable not found.")
		return False

	command = [str(typst_bin_path), mode, "--root", ".", "--font-path", str(fonts_dir), "--ignore-system-fonts", input]
	PROJECT_DIR = str(Path(__file__).parent.parent.resolve())

	command = [str(typst_bin_path), mode, "--root", PROJECT_DIR, "--font-path", str(fonts_dir), "--ignore-system-fonts", input]
	if mem_mode:
		if platform.system().lower() == "linux":
			command.extend(["/dev/shm/main.pdf"])
@@ -191,7 +193,6 @@ def invoke_typst(mode="c", mem_mode=False, input="main.typ"):

def main():
	parser = argparse.ArgumentParser(description="Run Typst with specified mode.")
	parser.add_argument('input', type=str, help="The Typst file to compile.")
	parser.add_argument('--mode', type=str, choices=['w', 'c'], default='c',
						help="Mode to run Typst: 'w' for watch mode, 'c' for compile mode.")
	parser.add_argument('--mem', action='store_true',
@@ -203,7 +204,7 @@ def main():
	if not prepare_typst():
		return

	invoke_typst(mode=args.mode, mem_mode=args.mem, input=args.input)
	invoke_typst(mode=args.mode, mem_mode=args.mem, input="main.typ")

if __name__ == "__main__":
	main()

paper/template.typ

0 → 100644
+66 −0
Original line number Diff line number Diff line
#let font = (
  "sans": "Noto Sans CJK SC",
  "serif": "Noto Serif CJK SC",
  "mono": "Fira Code",
  "math": "Concrete Math",
  "fangsong": "Zhuque Fangsong (technical preview)",
)

#let project(title, body) = {
  set document(title: title, author: "施乐存")
  set page(
    paper: "a4",
  )
  set text(
    11pt,
    font: font.serif,
    lang: "zh",
  )
  set par(
    justify: true,
    spacing: 1.33em,
    leading: 0.75em,
    first-line-indent: (
      amount: 2em,
      all: true,
    ),
  )
  show heading: set text(font: font.sans, weight: "semibold")
  set heading(numbering: "1.1")
  show math.equation: set text(font: (font.math, font.serif))
  set math.vec(delim: ("[", "]"))
  set math.mat(delim: ("[", "]"))
  set footnote(numbering: "注1")
  show footnote: set text(9pt, font: font.fangsong)
  show figure.caption: set text(9pt, font: font.fangsong)

  show heading: body => {
    v(1em)
    body
    v(1em)
  }

  set page(
    footer: context {
      let this_page = counter(page).get().at(0)
      set text(9pt, font: font.sans, weight: "semibold")
      h(1fr)
      numbering("第 1 页,共 1 页", this_page, counter(page).final().at(0))
    },
    header: context {
      set text(9pt, font: font.sans, weight: "semibold")

      title
    },
  )

  body
}

#let unset-par-indent(body) = {
  set par(
    first-line-indent: 0em,
    hanging-indent: 0em,
  )
  body
}
Loading