夏天即将结束,八月特别寒冷。 我的11年级开始了,我意识到现在是提高职业能力的最后机会(破坏者:否)。 几年来,我一直在努力地执行各种IT项目,一个人一个人,一个人在团队中。 但是现在
我母亲的女朋友的所有
儿子已经在做些漂亮的事。 也许没用,但外观漂亮。 有人以gif形式对粒子进行粘性模拟,有人投入了机器学习并进行了各种样式转换。 而我最糟糕的是什么? 我也想!
仿真的一个例子也很不错。我的一个朋友的粒子模拟示例正是出于这种想法,我开始了对机器学习的研究。 就我的培训而言,没有什么新鲜的东西了,就像在其他IT领域一样,这里需要实践。 但是,如果我对任何音调分析仪不感兴趣怎么办? 我们必须发明自己的东西。
再次浏览VKontakte新闻提要,我意识到这个社交网络的社区是数据科学的真正宝藏。 如果您以图片或音乐的形式处理文字,模因或收藏中的音乐,则可以获得与现代人相关的大量相关信息:流行音乐类型,词汇或大多数人活动的时间。 这是许多发现的领域。
但是普通百姓需要多少统计数据? 好像我想念音乐,还是无法访问“热门”部分? 因此,您需要考虑一些实用的东西,至少可以吸引一定比例的用户。
值得一提的是,在此之前的几个月,我读了一篇很酷的文章,内容涉及
创建我的家庭搜索引擎 ,这确实使我感到震惊。 像作者一样,我对大型项目感到非常渴望,因为它们日夜都要处理大量的千兆字节信息。

现在,我们回到八月,这比本文开始时要暖和一些。 当我意识到自己现在拥有大量信息时,我意识到是时候了。 我们自己的庞然大物的时代到了。 但是几天之后,主要的问题仍然存在-我该怎么办? 为用户提供什么? 我不会折磨读者,我只会告诉您,就像我的一些朋友一样,这对我来说很难找到我喜欢的新VKontakte小组。 现在,每个第一批公众都有一个名字-一组随机单词。 管理员试图使其变得最荒谬,这可能是某种种族,只有他们可以理解。
然后,我决定编写一项服务,以帮助用户选择社区,推荐您可以订阅的服务。 所以我的主意出现了。
引言很长一段时间并不是偶然的,它应该传达我的情感并表明这个主意并非偶然。 实际上,就像哈布雷的其他想法一样。
我的服务仍在运行中,已经进行了四个多月(如果从第一次成功的实验开始算起)。 但是我已经有经验想与大家分享。 现在将有一个简短,最简洁的项目描述。 接下来,我将概述一些关键点。 而且,如果该文章特别吸引哈布拉游击队,那么它将继续出现,其中将包含更多纯技术信息和代码。
一切都包括三个部分:
- 搜索机器人(如果可以这样称呼)
- 数据处理引擎
- 用户的网站(具有用于管理员的控制和监视面板)
该机器人的功能包括搜索新的组,并将文本和其他信息“剥离”到数据库中。 该引擎将进一步处理这些数据,我将在下面进行介绍。 该站点仅允许用户使用所有这些。
搜索机器人
这里没有新内容。 我只是在VK上获取某人的个人资料,并从他那里获得群组及其朋友的列表。 所有这些都是通过VK API进行的。 而且,如果此IPA设法获取了用户及其朋友的组列表,那么他就没有设法获取组的内容...我只是遇到了限制而已。 然后我想起了一段时间以前,VKontakte只是为了这种事情而推广他们的炫酷系统。 该系统的名称是Streaming API。
流API-一种用于从VK中随机选择记录的工具。 在说明页面上写道,您最多只能获取所有信息的1%,为了最多获取100条信息,您需要写信给支持部门并向他们解释您的意图。
看来一切都很棒。 但是没有 我可能和许多人一样,错过了上面描述中最重要的词。 这就是介词“之前”。 没有人会提供全部100%的数据。 这只是一个漂亮的上方栏,仅此而已。 实际上,我们得到这样的结果:
希望代理#365不会一年365天都讨厌我这个屏幕截图也就是说,我每天只能获得3万个事件。 这个数字包括评论,只是转发。 还必须指出一些标记词,只有它们一起出现的消息。 剩下的一些帖子对我不感兴趣,因为它贴在用户墙上。 仍然相当多。 作为参考,在我目前的实现中,我可以在几天的不正常运行时间(总计-大约10个小时,但没有精确的测量)中获得多达850万条记录。
在这里,我不得不说说我从整个实验中确定的一条规则。 切勿以一个职位来评判一个团队。 特别是如果您是容易受到此类噪音干扰的人工智能。 因此,您至少需要一些帖子才能对公众进行客观描述。 现在,让我们估计一些内容真正高质量的小组每几周发布一次。 而且即使由于流API的不完善,我也可以跳过它。 如果知道了,我应该多长时间一点一点地收集内容?
我决定那太久了,反而走了。 由于我无法从VKontakte得到JSON格式的简洁答案,因此我将解析社区的围墙。 是的,任务有点复杂,解决方案的速度变慢,但是我别无选择。 这就是我开始编写系统第一块的方式。 顺便说一下,我使用Jsoup在Java中编写了该库,该库使从HTML文本提取内容非常方便。 我没有忘记处理上一篇文章的发布日期,我不需要死社区,我只是不索引它们。 标有广告的帖子也将被丢弃。 并非所有管理员都做这样的注释,但是这个问题并不是那么容易解决,我无法创建适当的广告过滤器,因此,我暂时拒绝这种过滤。
引擎
这可能是该项目中最有趣的部分,但是在本出版物中,我不会详细介绍所有内容。 如果有人会对这些细节感兴趣,请以各种可能的方式向我询问。
以神经网络可以理解的格式显示文本的所有方法中,最简单的方法就是词袋。

向量化过程以及有关BOW的更多信息我预先准备了所有常见单词的字典(不要忘记排除直接常见的单词,例如``一个'',``什么'',``哪个''和其他;它们不会将其文本与其他背景区别开来),每个单词都有自己的编号。 然后,当我需要使用神经网络处理文本时,我会从字典中获取每个单词的编号(如果有的话),并获得一个向量(在编程中也称为数组)。 这是这样一个有序的数字集,其中文本中每个单词编号的位置都有一个单位(请参见上图)。 事实证明,这种数据类型对于网络而言是可以理解的。 我的每个向量的长度为30,000,大约是我在开发的第一阶段收集到的足够多的单词。
同样重要的是不要忘记,例如“ habr”和“(c)habr”这两个词在理解上几乎是相同的。 但是对于上述算法,这些是完全不同的词。 为了解决这个问题,我使用了
JMorphy2形态分析器。 这是原始PyMorphy2 for Java的端口。 他可以做很多很酷的事情,例如,更改单词的形式(大小写,性别,数字等)。 我需要它来获取单词的初始形式。 如您所知,“相同”单词的初始形式是相同的。 这样就解决了上述问题。
6929 21903 25126 11441 7374 1925 1626 23128 6241 25584
词典中的单词列表及其编号(以空格分隔)的示例上面的列表显示单词“ dragon”没有变成“ dragon”。 这有点不对,但是即使这样的文本预处理也足够了。 通常,此库有很多错误,但大多数不会影响系统的运行。
该服务面向说俄语的听众。 为简单起见,目前仅处理俄语。 其他字母中的所有字符(其中的字母)都被扔掉了,例如标点符号,数字,表情符号……再次简化了。 另外,不要忘记从部分使用俄语字母的语言中过滤掉单词,但添加自己的字母(例如,乌克兰语)。
但是,从VKontakte的任何帖子已经变成矢量(我称为矢量化)的那一刻起,我将继续。 这里连接了以下链接:神经网络。 我决定使用它,因为它对我来说很有趣,并设法找到适合我任务的体系结构。
“ Keras中的自动编码器”系列的
第一篇文章帮助了我。 是的,我决定使用最常见的自动编码器,因为它在速度和培训方面都非常有用。 但是,让我们依次讨论所有内容。
对于所有其他自动编码器,您需要创建两个神经网络(编码器和解码器)并将它们组合为一个。 我这样做如下:
from keras.layers import Input, Dense, Flatten, Reshape from keras.models import Model
但是为什么我们需要两个网络? 无论如何,作者,您没有描述为什么这就是
全部 !
冷静,现在一切都会好起来。 例如,要进行训练,仅编码器是不可能的-根本不清楚他所做的预测如何正确。 为此,我们训练第二个网络,该网络将立即解码第一个网络的输出(解码器)。 也使用相同的输入和输出数据。 一堆两个网络(称为自动编码器)学习从输入数据中获取相同的内容。 但是所有数据都以64个神经元的形式经过一个狭窄的“瓶颈”。 这将丢弃最不必要的信息。 因此,神经网络学会以最大的质量传递有关文本的重要信息,并消除所有噪音。 然后我只需要删除解码器即可。 您可以获得更好的结果,但是随后您需要增加编码器/输入解码器的输出层的尺寸。 然后,有必要在数据库中存储更多的值,它将权衡更多+在长向量上的所有操作都将更长(稍后会更多)。 或者,您可以添加层/神经元,但是训练和矢量化的时间会更长。
编码器本身允许您“压缩向量的尺寸”。 还记得零和一的向量吗? 因此,编码器使您可以将其大小从30K更改为64,而不会丢失很多重要信息。 完成此步骤后,通常可以比较两个向量以确定它们的相似性...
但是我们是根据VK社区的推荐而不是个人记录来查看服务的工作。 这意味着我们需要以某种方式获得整个公众的引导。 五年级的数学很容易做到。 这是一个粗略的方法,但它可以工作。 我只取并添加了一个社区的所有记录向量(例如,取三个小向量{1,2,3},{2,3,4},{0,4,2},我们得到向量{3,9,9 })。 然后将其每个元素除以向量的数量(我们得到向量{1,3,3})。 如此,我们将该组的所有记录合并为一个。 将来,您需要提出一些更棘手的内容,以便例如以带有广告的帖子形式发出声音。 但是现在这就足够了。
我们转向数学部分本身,但是由于每个人都出于某种原因而害怕它,因此我将尽可能地对其进行签名。 让我们从数学意义上的向量开始。 向量是有向片段。 这种东西具有起点的坐标(最方便的是使用零)和终点的坐标。 后者记录在花括号中。 例如,向量{
1,0,1 }
youtube的末端的坐标是具有坐标(
1、0、1 )的点。 但是我们将考虑两个二维向量
{5,2}和
{5,0}。 让我们在一个坐标系中构建它们:

让向量
粉红色
-黄色 然后,根据第九类的数学事实,它们之间的角度的余弦值等于其标量乘积与模块乘积的比。
标量产品<
,
>等于相应元素乘积的和
。
向量模块可通过以下公式找到:
哪里
和
这分别是向量a的第一个和第二个值。 因此:
根据公式组合所有内容,我们得到:
可以通过形成的直角三角形的三角函数来检查计算的正确性。 在该项目中,所有计算都是根据这样的公式进行的,但是只有向量末端的坐标不是2,而是64。
这些信息能提供什么? 事实证明,余弦值越大(角度越小),对应于矢量的文本越相似。 因此,找到与组A最相似的组的任务归结为找到该组矢量与所有其他矢量之间的角度的余弦值。 然后,引擎离开所有余弦值与A一起大于0.99的组。 在此阶段,您可以像以前一样简单地显示结果。 但是,在10万个社区中,这个过程已经很漫长了,比如说在1M时会发生什么?
为了解决这个问题,我使用了图表。 所有组均表示为其顶点,如果与它们相对应的矢量之间的角度的余弦值大于0.99,则连接两个点。 但是,如果您不了解图表名称的结构,那么您可以想象一下,我预先计算了数据库中最相似的社区对并将其保存。 而且我不会忘记在将新组添加到数据库时更新图。 是的,这是一个很长的时间,但是对于用户而言,它比以前更容易。
网站
我不会画关于该网站的所有内容,因为这是最简单,最无聊的部分。 我从来没有从头开始编写过网站,我总是使用各种现成的引擎。 但是在这个项目中,我意识到制作萨摩皮鱼会更容易。 因此,站点引擎是使用Flask用Python 3编写的。 并且使用了Ninja2模板引擎,这使得在静态HTML(和js)代码中替换动态值更加方便。 我没有忘记通过VKontakte进行授权,因为这是最佳选择。 如果有人想加入该项目,那么就像布局设计师一样,设计师会让我很讨厌-欢迎。
该网站结果的第一行问题所在
我遇到了一些我成功解决的不愉快情况。 VK API的问题已在上面编写,其解决方案对于服务而言尤其令人不快,因为速度下降了很多。 如果在一个请求中收到一百篇帖子之前,现在我需要下载一些大型HTML代码,然后对其进行解析,然后再对其进行处理。 现在,限制获取用户,他们的朋友和组存在一个问题,但是在此阶段,此限制实际上并没有干扰。 然后,您必须像第一个方法一样解决它。
现代互联网上的文字每天都变得越来越不重要。 多年来,VKontakte拥有许多小组,提供视频,图片和音乐。 为了获得良好的建议,您需要对其进行处理。

但这不是文本,确实需要严肃的计算能力。 例如,这是一个高端视频卡,但是现在我还没有,并且我不想为所有这些使用服务器(为时过早)。 但总的来说,我已经拥有用于此任务的神经网络体系结构的最佳实践。 我将使用一些神经元对图像进行分类,从中“切除”上部,这负责对象的分类。 剩下的将是将绘制图片标记的内容。 我可能会用另一个编码器挤压这张卡,就是这样,所有后续操作都类似于“文本”操作。
关于我每单位时间可以向VKontakte站点发出多少请求,还有另一个未解决的问题。 还是一天。 现在我还没有遇到这个限制,但是它可能在最不适当的时刻发生。
未来计划
我迫切需要一个漂亮的控制面板和统计信息。 它已经处于初始状态,但是需要完成。 通过它,我想控制微服务的启动/停止(即,引擎由微服务组成),队列的大小,处理速度以及所有这些。 那么,统计数字,谁不想看他们的数字呢? 当然,我需要优化所有内容并使其适合用户,尤其是我需要重做网站的外部部分,因为它不符合我的便利性标准。
结论
我设法走上了创建具有有趣结构的服务的道路(至少对我而言),我将用它来参加一项竞赛,这将使我能够进入俄罗斯最好的大学(我不会说这是第一类型的非经典大学)。 我认为,如果您仍在工作,则可以从中获得更多有趣的东西,例如,出版物质量分析器,为社区管理提供分析服务或其他。
我第一次从上面的文本中发现了很多东西。 这意味着我可能做错了。 如果我的读者知道可以改进/解决的问题,还有其他问题等等,请在评论中写下。 我想请您对文章的质量提出批评,以便我下次可以改进它。 谢谢啦