风控算法(2)字节-小样本半监督风险识别

字节跳动安全AI挑战赛-大佬等等我

  • 比赛链接:https://security.bytedance.com/fe/ai-challenge#/challenge
    • 基于文本和多模态数据的风险识别
      • 电商黄牛地址识别
      • 色情导流用户识别
    • 小样本半监督风险识别
      • 人机识别
      • 少样本作弊样本检测任务
  • 人工智能竞赛复盘:2021安全AI挑战赛 :https://www.bilibili.com/video/BV1PL4y1n7SN?spm_id_from=333.337.search-card.all.click&vd_source=29387dc08d18f642078183a6816e93e8
  • 炼丹术士Zoro:https://www.zhihu.com/people/AIMuseum/posts
  • 字节跳动安全AI挑战赛直播笔记 - 知乎 https://zhuanlan.zhihu.com/p/435018506

小样本半监督风险识别

一、赛题描述

在真实的社交网络中,存在的作弊用户会影响社交网络平台。在真实场景中,会受到多方面的约束,我们仅能获取到少部分的作弊样本和一部分正常用户样本,现需利用已有的少量带标签的样本,去挖掘大量未知样本中的剩余作弊样本。给定一段时间内的样本,其中包含少量作弊样本,部分正常样本以及标签未知的样本。参赛者应该利用这段时间内已有的数据,提出自己的解决方案,以预测标签未知的样本是否为作弊样本。数据处理方法和算法不限,但是参赛者需要综合考虑算法的效果和复杂度,从而构建合理的解决方案。

1.1 赛题数据与评价指标

赛题数据:本次比赛给出的数据是T~T+N 时刻内点赞、关注事件下按比例抽样数据以及其对应账号的基础特征数据。

评价指标:本赛题使用F1-score来评估模型的准召程度

二、 解决方案一

首先明确本赛题实质上仍然是一个二分类的问题,我们也可以完全从此角度出来先构建出一个基础分类模型,然后再利用大量无标签的数据进行半监督学习来提升模型性能

风险识别:第二名源代码 https://github.com/Ljwccc/ByteDanceSecurityAI

  • 用户侧特征:
    • 账户本身的基础特征
    • 账户本身的特征计数统计
    • 粉丝量、关注量、发帖量、被点赞量、最后登陆时间-注册时间 乘除交叉
    • 从请求数据中提取出来的device_type, app_version, app_channel类别特征,直接作为静态画像使用
    • 类别特征下的数值统计特征 min/sum/max/std
  • 请求侧特征:
    • 用户请求的时间序列特征, 时间差序列特征 min/sum/max/std
    • w2v特征, 每个用户的请求ip序列建模

2.1 特征工程

从序列特征中提取用户的设备信息、channel信息和app_version信息

1
2
3
4
5
6
7
8
9
10
11
12
# 先 group
user_request_cat_group = user_request.groupby(['request_user'],as_index=False)

user_request_device_type = user_request_cat_group['request_device_type'].agg({'device_type_list':list})
user_request_channel = user_request_cat_group['request_app_channel'].agg({'channel_list':list})
user_request_app_version = user_request_cat_group['request_app_version'].agg({'app_version_list':list})

user_request_device_type['device_type'] = user_request_device_type['device_type_list'].apply(lambda x:x[0])
user_request_channel['channel'] = user_request_channel['channel_list'].apply(lambda x:x[0])
user_request_app_version['app_version'] = user_request_app_version['app_version_list'].apply(lambda x:x[-1])

user_feat_from_action = pd.concat([user_request_device_type[['request_user','device_type']],user_request_channel[['channel']], user_request_app_version[['app_version']]],axis=1).rename(columns={'request_user':'user'})

2.1.1 用户基础特征

类别特征

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 类别特征
cat_cols = ['user_name','user_profile','user_register_type','user_register_app','user_least_login_app','user_freq_ip','user_freq_ip_3','device_type','channel','app_version','user_freq_ip_2','user_freq_ip_1',]

# 手工类别特征
user_info['user_freq_ip_3'] = user_info['user_freq_ip'].apply(lambda x:'.'.join(str(x).split('.')[:3])) # 常用ip取前3位
user_info['user_freq_ip_2'] = user_info['user_freq_ip'].apply(lambda x:'.'.join(str(x).split('.')[:2])) # 常用ip取前2位
user_info['user_freq_ip_1'] = user_info['user_freq_ip'].apply(lambda x:'.'.join(str(x).split('.')[:1])) # 常用ip取前1位

# 合并从request中提取的基础特征
user_info = user_info.merge(user_feat_from_action,on='user',how='left')
del user_feat_from_action

# 类别特征的频次
for col in cat_cols:
user_info = freq_enc(user_info,col)

# 对所有类别特征做label_encoder
user_info = label_enc(user_info,cat_cols)

点赞量,关注量等交叉特征,直接梭哈所有乘除法

1
2
3
4
5
6
num_cols = ['user_fans_num','user_follow_num','user_post_num','user_post_like_num']

for col1 in num_cols:
for col2 in [col for col in num_cols if col!=col1]:
user_info[f'{col1}_{col2}_mul'] = user_info[col1]*user_info[col2]
user_info[f'{col1}_{col2}_div'] = user_info[col1]/(user_info[col2]+1e-3)

类别特征下粉丝量、关注量、发帖量、被点赞量、请求数量的统计值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
num_cols = ['user_fans_num','user_follow_num','user_post_num','user_post_like_num']
for cat_col in cat_cols:
cat_group = user_info.groupby(cat_col)[num_cols]
# 平均值
cat_col_stat = cat_group.transform(np.mean)
cat_col_stat.rename(columns={name:f'{name}_{cat_col}_mean' for name in cat_col_stat.columns},inplace=True)
user_info = pd.concat([user_info,cat_col_stat],axis=1)
# 和
cat_col_stat = cat_group.transform(np.sum)
cat_col_stat.rename(columns={name:f'{name}_{cat_col}_sum' for name in cat_col_stat.columns},inplace=True)
user_info = pd.concat([user_info,cat_col_stat],axis=1)
# 方差
cat_col_stat = cat_group.transform(np.std)
cat_col_stat.rename(columns={name:f'{name}_{cat_col}_std' for name in cat_col_stat.columns},inplace=True)
user_info = pd.concat([user_info,cat_col_stat],axis=1)

del cat_col_stat

2.1.2 序列特征

用户请求序列特征

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
user_request_list = user_request.groupby(['request_user'],as_index=False)['request_target'].agg({'request_list':list})

# 先按照时间进行排序
user_request = user_request.sort_values(by='request_time',)
# 请求的数量
user_action_feat = user_request.groupby(['request_user'],as_index=False)['request_user'].agg({'request_num':'count'})

# 用户请求的时间统计量,但是80%的用户只有一次请求行为
user_action_feat_temp = user_request.groupby(['request_user'],as_index=False)['request_time'].agg({'time_list':list})
user_action_feat = user_action_feat.merge(user_action_feat_temp,on='request_user',how='left')
user_action_feat['time_min'] = user_action_feat['time_list'].apply(min)
user_action_feat['time_max'] = user_action_feat['time_list'].apply(max)
user_action_feat['time_var'] = user_action_feat['time_list'].apply(np.var)
user_action_feat['time_max-min'] = user_action_feat['time_list'].apply(lambda x:np.max(x)-np.min(x))

# 时间间隔的平均值,最大值,最小值,方差
def diff_value(time):
time_shift = list(time[1:])
time_shift.append(time[-1])

diff_time = time_shift-time
return diff_time
user_action_feat['diff_time'] = user_action_feat['time_list'].apply(lambda x: diff_value(np.array(x)))
user_action_feat['diff_time_max'] = user_action_feat['diff_time'].apply(max)
user_action_feat['diff_time_var'] = user_action_feat['diff_time'].apply(np.var)
user_action_feat['diff_time_mean'] = user_action_feat['diff_time'].apply(np.mean)
user_action_feat['diff_time_min'] = user_action_feat['diff_time'].apply(min)

用户请求序列做一个embedding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
sentences = user_request_list['request_list'].values.tolist()
emb_size = 64
for i in range(len(sentences)):
sentences[i] = [str(x) for x in sentences[i]] # 数字转化为字符串用于训练w2v

model = Word2Vec(sentences, size=emb_size, window=5, min_count=5, sg=0, hs=0, seed=1, iter=5, workers=8)

emb_matrix = []
for seq in sentences:
vec = []
for w in seq:
if w in model.wv.vocab:
vec.append(model.wv[w])
if len(vec) > 0:
emb_matrix.append(np.mean(vec, axis=0))
else:
emb_matrix.append([0] * emb_size)
emb_matrix = np.array(emb_matrix)

emb_size = 64
for i in range(emb_size):
user_request_list['action_emb_{}'.format(i)] = emb_matrix[:, i]

user_request_list = user_request_list.drop(['request_list'],axis=1)
user_action_feat = user_action_feat.merge(user_request_list,how='left',on='request_user')

合并基础特征和序列特征

1
user_info = user_info.merge(user_action_feat,how='left',on='user')

2.2 模型训练

2.2.1 交叉验证

1
2
3
4
5
6
7
folds = KFold(n_splits=10, shuffle=True, random_state=546789)
oof_preds, test_preds, importances = train_model_cat(train, test, y, folds, cat_cols)

test_preds['label'] = test_preds['label'].apply(lambda x:0 if x<0.4 else 1)
test_preds = test_preds.drop_duplicates(subset=['user']) # 去除相同的user
# 生成结果
test_preds[['user', 'label']].to_csv('submission.csv', index=False, header=None)

2.2.2 模型训练

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
useless_cols = ['user','user_status']

def train_model_cat(data_, test_, y_, folds_, cat_cols, semi_data_=None):
oof_preds = np.zeros(data_.shape[0]) # 验证集预测结果
sub_preds = np.zeros(test_.shape[0]) # 测试集预测结果
feature_importance_df = pd.DataFrame()
feats = [f for f in data_.columns if f not in useless_cols]

# 半监督每批训练数据
if not semi_data_ is None:
semi_num = semi_data_.shape[0]/5
semi_y = semi_data_['user_status']

for n_fold, (trn_idx, val_idx) in enumerate(folds_.split(data_)):

if not semi_data_ is None:
semi_data_batch = semi_data_[feats].iloc[int(n_fold*semi_num):int((n_fold+1)*semi_num)]
semi_y_batch = semi_y.iloc[int(n_fold*semi_num):int((n_fold+1)*semi_num)]

trn_x, trn_y = pd.concat([data_[feats].iloc[trn_idx],semi_data_batch]), pd.concat([y_.iloc[trn_idx],semi_y_batch])
else:
trn_x, trn_y = data_[feats].iloc[trn_idx], y_.iloc[trn_idx] # 训练集数据

val_x, val_y = data_[feats].iloc[val_idx], y_.iloc[val_idx] # 验证集数据

clf = CatBoostClassifier(
iterations=6000,
learning_rate=0.08, # 0.08
# num_leaves=2**5,
eval_metric='AUC',
task_type="CPU",
loss_function='Logloss',
colsample_bylevel = 0.8,

subsample=0.9, # 0.9
max_depth=7,
reg_lambda = 0.3,
verbose=-1,
)

clf.fit(trn_x, trn_y,
eval_set= [(trn_x, trn_y), (val_x, val_y)],
verbose_eval=300, early_stopping_rounds=100, # 这个参数有点小,可以再大一点
cat_features = cat_cols
)
oof_preds[val_idx] = clf.predict_proba(val_x)[:, 1] # 验证集结果

sub_preds += clf.predict_proba(test_[feats])[:, 1] / folds_.n_splits # 测试集结果

fold_importance_df = pd.DataFrame()
fold_importance_df["feature"] = feats
fold_importance_df["importance"] = clf.feature_importances_
fold_importance_df["fold"] = n_fold + 1
feature_importance_df = pd.concat([feature_importance_df, fold_importance_df], axis=0)

print('Fold %2d AUC : %.6f' % (n_fold + 1, roc_auc_score(val_y, oof_preds[val_idx])))
del clf, trn_x, trn_y, val_x, val_y
gc.collect()

oof_preds = [1 if i >= 0.4 else 0 for i in oof_preds]
print('Full F1 score %.6f' % f1_score(y_, oof_preds))
test_['label'] = sub_preds

return oof_preds, test_[['user', 'label']], feature_importance_df

三、解决方案二

  • 基于账户本身基础特征,可以做这些类别特征的计数统计、对于粉丝量等数值特征可以做除法的交叉、登录时间和注册时间特征可以做减法交叉,基于请求行为,我们可以对机型、ip、app_version、app_channel做频数统计
  • 基于用户的请求行为序列,我们可以构建w2v特征(把用户请求行为序列看成句子,行为看作词,训练Word2Vec模型得到每个行为的表征
  • 基于用户的请求时间,我们可以计算请求时间的均值方差、请求时间间隔的统计特征等等。

四、A Novel Framework for Social Bots Detection in Online Social Networks Based on Graph Embedding and Community Detection

摘要

随着在线社交网络的广泛普及,近年来用户数量也呈指数级增长。与此同时,社交机器人,即由程序控制的账户,也在上升。OSN的服务提供商经常使用它们来保持社交网络的活跃。与此同时,一些社交机器人也出于恶意目的注册。有必要检测这些恶意社交机器人,以呈现真实的舆论环境。我们提出了BotFinder,一个在OSN中检测恶意社交机器人的框架。具体来说,它将机器学习和图方法相结合,以便有效地提取社交机器人的潜在特征。关于特征工程,我们生成二阶特征,并使用编码方法对具有高基数的变量进行编码。这些特征充分利用了标记和未标记的样本。对于图,我们首先通过嵌入方法生成节点向量,然后进一步计算人类和机器人向量之间的相似性;然后,我们使用无监督的方法扩散标签,从而再次提高性能。为了验证该方法的性能,我们在由800多万条用户记录组成的人工竞赛提供的数据集上进行了广泛的实验。结果表明,我们的方法达到了0.8850的F1分数,这比最先进的方法要好得多

说明

与报纸等传统媒体相比。社交机器人,即由程序控制的帐户,可用于保持社交网络的活跃。虽然OSN中存在有益的社交机器人,但一些恶意社交机器人的出现会产生有害影响。例如,一些人可以出于各种目的注册大量帐户,例如增加粉丝数量或恶意喜欢。这些恶意行为已成为威胁社交网络平台健康发展的重要信息安全问题[1-2]。因此,有必要检测那些恶意的社交机器人,也称为社交机器人检测。特别是,当前的大多数研究涉及Twitter和其他国外平台,而很少有研究调查中国的OSN。因此,众多学者致力于研究社交机器人的检测问题。当前与社交机器人检测相关的工作主要分为两类,即机器学习方法和基于图的方法。然而,这一主题仍然存在一些挑战:

1) 一般来说,大多数方法依赖于单个算法来识别社交机器人,由于数据集的多样性,这可能不是理想的选择。

2) 实际上,大多数数据都是未标记的,这表明标签的数量通常很小。因此,有效利用未标记数据是一个巨大的挑战

为了应对上述挑战,我们在此共同考虑用户的配置文件、行为以及它们之间的关系。此外,我们将特征工程和图方法相结合,提出了一种检测社交机器人的集成机制BotFinder。首先,在数据集上进行特征工程以提取全局信息。然后,通过嵌入方法生成节点向量。然后,我们计算人类和机器人的向量之间的相似性。最后,为了进一步提高性能,我们采用了无监督方法(这里考虑了社区检测算法)。使用所提出的算法,我们可以轻松地检测这些机器帐户。

本文的贡献总结如下:

1) 首先,在节点数较多、边数较少的情况下,在绘制过程中可能会忽略一些单个节点。然而,机器学习方法无法学习拓扑结构。因此,我们结合机器学习方法和图方法来克服这些问题。

2) 其次,在特征工程中,我们试图获得二阶特征,并采用编码方法对具有高基数的变量进行编码,或者换句话说,包含大量不同值的变量进行编码。对于图,我们通过嵌入方法生成节点向量。然后,我们利用无监督方法扩散标签以提高性能。这些方法充分利用了标记和未标记的样本。

本文的其余部分组织如下。在第二节中,我们回顾了一些相关的工作。在第3节中,我们介绍了拟议的框架BotFinder。然后,在第4节中,我们详细描述了所研究的数据集,并在充分分析的基础上进行了实验。最后,我们在第5节总结了我们的研究。

二、Related works

2.1 机器学习方法

在机器学习方法中,监督学习方法得到了广泛的研究。早期的反作弊算法仅利用用户配置文件或用户行为来构建模型。Breno等人[3]提出了一种使用人工神经网络进行数据预处理和挖掘的方法。Chang等人[4]提出了一种特征选择方法,然后使用决策树来检测机器人。Ganji等人[5]将K-最近邻(KNN)应用于信用卡欺诈检测。Ferrara等人[6-7]利用机器学习和认知行为建模技术分析了2017年法国总统选举和2017年加泰罗尼亚独立公投中的社交机器人。Denis等人[8]提出了一种用于检测Twitter上机器人的集成学习方法。 随着深度学习方法(LSTM、CNN等)的发展,研究人员也尝试开发新的方法来检测社交机器人,以进一步提高检测精度。通过将用户内容视为时间文本数据,Cai等人[9]提出了BeDM方法用于机器人检测。Kudugunta等人[10]提取了用户元数据和推文文本,这些数据被视为LSTM深度网络的输入。在实践中,大多数真实世界的数据都是未标记的,而无监督学习方法被广泛研究,这通常依赖于社交机器人的共同特征。Cresci等人[11-12]提出了一种基于DNA启发技术的改进方法,以模拟在线用户行为。陈等人[13]提出了一种无监督的方法来实时检测推特垃圾邮件活动。姜等人[14]提出了CATCHSYNC,仅使用没有标签的拓扑来检测可疑节点。Su等人[15]提出了物联网RU。Mazza等人[16]将转发的时间序列转换为特征向量,然后进行聚类。

2.2 图算法

机器学习方法只考虑节点的特征。然而,节点之间的关系也包含有价值和有用的信息。随着深度学习和图算法的发展,需要考虑图的拓扑信息以进一步改进。社交机器人具有图形聚合的特点。而社区检测用于发现网络中的社区结构,也可以看作是一种广义聚类算法。因此,社区检测算法可能适用于检测社交机器人。许多研究者对这一课题进行了不懈的研究。Guillaume等人[17]提出了一种基于模块化优化的启发式方法。李等人[18]提出了基于深度稀疏自动编码器的WCD算法。对于特征丰富的样本,很难充分挖掘特征中存在的信息。然后,提出了新的方法,首先将节点的拓扑信息转换为特征向量,然后使用机器学习算法进行训练和推理。例如,Lerer等人[19]提出的Pytorch BigGraph,Yu等人[20]提出的NetWalkGrover等人[21]提出的Node2Vec,Pham等人[22]提出的Bot2Vec。此外,Kipf等人[23]提出了图卷积网络(GCN),对节点和网络拓扑的特征进行建模,Aljohani等人[24]将GCN应用于检测Twitter上的机器人。李等人[25]提出了用于网络免疫的BPD-DMP算法。聂等人[26]考虑了社交网络和发布内容;然后,他们提出了DCIM算法。高等人[27]对动态行为进行了表征,并提出了一种基于网络的模型。朱等人[28]研究了流行病在多层网络上的传播过程。Su等人[29]提出了检测车载网络中恶意节点的IDE。 大多数方法依赖于单个算法来识别社交机器人。在准确性和其他相关评估指标方面,以前的识别方法仍然有很大的局限性。

三、BotFinder

在本节中,我们主要介绍BotFinder,它主要包括三个步骤:1)我们在表格数据上表示特征工程技术;2) 我们推导节点嵌入,然后测量人类和机器人之间的相似性;3) 我们应用社区检测算法来进一步提高性能

image-20220719205923660

图1详细说明了这些步骤。第一步,利用特征工程技术生成特征矩阵。第二步,我们使用图嵌入方法生成相似矩阵,然后合并这两个矩阵。然后,我们采用LightGBM[30]来训练合并矩阵并推断临时结果。第三步,我们应用社区检测方法生成部分结果,并使用这些结果校正LightGBM的结果。

3.1 Feature Engineering

在这里,我们试图获得二阶特征、时间间隔特征、计数编码和k倍目标编码。然后,我们应用LightGBM来训练获得的特征并推断临时结果。

二阶特征:为了表示表中分类变量的组合,我们假设二阶特征表示为 COUNT、NUNIQUE、RATIO

  • COUNT 反映了活动程度。具体来说,我们选择一对变量(即 V1和 V2),并预计记录这对变量在数据集中出现的次数。我们将其缩写为 COUNT(v1, v2)。例如,用户向使用设备类型( V1)iPhone12,1和应用程序版本( V2)126.7.0组合的人thump-up,这种组合在数据集中出现了k次。然后,使用iPhone12、1和126.7.0的用户将获得k的 COUNT值。【记录元组出现的次数】【并行化】

  • UNIQUE表明了给定范围内的多样性。我们使用一个变量( V1)作为主键,并在另一个变量(V2)中记录唯一类别的数量。我们将其缩写为 UNIQUE(V1)[V2] 。例如,对于使用device type( V1)iPhone12,1的用户,数据集中有k个不同的应用程序版本。然后,使用iPhone12,1的用户将获得 UNIQUE 值k。

  • RATIO描述计数比例。它计算为 COUNT(v1, v2) / COUNT(v1)。例如,device type(V1)iPhone12,1 和 app version( V2)126.7.0的组合在数据集中出现k次,device type(V1)iPhone12在数据集中出现V次。然后,所有使用iPhone12、1和126.7.0的用户将获得 k/v 的 RATIO 值。

时间间隔特性:请求时间间隔因用户而异。这里,我们主要考虑时间间隔的最大值、最小值、中值和和。

计数编码:计数编码是通过将类别替换为在数据集上计算的类别计数来进行的。然而,某些变量的计数可能相同,这可能导致两个类别可能编码为相同值的冲突。这将导致模型性能下降。因此,我们在此介绍一种目标编码技术。

K-折叠目标编码(或似然编码、影响编码、平均编码):目标编码是通过目标(标签)对分类变量进行计数。在这里,我们用目标的相应概率替换分类变量的每一类。为了减少目标泄漏,我们采用k倍目标编码。具体实现如下:

  • 将训练数据分成10折。
  • 将折#2-10目标的平均值作为折#1的编码值,并类似地计算#2-10的编码值。
  • 使用训练数据的目标来确定测试数据的编码值。

3.2 Similarity Calculation

在这里,我们采用Node2vec[21]来获得用户的节点嵌入(向量),然后计算用户和标记用户之间嵌入的余弦相似性。相似度值表示两个用户具有相同标签的概率;例如,如果user1和user2之间的余弦相似性相对较大,则它们很可能具有高概率的相同标签。

然后,对于训练集和测试集中的每个节点向量C,我们计算机器人和人类之间的最大和平均余弦相似度,该相似度表示为一个向量。【Smax1、Smean1,Smax0,Smean0】

image-20220719212846481

3.3 community detection

对于社区检测,我们采用典型的Louvain方法[17],将构建的图划分为社区。之后,我们将用以下规则标记社区:

[1] Guillaume L. Fast unfolding of communities in large networks[J]. Journal Statistical Mechanics: Theory and Experiment, 2008, 10: P1008.

1) 如果具有标签的用户属于同一社区,则社区中的所有用户都应该具有相同的标签。

2) 如果社区中的用户没有任何标签,或者用户具有不同的标签,我们将不会进行预测。

然而,预测可能不会覆盖所有用户。因此,该规则的性能是有限的。但该规则的结果比LightGBM更准确。通过将上述两个步骤结合起来,可以进一步提高性能。

四、实验

为了评估该机制的性能,我们从一个大型社交网络平台的数据中心收集了一个数据集(https://security.bytedance.com/fe/ai-challenge#/sec-project?id=2&active=1)。它包含超过800万条记录,包括用户配置文件用户请求(关注或喜欢某人)。数据集的基本信息如表1和表2所示:表1显示了用户的个人信息(配置文件),而表2说明了用户的行为(请求),包括当时用于启动请求的设备和应用程序版本。

任务描述如下:给定用户配置文件及其请求。只有一小部分用户被标记。因此,我们必须建立一个合理、解释性和有效的模型来检测来自用户的恶意机器人。

五、结论

本文提出了一种社交机器人检测方法BotFinder。为了验证所开发方法的性能,我们收集了一个包含800多万条用户记录的数据集。同时,应用机器学习和图方法从此类数据集中提取社交机器人的潜在特征。特别是,对于特征工程,我们生成二阶特征,并使用编码方法对高基数变量进行编码。在图方面,我们为账户生成节点向量,然后利用无监督方法(这里我们利用社区检测)扩散标签,以进一步提高性能。通过在收集的数据集上进行的实验,所提出的集成机制的有效性得到了相对较大的F1分数0.8850的保证。与现有方法相比,该方法的性能优越。