【学习笔记】 陈强-机器学习-Python-Ch8 朴素贝叶斯

系列文章目录

【学习笔记】 陈强-机器学习-Python-Ch4 线性回归
【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归
【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv)
【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归
【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析



前言

本学习笔记 仅为以防自己忘记了,顺便分享给一起学习的网友们参考。如有不同意见/建议,可以友好讨论。

本学习笔记 所有的代码和数据都可以从 陈强老师的个人主页 上下载

参考书目:陈强.机器学习及Python应用. 北京:高等教育出版社, 2021.

数学原理等 详见陈强老师的 PPT


参考了网友阡之尘埃Python机器学习06——朴素贝叶斯


一、朴素贝叶斯 案例:spam.scv

1. spam.scv数据

1)基本信息

import pandas as pd
import numpy as np

#读取CSV文件的路径
csv_path = r'D:\桌面文件\Python\【陈强-机器学习】MLPython-PPT-PDF\MLPython_Data\spam.csv'
spam = pd.read_csv(csv_path)
spam.shape

pd.options.display.max_columns =60 #控制DataFrame在输出时最多显示60列。
'''默认情况下,pandas 会根据终端的宽度和 DataFrame 的大小自动调整显示的列数。
如果 DataFrame 列数超过了默认显示的最大列数,pandas 可能会省略中间的列,仅显示开始和结束的列。'''
spam.head(1) #显示60列的第一行

结果输出:(4601, 58)
A.1 A.2 A.3 A.4 A.5 A.6 A.7 A.8 A.9 A.10 A.11 A.12 A.13 A.14 A.15 A.16 A.17 A.18 A.19 A.20 A.21 A.22 A.23 A.24 A.25 A.26 A.27 A.28 A.29 A.30 A.31 A.32 A.33 A.34 A.35 A.36 A.37 A.38 A.39 A.40 A.41 A.42 A.43 A.44 A.45 A.46 A.47 A.48 A.49 A.50 A.51 A.52 A.53 A.54 A.55 A.56 A.57 spam
0 0.0 0.64 0.64 0.0 0.32 0.0 0.0 0.0 0.0 0.0 0.0 0.64 0.0 0.0 0.0 0.32 0.0 1.29 1.93 0.0 0.96 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.778 0.0 0.0 3.756 61 278 spam

2)响应变量spam的分布

#响应变量spam的分布
print(spam.spam.value_counts())
spam.spam.value_counts(normalize=True)  #百分比计算

spam
email 2788
spam 1813
Name: count, dtype: int64
spam
email 0.605955
spam 0.394045
Name: proportion, dtype: float64

笔记:value_counts

value_counts 用于计算每个唯一值的频数。

#基本语法和参数
Series.value_counts(
	normalize=False,  #normalize:默认为 False。如果为 True,返回每个唯一值的比例,而不是频数。
	sort=True,  #sort:默认为 True(按频数从高到低排序)。如果为 False,则按唯一值排序。
	ascending=False,  #ascending:默认为 False。如果为 True,以升序排序频数。与 sort 参数配合使用。
	bins=None,  #bins:(整数)默认为 None。用于将数据分箱(即将数据分成指定数量的区间),通常用于连续数据。
	dropna=True) #dropna:默认为 True(忽略 NaN 值)。如果为 False,包括 NaN 的计数。

3)特征变量的分布(直方图)

import matplotlib.pyplot as plt
import seaborn as sns
spam.iloc[:, :5].plot.hist( #绘制 spam DataFrame 的前五列的直方图
    subplots=True, 
    bins=100) 

在这里插入图片描述

spam.iloc[:, -4:].plot.hist( #绘制 spam DataFrame 的最后3个特征变量的直方图
    grid=True,                 # 显示网格线
    bins=100) 

在这里插入图片描述

笔记:plot.hist()

(pandas 的)plot.hist() 用于绘制直方图。

#基本语法和参数
DataFrame.plot.hist(
    bins=None, #指定直方图的条形数量或边界数。可以是一个整数(条形的数量),也可以是一个列表(每个条形的边界)。
    range=None, #元组 (min, max),指定直方图显示的值的范围。默认情况下使用数据的最小和最大值。
    density=False, #默认为 False。如果为 True,显示概率密度,而不是频数。
    weights=None, #数组,指定每个值的权重,用于加权的直方图。
    cumulative=False, #默认为 False。如果为 True,显示累积直方图。
    bottom=None, #标量或数组,设置条形的底部位置,通常用于堆积直方图。
    histtype='bar', #指定直方图的类型。可选值包括 'bar'(条形),'barstacked'(堆叠条形),'step'(线条),'stepfilled'(填充的线条)。
    align='mid', #指定条形的对齐方式。可选值有 'left'、'mid' 和 'right'。
    orientation='vertical', #指定直方图的方向。可选值为 'vertical'(垂直)和 'horizontal'(水平)。
    rwidth=None, #浮点数,指定条形的宽度占整个区间宽度的比例。
    log=False, #默认为 False。如果为 True,则 y 轴以对数尺度显示。
    color=None, #指定条形的颜色。可以是单个颜色,也可以是颜色列表。
    edgecolor='black', #指定条形边框的颜色。
    linestyle=None, #指定条形边框的样式。
    subplots=False, #默认为 False。如果为 True,为 DataFrame 的每列绘制一个子图。
    sharex=False, #默认为 False。如果为 True,所有子图共享 x 轴。
    sharey=False, #默认为 False。如果为 True,所有子图共享 y 轴。
    figsize=None, #元组 (宽度, 高度),指定图形的大小。
    grid=True, #默认为 True。是否显示网格线。
    ax=None, #Matplotlib 的 Axes 对象,指定绘制图形的轴。
    layout=None, #元组 (行数, 列数),指定子图的布局。
    legend=True, #默认为 True。是否显示图例。
    title=None, #字符串,指定图形的标题。

4)定义数据矩阵X与响应向量y

#定义X与y
X = spam.iloc[:, :-1]
y = spam.iloc[:, -1]

#全样本随机分20%测试集和80%训练集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
    X, y, 
    test_size=0.2, 
    stratify=y, 
    random_state=0)

2.朴素贝叶斯估计

1)高斯朴素贝叶斯 (Gaussian Naive Bayes)

适用于:特征符合高斯(正态)分布连续数据。

#高斯朴素贝叶斯(Gaussian Naive Bayes)
from sklearn.naive_bayes import GaussianNB
GNB = GaussianNB()
GNB.fit(X_train, y_train)

# 进行预测
y_pred_GNB = GNB.predict(X_test)

# 测试集的预测准确率
print("GaussianNB 测试集的预测准确率:",GNB.score(X_test, y_test))

#打印 混淆矩阵
from sklearn.metrics import confusion_matrix
print("GaussianNB 混淆矩阵:\n",confusion_matrix(y_test, y_pred_GNB))

# 打印分类报告
from sklearn.metrics import classification_report
print("GaussianNB Classification Report:\n", classification_report(y_test, y_pred_GNB))

结果输出: GaussianNB 测试集的预测准确率: 0.8447339847991314
GaussianNB 混淆矩阵:
[[428 130]
[ 13 350]]
在这里插入图片描述

笔记:GaussianNB

GaussianNB 是 scikit-learn 中实现的高斯朴素贝叶斯分类器,用于处理特征分布符合高斯分布的二分类或多分类问题。它属于朴素贝叶斯分类器的一种,假设每个特征的条件分布都是高斯分布。

#基本语法和参数
from sklearn.naive_bayes import GaussianNB
	# 创建 GaussianNB 对象
gnb = GaussianNB(
    priors = None, #(可选)类别的先验概率。默认值为 None。也可以指定了 priors 参数,必须提供一个一维数组,数组的长度等于类别的数量。数组中的每个值对应于各个类别的先验概率。
    var_smoothing=1e-9) #(高级配置)如果你数据特征的方差较小或者存在异常值,可以使用 var_smoothing 参数来进行平滑处理。默认=1e-9

2)多项朴素贝叶斯 (Multinomial Naive Bayes)

多项朴素贝叶斯(Multinomial Naive Bayes) 适用于特征是离散计数数据的情况,比如文档分类中的词频特征。
假设特征符合多项分布,用于处理分类数据或文本数据。

#多项朴素贝叶斯 (Multinomial Naive Bayes)
from sklearn.naive_bayes import MultinomialNB
MNB = MultinomialNB(alpha=0)
MNB.fit(X_train, y_train)

# 进行预测
y_pred_MNB = MNB.predict(X_test)

# 测试集的预测准确率
print("MultinomialNB 测试集的预测准确率:",MNB.score(X_test, y_test))

#打印 混淆矩阵
print("MultinomialNB 混淆矩阵:\n",confusion_matrix(y_test, y_pred_MNB))

# 打印分类报告
print("MultinomialNB Classification Report:\n", classification_report(y_test, y_pred_MNB))

结果输出: MultinomialNB 测试集的预测准确率: 0.7926167209554832
MultinomialNB 混淆矩阵:
[[473 85]
[106 257]]
在这里插入图片描述

笔记:MultinomialNB

**MultinomialNB ** 是 用于处理具有离散特征的数据,通常应用于文本分类等任务。它假设特征的分布符合多项分布。

#基本语法和参数
from sklearn.naive_bayes import MultinomialNB
	# 创建 MultinomialNB 对象
mnb = MultinomialNB(
    alpha=1, #平滑参数,用于避免在训练数据中某些特征频率为零时出现问题。alpha 为 1.0 对应拉普拉斯平滑(加1平滑),alpha 值越小,平滑效果越弱。
    fit_prior=False, #是否学习类别的先验概率。默认=True;如果设置为 False,则所有类别的先验概率将被设置为相等值。
    class_prior =None #类别的先验概率。如果 fit_prior 为 False,需要显式指定 class_prior,以设置每个类别的先验概率。数组长度应与类别数量匹配。
)
(1)拉普拉斯修正
#拉普拉斯修正(alpha=1)
MNB_1 = MultinomialNB(alpha=1)
MNB_1.fit(X_train, y_train)

# 进行预测
y_pred_MNB_1 = MNB_1.predict(X_test)

# 测试集的预测准确率
print("MultinomialNB拉普拉斯修正 测试集的预测准确率:",MNB_1.score(X_test, y_test))

#打印 混淆矩阵
print("MultinomialNB拉普拉斯修正 混淆矩阵:\n",confusion_matrix(y_test, y_pred_MNB_1))

# 打印分类报告
print("MultinomialNB拉普拉斯修正 Classification Report:\n", classification_report(y_test, y_pred_MNB_1))

在这里插入图片描述

(2)互补朴素贝叶斯(Complement Naive Bayes)

互补朴素贝叶斯(Complement Naive Bayes)是多项朴素贝叶斯的一种改进,专为处理类别不平衡问题设计。
在训练过程中,它使用每个类别的补集来计算概率,有助于提升分类性能。

#互补朴素贝叶斯(Complement Naive Bayes)
from sklearn.naive_bayes import ComplementNB
CNB = ComplementNB(alpha=1)
CNB.fit(X_train, y_train)

# 进行预测
y_pred_CNB = CNB.predict(X_test)

# 测试集的预测准确率
print("CNB 测试集的预测准确率:",CNB.score(X_test, y_test))

#打印 混淆矩阵
print("CNB 混淆矩阵:\n",confusion_matrix(y_test, y_pred_CNB))

# 打印分类报告
print("CNB Classification Report:\n", classification_report(y_test, y_pred_CNB))

在这里插入图片描述

笔记:ComplementNB

ComplementNB 特别设计用于处理类别不平衡的数据集。它是一种改进的朴素贝叶斯算法,旨在解决标准 MultinomialNB 在类别不平衡情况下性能下降的问题。

#基本语法和参数
from sklearn.naive_bayes import ComplementNB
	# 创建 ComplementNB 对象
norm  = ComplementNB (
    alpha=1,#平滑参数,用于避免在训练数据中某些特征频率为零时出现问题。alpha 为 1.0 对应拉普拉斯平滑(加1平滑),alpha 值越小,平滑效果越弱。
    norm = True, #是否对每个类别的特征频率进行归一化。默认=True(归一化,以确保类别间的公平比较);如果设置为 False,则不进行归一化。
    fit_prior=False, #是否学习类别的先验概率。默认=True;如果设置为 False,则所有类别的先验概率将被设置为相等值。
    class_prior =None) #类别的先验概率。如果 fit_prior 为 False,需要显式指定 class_prior,以设置每个类别的先验概率。数组长度应与类别数量匹配。

3)二项朴素贝叶斯(Bernoulli Naive Bayes)

二项朴素贝叶斯(Bernoulli Naive Bayes)适用于特征是二值(0或1)的情况,比如文档分类中的词是否出现。
假设每个特征是二项分布的,用于处理
离散
的二值特征。

#二项朴素贝叶斯(Bernoulli Naive Bayes)
from sklearn.naive_bayes import BernoulliNB
BNB = BernoulliNB() #默认参数“alpha=1”
BNB.fit(X_train, y_train)

# 进行预测
y_pred_BNB = BNB.predict(X_test)

# 测试集的预测准确率
print("BNB 测试集的预测准确率:",BNB.score(X_test, y_test))

# 打印分类报告
print("BNB Classification Report:\n", classification_report(y_test, y_pred_BNB))

'''不同门槛值'''
BNB_0 = BernoulliNB(binarize=0.1,alpha=1) 
BNB_0.fit(X_train, y_train)

# 进行预测
y_pred_BNB_0 = BNB_0.predict(X_test)

# 测试集的预测准确率
print("BNB(门槛值0.1) 测试集的预测准确率:",BNB_0.score(X_test, y_test))

# 打印分类报告
print("BNB(门槛值0.1)  Classification Report:\n", classification_report(y_test, y_pred_BNB_0))

在这里插入图片描述
在这里插入图片描述

笔记:BernoulliNB

BernoulliNB 适用于特征符合伯努利分布的场景。通常用于二分类问题或特征值为二元(如是否存在某个特征)的场景,例如文本分类中的词是否存在(布尔值特征)。

#基本语法和参数
from sklearn.naive_bayes import BernoulliNB
	# 创建 BernoulliNB 对象
bnb = BernoulliNB(
    alpha=1,#平滑参数,用于避免在训练数据中某些特征频率为零时出现问题。alpha 为 1.0 对应拉普拉斯平滑(加1平滑),alpha 值越小,平滑效果越弱。
    binarize = 0.0, #用于将特征值转换为布尔值的阈值。对于特征值大于等于 binarize 的情况,该特征被认为存在(1),否则认为不存在(0)。默认值为 0.0,意味着所有的非零值都被视为特征存在。
    fit_prior=False, #是否学习类别的先验概率。默认=True;如果设置为 False,则所有类别的先验概率将被设置为相等值。
    class_prior =None)#类别的先验概率。如果 fit_prior 为 False,需要显式指定 class_prior,以设置每个类别的先验概率。数组长度应与类别数量匹配。
(1)超参数(binarize与alpha)的取值
#超参数(binarize与alpha)的取值:双重for循环
best_score = 0 #初始化最佳预测准确率为0
for binarize in np.arange(0, 1.1, 0.1): #循环遍历 binarize 参数的取值范围从 0 到 1(不包括 1),步长为 0.1
    for alpha in np.arange(0, 1.1, 0.1): #在每个 binarize 参数下,再次循环遍历 alpha 参数的取值范围
        model = BernoulliNB(binarize=binarize, alpha=alpha) #创建一个 BernoulliNB 模型,设置当前的 binarize 和 alpha 参数取值。
        model.fit(X_train, y_train)
        score = model.score(X_test, y_test) 
        if score > best_score: #如果当前模型的预测准确率高于之前记录的最佳预测准确率,则执行以下操作: 
            best_score = score #更新 最佳预测准确率为当前模型的准确率。
            best_parameters = { #记录当前的 binarize 和 alpha 参数取值作为最佳参数组合。
            'binarize': binarize, 'alpha': alpha} 
best_score #最佳预测准确率
best_parameters #最佳超参数 取值

结果输出: 0.9218241042345277
{‘binarize’: 0.30000000000000004, ‘alpha’: 1.0}

这种方法严格来说等于提前泄露测试集的信息,可能会导致过拟合。

(2)解决过拟合的两种方法
方法一:全样本分为三份(训练集、测试集、验证集):要求原始数据样本容量较大
#方法一:全样本分为三份(训练集、测试集、验证集):要求原始数据样本容量较大
X_trainval, X_test, y_trainval, y_test = train_test_split(
    X, y, test_size=0.2, stratify=y, random_state=0)

X_train, X_val, y_train, y_val = train_test_split(
    X_trainval, y_trainval, test_size=0.25, 
    stratify=y_trainval, random_state=123)

y_train.shape, y_val.shape, y_test.shape

#超参数(binarize与alpha)的取值:双重for循环
best_val_score = 0
for binarize in np.arange(0, 1.1, 0.1):
    for alpha in np.arange(0, 1.1, 0.1):
        model = BernoulliNB(binarize=binarize, alpha=alpha)
        model.fit(X_train, y_train)
        score = model.score(X_val, y_val) 
        if score > best_val_score:
            best_val_score = score
            best_val_parameters = {'binarize': binarize, 'alpha': alpha}
print(best_val_score) #最佳预测准确率
print(best_val_parameters) #最佳超参数 取值

#使用训练集与验证集的合集,进行BernoulliNB,并估计 测试集的预测准确率
model_val = BernoulliNB(**best_val_parameters) #将best_val_parameters字典中的键值对作为参数传递给BernoulliNB类的构造函数。
''' ** 用于字典展开(dictionary unpacking),将字典中的键值对作为关键字参数传递给函数或类的构造函数。'''
model_val.fit(X_trainval, y_trainval)
model_val.score(X_test, y_test) 

结果输出: ((2760,), (920,), (921,))
0.9065217391304348
{‘binarize’: 0.30000000000000004, ‘alpha’: 0.1}
0.9207383279044516

方法二:交叉验证
#方法二:交叉验证 cross_val_score()
from sklearn.model_selection import StratifiedKFold
from sklearn.model_selection import cross_val_score

#超参数(binarize与alpha)的取值:双重for循环
best_kfold_score = 0
kfold = StratifiedKFold(
    n_splits=10, shuffle = True, random_state=1)
for binarize in np.arange(0, 1.1, 0.1):
    for alpha in np.arange(0, 1.1, 0.1):
        model = BernoulliNB(binarize=binarize, alpha=alpha)
        scores = cross_val_score(
            model, X_trainval, y_trainval, cv=kfold) 
        score = np.mean(scores)
        if score > best_kfold_score:
            best_kfold_score = score
            best_kfold_parameters = {'binarize': binarize, 'alpha': alpha}

print(best_kfold_score) #最佳预测准确率
print(best_kfold_parameters) #最佳超参数 取值

#使用训练集与验证集的合集,进行BernoulliNB,并估计 测试集的预测准确率
model_kfold = BernoulliNB(**best_kfold_parameters)
model_kfold.fit(X_trainval, y_trainval)
model_kfold.score(X_test, y_test) 

结果输出: 0.8991847826086957
{‘binarize’: 0.1, ‘alpha’: 0.1}
0.9153094462540716

网格上交叉验证
#定义超参数网格
param_grid = {'binarize': np.arange(0, 1.1, 0.1), 
              'alpha': np.arange(0, 1.1, 0.1)}

from sklearn.model_selection import GridSearchCV
GCV = GridSearchCV(BernoulliNB(), param_grid, cv=kfold)
GCV.fit(X_trainval, y_trainval)
#测试集评分
print(GCV.score(X_test, y_test))
#模型最优参数
print(GCV.best_params_)
#验证时最优评分
print(GCV.best_score_)       
#最佳的估计器
print(GCV.best_estimator_)

结果输出: 0.9153094462540716
{‘alpha’: 0.1, ‘binarize’: 0.1}
0.8991847826086957
BernoulliNB(alpha=0.1, binarize=0.1)

展示交叉验证结果
#获取每个交叉验证的详细信息,变为数据框
results = pd.DataFrame(GCV.cv_results_)
results.head(2)

#热力图:10个子样本的 平均预测准确率
scores = np.array(results.mean_test_score).reshape(11,11) 
ax = sns.heatmap(scores, cmap='nipy_spectral', annot=True, fmt='.3f')
ax.set_xlabel('binarize')
ax.set_xticklabels([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1])
ax.set_ylabel('alpha')
ax.set_yticklabels([0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1])
plt.tight_layout()

在这里插入图片描述

4)预测 结果 展示

#预测概率
prob = GCV.predict_proba(X_test)
prob[:3]

结果输出:
array([[4.76074721e-05, 9.99952393e-01],
[9.99997643e-01, 2.35698580e-06],
[9.98936466e-01, 1.06353378e-03]])

#预测类别
pred = GCV.predict(X_test)
pred[:3]

结果输出: array([‘spam’, ‘email’, ‘email’], dtype=‘<U5’)

#数据透视表,混淆矩阵
table = pd.crosstab(y_test, pred, rownames=['Actual'], colnames=['Predicted'])
table

结果输出: 在这里插入图片描述

#计算准确率、错误率、敏感度、特异度、召回率、科恩指标
table = np.array(table)
Accuracy = (table[0, 0] + table[1, 1]) / np.sum(table)
print(Accuracy)  #准确率
 
Error_rate = 1 - Accuracy
print(Error_rate)  #错误率
 
Sensitivity  = table[1, 1]/(table[1, 0] + table[1, 1])
print(Sensitivity)   # 敏感度
 
Specificity = table[0, 0] / (table[0, 0] + table[0, 1])
print(Specificity)   #特异度
 
Recall = table[1, 1] / (table[0, 1] + table[1, 1])
print(Recall)    #召回率


from sklearn.metrics import cohen_kappa_score
print(cohen_kappa_score(y_test, pred))  #科恩指标

结果输出: 0.9153094462540716
0.08469055374592838
0.8760330578512396
0.9408602150537635
0.905982905982906
0.821639256346085

#绘制 roc:RocCurveDisplay
from sklearn.metrics import RocCurveDisplay
RocCurveDisplay.from_estimator(GCV, X_test, y_test, plot_chance_level=True)

在这里插入图片描述

笔记:RocCurveDisplay

RocCurveDisplay 是 scikit-learn 中用于绘制 ROC 曲线的显示类。

from sklearn.metrics import RocCurveDisplay

display = RocCurveDisplay.from_predictions(
    y_true, #真实标签,通常是二进制(0 和 1)
    y_score, #模型的预测"概率",用于计算 ROC 曲线
    pos_label=None, #正类标签,默认为 None。指定正类的标签值。如果标签不是二进制,必须提供此参数。
    sample_weight=None, #样本权重,默认为 None。用于加权样本。
    drop_intermediate=True, #控制是否在计算过程中丢弃中间步骤。默认为True(在计算过程中丢弃中间步骤), False(保留中间步骤)。
    response_method='predict_proba') #表示获取预测概率的方法,默认为 'predict_proba'。可以是 'decision_function' 或 'predict_proba'。

二、iris数据作为案例:高斯朴素贝叶斯

from sklearn.datasets import load_iris
from mlxtend.plotting import plot_decision_regions
 
X, y = load_iris(return_X_y=True)
X2 = X[:, 2:4]

#进行 高斯朴素贝叶斯 估计
model = GaussianNB()
model.fit(X2, y)
print(model.score(X2, y))
 
#画出 模型决策边界
plot_decision_regions(X2, y, model)
plt.xlabel('petal_length')
plt.ylabel('petal_width')
plt.title('Decision Boundary for Gaussian Naive Bayes')

结果输出: 0.96
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值