首页 文章 精选 留言 我的

精选列表

搜索[AI漏洞挖掘],共10000篇文章
优秀的个人博客,低调大师

Spark应用HanLP对中文语料进行文本挖掘--聚类

软件:IDEA2014、Maven、HanLP、JDK; 用到的知识:HanLP、Spark TF-IDF、Spark kmeans、Spark mapPartition; 用到的数据集:http://www.threedweb.cn/thread-1288-1-1.html(不需要下载,已经包含在工程里面); 工程下载:https://github.com/fansy1990/hanlp-test。 问题描述 现在有一个中文文本数据集,这个数据集已经对其中的文本做了分类,如下: 其中每个文件夹中含有个数不等的文件,比如环境有200个,艺术有248个;同时,每个文件的内容基本上就是一些新闻报道或者中文描述,如下:现在需要做的就是,把这些文档进行聚类,看其和原始给定的类别的重合度有多少,这样也可以反过来验证我们聚类算法的正确度。 解决思路: 2.1 文本预处理: 1. 由于文件的编码是GBK的,读取到Spark中全部是乱码,所以先使用Java把代码转为UTF8编码; 2. 由于文本存在多个文件中(大概2k多),使用Spark的wholeTextFile读取速度太慢,所以考虑把这些文件全部合并为一个文件,这时又结合1.的转变编码,所以在转变编码的时候就直接把所有的数据存入同一个文件中; 其存储的格式为: 每行: 文件名.txtt文件内容 如: 41.txt 【 日 期 】199601....这样子的话,就可以通过.txtt 来对每行文本进行分割,得到其文件名以及文件内容,这里每行其实就是一个文件了。 2.2 分词 分词直接采用HanLP的分词来做,HanLP这里选择两种:Standard和NLP(还有一种就是HighSpeed,但是这个木有用户自定义词典,所以前期考虑先用两种),具体参考:https://github.com/hankcs/HanLP ; 2.3 词转换为词向量 在Kmeans算法中,一个样本需要使用数值类型,所以需要把文本转为数值向量形式,这里在Spark中有两种方式。其一,是使用TF-IDF;其二,使用Word2Vec。这里暂时使用了TF-IDF算法来进行,这个算法需要提供一个numFeatures,这个值越大其效果也越好,但是相应的计算时间也越长,后面也可以通过实验验证。2.4 使用每个文档的词向量进行聚类建模在进行聚类建模的时候,需要提供一个初始的聚类个数,这里面设置为10,因为我们的数据是有10个分组的。但是在实际的情况下,一般这个值是需要通过实验来验证得到的。2.5 对聚类后的结果进行评估这里面采用的思路是: 得到聚类模型后,对原始数据进行分类,得到原始文件名和预测的分类id的二元组(fileName,predictId); 针对(fileName,predictId),得到(fileNameFirstChar ,fileNameFirstChar.toInt - predictId)的值,这里需要注意的是fileNameFirstChar其实就是代表这个文件的原始所属类别了。 这里有一个一般假设,就是使用kmeans模型预测得到的结果大多数是正确的,所以fileNameFirstChar.toInt-predictId得到的众数其实就是分类的正确的个数了(这里可能比较难以理解,后面会有个小李子来说明这个问题); 得到每个实际类别的预测的正确率后就可以去平均预测率了。 改变numFeatuers的值,看下是否numFeatures设置的比较大,其正确率也会比较大? 具体步骤:3.1 开发环境--Maven 首先第一步,当然是开发环境了,因为用到了Spark和HanLP,所以需要在pom.xml中加入这两个依赖:其版本为:portable-1.3.4.version>、1.6.0-cdh5.7.3.version>。3.2 文件转为UTF-8编码及存储到一个文件这部分内容可以直接参考:src/main/java/demo02_transform_encoding.TransformEncodingToOne 这里的实现,因为是Java基本的操作,这里就不加以分析了。 3.3 Scala调用HanLP进行中文分词 Scala调用HanLP进行分词和Java的是一样的,同时,因为这里有些词语格式不正常,所以把这些特殊的词语添加到自定义词典中,其示例如下: 作者:fansy1990 来源:CSDN 原文:https://blog.csdn.net/fansy1990/article/details/77577061 版权声明:本文为博主原创文章,转载请附上博文链接!运行完成后,即可得到分词的结果,如下:考虑到使用方便,这里把分词封装成一个函数:输入即是一个中文的文本,输出就是分词的结果,同时去掉了一些常用的停用词。 3.4 求TF-IDF在Spark里面求TF-IDF,可以直接调用Spark内置的算法模块即可,同时在Spark的该算法模块中还对求得的结果进行了维度变换(可以理解为特征选择或“降维”,当然这里的降维可能是提升维度)。代码如下:变量docs是一个DataFrame[fileName, sentence_words] ,经过HashingTF后,变成了变量 featurizedData ,同样是一个DataFrame[fileName,sentence_words, rawFeatures]。这里通过setInputCol以及SetOutputCol可以设置输入以及输出列名(列名是针对DataFrame来说的,不知道的可以看下DataFrame的API)。接着,经过IDF模型,得到变量 rescaledData ,其DataFrame[fileName,sentence_words, rawFeatures, features] 。执行结果为:3.5 建立KMeans模型直接参考官网给定例子即可:这里有计算cost值的,但是这个值评估不是很准确,比如我numFeature设置为2000的话,那么这个值就很大,但是其实其正确率会比较大的。3.6 模型评估这里的模型评估直接使用一个小李子来说明:比如,现在有这样的数据:其中,1开头,2开头和4开头的属于同一类文档,后面的0,3,2,1等,代表这个文档被模型分类的结果,那么可以很容易的看出针对1开头的文档,其分类正确的有4个,其中("123.txt",3)以及(“126.txt”,1)是分类错误的结果,这是因为,在这个类别中预测的结果中0是最多的,所以0是和1开头的文档对应起来的,这也就是前面的假设。 把同一类文档分到同一个partition中; 这里的file_index,是对不同类的文档进行编号,这个编号就对应每个partition,看MyPartitioner的实现: 针对每个partition进行整合操作:在整合每个partition之前,我们先看下我们自定义的MyPartitioner是否在正常工作,可以打印下结果: 运行如下:其中第一列代表每个partition的id,第二列是数据,发现其数据确实是按照预期进行处理的;接着可以针对每个partition进行数据整合:在整合之前先执行一个map操作,把数据变成((fileNameFirstChar, fileNameFirstChar.toInt - predictId), 1),其中fileNameFirstChar代表文件的第一个字符,其实也就是文件的所属实际类别,后面的fileNameFirstChar.toInt-predictId 其实就是判断预测的结果是否对了,这个值的众数就是预测对的;最后一个值代码前面的这个键值对出现的次数,其实就是统计属于某个类别的实际文件个数以及预测对的文件个数,分别对应上面的total和total_right变量;输出结果为:(4,6,3)(1,6,4)(2,6,4)发现其打印的结果是正确的,第一列代表文件名开头,第二个代表属于这个文件的个数,第三列代表预测正确的个数这里需要注意的是,这里因为文本的实际类别和文件名是一致的,所以才可以这样处理,如果实际数据的话,那么mapPartitions函数需要更改。 针对数据结果进行统计:最后只需要进行简单的计算即可: 输出结果为: 实验 设置不同的numFeature,比如使用200和2000,其对比结果为: 所以设置numFeatures值越大,其准确率也越高,不过计算也比较复杂。 总结 HanLP的使用相对比较简单,这里只使用了分词及停用词,感谢开源; Spark里面的TF-IDF以及Word2Vector使用比较简单,不过使用这个需要先分词; 这里是在IDEA里面运行的,如果使用Spark-submit的提交方式,那么需要把hanpl的jar包加入,这个有待验证; 文章来源于fansy1990的博客

优秀的个人博客,低调大师

唤醒沉睡的信息资源 工业数据价值"冰山"待挖掘

在“中国制造2025”发展浪潮中,云计算、物联网、大数据在工业领域中各显神通,制造业和互联网逐步向深度融合的方向发展,数字化技术将为化工企业智能化建设提供一系列行之有效的解决方案。这是1月20日于天津召开的首届科技化工产业峰会上,与会专家提出的观点。 “过去,数据资产一直处于被忽视的状态,人们更加注重的是可视的物理资产。在这种状态下,制造业的系统和信息是相互独立的,缺少集成,数据缺少复用性和协同性,大量潜在的信息被浪费了。”沃利帕森中国区高级副总裁郝杰表示。 阿里云研究中心高级发展战略专家王岳认为,工厂在消耗资源生产产品的同时,也在不断产生新的数据。过去因为没有云计算、大数据、物联网,数据在设备中基本处于沉睡状态,没有被重新采用过。随着算法能力的提升,数据的潜在价值得到重视,大数据和工厂的结合成为实现智能制造的必经之路。 “当前我国正大

优秀的个人博客,低调大师

从C#垃圾回收(GC)机制中挖掘性能优化方案

GC,Garbage Collect,中文意思就是垃圾回收,指的是系统中的内存的分配和回收管理。其对系统性能的影响是不可小觑的。今天就来说一下关于GC优化的东西,这里并不着重说概念和理论,主要说一些实用的东西。关于概念和理论这里只做简单说明,具体的大家可以看微软官方文档。 一、什么是GC GC如其名,就是垃圾收集,当然这里仅就内存而言。Garbage Collector(垃圾收集器,在不至于混淆的情况下也成为GC)以应用程序的root为基础,遍历应用程序在Heap上动态分配的所有对象[2],通过识别它们是否被引用来确定哪些对象是已经死亡的、哪些仍需要被使用。已经不再被应用程序的root或者别的对象所引用的对象就是已经死亡的对象,即所谓的垃圾,需要被回收。这就是GC工作的原理。为了实现这个原理,GC有多种算法。比较常见的算法有Reference Counting,Mark Sweep,Copy Collection等等。目前主流的虚拟系统.NET CLR,Java VM和Rotor都是采用的Mark Sweep算法。(此段内容来自网络) .NET的GC机制有这样两个问题: 首先,GC并不是能释放所有的资源。它不能自动释放非托管资源。 第二,GC并不是实时性的,这将会造成系统性能上的瓶颈和不确定性。 GC并不是实时性的,这会造成系统性能上的瓶颈和不确定性。所以有了IDisposable接口,IDisposable接口定义了Dispose方法,这个方法用来供程序员显式调用以释放非托管资源。使用using语句可以简化资源管理。 二、托管资源和非托管资源 托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源。托管资源的回收工作是不需要人工干预的,有.NET运行库在合适调用垃圾回收器进行回收。 非托管资源指的是.NET不知道如何回收的资源,最常见的一类非托管资源是包装操作系统资源的对象,例如文件,窗口,网络连接,数据库连接,画刷,图标等。这类资源,垃圾回收器在清理的时候会调用Object.Finalize()方法。默认情况下,方法是空的,对于非托管对象,需要在此方法中编写回收非托管资源的代码,以便垃圾回收器正确回收资源。 在.NET中,Object.Finalize()方法是无法重载的,编译器是根据类的析构函数来自动生成Object.Finalize()方法的,所以对于包含非托管资源的类,可以将释放非托管资源的代码放在析构函数。 三、关于GC优化的一个例子 正常情况下,我们是不需要去管GC这些东西的,然而GC并不是实时性的,所以我们的资源使用完后,GC什么时候回收也是不确定的,所以会带来一些诸如内存泄漏、内存不足的情况,比如我们处理一个约500M的大文件,用完后GC不会立刻执行清理来释放内存,因为GC不知道我们是否还会使用,所以它就等待,先去处理其他的东西,过一段时间后,发现这些东西不再用了,才执行清理,释放内存。 下面,来介绍一下GC中用到的几个函数: GC.SuppressFinalize(this); //请求公共语言运行时不要调用指定对象的终结器。 GC.GetTotalMemory(false); //检索当前认为要分配的字节数。一个参数,指示此方法是否可以等待较短间隔再返回,以便系统回收垃圾和终结对象。 GC.Collect(); //强制对所有代进行即时垃圾回收。 GC运行机制 写代码前,我们先来说一下GC的运行机制。大家都知道GC是一个后台线程,他会周期性的查找对象,然后调用Finalize()方法去消耗他,我们继承IDispose接口,调用Dispose方法,销毁了对象,而GC并不知道。GC依然会调用Finalize()方法,而在.NET 中Object.Finalize()方法是无法重载的,所以我们可以使用析构函数来阻止重复的释放。我们调用完Dispose方法后,还有调用GC.SuppressFinalize(this) 方法来告诉GC,不需要在调用这些对象的Finalize()方法了。 下面,我们新建一个控制台程序,加一个Factory类,让他继承自IDispose接口,代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace GarbageCollect { public class Factory : IDisposable { private StringBuilder sb = new StringBuilder(); List<int> list = new List<int>(); //拼接字符串,创造一些内存垃圾 public void MakeSomeGarbage() { for (int i = 0; i < 50000; i++) { sb.Append(i.ToString()); } } //销毁类时,会调用析构函数 ~Factory() { Dispose(false); } public void Dispose() { Dispose(true); } protected virtual void Dispose(bool disposing) { if (!disposing) { return; } sb = null; GC.Collect(); GC.SuppressFinalize(this); } } } 只有继承自IDispose接口,使用这个类时才能使用Using语句,在main方法中写如下代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; namespace GarbageCollect { class Program { static void Main(string[] args) { using(Factory f = new Factory()) { f.MakeSomeGarbage(); Console.WriteLine("Total memory is {0} KBs.", GC.GetTotalMemory(false) / 1024); } Console.WriteLine("After GC total memory is {0} KBs.", GC.GetTotalMemory(false) / 1024); Console.Read(); } } } 运行结果如下,可以看到资源运行MakeSomeGarbage()函数后的内存占用为1796KB,释放后成了83Kb. 代码运行机制: 我们写了Dispose方法,还写了析构函数,那么他们分别什么时候被调用呢?我们分别在两个方法上面下断点。调试运行,你会发现先走到了Dispose方法上面,知道程序运行完也没走析构函数,那是因为我们调用了GC.SuppressFinalize(this)方法,如果去掉这个方法后,你会发现先走Dispose方法,后面又走析构函数。所以,我们可以得知,如果我们调用Dispose方法,GC就会调用析构函数去销毁对象,从而释放资源。 四、什么时候该调用GC.Collect 这里为了让大家看到效果,我显示调用的GC.Collect()方法,让GC立刻释放内存,但是频繁的调用GC.Collect()方法会降低程序的性能,除非我们程序中某些操作占用了大量内存需要马上释放,才可以显示调用。下面是官方文档中的说明: 垃圾回收GC类提供GC.Collect方法,您可以使用该方法让应用程序在一定程度上直接控制垃圾回收器。通常情况下,您应该避免调用任何回收方法,让垃圾回收器独立运行。在大多数情况下,垃圾回收器在确定执行回收的最佳时机方面更有优势。但是,在某些不常发生的情况下,强制回收可以提高应用程序的性能。当应用程序代码中某个确定的点上使用的内存量大量减少时,在这种情况下使用GC.Collect方法可能比较合适。例如,应用程序可能使用引用大量非托管资源的文档。当您的应用程序关闭该文档时,您完全知道已经不再需要文档曾使用的资源了。出于性能的原因,一次全部释放这些资源很有意义。有关更多信息,请参见GC.Collect方法。 在垃圾回收器执行回收之前,它会挂起当前正在执行的所有线程。如果不必要地多次调用GC.Collect,这可能会造成性能问题。您还应该注意不要将调用GC.Collect的代码放置在程序中用户可以经常调用的点上。这可能会削弱垃圾回收器中优化引擎的作用,而垃圾回收器可以确定运行垃圾回收的最佳时间。 参考资料:http://stackoverflow.com/questions/538060/proper-use-of-the-idisposable-interface 作者:阿笨 官方QQ群:422315558 个人讲师课堂主页:http://study.163.com/instructor/2544628.htm 个人微信公众号课程主页:http://dwz.cn/ABenNET

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册