[R语言]文本分类(2)

上一节,介绍了R语言,和本人做文本分类时运用的几个包,还有个小例子。
这一节就用代码来简单介绍下我做文本分类的过程。

我的分类很简单,就是给你一段文字,你将它分类到特定的类别。当然,这是前提是需要大量的语料库,且已经分好类。可以理解为运用监督学习的方法吧。不过我的类别较多,不是二元分类,但是目前的分类器都是二元的,二元的可以改造成多元分类器。有One to One 和 One to the other分类。所幸,R语言里的maxent包,本身就已经帮你做好了,且它会根据类别近似度打分,你可以得到该文档在各类别下的分数,得到排名,从而得出与之相近的多个类别。无疑是非常有用的。

制作语料库

1、我的文本数据在经过一些处理后格式就是:

文本标题(Title) 文本描述(Description) 类别(Type)
…… …… A
…… …… B
…… …… C

我是以词类作为特征的,暂时将标题也作为特征。所以先将标题和描述合并。
可通过如下函数:

BindData <- function(data)
{
  #将标题和描述合并为一个表
  temp <- data.frame(des=NULL,typ=NULL)
  #x <- NULL
  for(i in 1:dim(data)[1])
  {
    x <- paste(data[i,1],data[i,2],sep=",") #合并标题和描述
    tempx <- data.frame(des=x) #创建临时数据框用于合并

    y <- as.character(data[i,3])
    tempy <- data.frame(typ=y)

    tempxy <- cbind(tempx,tempy)
    temp <- rbind(temp,tempxy)
    print(i)
  }
  return (temp)
}

完成后:

文本(Des) 类别(Type)
…… A
…… B
…… C

可以算作“初始”语料库。
2、继续制作语料库。
主要步骤(采用比较简单的步骤):

  1. 分词
  2. 去停用词
  3. 生成文档-词项矩阵

代码如下:

library(tm)
library(rJava)
library(Rwordseg)
#读取刚刚的“初始”语料库。
text= read.table("maxent_10.txt",header = TRUE,row.names=1,fileEncoding = "UTF-8")
#读取停用词,stopwords_CN可在网上下载到。
data_stw <- readLines("stopwords_CN.txt",encoding  = "UTF-8")

#去停用词的函数,将分词后的词项,如有符合停用词的,则去掉。这个函数在后面讲会调用
removeStopWords<-function(x,words){
  ret<-character(0)
  index<-1
  it_max<-length(x)
  while(index<=it_max){
    if(length(words[words==x[index]])<1)ret<-c(ret,x[index])
    index<-index+1
  }
  ret
}

#新建列表,用于存放去停用词后的,各文档词项。
doc_CN <- list()
for(j in 1:dim(text)[1])
{
  x <- c(segmentCN(as.character(text[j,1])),nosymbol=TRUE) #对文档分词
  doc_CN[[j]] <- removeStopWords(x,data_stw)    #去停用词
}

kvid <- Corpus(VectorSource(doc_CN)) #调用tm包中的函数,生成语料库格式文档。

kvid <- tm_map(kvid,stripWhitespace)#去除文档中因去停用词导致的空白词。

#生成词项-文档矩阵(TDM)
control=list(removePunctuation=T,minDocFreq=1,wordLengths = c(1, Inf)) 
#默认的加权方式是TF-IDF,removePunctution,去除标点,
#minDocFreq = 1表示至少词项至少出现了1次,wordLengths则表示词的长度。

**有个特别说明这边也可以用DocumentTermMatrix(kvid,control)——文档-词项矩阵
**这样就是我最适合的模型了。后面有介绍。
tdm=TermDocumentMatrix(kvid,control)#词项-文档矩阵

#length(tdm$dimnames$Terms),用于查看当前的维度
tdm_removed=removeSparseTerms(tdm, 0.99) #一般词类做特征,维度都非常大,故需要降维。
#length(tdm_removed$dimnames$Terms)

###tdm_removed可以用inspect(tdm_removed[1:524,1:5])查看,1:524表示1到524行,1:5表示1到5行。

#读取类别和其对应的数量。为的是在词项文档矩阵后加入类别,便于后来的分类。
#这段代码很随意,只是针对我自己的文档来做的。
typ_text = read.table("部门类别及数量.txt",sep='\t',header = TRUE,row.names=1,fileEncoding = "UTF-8")
n=1
#我的文档有10个类别,因此生成10个文本,每个文本都是文档词项矩阵和对应类别,且我是按次序排好的
for(i in 1:10)
{
  m <- n + typ_text[i,2]
  ts <- inspect(tdm_removed[1:length(tdm_removed$dimnames$Terms),n:m-1])
  #这是转置,先前没考虑那么多所以用了TermDocumentMatrix(kvid,control)。
  #如果用了DocumentTermMatrix(kvid,control),就不需要转置了。
  tk <- t(ts) 
  type <- data.frame(tp=rep(typ_text[i,1],dim(tk)[1]))  
  tm <- cbind(tk,type)  #加入类别
  filename <- paste(i,'.txt',sep = "")
  write.table(tm,filename,sep = "\t", col.names = NA,fileEncoding = "UTF-8")
  n <- typ_text[i,2] + n
}

到这,就生成了我所需要的语料库了。各人情况不同,可互相参考。

文档-词项矩阵:

文本编号\词项 词项1 词项2 词项3 词项4
001 1 1 1 1
002 1 1 1 1
003 1 1 1 1

词项-文档矩阵:

文本编号\词项 001 002 003 004
词项1 1 1 1 1
词项2 1 1 1 1
词项3 1 1 1 1

明显,文档-词项矩阵符合我的要求。

你可能感兴趣的:(R语言)