讯飞-糖尿病遗传风险检测挑战赛

  • 前言
  • 相关库
  • 一、比赛报名
    • 1.1 赛事任务
    • 1.2 读取数据
      • 训练数据集
      • 测试数据集
    • 1.3 数据集基本信息
      • 数据集维度
      • 数据表基本信息
  • 二、比赛数据分析
    • 2.1 缺失值统计
    • 2.2 分析字段类型
      • 每一列数据的类型
      • int 和 float 类型数据的描述性统计
    • 2.3 字段相关性
    • 2.4 小结
  • 三、逻辑回归尝试
    • 3.1 使用名义变量重构糖尿病家族史和性别
    • 3.2 处理缺失值
    • 3.3 网格搜索查找最佳超参数
    • 3.4 初步评分
  • 四、特征工程
    • 4.1 增加年龄特征
    • 4.2 增加个体与性别平均值之间的差值字段

前言

本文章是在Coggle 30 Days of ML(22年7月)活动中创作的

截至2022年,中国糖尿病患者近1.3亿。中国糖尿病患病原因受生活方式、老龄化、城市化、家族遗传等多种因素影响。同时,糖尿病患者趋向年轻化。

糖尿病可导致心血管、肾脏、脑血管并发症的发生。因此,准确诊断出患有糖尿病个体具有非常重要的临床意义。糖尿病早期遗传风险预测将有助于预防糖尿病的发生。

根据《中国2型糖尿病防治指南(2017年版)》,糖尿病的诊断标准是具有典型糖尿病症状(烦渴多饮、多尿、多食、不明原因的体重下降)且随机静脉血浆葡萄糖≥11.1mmol/L或空腹静脉血浆葡萄糖≥7.0mmol/L或口服葡萄糖耐量试验(OGTT)负荷后2h血浆葡萄糖≥11.1mmol/L。

在这次比赛中,需要通过训练数据集构建糖尿病遗传风险预测模型,然后预测出测试数据集中个体是否患有糖尿病,和我们一起帮助糖尿病患者解决这“甜蜜的烦恼”。


相关库

  1. pandas(1.1.5)
  2. numpy(1.19.5)
  3. matplotlib(3.3.4)
  4. seaborn(0.11.2)
  5. scikit-learn(0.24.2)
%matplotlib inline
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import MinMaxScaler
from sklearn.pipeline import make_pipelineplt.rcParams['font.sans-serif'] = ['FangSong']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

一、比赛报名

1.1 赛事任务

以下介绍从官网上复制而来

数据集字段说明:

  • 编号:标识个体身份的数字;
  • 性别:1 表示男性,0 表示女性;
  • 出生年份,出生的年份,XXXX 格式;
  • 体重指数:体重除以身高的平方,单位 kg/m2kg/m^2kg/m2;
  • 糖尿病家族史,标识糖尿病的遗传特征,记录家族里面患有糖尿病的家属;
  • 舒张压:心脏舒张时,动脉血管弹性回缩时,产生的压力成为舒张压,单位 mmHgmmHgmmHg;
  • 口服耐糖量测试:比赛数据采用 120 分钟耐糖测试后的血糖值,单位 mmol/Lmmol/Lmmol/L;
  • 胰岛素释放实验:空腹时定量口服葡萄糖刺激 β\betaβ 细胞释放胰岛素,比赛数据采用服糖后 120 分钟的血浆胰岛素水平,单位 pmol/L;
  • 肱三头肌皮褶厚度:在右上臂后面肩峰与鹰嘴连线的重点处,夹取与上肢衣袖平行的皮褶,纵向测量,单位 cm;
  • 患有糖尿病标识:数据标签,1 表示患有糖尿病,0 表示未患有糖尿病。

1.2 读取数据

训练数据集

df_train = pd.read_csv(filepath_or_buffer='../data/比赛训练集.csv', encoding='gbk', index_col='编号')
df_train.head()
性别 出生年份 体重指数 糖尿病家族史 舒张压 口服耐糖量测试 胰岛素释放实验 肱三头肌皮褶厚度 患有糖尿病标识
编号
1 0 1996 30.1 无记录 106.0 3.818 7.89 0.0 0
2 0 1988 27.5 无记录 84.0 -1.000 0.00 14.7 0
3 1 1988 36.5 无记录 85.0 7.131 0.00 40.1 1
4 1 1992 29.5 无记录 91.0 7.041 0.00 0.0 0
5 0 1998 42.0 叔叔或者姑姑有一方患有糖尿病 NaN 7.134 0.00 0.0 1

测试数据集

df_test = pd.read_csv(filepath_or_buffer='../data/比赛测试集.csv', encoding='gbk', index_col='编号')
df_test.head()
性别 出生年份 体重指数 糖尿病家族史 舒张压 口服耐糖量测试 胰岛素释放实验 肱三头肌皮褶厚度
编号
1 0 1987 33.1 无记录 72.0 6.586 24.16 2.94
2 0 1998 20.6 叔叔或者姑姑有一方患有糖尿病 68.0 3.861 0.00 0.00
3 1 1979 42.1 无记录 98.0 5.713 0.00 3.53
4 0 1999 34.6 无记录 66.0 4.684 0.00 3.14
5 0 1997 27.7 无记录 89.0 7.948 14.65 2.65

1.3 数据集基本信息

数据集维度

print(df_train.shape)
print(df_test.shape)
(5070, 9)
(1000, 8)

数据表基本信息

print('训练集:')
df_train.info()
训练集:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 5070 entries, 1 to 5070
Data columns (total 9 columns):#   Column    Non-Null Count  Dtype
---  ------    --------------  -----  0   性别        5070 non-null   int64  1   出生年份      5070 non-null   int64  2   体重指数      5070 non-null   float643   糖尿病家族史    5070 non-null   object 4   舒张压       4823 non-null   float645   口服耐糖量测试   5070 non-null   float646   胰岛素释放实验   5070 non-null   float647   肱三头肌皮褶厚度  5070 non-null   float648   患有糖尿病标识   5070 non-null   int64
dtypes: float64(5), int64(3), object(1)
memory usage: 396.1+ KB
df_train['糖尿病家族史'].unique()
array(['无记录', '叔叔或者姑姑有一方患有糖尿病', '叔叔或姑姑有一方患有糖尿病', '父母有一方患有糖尿病'],dtype=object)
print('测试集:')
df_test.info()
测试集:
<class 'pandas.core.frame.DataFrame'>
Int64Index: 1000 entries, 1 to 1000
Data columns (total 8 columns):#   Column    Non-Null Count  Dtype
---  ------    --------------  -----  0   性别        1000 non-null   int64  1   出生年份      1000 non-null   int64  2   体重指数      1000 non-null   float643   糖尿病家族史    1000 non-null   object 4   舒张压       951 non-null    float645   口服耐糖量测试   1000 non-null   float646   胰岛素释放实验   1000 non-null   float647   肱三头肌皮褶厚度  1000 non-null   float64
dtypes: float64(5), int64(2), object(1)
memory usage: 70.3+ KB
df_test['糖尿病家族史'].unique()
array(['无记录', '叔叔或者姑姑有一方患有糖尿病', '父母有一方患有糖尿病', '叔叔或姑姑有一方患有糖尿病'],dtype=object)

二、比赛数据分析

2.1 缺失值统计

分析 1.3 数据集基本信息和下面的统计,发现训练集一共有 5070 条数据,但舒张压字段却只有 4823 个非空数据,其他字段都有 5070 个非空数据;测试集一共有 1000 条数据,舒张压字段只有 951 个非空数据。因此,可以发现无论是训练集还是测试集,只有舒张压字段存在缺失值,其中训练集存在 247 条带缺失值的数据,测试集 存在 49 条带缺失值的数据。

print('训练集每一列缺失值统计个数:')
df_train.isnull().sum()
训练集每一列缺失值统计个数:性别            0
出生年份          0
体重指数          0
糖尿病家族史        0
舒张压         247
口服耐糖量测试       0
胰岛素释放实验       0
肱三头肌皮褶厚度      0
患有糖尿病标识       0
dtype: int64
print('测试集每一列缺失值统计个数:')
df_test.isnull().sum()
测试集每一列缺失值统计个数:性别           0
出生年份         0
体重指数         0
糖尿病家族史       0
舒张压         49
口服耐糖量测试      0
胰岛素释放实验      0
肱三头肌皮褶厚度     0
dtype: int64

训练集和测试集各列缺失比例计算:

df_train.isnull().mean(0)
性别          0.000000
出生年份        0.000000
体重指数        0.000000
糖尿病家族史      0.000000
舒张压         0.048718
口服耐糖量测试     0.000000
胰岛素释放实验     0.000000
肱三头肌皮褶厚度    0.000000
患有糖尿病标识     0.000000
dtype: float64
df_test.isnull().mean(0)
性别          0.000
出生年份        0.000
体重指数        0.000
糖尿病家族史      0.000
舒张压         0.049
口服耐糖量测试     0.000
胰岛素释放实验     0.000
肱三头肌皮褶厚度    0.000
dtype: float64

从上面两处结果可以看出训练集和测试集的缺失值分布差异不大,唯一包含缺失值的是舒张压这一列,且缺失值占比不大。

2.2 分析字段类型

每一列数据的类型

训练集数据类型

df_train.dtypes
性别            int64
出生年份          int64
体重指数        float64
糖尿病家族史       object
舒张压         float64
口服耐糖量测试     float64
胰岛素释放实验     float64
肱三头肌皮褶厚度    float64
患有糖尿病标识       int64
dtype: object

测试集数据类型

df_test.dtypes
性别            int64
出生年份          int64
体重指数        float64
糖尿病家族史       object
舒张压         float64
口服耐糖量测试     float64
胰岛素释放实验     float64
肱三头肌皮褶厚度    float64
dtype: object

int 和 float 类型数据的描述性统计

训练集描述性统计

df_train[['性别', '出生年份', '体重指数', '舒张压', '口服耐糖量测试', '胰岛素释放实验', '肱三头肌皮褶厚度']].describe()
性别 出生年份 体重指数 舒张压 口服耐糖量测试 胰岛素释放实验 肱三头肌皮褶厚度
count 5070.000000 5070.000000 5070.000000 4823.000000 5070.000000 5070.000000 5070.000000
mean 0.456805 1986.869231 37.986785 89.423595 5.612839 4.114321 6.994371
std 0.498180 8.919737 11.447095 9.266992 2.257649 8.726001 13.651442
min 0.000000 1943.000000 0.000000 30.000000 -1.000000 0.000000 0.000000
25% 0.000000 1980.000000 28.400000 85.000000 4.314000 0.000000 0.000000
50% 0.000000 1987.000000 36.550000 89.000000 5.760000 0.000000 0.000000
75% 1.000000 1995.000000 47.600000 96.000000 7.193000 7.100000 4.120000
max 1.000000 2009.000000 65.900000 126.000000 10.839000 108.960000 45.000000

测试集描述性统计

df_test[['性别', '出生年份', '体重指数', '舒张压', '口服耐糖量测试', '胰岛素释放实验', '肱三头肌皮褶厚度']].describe()
性别 出生年份 体重指数 舒张压 口服耐糖量测试 胰岛素释放实验 肱三头肌皮褶厚度
count 1000.000000 1000.000000 1000.000000 951.000000 1000.000000 1000.000000 1000.000000
mean 0.481000 1986.386000 39.439000 89.638275 5.872314 4.102700 7.064240
std 0.499889 8.816163 11.284861 9.379124 1.930880 8.594005 13.900938
min 0.000000 1958.000000 0.000000 28.000000 -1.000000 0.000000 0.000000
25% 0.000000 1979.000000 29.975000 85.000000 4.516000 0.000000 0.000000
50% 0.000000 1987.000000 38.900000 89.000000 5.851500 0.000000 0.000000
75% 1.000000 1994.000000 48.950000 96.000000 7.465000 7.202500 3.820000
max 1.000000 2003.000000 60.000000 112.000000 10.613000 123.890000 44.900000

对训练集和测试集进行描述性统计,发现两个数据集在平均值、方差、四分位数、中位数等方面差异不大。

2.3 字段相关性

训练集各字段及标签之间的相关性

# 训练集相关性热力图矩阵
plt.subplots(figsize=(10,10))
sns.heatmap(df_train.corr(method='pearson'), annot=True, vmax=1, square=True, cmap='RdBu_r')
plt.savefig('../images/train_pearson.jpg', dpi=800)


测试集各字段相关性

# 测试集相关性热力图矩阵
plt.subplots(figsize=(10,10))
sns.heatmap(df_test.corr(method='pearson'), annot=True, vmax=1, square=True, cmap='RdBu_r')
plt.savefig('../images/test_pearson.jpg', dpi=800)


从 2.3 中的两个热力图可以看出,训练集中体重指数和肱三头肌皮褶厚度与标签的相关性相对较高,肱三头肌皮褶厚度与标签的相关性最高。各字段之间的相关性普遍不高。

2.4 小结

通过对训练集和测试集计算缺失值比例、分析字段类型、进行描述性统计、计算字段相关性,可以发现训练集和测试集各项指标间的差异很小,甚至几乎没有,实现控制异常数据对模型的干扰。

三、逻辑回归尝试

3.1 使用名义变量重构糖尿病家族史和性别

dict_糖尿病家族史 = {'无记录': 0,'叔叔或姑姑有一方患有糖尿病': 1,'叔叔或者姑姑有一方患有糖尿病': 1,'父母有一方患有糖尿病': 2
}df_train['糖尿病家族史'] = df_train['糖尿病家族史'].map(dict_糖尿病家族史)
df_train['糖尿病家族史'] = df_train['糖尿病家族史'].astype('category')df_test['糖尿病家族史'] = df_test['糖尿病家族史'].map(dict_糖尿病家族史)
df_test['糖尿病家族史'] = df_test['糖尿病家族史'].astype('category')
# 查看重构后的结果
print(df_train['糖尿病家族史'].unique())
print(df_test['糖尿病家族史'].unique())
[0, 1, 2]
Categories (3, int64): [0, 1, 2]
[0, 1, 2]
Categories (3, int64): [0, 1, 2]
df_train['性别'] = df_train['性别'].astype('category')
df_test['性别'] = df_test['性别'].astype('category')
print(df_train['性别'].unique())
print(df_test['性别'].unique())
[0, 1]
Categories (2, int64): [0, 1]
[0, 1]
Categories (2, int64): [0, 1]

3.2 处理缺失值

这里要提一下,我是第一次做讯飞的数据挖掘题,所以对比赛数据格式不是很了解,最开始处理缺失值的时候采用的是 dropna 的方法,这样做会将部分编号的数据给删掉,但是这样做会导致评测失败,失败原因:输入格式错误。所以后来换了 fillna 的方法。

# 用前一个非空白值填补
df_train['舒张压'].fillna(method='ffill', inplace=True)
df_test['舒张压'].fillna(method='ffill', inplace=True)
print('训练集每一列缺失值统计个数:')
print(df_train.isnull().sum())
print('\n')
print('测试集每一列缺失值统计个数:')
print(df_test.isnull().sum())
训练集每一列缺失值统计个数:
性别          0
出生年份        0
体重指数        0
糖尿病家族史      0
舒张压         0
口服耐糖量测试     0
胰岛素释放实验     0
肱三头肌皮褶厚度    0
患有糖尿病标识     0
dtype: int64测试集每一列缺失值统计个数:
性别          0
出生年份        0
体重指数        0
糖尿病家族史      0
舒张压         0
口服耐糖量测试     0
胰岛素释放实验     0
肱三头肌皮褶厚度    0
dtype: int64
df_train.head()
性别 出生年份 体重指数 糖尿病家族史 舒张压 口服耐糖量测试 胰岛素释放实验 肱三头肌皮褶厚度 患有糖尿病标识
编号
1 0 1996 30.1 0 106.0 3.818 7.89 0.0 0
2 0 1988 27.5 0 84.0 -1.000 0.00 14.7 0
3 1 1988 36.5 0 85.0 7.131 0.00 40.1 1
4 1 1992 29.5 0 91.0 7.041 0.00 0.0 0
5 0 1998 42.0 1 91.0 7.134 0.00 0.0 1
df_test.head()
性别 出生年份 体重指数 糖尿病家族史 舒张压 口服耐糖量测试 胰岛素释放实验 肱三头肌皮褶厚度
编号
1 0 1987 33.1 0 72.0 6.586 24.16 2.94
2 0 1998 20.6 1 68.0 3.861 0.00 0.00
3 1 1979 42.1 0 98.0 5.713 0.00 3.53
4 0 1999 34.6 0 66.0 4.684 0.00 3.14
5 0 1997 27.7 0 89.0 7.948 14.65 2.65

挑选出字段集和标签集

X = df_train.drop(columns='患有糖尿病标识', inplace=False)
y = df_train['患有糖尿病标识']

3.3 网格搜索查找最佳超参数

使用 sklearn 库的 GridSearchCV 实现网格搜索,并在上面训练集 df_train 上划分出的数据集 X_train 和 y_train 上进行 5 折交叉验证,用 X_test 和 y_test 进行检测,查找最佳超参数。

model = make_pipeline(MinMaxScaler(), LogisticRegression(penalty='l2', multi_class='ovr',max_iter=10000))
params = {'logisticregression__solver': ['liblinear', 'sag', 'saga', 'newton-cg', 'lbfgs'],'logisticregression__C': np.linspace(0.1, 1, 10)
}
model.get_params().keys()
dict_keys(['memory', 'steps', 'verbose', 'minmaxscaler', 'logisticregression', 'minmaxscaler__clip', 'minmaxscaler__copy', 'minmaxscaler__feature_range', 'logisticregression__C', 'logisticregression__class_weight', 'logisticregression__dual', 'logisticregression__fit_intercept', 'logisticregression__intercept_scaling', 'logisticregression__l1_ratio', 'logisticregression__max_iter', 'logisticregression__multi_class', 'logisticregression__n_jobs', 'logisticregression__penalty', 'logisticregression__random_state', 'logisticregression__solver', 'logisticregression__tol', 'logisticregression__verbose', 'logisticregression__warm_start'])
grid = GridSearchCV(estimator=model, param_grid=params, cv=5, verbose=1)
grid.fit(X=X, y=y)
Fitting 5 folds for each of 50 candidates, totalling 250 fitsGridSearchCV(cv=5,estimator=Pipeline(steps=[('minmaxscaler', MinMaxScaler()),('logisticregression',LogisticRegression(max_iter=10000,multi_class='ovr'))]),param_grid={'logisticregression__C': array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ]),'logisticregression__solver': ['liblinear', 'sag','saga', 'newton-cg','lbfgs']},verbose=1)
df_test['label'] = grid.predict(df_test)
df_test.head()
性别 出生年份 体重指数 糖尿病家族史 舒张压 口服耐糖量测试 胰岛素释放实验 肱三头肌皮褶厚度 label
编号
1 0 1987 33.1 0 72.0 6.586 24.16 2.94 0
2 0 1998 20.6 1 68.0 3.861 0.00 0.00 0
3 1 1979 42.1 0 98.0 5.713 0.00 3.53 0
4 0 1999 34.6 0 66.0 4.684 0.00 3.14 0
5 0 1997 27.7 0 89.0 7.948 14.65 2.65 0
df_test.index.name = 'uuid'
df_test['label'].to_csv(path_or_buf='../data/submit.csv', index='uuid')

3.4 初步评分

这里的分数只有 0.7,可能是因为训练模型过拟合,也可能是模型原因,后续再加以改进


四、特征工程

4.1 增加年龄特征

df_train['年龄'] = 2022 - df_train['年龄']
df_test['年龄'] = 2022 - df_test['年龄']

4.2 增加个体与性别平均值之间的差值字段

先到这,后面再补充

讯飞-糖尿病遗传风险检测挑战赛相关推荐

  1. 2022讯飞——糖尿病遗传风险检测挑战赛解决方案

    目录: 0. 赛事背景 1. 读取数据 2. 数据探索及预处理 2.1 缺失值 2.2 分析字段类型 2.3 计算字段相关性 3. 特征工程 3.1 特征构造 4. 模型训练 4.1 LightGBM ...

  2. 糖尿病遗传风险检测挑战赛(Coggle 30 Days of ML)

    本次跟着Coggle 30 Days of ML学习算法竞赛,而不是基于现成baseline来操作,预计重新熟悉并学习 Pandas.Numpy 处理数据 Sklearn.LightGBM 模型使用 ...

  3. 糖尿病遗传风险检测挑战赛竞赛学习

    目录 一:报名比赛 二:比赛数据分析 三:逻辑回归尝试 五:特征筛选 六:高阶树模型 七:多折训练与集成 !!!Staking!!! 任务一:报名比赛 糖尿病遗传风险检测挑战赛是讯飞开放平台上的一个算 ...

  4. 糖尿病遗传风险检测挑战赛

    糖尿病遗传风险检测挑战赛 加载数据 import pandas as pd import lightgbm import matplotlib.pyplot as plt %matplotlib in ...

  5. 【Coggle 】糖尿病遗传风险检测挑战赛

    文章目录 活动背景 一.赛题介绍 二.打卡任务 任务1:报名比赛 步骤1:报名比赛 步骤2:下载比赛数据(点击比赛页面的赛题数据) 步骤3:解压比赛数据,并使用pandas进行读取: 步骤4:查看训练 ...

  6. 竞赛打卡:糖尿病遗传风险检测挑战赛

    竞赛打卡:糖尿病遗传风险检测挑战赛 本博客是竞赛学习打卡记录博客.学习地址Coggle七月学习打卡.就是记录在竞赛学习过程中的打卡内容(有可能不会按照内容全部进行打卡,时间可能不是很够

  7. 数据挖掘竞赛——糖尿病遗传风险检测挑战赛进阶

    本次比赛是一个数据挖掘赛,需要选手通过训练集数据构建模型,然后对验证集数据进行预测,预测结果进行提交. 本题的任务是构建一种模型,该模型能够根据患者的测试数据来预测这个患者是否患有糖尿病.这种类型的任 ...

  8. 糖尿病遗传风险检测挑战赛-Coggle 30 Days of ML

    前言 跟着coggle的7月竞赛学习活动,记录一些个人学习的过程,本博客围绕着科大讯飞糖尿病遗传风险检测挑战赛展开. 比赛地址:http://challenge.xfyun.cn/topic/info ...

  9. 【Datawhale】【机器学习】糖尿病遗传风险检测挑战赛

    糖尿病遗传风险检测挑战赛 赛题介绍 截至2022年,中国糖尿病患者近1.3亿.中国糖尿病患病原因受生活方式.老龄化.城市化.家族遗传等多种因素影响.同时,糖尿病患者趋向年轻化. 糖尿病可导致心血管.肾 ...

最新文章

  1. 仅需6步,教你轻易撕掉app开发框架的神秘面纱(3):构造具有个人特色的MVP模式
  2. 解密Kernel:为什么适用任何机器学习算法?
  3. Windows Vista即将发布SP1
  4. 新手教程:用.htaccess实现二级域名功能
  5. typedef和define一些问题
  6. pg与oracle区别,PostgresQL 学习记录之与oracle区别(一)
  7. sqlmap指定cookie_利用SQLMap进行cookie注入
  8. CentOS 下无线网卡的安装和使用
  9. java nio netty_Netty精粹之JAVA NIO开发需要知道的
  10. qt linux编程思路,关于QT编程入门的那些事
  11. Android sdk 环境变量配置无效
  12. 大唐双龙传JAVA版小游戏_大唐双龙传_JAVA游戏免费版下载_7723手机游戏[www.7723.cn]...
  13. 7-161 双曲余弦函数(*)
  14. uniapp使用企业微信SDK踩坑指南
  15. 春夏喝绿茶花茶、秋冬喝乌龙普洱红茶
  16. 因为Windows防火墙服务未运行,不能正常使用
  17. EditPlus字体放大方法
  18. python房价预测模型_python随机森林房价预测
  19. mcnpf5输出结果_MCNP4c3说明
  20. eclipse安装PyDev-使用eclipse开发python

热门文章

  1. 微PE装Win10详细教程:UEFI+GPT方式
  2. ADB系统变量的配置
  3. linux终端窗口适应屏幕,自动调整2个窗口占用屏幕一半的方法
  4. 【软件后门】资源(dll、ocx、exe)语言切换(汉化)、图标更改
  5. 002-CANoe 10.0 SP3 软件和CAN卡的配置笔记
  6. 128陷阱理解(Java中的128陷阱)
  7. 【分享】5S管理专员测试试题
  8. 基金a类和c类 收费什么区别
  9. 公司内服务器微信报警怎么做,一种用企业微信实现信息报警的装置制造方法及图纸...
  10. 树莓派安装Python-OpenCV