主题分析利器BERTopic详解与实战应用指南(附中文案例)

🤵‍♂️ 个人主页:@艾派森的个人主页

✍🏻作者简介:Python学习者
🐋 希望大家多多支持,我们一起进步!😄
如果文章对你有帮助的话,
欢迎评论 💬点赞👍🏻 收藏 📂加关注+


目录

一、引言:为什么我们需要 BERTopic?

📉 传统方法遇到的困境:

🚀 BERTopic 的出现,正是为了解决这些问题。

二、BERTopic 核心原理解析

2.1 整体流程一览图

2.2 语义向量生成:基于 Sentence-BERT 的文本编码

2.3 降维:UMAP 让高维语义空间更清晰

2.4 聚类:HDBSCAN 自动发现主题簇

2.5 主题提取:c-TF-IDF 关键词抽取算法

三、BERTopic 相比传统主题建模方法(如 LDA)的优势

四、实战案例

4.1前置准备

4.2加载数据

4.2中文分词

4.3构建模型

4.4训练模型

4.5结果可视化

4.6番外篇

源代码


一、引言:为什么我们需要 BERTopic?

        在文本挖掘和自然语言处理的众多任务中,主题建模(Topic Modeling)一直是一个核心技术。无论是从大量新闻中发现热点议题,还是从用户评论中提炼关注焦点,主题建模都扮演着重要角色。然而,传统的主题建模方法,尤其是经典的 LDA(Latent Dirichlet Allocation),却在如今信息爆炸、文本碎片化的时代面临越来越多的挑战。

📉 传统方法遇到的困境:

  • 语义理解能力弱:LDA 基于词袋模型(Bag-of-Words),无法理解上下文含义,难以识别“汽车”与“车辆”、“AI”与“人工智能”的同义关系;

  • 短文本效果差:在如微博、知乎、评论区等短文本环境中,LDA 因词频稀疏往往难以建模出清晰的主题;

  • 主题一致性差:生成的关键词往往关联性弱,主题解释困难;

  • 缺乏现代语义建模能力:面对今天以大模型为代表的 NLP 飞跃,LDA 的建模能力显得相对“过时”。

🚀 BERTopic 的出现,正是为了解决这些问题。

BERTopic(Bidirectional Encoder Representations for Topic Modeling)是一种结合 Transformer 预训练模型(如 BERT)与无监督聚类算法的现代主题建模方法。它不仅具备强大的上下文理解能力,还支持短文本建模、多语言处理和主题时间演变分析,逐步成为 NLP 应用中极具潜力的主题挖掘工具。

更重要的是,BERTopic 不仅是一种算法,更是一个集成完备、使用简单的开源工具包,极大降低了主题建模的门槛。通过少量代码,我们就可以高效地从大量文本中提取出清晰、可解释的主题结构。

那么,BERTopic 背后的原理是什么?它与传统方法相比有哪些显著优势?我们又该如何在真实数据中使用它呢?
本文将带你从原理到实战,全面解锁 BERTopic 的强大能力!

二、BERTopic 核心原理解析

在了解 BERTopic 如何运行之前,我们先来看它的整体工作流程:

文本输入 → 向量编码 → 降维 → 聚类 → 关键词抽取 → 主题建模

这个流程串联起了多个 NLP 和机器学习组件,也正是 BERTopic 与传统方法最大的不同。下面我们逐步拆解每个关键步骤。

2.1 整体流程一览图

2.2 语义向量生成:基于 Sentence-BERT 的文本编码

BERTopic 使用 Sentence-BERT(SBERT) 或其他语义向量模型(如 text2vec、mpnet)对每条文本进行编码,获取语义嵌入(embedding)。相比词袋模型,这一步带来了几大好处:

  • 能理解上下文含义("苹果手机" vs "苹果水果")

  • 适用于短文本,嵌入向量稳定、信息丰富

  • 支持多语言,包括中文(可使用如 text2vec-base-chinese

💡 Tips:SBERT 是 BERT 的轻量级句子对比版本,专为“句子级语义表示”优化,非常适合主题建模场景。

2.3 降维:UMAP 让高维语义空间更清晰

Transformer 编码后的向量通常有 768 维或更多,这对聚类和可视化都不太友好。为此,BERTopic 使用 UMAP(Uniform Manifold Approximation and Projection) 进行降维处理。

  • 保持语义结构相对完整

  • 聚类效果更稳,支持可视化

  • 比 t-SNE 更快、更稳定,适合实际项目

2.4 聚类:HDBSCAN 自动发现主题簇

接下来,BERTopic 将降维后的文本嵌入输入给 HDBSCAN(Hierarchical Density-Based Spatial Clustering) 进行无监督聚类。HDBSCAN 的优势包括:

  • 自动确定聚类数量(不像 KMeans 需要预设)

  • 能检测“噪声点”并排除无效文本

  • 能适应密度不均的真实语料(如评论、社交文本)

每个聚类簇,即被认为是一个潜在的“主题”。

2.5 主题提取:c-TF-IDF 关键词抽取算法

聚类完毕后,我们需要为每个“主题”提取代表性的关键词。此时,BERTopic 使用改进版的 class-based TF-IDF(简称 c-TF-IDF) 来做关键词提取:

  • 类比将每个主题视为一篇“巨文档”(把所有属于该主题的文本合并)

  • 对不同主题之间的词语差异性进行放大

  • 提取出更具代表性、可解释性的关键词

相比传统 TF-IDF,c-TF-IDF 更关注“在本主题中高频,而在其他主题中低频”的词语,也就是最能代表这个主题特征的词。

✅ 总结一下:BERTopic 的五个关键词是——

嵌入(Embedding)→ 降维(UMAP)→ 聚类(HDBSCAN)→ 抽词(c-TF-IDF)→ 构建主题模型

这样一套流程,既保留了深度语义信息,又兼顾了可解释性与可视化能力,是当前语义主题建模中的一大利器。

三、BERTopic 相比传统主题建模方法(如 LDA)的优势

对比维度传统LDA等方法BERTopic
语义建模能力基于词袋模型(Bag-of-Words),无法捕捉上下文语义利用 BERT 等预训练模型,能理解上下文和同义词
适用于短文本表现较差,词频稀疏问题严重表现优异,能准确捕捉短文本中的语义信息
主题一致性主题关键词可能无明显语义连贯性提取的关键词语义一致性更高
多语言支持支持有限,需手动适配可直接用多语种 BERT 处理
时间建模不支持时间变化支持分析主题随时间演变
可扩展性需指定主题数K,扩展性差HDBSCAN自动决定聚类数,灵活适应不同数据集
可视化工具通常需额外开发内置多种可视化功能,交互性强

四、实战案例

4.1前置准备

Python环境:3.9

需要下载的包:bertopic、sentence_transformers

pip install bertopic 

pip install sentence_transformers

数据集为新闻数据集,包含新闻内容(文本内容)、新闻类型(一般做主题建模没有这个变量,这里是为了方便对比主题分类结果)、时间(有时间变量的话可以分析主题随时间演变趋势)

4.2加载数据

导入第三方库并加载数据集

# 导入工具包
import numpy as np
from bertopic import BERTopic
from sentence_transformers import SentenceTransformer
from umap import UMAP
from hdbscan import HDBSCAN
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
import re
import jieba

# 加载数据
data = pd.read_excel("data_news_year.xlsx")
data

有八个新闻类别,每个各100条数据 

4.2中文分词

# 自定义中文分词的函数
def chinese_word_cut(mytext):
    jieba.load_userdict('自定义词典.txt')  # 这里你可以添加jieba库识别不了的网络新词,避免将一些新词拆开
    jieba.initialize()  # 初始化jieba
    # 文本预处理 :去除一些无用的字符只提取出中文出来
    new_data = re.findall('[\u4e00-\u9fa5]+', mytext, re.S)
    new_data = " ".join(new_data)
    # 文本分词
    seg_list_exact = jieba.lcut(new_data)
    result_list = []
    # 读取停用词库
    with open('stopwords.txt', encoding='utf-8') as f: # 可根据需要打开停用词库,然后加上不想显示的词语
        con = f.readlines()
        stop_words = set()
        for i in con:
            i = i.replace("\n", "")   # 去掉读取每一行数据的\n
            stop_words.add(i)
    # 去除停用词并且去除单字
    for word in seg_list_exact:
        if word not in stop_words and len(word) > 1:
            result_list.append(word)      
    return ' '.join(result_list)
# 调用分词函数
docs = data['content'].apply(chinese_word_cut).tolist()

print('文本条数: ', len(docs))
print('预览第一条: ', docs[0])

4.3构建模型

# 1. 词向量模型
model_path = "paraphrase-multilingual-MiniLM-L12-v2"
embedding_model = SentenceTransformer(model_path)
embeddings = embedding_model.encode(docs)  # 生成嵌入向量
print('向量shape:', embeddings.shape)

这一步如果你能正确运行,也就是会程序自动在huggingface下载模型

如果因为网络等问题不能正常运行,可以把模型下载到本地再运行

https://huggingface.co/sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2/tree/main

在这个网址中下载,注意需要科学上网!如果不会下载可进我的QQ粉丝群下载

如果是运行本地下载的模型,只需要将模型文件的路径填写即可,绝对路径和相对路径均可,我这里用的是相对路径,也就是代码和模型文件在同一级目录

# 1. 词向量模型,同时加载本地训练好的词向量
#https://huggingface.co/sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2/tree/main
model_path = "./paraphrase-multilingual-MiniLM-L12-v2"
embedding_model = SentenceTransformer(model_path)
embeddings = embedding_model.encode(docs)  # 生成嵌入向量
print('向量shape:', embeddings.shape)

接着准备UMAP、HDBSCAN、 CountVectorizer模型

# 2. 创建UMAP降维模型
umap_model = UMAP()
# 3. 创建HDBSCAN聚类模型
hdbscan_model = HDBSCAN()
# 4. 创建CountVectorizer模型
# 停用词
with open('stopwords.txt', "r", encoding='utf-8') as file:
    lines = file.readlines()
    stopwords = [line.strip() for line in lines]
vectorizer_model = CountVectorizer(stop_words=stopwords)

注意我这里初始化的模型都是使用默认参数,后期你可以自己调整参数进行优化

 UMAP模型的参数如下:

class UMAP(
    n_neighbors: int = 15,
    n_components: int = 2,
    metric: str = "euclidean",
    metric_kwds: Any | None = None,
    output_metric: str = "euclidean",
    output_metric_kwds: Any | None = None,
    n_epochs: Any | None = None,
    learning_rate: float = 1,
    init: str = "spectral",
    min_dist: float = 0.1,
    spread: float = 1,
    low_memory: bool = True,
    n_jobs: int = -1,
    set_op_mix_ratio: float = 1,
    local_connectivity: float = 1,
    repulsion_strength: float = 1,
    negative_sample_rate: int = 5,
    transform_queue_size: float = 4,
    a: Any | None = None,
    b: Any | None = None,
    random_state: Any | None = None,
    angular_rp_forest: bool = False,
    target_n_neighbors: int = -1,
    target_metric: str = "categorical",
    target_metric_kwds: Any | None = None,
    target_weight: float = 0.5,
    transform_seed: int = 42,
    transform_mode: str = "embedding",
    force_approximation_algorithm: bool = False,
    verbose: bool = False,
    tqdm_kwds: Any | None = None,
    unique: bool = False,
    densmap: bool = False,
    dens_lambda: float = 2,
    dens_frac: float = 0.3,
    dens_var_shift: float = 0.1,
    output_dens: bool = False,
    disconnection_distance: Any | None = None,
    precomputed_knn: Any = (None, None, None)
)

HDBSCAN模型参数如下:

class HDBSCAN(
    min_cluster_size: int = 5,
    min_samples: Any | None = None,
    cluster_selection_epsilon: float = 0,
    max_cluster_size: int = 0,
    metric: str = "euclidean",
    alpha: float = 1,
    p: Any | None = None,
    algorithm: str = "best",
    leaf_size: int = 40,
    memory: Memory = Memory(None, verbose=0),
    approx_min_span_tree: bool = True,
    gen_min_span_tree: bool = False,
    core_dist_n_jobs: int = 4,
    cluster_selection_method: str = "eom",
    allow_single_cluster: bool = False,
    prediction_data: bool = False,
    branch_detection_data: bool = False,
    match_reference_implementation: bool = False,
    cluster_selection_epsilon_max: float = float('inf'),
    **kwargs: Any
)

如果说你也不知道这些参数都表示什么意思,你可以鼠标放在模型名称上,然后就会弹出模型参数介绍的框框,往下翻还有每个模型的解释,只不过是英文的。注意我使用的代码编辑器是VS code,这个软件有这个功能。

 这里我列举几个最常用可能也相对关键的参数吧

# 2. 创建UMAP降维模型
umap_model = UMAP(
  n_neighbors=15,  # 控制局部邻域的大小
  n_components=5,  # 降维后的维度
  min_dist=0.05,    # 控制点与点之间的最小距离 min_dist=0.0 可能导致数据点过度重叠,建议调整为 0.05 以提升可视化清晰度。
  metric='cosine', # 距离度量方式
  random_state=42  # 随机种子,确保结果可复现
)
 
# 3. 创建HDBSCAN聚类模型
hdbscan_model = HDBSCAN(
  min_cluster_size=10,  # 控制最小簇的大小
  min_samples=5,        # 控制簇的核心点数量
  gen_min_span_tree=True
)

4.4训练模型

BERTopic模型中有一个nr_topics的参数,也就是指定主题的个数,默认就是不指定个数。

# 5. 正式创建BERTopic模型
topic_model = BERTopic(
  # nr_topics=8, # 主题数,可以不指定
  embedding_model=embedding_model,
  vectorizer_model=vectorizer_model,
  umap_model=umap_model,
  hdbscan_model=hdbscan_model
)

# 6.查看主题
topics, probs = topic_model.fit_transform(docs, embeddings=embeddings) #传入训练好的词向量
topic_info = topic_model.get_topic_info()
topic_info

没指定个数就有20几个主题,下面是我指定8个就生成8个主题 

可以使用下面代码把主题聚类结果保存为excel文件

# 保存聚类主题信息
topic_docs = topic_model.get_document_info(docs)
topic_docs.to_excel('聚类结果.xlsx',index=False)

4.5结果可视化

注意下面代码生成的都是html交互式的可视化文件,打开即可

# 结果可视化
#1 主题分布可视化
fig1 = topic_model.visualize_topics()
fig1.write_html("1.topics.html")

#2 主题相似度可视化
fig2 =topic_model.visualize_heatmap()
fig2.write_html("2.simi_heatmap.html")

# 3 文档散点图可视化
reduced_embeddings = UMAP().fit_transform(embeddings)
fig3 = topic_model.visualize_documents(docs, reduced_embeddings=reduced_embeddings)
fig3.write_html("3.docsvisual.html")

#4 主题关键词可视化
fig4 = topic_model.visualize_barchart()
fig4.write_html("4.keywords.html")

注意,这里为啥只显示8个主题的图,是因为该可视化函数中top_n_topics默认是8,这里你可以自行修改参数

#5 层级可视化
fig5= topic_model.visualize_hierarchy()
fig5.write_html("5.Hierarchical.html")

这是层次聚类的结果可视化图,从上往下看,可以看出主题18/8/11/6是属于同一个主题,此时我们可以去看聚类结果的excel文件来验证这几个主题是不是属于同一个主题,或者从主题关键词来判断。

可以发现主题18/8/11/6讲的都是房产相关的内容,可以归为一类。以此类推,主题2/9/13讲的是股票相关的内容,主题16/1讲的是游戏相关的内容,主题3/12讲的是电影娱乐相关的内容,主题7/0/21讲的是教育相关的内容,主题10/19讲的是科技相关的内容,主题20/15/4讲的是彩票相关的内容,主题17/5/14讲的是体育相关的内容。最终也就对应上原始的八个主题。分析到这一步,你可以根据层次聚类的可视化结果,判断出最优的主题数,然后再去前面的BERTopic模型中修改nr_topics的参数,指定主题数。

#6.动态主题模型
timestamps = [int(line) for line in data['year']] # 提取出时间列数据
topics_over_time = topic_model.topics_over_time(docs, timestamps)
fig6 = topic_model.visualize_topics_over_time(topics_over_time)
fig6.write_html("6.visualize_topics_over_time.html")

做这个图的前提是数据集中有时间变量,结果图中可以通过滑轮进行滚动查看各主题的颜色。

4.6番外篇

如果想进行主题优化,同时减少离群值,可以将4.4训练模型的代码改为下面的代码

# 主题优化
# 该模型会将冗余的词进行替换,生成更具有多样性的主题词。
from bertopic.representation import MaximalMarginalRelevance # 导入
representation_model = MaximalMarginalRelevance(diversity=0.3) # 创建mmr模型
topic_model = BERTopic(
  embedding_model=embedding_model,
  vectorizer_model=vectorizer_model,
  umap_model=umap_model,
  hdbscan_model=hdbscan_model,
  representation_model=representation_model # 传入模型
)

# 如何减少离群值-reduce outliers函数
# 调用函数
topics, probs = topic_model.fit_transform(docs, embeddings=embeddings)
new_topics = topic_model.reduce_outliers(docs, topics, probabilities=probs, strategy="probabilities", threshold=0.5)
# 应用更新
topic_model.update_topics(docs, topics=new_topics, vectorizer_model=vectorizer_model)
topic_info = topic_model.get_topic_info()
topic_info

使用上面优化的代码可能未必比没优化的效果好,具体怎么选由你自己来决定。

源代码

# 导入工具包
import numpy as np
from bertopic import BERTopic
from sentence_transformers import SentenceTransformer
from umap import UMAP
from hdbscan import HDBSCAN
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
import re
import jieba

# 加载数据
data = pd.read_excel("data_news_year.xlsx")
data
data['type'].value_counts()
# 自定义中文分词的函数
def chinese_word_cut(mytext):
    jieba.load_userdict('自定义词典.txt')  # 这里你可以添加jieba库识别不了的网络新词,避免将一些新词拆开
    jieba.initialize()  # 初始化jieba
    # 文本预处理 :去除一些无用的字符只提取出中文出来
    new_data = re.findall('[\u4e00-\u9fa5]+', mytext, re.S)
    new_data = " ".join(new_data)
    # 文本分词
    seg_list_exact = jieba.lcut(new_data)
    result_list = []
    # 读取停用词库
    with open('stopwords.txt', encoding='utf-8') as f: # 可根据需要打开停用词库,然后加上不想显示的词语
        con = f.readlines()
        stop_words = set()
        for i in con:
            i = i.replace("\n", "")   # 去掉读取每一行数据的\n
            stop_words.add(i)
    # 去除停用词并且去除单字
    for word in seg_list_exact:
        if word not in stop_words and len(word) > 1:
            result_list.append(word)      
    return ' '.join(result_list)
# 调用分词函数
docs = data['content'].apply(chinese_word_cut).tolist()

print('文本条数: ', len(docs))
print('预览第一条: ', docs[0])
# 1. 词向量模型
model_path = "paraphrase-multilingual-MiniLM-L12-v2"
embedding_model = SentenceTransformer(model_path)
embeddings = embedding_model.encode(docs)  # 生成嵌入向量
print('向量shape:', embeddings.shape)
# 1. 词向量模型,同时加载本地训练好的词向量
#https://huggingface.co/sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2/tree/main
model_path = "./paraphrase-multilingual-MiniLM-L12-v2"
embedding_model = SentenceTransformer(model_path)
embeddings = embedding_model.encode(docs)  # 生成嵌入向量
print('向量shape:', embeddings.shape)
# 2. 创建UMAP降维模型
umap_model = UMAP()
# 3. 创建HDBSCAN聚类模型
hdbscan_model = HDBSCAN()
# 4. 创建CountVectorizer模型
# 停用词
with open('stopwords.txt', "r", encoding='utf-8') as file:
    lines = file.readlines()
    stopwords = [line.strip() for line in lines]
vectorizer_model = CountVectorizer(stop_words=stopwords)
# 5. 正式创建BERTopic模型
topic_model = BERTopic(
  # nr_topics=8, # 主题数,可以不指定
  embedding_model=embedding_model,
  vectorizer_model=vectorizer_model,
  umap_model=umap_model,
  hdbscan_model=hdbscan_model
)

# 6.查看主题
topics, probs = topic_model.fit_transform(docs, embeddings=embeddings) #传入训练好的词向量
topic_info = topic_model.get_topic_info()
topic_info
# 保存聚类主题信息
topic_docs = topic_model.get_document_info(docs)
topic_docs.to_excel('聚类结果.xlsx',index=False)
# 结果可视化
#6.1 主题分布可视化
fig1 = topic_model.visualize_topics()
fig1.write_html("1.topics.html")
#6.2 主题相似度可视化
fig2 =topic_model.visualize_heatmap()
fig2.write_html("2.simi_heatmap.html")
# 6.3 文档散点图可视化
reduced_embeddings = UMAP().fit_transform(embeddings)
fig3 = topic_model.visualize_documents(docs, reduced_embeddings=reduced_embeddings)
fig3.write_html("3.docsvisual.html")
#6.4 主题关键词可视化
fig4 = topic_model.visualize_barchart()
fig4.write_html("4.keywords.html")
#6.5 层级可视化
fig5= topic_model.visualize_hierarchy()
fig5.write_html("5.Hierarchical.html")
#6.6.动态主题模型
timestamps = [int(line) for line in data['year']] # 提取出时间列数据
topics_over_time = topic_model.topics_over_time(docs, timestamps)
fig6 = topic_model.visualize_topics_over_time(topics_over_time)
fig6.write_html("6.visualize_topics_over_time.html")

资料获取,更多粉丝福利,关注下方公众号获取

 

### Bertopic主题建模 Bertopic 是一种先进的主题建模工具,它利用 BERT 的语义表示能力来提取档的主题。对于中主题建模,可以通过结合预训练的中语言模型实现更高质量的结果。 以下是基于 Bertopic 进行中主题建模的具体方法和示例代码: #### 安装依赖库 为了支持中处理,需要安装 `bertopic` 和其他必要的自然语言处理库,例如 `sentence-transformers` 和 `jieba`(用于分词)。执行以下命令完成环境配置: ```bash pip install bertopic sentence-transformers jieba ``` #### 数据准备 假设有一组中本数据存储在一个列表中,如下所示: ```python documents = [ "这是一篇关于人工智能的章。", "机器学习是人工智能的一个重要分支。", "深度学习在图像识别领域取得了显著进展。", "自然语言处理技术正在快速发展。", "大数据分析为企业提供了决策支持。", ] ``` #### 预处理 由于中没有天然的空格分割单词的功能,因此需要借助分词工具(如 Jieba)对本进行切分。这样可以提高嵌入向量的质量。 ```python import jieba def preprocess(texts): processed_texts = [] for text in texts: words = ' '.join(jieba.lcut(text)) processed_texts.append(words) return processed_texts processed_documents = preprocess(documents) print(processed_documents[:2]) ``` #### 初始化并拟合模型 通过加载适合中的 Sentence-BERT 模型(如 `paraphrase-multilingual-MiniLM-L12-v2`),可以更好地捕捉中语义特征。 ```python from bertopic import BERTopic from sklearn.datasets import fetch_20newsgroups # 加载多语言SentenceTransformer模型 embedding_model = "paraphrase-multilingual-MiniLM-L12-v2" topic_model = BERTopic(embedding_model=embedding_model, language="zh", calculate_probabilities=True) topics, probs = topic_model.fit_transform(processed_documents) ``` #### 查看主题及其关键词 使用 `get_topic_info()` 方法获取所有主题的信息,并通过索引访问特定主题的内容。 ```python # 获取所有主题信息 all_topics = topic_model.get_topic_info() print(all_topics) # 查看第 0 号主题的关键字分布 specific_topic = topic_model.get_topic(0)[^1] print(specific_topic) ``` #### 可视化结果 Bertopic 提供了多种可视化功能,帮助直观理解主题结构。 ```python # 主题分布图 fig = topic_model.visualize_topics() fig.show() # 主题关系图 doc_fig = topic_model.visualize_documents(processed_documents) doc_fig.show() ``` --- ### 注意事项 - 如果数据集较大,建议调整参数以优化性能,例如设置 `min_topic_size` 或者减少降维维度。 - 对于复杂的中场景,可能还需要进一步调优分词策略或者引入自定义停用词表[^2]。 ---
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾派森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值