机器学习实战01:预测信用卡逾期风险

目录

一、项目背景与金融风险评估

项目目标

二、数据集深入分析

数据概述

数据加载与基本探索

年龄分布与逾期情况分析

相关性分析

三、特征工程详解

数据预处理

特征选择与提取

四、机器学习模型构建与比较

数据集划分

模型选择与实现

模型训练与评估

模型性能可视化比较

五、结果分析与业务应用

模型性能分析

业务应用建议

六、完整代码

七.数据集关注call me 

一、项目背景与金融风险评估

在金融行业中,信用卡业务面临的核心挑战之一是如何准确评估客户的还款能力和意愿。逾期还款不仅会导致银行资金回笼困难,还可能引发一系列金融风险。传统的风险评估方法往往依赖于简单的规则和经验,难以应对日益复杂的客户行为和市场环境。

机器学习技术的发展为解决这一问题提供了新的思路。通过分析客户的历史数据和行为模式,我们可以构建预测模型,提前识别潜在的逾期风险,从而采取相应的措施,如调整信用额度、加强催收等。

项目目标

本项目的主要目标是构建一个机器学习模型,基于客户的个人信息、历史还款记录等多维度特征,预测客户在下个月是否会发生逾期还款行为。具体来说,我们将:

  • 探索信用卡还款数据集,了解数据特征和分布
  • 进行特征工程,提取和转换有价值的特征
  • 比较多种机器学习算法的性能,选择最优模型
  • 优化模型参数,提高预测准确率
  • 评估模型性能,为金融决策提供支持

二、数据集深入分析

数据概述

我们使用的数据集包含了信用卡客户的多维度信息,包括个人基本信息、信用额度、历史还款记录、账单金额等。数据集共有 25 个特征列和 30000 条记录。

下面是数据集的核心字段及其含义:

  • LIMIT_BAL:信用额度
  • SEX:性别
  • EDUCATION:教育程度
  • MARRIAGE:婚姻状况
  • AGE:年龄
  • PAY_0PAY_6:历史还款状态
  • BILL_AMT1BILL_AMT6:历史账单金额
  • PAY_AMT1PAY_AMT6:历史还款金额
  • payment.next.month:目标变量,表示下个月是否逾期还款

数据加载与基本探索

首先,让我们加载数据并进行基本的探索性分析:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 加载数据
data = pd.read_csv('Credit_Card.csv')

# 查看数据集行数和列数
rows, columns = data.shape

if rows < 1000:
    sample = 1
elif rows < 10000:
    sample = 0.5
else:
    sample = 0.1

# 查看数据的基本信息
print('数据基本信息:')
data.info()

# 查看数据集行数和列数
rows, columns = data.shape

# 查看数据集行数和列数
print('数据全部内容信息:')
print(data.to_csv(sep='\t', na_rep='nan'))

这段代码首先加载了数据集,并根据数据集的大小确定了采样比例。然后,它打印了数据的基本信息,包括列名、数据类型和非空值数量。最后,它将整个数据集以制表符分隔的格式输出,方便查看所有数据内容。

年龄分布与逾期情况分析

接下来,我们分析客户的年龄分布以及年龄与逾期还款之间的关系:

# 查看年龄分布情况
age = data['AGE']
payment = data[data["payment.next.month"]==1]['AGE']

# 设置年龄分组
bins = [20, 30, 40, 50, 60, 70, 80]

# 整体年龄分布
seg = pd.cut(age, bins, right=False)
counts = pd.value_counts(seg, sort=False)

plt.figure(figsize=(10, 6))
b = plt.bar(counts.index.astype(str), counts)
plt.bar_label(b, counts)
plt.title('客户年龄分布')
plt.xlabel('年龄区间')
plt.ylabel('客户数量')
plt.show()

# 逾期客户的年龄分布
payment_seg = pd.cut(payment, bins, right=False)
counts1 = pd.value_counts(payment_seg, sort=False)

plt.figure(figsize=(10, 6))
b2 = plt.bar(counts1.index.astype(str), counts1, color='r')
plt.bar_label(b2, counts1)
plt.title('逾期客户的年龄分布')
plt.xlabel('年龄区间')
plt.ylabel('逾期客户数量')
plt.show()

# 查看逾期率情况
next_month = data['payment.next.month'].value_counts()
df = pd.DataFrame({'payment.next.month': next_month.index, 'values': next_month.values})

plt.figure(figsize=(6, 6))
plt.title('逾期率客户\n (还款:0, 逾期:1)')
sns.set_color_codes("pastel")
sns.barplot(x='payment.next.month', y="values", data=df)
plt.show()

# 计算逾期比例
overdue_ratio = next_month[1] / (next_month[0] + next_month[1]) * 100
print(f'逾期比例: {overdue_ratio:.2f}%')

这段代码首先将客户年龄分为多个区间,然后分别绘制了整体客户和逾期客户的年龄分布柱状图。通过比较这两个分布,我们可以直观地看出哪个年龄段的客户更容易发生逾期还款。最后,代码计算并打印了整体逾期比例,这是一个重要的业务指标。

相关性分析

为了了解各特征与逾期还款之间的关系,我们进行相关性分析:

# 计算相关性矩阵
correlation = data.corr()

# 显示负号
plt.rcParams['axes.unicode_minus'] = False

# 绘制热力图
plt.figure(figsize=(18, 18))
sns.heatmap(correlation, annot=True, cmap='coolwarm', fmt='.2f', square=True)
plt.title('特征相关性热力图')
plt.show()

# 查看与目标变量相关性最强的10个特征
target_correlation = correlation['payment.next.month'].abs().sort_values(ascending=False)
print('与逾期还款相关性最强的10个特征:')
print(target_correlation[1:11])  # 排除自身相关性

相关性分析有助于我们识别哪些特征对逾期还款预测最为重要。热力图直观地展示了各特征之间的相关性强弱,而相关系数排名则让我们能够聚焦于最重要的预测因子。

三、特征工程详解

数据预处理

在构建模型之前,我们需要对数据进行预处理,包括去除无关特征、处理缺失值和异常值等:

# 去除ID列,因为它对预测没有帮助
data.drop(['ID'], inplace=True, axis=1)

# 检查缺失值
missing_values = data.isnull().sum()
print('缺失值统计:')
print(missing_values[missing_values > 0])

# 如果有缺失值,进行填充
if missing_values.sum() > 0:
    # 数值型特征用中位数填充
    numeric_cols = data.select_dtypes(include=[np.number]).columns.tolist()
    for col in numeric_cols:
        data[col].fillna(data[col].median(), inplace=True)
    
    # 分类特征用众数填充
    categorical_cols = data.select_dtypes(include=['object']).columns.tolist()
    for col in categorical_cols:
        data[col].fillna(data[col].mode()[0], inplace=True)

# 检查异常值
# 以LIMIT_BAL为例,查看是否有异常值
q1 = data['LIMIT_BAL'].quantile(0.25)
q3 = data['LIMIT_BAL'].quantile(0.75)
iqr = q3 - q1
lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr

outliers = data[(data['LIMIT_BAL'] < lower_bound) | (data['LIMIT_BAL'] > upper_bound)]
print(f'LIMIT_BAL特征的异常值数量: {len(outliers)}')

# 对于异常值,可以选择删除或进行转换,这里选择保留异常值,因为信用额度可能有较大差异

这段代码首先删除了ID列,因为它不包含预测所需的信息。然后检查了数据中的缺失值,并根据特征类型进行了相应的填充。接着,代码对LIMIT_BAL特征进行了异常值检测,虽然发现了一些异常值,但考虑到信用额度本身可能存在较大差异,决定保留这些异常值。

特征选择与提取

基于相关性分析和业务理解,我们选择对预测最重要的特征:

# 提取特征和目标变量
target = data['payment.next.month'].values
columns = data.columns.tolist()
columns.remove('payment.next.month')
features = data[columns].values

# 显示特征数量
print(f'提取的特征数量: {len(columns)}')
print('特征列表:')
print(columns)

这段代码将数据集分为特征矩阵和目标向量,为后续的模型训练做准备。

四、机器学习模型构建与比较

数据集划分

我们将数据集划分为训练集和测试集,比例为 70:30:

# 70%作为训练集,30%作为测试集
train_x, test_x, train_y, test_y = train_test_split(features, target, test_size=0.30, stratify=target, random_state=1)

print(f'训练集样本数: {len(train_x)}')
print(f'测试集样本数: {len(test_x)}')
print(f'训练集逾期样本比例: {np.mean(train_y):.2f}')
print(f'测试集逾期样本比例: {np.mean(test_y):.2f}')

使用stratify=target参数确保训练集和测试集中的逾期样本比例与原始数据集一致,这对于处理不平衡数据集非常重要。

模型选择与实现

我们选择多种常见的分类算法进行比较,包括支持向量机、决策树、随机森林和 K 近邻:

# 构造各种分类器
classifiers = [
    SVC(random_state=1, kernel='rbf'),
    DecisionTreeClassifier(random_state=1, criterion='gini'),
    RandomForestClassifier(random_state=1, criterion='gini'),
    KNeighborsClassifier(metric='minkowski'),
    LogisticRegression(random_state=1)
]

# 分类器名称
classifier_names = [
    'SVM',
    '决策树',
    '随机森林',
    'K近邻',
    '逻辑回归'
]

# 分类器参数
classifier_param_grid = [
    {'SVM__C': [1, 5, 10], 'SVM__gamma': [0.01, 0.1]},
    {'决策树__max_depth': [6, 9, 11]},
    {'随机森林__n_estimators': [3, 5, 6]},
    {'K近邻__n_neighbors': [4, 6, 8]},
    {'逻辑回归__C': [0.1, 1, 10]}
]

这里新增了逻辑回归算法作为基准模型,同时为每个算法定义了参数搜索空间。

模型训练与评估

使用网格搜索和交叉验证来寻找最优参数,并评估模型性能:

# 对具体的分类器进行GridSearchCV参数调优
def GridSearchCV_work(pipeline, train_x, train_y, test_x, test_y, param_grid, score='accuracy'):
    response = {}
    gridsearch = GridSearchCV(estimator=pipeline, param_grid=param_grid, scoring=score, cv=5, n_jobs=-1)
    
    # 寻找最优的参数和最优的准确率分数
    search = gridsearch.fit(train_x, train_y)
    print(f"GridSearch最优参数:{search.best_params_}")
    print(f"GridSearch最优交叉验证分数:{search.best_score_:.4f}")
    
    # 在测试集上的评估
    predict_y = gridsearch.predict(test_x)
    accuracy = accuracy_score(test_y, predict_y)
    print(f"测试集准确率:{accuracy:.4f}")
    
    # 计算混淆矩阵
    cm = confusion_matrix(test_y, predict_y)
    print("混淆矩阵:")
    print(cm)
    
    # 计算分类报告
    cr = classification_report(test_y, predict_y)
    print("分类报告:")
    print(cr)
    
    response['predict_y'] = predict_y
    response['accuracy_score'] = accuracy
    response['best_params'] = search.best_params_
    response['model'] = gridsearch.best_estimator_
    
    return response

# 存储所有模型的结果
results = []

# 对每个分类器进行训练和评估
for model, model_name, model_param_grid in zip(classifiers, classifier_names, classifier_param_grid):
    print(f"\n===== 正在训练 {model_name} =====")
    
    # 构建管道
    pipeline = Pipeline([
        ('scaler', StandardScaler()),
        (model_name, model)
    ])
    
    # 进行网格搜索
    result = GridSearchCV_work(pipeline, train_x, train_y, test_x, test_y, model_param_grid, score='accuracy')
    
    # 存储结果
    result['model_name'] = model_name
    results.append(result)

# 比较不同模型的性能
print("\n===== 模型性能比较 =====")
for result in results:
    print(f"{result['model_name']}: 准确率 = {result['accuracy_score']:.4f}")

这段代码定义了一个通用的模型训练和评估函数,它使用网格搜索找到最优参数组合,并在测试集上评估模型性能。评估指标包括准确率、混淆矩阵和分类报告,这些指标能全面反映模型在各类别上的表现。

模型性能可视化比较

# 提取模型名称和准确率
model_names = [result['model_name'] for result in results]
accuracies = [result['accuracy_score'] for result in results]

# 创建条形图比较模型性能
plt.figure(figsize=(12, 6))
plt.bar(model_names, accuracies, color='skyblue')
plt.ylim([0.7, 0.9])  # 设置y轴范围,使差异更明显
plt.title('不同模型的准确率比较')
plt.xlabel('模型')
plt.ylabel('准确率')
plt.grid(axis='y', linestyle='--', alpha=0.7)

# 添加数值标签
for i, v in enumerate(accuracies):
    plt.text(i, v + 0.002, f'{v:.4f}', ha='center')

plt.tight_layout()
plt.show()

这段代码创建了一个条形图,直观地比较了不同模型的准确率,帮助我们快速选择性能最优的模型。

五、结果分析与业务应用

模型性能分析

通过比较不同模型的性能,我们可以得出以下结论:

  1. 随机森林模型在准确率和综合性能上表现最好,能够有效预测信用卡还款情况。
  2. 特征重要性:从随机森林模型中可以提取特征重要性,发现历史还款状态(如PAY_0PAY_2等)和信用额度(LIMIT_BAL)是影响逾期还款的最重要因素。
  3. 模型优化:通过网格搜索,我们找到了每个模型的最优参数组合,进一步提升了模型性能。

业务应用建议

基于模型分析结果,我们可以为金融机构提供以下建议:

  1. 风险评估策略优化:将机器学习模型的预测结果纳入现有的风险评估体系,提高风险识别的准确性。
  2. 差异化管理:针对高风险客户,可以采取更加严格的风险管理措施,如降低信用额度、加强催收等;对于低风险客户,可以提供更优惠的服务和产品。
  3. 客户教育:根据模型分析结果,向客户提供个性化的还款建议和财务知识教育,帮助客户提高还款意识和能力。
  4. 持续监控与模型更新:定期监控模型性能,根据新数据不断更新模型,确保模型的预测能力始终保持在最佳状态。

六、完整代码

下面是整个项目的完整代码,包括数据探索、特征工程、模型训练和评估的全过程:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 加载数据
data = pd.read_csv('Credit_Card.csv')

# 查看数据集行数和列数
rows, columns = data.shape

if rows < 1000:
    sample = 1
elif rows < 10000:
    sample = 0.5
else:
    sample = 0.1

# 查看数据的基本信息
print('数据基本信息:')
data.info()

# 查看数据集行数和列数
rows, columns = data.shape

# 查看数据集行数和列数
print('数据全部内容信息:')
print(data.to_csv(sep='\t', na_rep='nan'))

# 查看年龄分布情况
age = data['AGE']
payment = data[data["payment.next.month"]==1]['AGE']

# 设置年龄分组
bins = [20, 30, 40, 50, 60, 70, 80]

# 整体年龄分布
seg = pd.cut(age, bins, right=False)
counts = pd.value_counts(seg, sort=False)

plt.figure(figsize=(10, 6))
b = plt.bar(counts.index.astype(str), counts)
plt.bar_label(b, counts)
plt.title('客户年龄分布')
plt.xlabel('年龄区间')
plt.ylabel('客户数量')
plt.show()

# 逾期客户的年龄分布
payment_seg = pd.cut(payment, bins, right=False)
counts1 = pd.value_counts(payment_seg, sort=False)

plt.figure(figsize=(10, 6))
b2 = plt.bar(counts1.index.astype(str), counts1, color='r')
plt.bar_label(b2, counts1)
plt.title('逾期客户的年龄分布')
plt.xlabel('年龄区间')
plt.ylabel('逾期客户数量')
plt.show()

# 查看逾期率情况
next_month = data['payment.next.month'].value_counts()
df = pd.DataFrame({'payment.next.month': next_month.index, 'values': next_month.values})

plt.figure(figsize=(6, 6))
plt.title('逾期率客户\n (还款:0, 逾期:1)')
sns.set_color_codes("pastel")
sns.barplot(x='payment.next.month', y="values", data=df)
plt.show()

# 计算逾期比例
overdue_ratio = next_month[1] / (next_month[0] + next_month[1]) * 100
print(f'逾期比例: {overdue_ratio:.2f}%')

# 计算相关性矩阵
correlation = data.corr()

# 显示负号
plt.rcParams['axes.unicode_minus'] = False

# 绘制热力图
plt.figure(figsize=(18, 18))
sns.heatmap(correlation, annot=True, cmap='coolwarm', fmt='.2f', square=True)
plt.title('特征相关性热力图')
plt.show()

# 查看与目标变量相关性最强的10个特征
target_correlation = correlation['payment.next.month'].abs().sort_values(ascending=False)
print('与逾期还款相关性最强的10个特征:')
print(target_correlation[1:11])  # 排除自身相关性

# 去除ID列,因为它对预测没有帮助
data.drop(['ID'], inplace=True, axis=1)

# 检查缺失值
missing_values = data.isnull().sum()
print('缺失值统计:')
print(missing_values[missing_values > 0])

# 如果有缺失值,进行填充
if missing_values.sum() > 0:
    # 数值型特征用中位数填充
    numeric_cols = data.select_dtypes(include=[np.number]).columns.tolist()
    for col in numeric_cols:
        data[col].fillna(data[col].median(), inplace=True)
    
    # 分类特征用众数填充
    categorical_cols = data.select_dtypes(include=['object']).columns.tolist()
    for col in categorical_cols:
        data[col].fillna(data[col].mode()[0], inplace=True)

# 检查异常值
# 以LIMIT_BAL为例,查看是否有异常值
q1 = data['LIMIT_BAL'].quantile(0.25)
q3 = data['LIMIT_BAL'].quantile(0.75)
iqr = q3 - q1
lower_bound = q1 - 1.5 * iqr
upper_bound = q3 + 1.5 * iqr

outliers = data[(data['LIMIT_BAL'] < lower_bound) | (data['LIMIT_BAL'] > upper_bound)]
print(f'LIMIT_BAL特征的异常值数量: {len(outliers)}')

# 提取特征和目标变量
target = data['payment.next.month'].values
columns = data.columns.tolist()
columns.remove('payment.next.month')
features = data[columns].values

# 显示特征数量
print(f'提取的特征数量: {len(columns)}')
print('特征列表:')
print(columns)

# 70%作为训练集,30%作为测试集
train_x, test_x, train_y, test_y = train_test_split(features, target, test_size=0.30, stratify=target, random_state=1)

print(f'训练集样本数: {len(train_x)}')
print(f'测试集样本数: {len(test_x)}')
print(f'训练集逾期样本比例: {np.mean(train_y):.2f}')
print(f'测试集逾期样本比例: {np.mean(test_y):.2f}')

# 构造各种分类器
classifiers = [
    SVC(random_state=1, kernel='rbf'),
    DecisionTreeClassifier(random_state=1, criterion='gini'),
    RandomForestClassifier(random_state=1, criterion='gini'),
    KNeighborsClassifier(metric='minkowski'),
    LogisticRegression(random_state=1)
]

# 分类器名称
classifier_names = [
    'SVM',
    '决策树',
    '随机森林',
    'K近邻',
    '逻辑回归'
]

# 分类器参数
classifier_param_grid = [
    {'SVM__C': [1, 5, 10], 'SVM__gamma': [0.01, 0.1]},
    {'决策树__max_depth': [6, 9, 11]},
    {'随机森林__n_estimators': [3, 5, 6]},
    {'K近邻__n_neighbors': [4, 6, 8]},
    {'逻辑回归__C': [0.1, 1, 10]}
]

# 对具体的分类器进行GridSearchCV参数调优
def GridSearchCV_work(pipeline, train_x, train_y, test_x, test_y, param_grid, score='accuracy'):
    response = {}
    gridsearch = GridSearchCV(estimator=pipeline, param_grid=param_grid, scoring=score, cv=5, n_jobs=-1)
    
    # 寻找最优的参数和最优的准确率分数
    search = gridsearch.fit(train_x, train_y)
    print(f"GridSearch最优参数:{search.best_params_}")
    print(f"GridSearch最优交叉验证分数:{search.best_score_:.4f}")
    
    # 在测试集上的评估
    predict_y = gridsearch.predict(test_x)
    accuracy = accuracy_score(test_y, predict_y)
    print(f"测试集准确率:{accuracy:.4f}")
    
    # 计算混淆矩阵
    cm = confusion_matrix(test_y, predict_y)
    print("混淆矩阵:")
    print(cm)
    
    # 计算分类报告
    cr = classification_report(test_y, predict_y)
    print("分类报告:")
    print(cr)
    
    response['predict_y'] = predict_y
    response['accuracy_score'] = accuracy
    response['best_params'] = search.best_params_
    response['model'] = gridsearch.best_estimator_
    
    return response

# 存储所有模型的结果
results = []

# 对每个分类器进行训练和评估
for model, model_name, model_param_grid in zip(classifiers, classifier_names, classifier_param_grid):
    print(f"\n===== 正在训练 {model_name} =====")
    
    # 构建管道
    pipeline = Pipeline([
        ('scaler', StandardScaler()),
        (model_name, model)
    ])
    
    # 进行网格搜索
    result = GridSearchCV_work(pipeline, train_x, train_y, test_x, test_y, model_param_grid, score='accuracy')
    
    # 存储结果
    result['model_name'] = model_name
    results.append(result)

# 比较不同模型的性能
print("\n===== 模型性能比较 =====")
for result in results:
    print(f"{result['model_name']}: 准确率 = {result['accuracy_score']:.4f}")

# 提取模型名称和准确率
model_names = [result['model_name'] for result in results]
accuracies = [result['accuracy_score'] for result in results]

# 创建条形图比较模型性能
plt.figure(figsize=(12, 6))
plt.bar(model_names, accuracies, color='skyblue')
plt.ylim([0.7, 0.9])  # 设置y轴范围,使差异更明显
plt.title('不同模型的准确率比较')
plt.xlabel('模型')
plt.ylabel('准确率')
plt.grid(axis='y', linestyle='--', alpha=0.7)

# 添加数值标签
for i, v in enumerate(accuracies):
    plt.text(i, v + 0.002, f'{v:.4f}', ha='center')

plt.tight_layout()
plt.show()

# 输出最优模型
best_model_idx = np.argmax(accuracies)
best_model = results[best_model_idx]['model']
best_model_name = results[best_model_idx]['model_name']
best_accuracy = results[best_model_idx]['accuracy_score']

print(f"\n最优模型:{best_model_name},准确率:{best_accuracy:.4f}")
print(f"最优模型参数:{results[best_model_idx]['best_params']}")

# 如果是随机森林模型,查看特征重要性
if best_model_name == '随机森林':
    feature_importance = best_model.named_steps['随机森林'].feature_importances_
    feature_importance_df = pd.DataFrame({
        '特征': columns,
        '重要性': feature_importance
    })
    feature_importance_df = feature_importance_df.sort_values('重要性', ascending=False)
    
    print("\n特征重要性排名:")
    print(feature_importance_df)
    
    # 绘制特征重要性图
    plt.figure(figsize=(12, 8))
    sns.barplot(x='重要性', y='特征', data=feature_importance_df)
    plt.title('随机森林模型特征重要性')
    plt.tight_layout()
    plt.show()

七.数据集关注call me 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值