手把手|用Python端对端数据分析识别机器人“僵尸粉”

简介:

导读:不仅微博,在twitter中也存在大批的“僵尸粉”。Twitter中的“僵尸粉”不仅能够在无人干预下撰写和和发布推文的程序,并且所产生的推文相当复杂。如何识别这批“僵尸粉”或者说“机器人粉丝”?下面我们将通过PythonPandas库、自然语言处理学习NLTKscikit-learn创建分类器对Twitter机器人进行识别。


在本文中,我想要讨论一个互联网现象:机器人,特别是Twitter机器人。


我之所以一直关注Twitter机器人主要是因为它们有趣又好玩,另外也因为Twitter提供了丰富而全面的API,让用户可以访问到Twitter平台信息并了解它们是如何运作的。简而言之,这让Python强大的数据分析能力得到了充分地展示,但也暴露了它相对薄弱的环节。


对于那些不熟悉Twitter的人, 我们先简单介绍一下。Twitter是一个社交媒体平台,在该平台上用户可以发布140字以内的恶搞笑话,称之为“推文”。Twitter根本上区别于其它的社交媒体是因为推文默认是公开的,并且在Twitter上互相关注的人实际上不一定彼此认识。你可以认为Twitter不单单是个人信息流,更像是一个想法交易市场,流通的货币则是粉丝和推文转发。


640?wx_fmt=png

 

Twitter另外一个显著的特点是它自身内容的“嵌入式能力”(见上图的搞笑例子)。如今,将推文作为新媒体的一部分是稀疏平常的一件事。主要是因为Twitter开放式的API,这些API能让开发者通过程序来发推文并且将时间轴视图化。但是,开放式的APITwitter在互联网广泛传播,也对一些不受欢迎的用户开放了门户,例如:机器人。


Twitter机器人是能够在无人干预下撰写和和发布推文的程序,并且所产生的推文相当复杂。其中一些机器人相对不活跃,只是用来增加粉丝和收藏推文的。而另一些会借助复杂的算法来创建具有说服力的推文。所有的Twitter机器人都可能变得让人讨厌,因为它们的出现破坏了Twitter分析的可信度和商业价值,最终甚至会触及底线。


那么Twitter能对这些机器人做些什么呢?首先,要做的是去识别它们,以下是我的方法。

 ◆ 

创建标签


核心目标是创建一个分类器来识别哪些账号是属于Twitter机器人的,我是通过监督学习来实现的。“监督”意味着我们需要已有标注的样本数据。例如,在最开始的时候,我们需要知道哪些账号属于机器人,哪些账号属于人类。在过去的研究中,这个费力不讨好的任务已经被研究生的使用(和滥用)完成了。例如:Jajodia 等人通过手动检测账号,并且运用Twitter版本的图灵检测来判断一个账号是否属于机器人,判断推文是否由机器人发布的。问题是我已经不再是个研究生了并且时间宝贵(开玩笑)。我解决了这个问题多亏我的朋友兼同事Jim Vallandingham 提出的绝妙建议,他向我推荐了fiverr,一个花5美元就能获取各类奇特服务的网站。



640?wx_fmt=png

 


花了5美元,等待24小时之后,我有了5500个新粉丝。因为我知道在机器人关注之前,我的粉丝都有哪些,所以我可以有效地识别哪些是人类,哪些是一夜激增的机器人粉丝。


 ◆ 

创建特征


由于Twitter有丰富的REST APIREST指一组架构约束条件和原则,满足约束条件和原则的应用程序设计——译者注),创建特征集是几乎不违反服务条约的行为。我使用Python-twitter模型去查询两个终端指标:GET users/lookup(获取用户信息)和 GET statuses/user_timeline(获取用户状态、时间轴信息)。获取用户信息的终端会返回JSON文本,这些文本中包含了你所希望得到的用户账号信息。例如:用户是否使用了默认的模板配置,关注者/被关注者的数量,发布推文的数量。从获取的用户时间轴信息中,我抓取了数据集中每个用户最新的200条推文。


问题是,Twitter官方不允许你直接大量地收集你所想要的数据。Twitter限制了API的调用频率,这样意味着你只能在需求范围内获取少量的样本数据进行分析,因此,我使用了以下美妙的方法(blow_chunks)来获取数据:

#不要超出API的限制


blow_chunks函数作为查询列表输入,例如:用户名(user ids),并将它按最大长度分块。但是该函数并不返回那些块,它返回一个生成器。可以这样使用:

chunks = self.blow_chunks(user_ids, max_chunk_size = max_query_size)

while True:

  try:

    current_chunk = chunks.next()

    for user in current_chunk:

      try:

        user_data = self.api.GetUser(user_id = str(user))

        results.append(user_data.AsDict())

      except:

        print "got a twitter error! D:"

        pass

    print "nap time. ZzZzZzzzzz..."

    time.sleep(60 * 16)

    continue

  except StopIteration:

    break

 


如果查询的长度大于所允许的最大值,那么将查询分块。调用生成器.next()方式来抓取第一个块并将此需求发往API。然后暂停获取数据,两个数据请求需要间隔16分钟。如果所有的块都发出了,那么生成器将会停止工作并且终止循环。


 ◆ 

机器人是怪物


通过快速地清理和整理数据,你会很快发现不正常的数据。通常情况下,机器人的关注量是1400,而人类的关注量是500。机器人的粉丝分布具有很大的差异性,而人类的粉丝分布差异性较小。有些人的人气很高,有一些却没那么高,大多数人是介于两者之间。相反,这些机器人的人气非常低,平均只有28个粉丝。


 ◆ 

将推文变成数据


当然,这些机器人在账号信息层面上看起来很奇怪,但是也有很多人的人气很低,而且账号中几乎空荡荡的,只有一张头像。那么他们发布的推文是怎样的呢?为了将推文数据加入到分类器中,一个账号的推文信息需要被汇总成一行数据。有一种摘要度量方式建立在词汇多样性之上,就是每个特定词汇数量占文档总词汇数量的比例。词汇多样性的范围是从01,其中0代表这个文档中没有任何词汇,1代表该文档中所有词都只出现过一次。可以将词汇多样性作为词汇复杂性的度量方法。


我用Pandas 来快速优雅地运用归纳函数,例如词汇多样性,对推文进行处理。首先,我把每个用户的所有推文放进一个文档,并进行标记,这样我会得到一个词汇列表。然后,我再利用NLTK(自然语言处理技术)移除所有标点符合和间隔词。


通过Pandas在数据集上使用自定义函数是极其方便的。利用groupby,我通过账户名将推文分组,并且在这些分组推文中应用词汇多样性函数。我钟爱这个语法的简洁和灵活,可以将任何类别的数据分组并且适用于自定义的归纳函数。举个例子,我可以根据地理位置或者性别分类,并且仅仅根据分组的变量,计算所有组的词汇多样性。

def lexical_diversity(text):

  if len(text) == 0:

    diversity = 0

  else:

   diversity = float(len(set(text))) / len(text)

  return diversity

 

#容易得到每个用户的总结性数据

grouped = tweets.groupby('screen_name')

diversity = grouped.apply(lexical_diversity)

 


同样的,这些机器人看上去很怪异。人类用户有着一个美得像教科书一般的正态分布,其中大部分的词汇多样性比例集中在0.7。而机器人的却很极端化,词汇多样性接近于1。语义差异性为1,这意味着每个词在文档中都是独特的,也就是说机器人要么几乎不发推文,要么只是发随机文字。



640?wx_fmt=png

 


 ◆ 

建模


我利用stickit-learnPython中最重要的机器学习模块,进行建模和校验。我的分析计划差不多是这样的,因为我主要关注预测精准度,为什么不试试一些分类方法来看看哪个更好呢?Scikit-learn的一个强项是简洁,同时在构建模型与管道时与API兼容,这样易于测试一些模型。

# Naive Bayes

bayes = GaussianNB().fit(train[features], y)

bayes_predict = bayes.predict(test[features])

 

# Logistic regression

logistic = LogisticRegression().fit(train[features], y)

logistic_predict = logistic.predict(test[features])

 

# Random Forest

rf = RandomForestClassifier().fit(train[features], y)

rf_predict = rf.predict(test[features])

 


我试了3个分类器,分别是朴素贝叶斯、逻辑回归和随机森林分类器。可以看到这三种分类方法的语法是一样的。在第一行中,我拟合分类器,提供从训练集和标签为y的数据中得到的特征。然后,简单地通过将来自测试集的特征传入模型来预测,并且从分类报告查看精确度。

#分类指标

print(metrics.classification_report(test.bot, bayes_predict))

print(metrics.classification_report(test.bot, logistic_predict))

print(metrics.classification_report(test.bot, rf_predict))


毫无疑问,随机森林表现得最好,整体精度为0.9,而朴素贝叶斯的是0.84,逻辑回归的是0.87。令人惊讶的是,利用现有的分类器,我们识别机器人的准确率可以达到90%,但是我们是否可以做得更好?答案是:可以。事实上,利用GridSearchCV可以非常容易地调试分类器。GridSearchCV采用了一种分类方法和一系列的参数设置进行测试。其中,这一系列参数是一个键入了该模型配置参数的字典。GridSearchCV最好的一点是可以像对待刚才我们看到的分类方法一样地对待它。也就是说,我们可以使用.fit().predict()函数。

# 配置参数

param_grid = {'max_depth': [1, 3, 6, 9, 12, 15, None],

              'max_features': [1, 3, 6, 9, 12],

              'min_samples_split': [1, 3, 6, 9, 12, 15],

              'min_samples_leaf': [1, 3, 6, 9, 12, 15],

              'bootstrap': [True, False],

              'criterion': ['gini', 'entropy']}

 

# 最合适的分类

grid_search = GridSearchCV(RandomForestClassifier(),

param_grid = param_grid).fit(train[features], y)

 

# 评估预测准确度

predict = grid_search.predict(test[features])

print(metrics.classification_report(test.bot, predict))


啊哈,更加精确了!简单的调试步骤产生了一个新格局,预测的准确率提高了2%。为调试过的随机森林检查变量重要性策略产生了一些惊喜。朋友数量和粉丝数量是机器人识别中最重要的变量。



640?wx_fmt=png

 

 

 ◆ 

但是,我们需要更好的工具来开发迭代模型


Scikit-learn还有很大的提升空间,特别是生成模型诊断和模型比较应用上的功能性。一个说明我的意思的例子是,我想带你走进另一个世界,那里不用Python,而是R语言。那里也没有scikit-learn,只有caretClassification and Regression Training,是为了解决分类和回归问题的数据训练而创建的一个综合工具包——译者注)。让我告诉你一些caret的,在scikit-learn里可以被复制的强项。


以下是confusionMatrix函数的输出结果,与scikit-learn分类报告的概念等价。你会注意到有关comfusionMatrix函数输出的准确度报告的深度。有混淆矩阵(confusion matrix)和大量将混淆矩阵作为输入的准确度测量维度。大多数时候,你也许只会使用到一个或者两个测量维度,但是如果它们都可用是最好的,这样,可以在你所处的环境下使用效果最好的,而无需增加额外代码。

> confusionMatrix(logistic_predictions, test$bot)

Confusion Matrix and Statistics

 

          Reference

Prediction   0   1

         0 394  22

         1 144  70

 

               Accuracy : 0.7365          

                 95% CI : (0.7003, 0.7705)

    No Information Rate : 0.854           

    P-Value [Acc > NIR] : 1               

 

                  Kappa : 0.3183          

 Mcnemars Test P-Value :


Caret最大的一个优势是提取推理模型诊断的能力,而这在scikit-learn中是看似不可能完成的。以拟合一个回归方法为例:你自然想看看回归系数,样本满意度,P值和拟合优度。即使你仅仅对预测准确性感兴趣,理解模型的原理和知道模型是否满足假设条件也是有用的。为了在Python中复制这样的输出,需要在与statsmodels类似的地方改装模型,这样会造成建模过程的浪费和繁琐。

summary(logistic_model)

 

Call:

NULL

 

Deviance Residuals:

    Min       1Q   Median       3Q      Max  

-1.2620  -0.6323  -0.4834  -0.0610   6.0228  

 

Coefficients:

                Estimate Std. Error z value Pr(>|z|)    

(Intercept)      -5.7136     0.7293  -7.835 4.71e-15 ***

statuses_count   -2.4120     0.5026  -4.799 1.59e-06 ***

friends_count    30.8238     3.2536   9.474  < 2e-16 ***

followers_count -69.4496    10.7190  -6.479 9.22e-11 ***

---

 

(Dispersion parameter for binomial family taken to be 1)

 

    Null deviance: 2172.3  on 2521  degrees of freedom

Residual deviance: 1858.3  on 2518  degrees of freedom

AIC: 1866.3

 

Number of Fisher Scoring iterations: 13


但是,我认为R语言中caret包最大的特点是能够容易地比较不同的模型。使用 resamples 函数,可以很快地生成可视化效果来比较我选择的指标模型的性能。这种类型的效用函数在建模过程中是超级有用的,也让你在不想花费大量时间来制作图的终稿的时候可以就早期的结果进行交流。

# compare models

results = resamples(list(tree_model = tree_model,

                         bagged_model = bagged_model,

                         boost_model = boost_model))

# plot results

dotplot(results)

 

 

640?wx_fmt=png

 


对于我而言,这些功能产生了所有的差异,这也是R语言仍然是我建模首选语言的主要原因。


 ◆ 

结语


如果你从本文中学到了一些东西,我希望是:Python是用于数据任务的一个极其强大的工具。我们可以通过API获取数据,利用Python做所有的工作:清理,处理数据,建立和测试分类器。我们也看到它有改进的空间。在R语言中的caret包提供了丰富的应用用于快速、迭代模型的开发,同时caretscikit-learn今后发展道路上的一个伟大榜样。

原文发布时间为:2016-06-22

本文来自云栖社区合作伙伴“大数据文摘”,了解相关信息可以关注“BigDataDigest”微信公众号

相关文章
|
12天前
|
机器学习/深度学习 数据采集 数据挖掘
如何用Python进行数据分析?
【6月更文挑战第13天】如何用Python进行数据分析?
108 66
|
9天前
|
数据采集 数据可视化 数据挖掘
数据挖掘实战:使用Python进行数据分析与可视化
在大数据时代,Python因其强大库支持和易学性成为数据挖掘的首选语言。本文通过一个电商销售数据案例,演示如何使用Python进行数据预处理(如处理缺失值)、分析(如销售额时间趋势)和可视化(如商品类别销售条形图),揭示数据背后的模式。安装`pandas`, `numpy`, `matplotlib`, `seaborn`后,可以按照提供的代码步骤,从读取CSV到数据探索,体验Python在数据分析中的威力。这只是数据科学的入门,更多高级技术等待发掘。【6月更文挑战第14天】
45 11
|
2天前
|
数据采集 机器学习/深度学习 数据可视化
利用Python和Pandas库构建高效的数据分析流程
在数据驱动的时代,数据分析已成为企业决策的关键环节。本文介绍如何利用Python编程语言及其强大的数据分析库Pandas,构建一套高效且可扩展的数据分析流程。与常规的数据分析流程不同,本文不仅涵盖数据加载、清洗、转换等基础步骤,还强调数据可视化、模型探索与评估等高级分析技巧,并通过实际案例展示如何在Python中实现这些步骤,为数据分析师提供一套完整的数据分析解决方案。
|
4天前
|
机器学习/深度学习 数据采集 数据可视化
使用Python进行数据分析涉及数据收集
【6月更文挑战第21天】使用Python进行数据分析涉及数据收集(如数据库、文件、API),数据清洗(处理缺失值、异常值和重复项),数据探索(统计摘要、可视化和相关性分析),特征工程(创建新特征和编码),模型构建(选择算法、训练与调整),模型评估(计算指标、可视化效果),结果解释(报告和可视化),以及部署与维护。此过程因项目需求而异,可能需迭代。常用库有`pandas`、`requests`、`BeautifulSoup`、`Matplotlib`等。
11 1
|
7天前
|
数据挖掘 数据库连接 Python
GitHub高赞!Python零基础也能搞定的数据分析与处理
经常会有人让我推荐一些 Python 入门教程。虽然 Python 入内教程到处都有,但是这些教程要么太宽泛(没有讲任何关于数据分析的内容),要么太专业(全是关于科学原理的内容)。然而Excel用户往往处在一个中间位置:他们的确是和数据打交道,但是科学原理对于他们来说可能又太专业了。他们常常有一些现有教程无法满足的特殊需求,举例如下 • 为完成某个任务,我应该用哪个 Python-Excel包? • 我如何将 Power Query 数据库连接迁移到 Python? • Excel中的 AutoFilter和数据透视表在 Python 中对应的是什么?
|
7天前
|
存储 数据挖掘 索引
Python streamlit框架开发数据分析网站并免费部署
使用Python的Streamlit框架,开发了一个在线数据分析工具,替代Excel查看设备温度CSV数据。通过pandas读取数据,matplotlib绘制图表。程序处理CSV,提取所需列,计算最大最小平均值,用户可多选查看特定数据。[GitHub](https://github.com/yigedaigua/MGHB)上有完整代码,应用已部署至Streamlit Cloud。
|
10天前
|
数据采集 机器学习/深度学习 数据可视化
数据挖掘实战:Python在金融数据分析中的应用案例
Python在金融数据分析中扮演关键角色,用于预测市场趋势和风险管理。本文通过案例展示了使用Python库(如pandas、numpy、matplotlib等)进行数据获取、清洗、分析和建立预测模型,例如计算苹果公司(AAPL)股票的简单移动平均线,以展示基本流程。此示例为更复杂的金融建模奠定了基础。【6月更文挑战第13天】
41 3
|
5天前
|
数据采集 数据可视化 数据挖掘
Python数据分析入门指南
Python数据分析涉及环境搭建(推荐Anaconda,含pandas和matplotlib库)。使用`pandas`读取CSV数据,如`data = pd.read_csv(&#39;data.csv&#39;)`。数据清洗包括检查缺失值(`data.isnull().sum()`)和处理异常值。然后进行数据处理,如创建新列、选择特定列及分组。利用`matplotlib`进行数据可视化,绘制直方图和散点图,以`plt.hist()`和`plt.scatter()`展示数据。
|
7天前
|
机器学习/深度学习 人工智能 算法框架/工具
Python赋能AI数据分析
Python赋能AI数据分析
23 0
|
11天前
|
机器学习/深度学习 编解码 文字识别
【开源】轻松实现车牌检测与识别:yolov8+paddleocr【python源码+数据集】
【开源】轻松实现车牌检测与识别:yolov8+paddleocr【python源码+数据集】

热门文章

最新文章