全文链接:http://tecdat.cn/?p=30413
开源软件存储库上有数千个开源软件,可以从中免费使用该软件。为了能够有效和高效地识别用户所需的软件,已根据软件的功能和属性向软件判断了标记(点击文末“阅读原文”获取完整代码数据)。
因此,标签分配成为开源软件存储库软件维护成功的关键。手动分配需要专家判断软件的功能和性能,并从软件的大型标签池中选择适当的预定义标签,这显然很耗时。因此,此任务上的软件挖掘的目的是利用数据挖掘的进步,为新上传的软件项目启用自动标记分配(重新推荐)。
为了降低数据预处理(特别是网页解析)的难度,在知名开源软件仓库中介绍不同开源软件的网页的主要内容被提取并按照以下格式妥善存储。
要挖掘的数据
数据以 txt 格式存储(查看文末了解数据免费获取方式)。每行对应于一个以该项目的 id 开头的软件项目。在id之后,有“#$#”引用的该软件项目的提取文本描述。在此行的末尾,将附加标记(用“,”分隔)。所有数据被拆分为两个不相交的数据集。一个被命名为“train.data”(包含4465个软件项目),而另一个被命名为“test.data”(包含大约1000个新软件项目)。这两个文件之间的唯一格式区别是所有标签都替换为单个未知标记“?”。可以分配给任何软件项目的标签集在“allTags.txt”中提供,其中每行对应于一个标签。
使用“train”来构建一个模型。data,然后使用构建的模型在评估阶段为”test.data“中的每个软件项目的标记提供预测。
问题剖析
本次项目本质上属于数据挖掘中的分类问题,那总体的思路就是在提供的训练集上采用分类算法构造出分类模型, 然后将分类模型应用在测试集上, 得出测试集中所有记录的分类结果。
从项目背景上就可以看出数据集在特征上的取值是稀疏的,文本信息中会出现大量的单词,而一些常用的单词,如 a ,an , and等是不具有分类特征的词汇,属于常用词汇,因此在文本挖掘的过程中必须剔除这些词汇。因此我们首先要做的就是对数据文本挖掘,然后对得到的词频进行预处理,剔除标点,常用词等,同时降低其稀疏性,也就是剔除出现频率特别低的词汇。其中注意的是在预处理过程中我们应该保证训练集和测试集在形式上的一致,比如他们的属性个数、类别应该一致。
在数据预处理完成的基础上,就应该进行选择分类算法,利用训练集构造模型了。
最后就是应用模型,得出测试集中结果。
数据挖掘过程
经过问题分析后就开始进行各项工作了, 那首先就是平台的选择, 经过比较后我最终采用了 R工具,因为此工具中功能比较健全,有助于我们分析。
文件导入
由于训练数据是文本数据,因此不能用读取excel或者读取table的方式读取数据,只能通过readlines对数据的每一行文本进行读取,主要思路就是读文件到r,保存为训练数据,然后读取标签数据。因为标签数据是文档格式数据,可以直接用read.table读取到r。
数据预处理
A、分割:
因为读取后数据并不是格式化的,因此第一步就是对他进行分割处理,原有的数据每一行都包含了序号,文本和标签并用"#$#"隔开,因此,我们可以利用这个分割符号来对每个样本进行处理。这里用到的是strsplit语句。分割后得到的标签数据仍然是混合在一起的,同样可以找到分隔符号为“,”,因此再次对标签数据进行分割。得到每个样本的标签数据。
B .格式化
由于得到的每个样本的标签数据是一个集合,对于后面的分类问题来说,不是理想的数据格式,因此需要将标签数据转化成二维矩阵的格式,每一行为一个样本,每一列代表一个标签,所有列就是所有出现过的标签。如果该样本中包含一个或多个标签,就将这些标签所对应的元素标为1,没有出现的元素为0.最后生成一个标签矩阵。
算法选择
分类算法无穷无尽, 针对不同的数据集, 算法的效率也不一样, 因此选择合适的算法是很重要的工作。
决策树易于理解和解释。人们在通过解释后都有能力去理解决策树所表达的意义。但由于本项目中样本属性较多,因此可能会出现较多的分支和较大的树,从而很难得到有效的判断。人工神经网络虽然分类的准确度高,并行分布处理能力强,不能观察之间的学习过程,输出结果难以解释。
Knn算法虽然原理简单有效,但是计算量较大,对于数据量较大的数据不太合适,对高维数据进行分类时会而且导致其准确率下降。
而SVM可以解决高维问题,同时可以避免神经网络结构选择和局部极小点问题。因此,最终选用该算法来建立分类模型。
支持向量机
SVM 是支持向量机的简称, 是统计学习理论中 最年轻的内容, 也是最实用的部分。其核心内容是在 1992 到 1995 年间提出的, 目前仍处在不断发展阶段。支持向量机可用 于模式识别、回归分析 、主成分分析等.下面以模式 分类为例来介绍支持向量机的含义 。
给定一组训练数据(x 1 , y 1), … ,(x l , y l), xi ∈ R n , yi ∈{ +1 , -1} , i =1 , 2 , …, l,我们要寻找一 个分类规则 I(x),使它能对未知类别的新样本(新 样本与训练样本独立同分布)作尽可能正确的划分 。支持向量机用于分类问题其实就是寻找一个最 优分类超平面, 把此平面作为分类决策面.同时它还 通过引进核函数巧妙地解决了在将低维空间向量映 射到高维空间向量时带来的“维数灾难”问题。
基于LDA的文本主题挖掘
对于文本处理过程首先要拥有分析的语料(text corpus),比如报告、出版物、网页文章等。而后根据这些语料建立半结构化的文本库(text database),生成包含词频的结构化的词条 -文档矩阵(term-document matrix)。
LDA是一种非监督机器学习技术,可以用来识别大规模文档集(document collection)或语料库(corpus)中潜藏的主题信息。它采用了词袋(bag of words)的方法,这种方法将每一篇文档视为一个词频向量,从而将文本信息转化为了易于建模的数字信息。但是词袋方法没有考虑词与词之间的顺序,这简化了问题的复杂性,同时也为模型的改进提供了契机。每一篇文档代表了一些主题所构成的一个概率分布,而每一个主题又代表了很多单词所构成的一个概率分布。由于 Dirichlet分布随机向量各分量间的弱相关性(之所以还有点“相关”,是因为各分量之和必须为1),使得我们假想的潜在主题之间也几乎是不相关的,这与很多实际问题并不相符,从而造成了LDA的又一个遗留问题。
对于语料库中的每篇文档,LDA定义了如下生成过程(generative process):
- 对每一篇文档,从主题分布中抽取一个主题;
- 从上述被抽到的主题所对应的单词分布中抽取一个单词;
- 重复上述过程直至遍历文档中的每一个单词。
更形式化一点说,语料库中的每一篇文档与 T(通过反复试验等方法事先给定)个主题的一个多项分布相对应,将该多项分布记为 θ。每个主题又与词汇表(vocabulary)中的 V个单词的一个多项分布相对应,将这个多项分布记为 ϕ。
上述词汇表是由语料库中所有文档中的所有互异单词组成,但实际建模的时候要剔除一些停用词(stopword),还要进行一些词干化(stemming)处理等。θ 和ϕ分别有一个带有超参数(hyperparameter)α和β的Dirichlet先验分布。对于一篇文档d中的每一个单词,我们从该文档所对应的多项分布θ中抽取一个主题z,然后我们再从主题z所对应的多项分布ϕ中抽取一个单词w。将这个过程重复Nd次,就产生了文档d,这里的Nd是文档d的单词总数。这个生成过程可以用如下的图模型表示:
这个图模型表示法也称作“盘子表示法”(plate notation)。图中的阴影圆圈表示可观测变量(observed variable),非阴影圆圈表示潜在变量(latent variable),箭头表示两变量间的条件依赖性(conditional dependency),方框表示重复抽样,重复次数在方框的右下角。
该模型有两个参数需要推断(infer):一个是“文档-主题”分布θ,另外是T个“主题-单词”分布ϕ。通过学习(learn)这两个参数,我们可以知道文档作者感兴趣的主题,以及每篇文档所涵盖的主题比例等。推断方法主要有LDA模型作者提出的变分-EM算法,还有现在常用的Gibbs抽样法。
LDA模型现在已经成为了主题建模中的一个标准。如前所述,LDA模型自从诞生之后有了蓬勃的扩展,特别是在社会网络和社会媒体研究领域最为常见。
算法实现
根据SVM和LDA文本挖掘的原理,通过r语言可以做出以下的代码实现:
for(j in 1:length(colindex))tagmatrix[j,colindex[[j]]]=1; ####建立语料库 reuters <- Corpus(VectorSource(traindata)) #下一步用tm_map命令对语料库文件进行预处理,将其转为纯文本并去除多余空格,转换小写,去除常用词汇、合并异形同意词汇 reuters <- tm_map(reuters, as.PlainTextDocument)
再之后就可以利用R语言中任何工具加以研究了,下面用层次聚类试试看: 先进行标准化处理,再生成距离矩阵,再用层次聚类.
d <- dist(data.scale, method = "euclidean")
绘制词汇图
wordcloud(names(d),d,random.order=FALSE,random.color=FALSE,colors=mycolors,family="my
点击标题查阅往期内容
自然语言处理NLP:主题LDA、情感分析疫情下的新闻文本数据
01
02
03
04
建立分类器
tagmod=tagmatrix[,1]#每个样本的第一个分类标签
SVM分类
preds <- predict(model.svm, trainmod,type="class") tab=table(preds,trainmod[,ncol(trainmod)])#分类混淆矩阵 k=10#设置为10折交叉验证 for(kk in 1:k){ index=sample(1:dim(trainmod)[1],floor(dim(trainmod)[1]*(1/k)),replace=F)#筛选样本 test=as.data.frame(trainmod[index,])#训练集
结果分析
经过算法的实现,我们已经通过训练集得到了分类模型,经过十折交叉验证发现其准确率能达到 99.8%,接下来就是将测试集导入并且运用刚刚生成的模型产生结果了, 同样的是运用 R工具。其中需要注意的是测试集中缺失的类别值用?来代替。将生成的结果保存下来发现?前面出现了数字,这就是我们所要寻找的类别值。
虽然前面训练集产生的模型的准确率能达到99.8%,但是实际测试集的准确率又是不确定的, 不一定比他高还是比他低, 但幅度肯定不会很大。同时从算法本身来看就存在着一定的缺陷, 因为经典的SVM分类算法要求分类属性是二元变量,而对于多元变量来说,必须组合多个SVM模型,从而可能是算法的准确度下降,对本项目的数据来说,每一个样本可能属于多个类别,因此使用svm分类的时候,可能导致算法的准确度下降。
误差肯定还不止以上的方面, 但是总体来说这个分类器还是可以的, 经过十折交叉验证准确率还是有保证的。