TF-IDF提取英文文章特征词

# -*- coding: utf-8 -*-
"""
Created on Wed Mar 28 16:49:38 2018

@author: 47899
"""
import codecs
import os
import nltk
import math
import operator
from nltk.tokenize import WordPunctTokenizer

def participles(text): #分词函数
    pattern = r"""(?x)                   # set flag to allow verbose regexps 
              (?:[A-Z]\.)+           # abbreviations, e.g. U.S.A. 
              |\d+(?:\.\d+)?%?       # numbers, incl. currency and percentages 
              |\w+(?:[-']\w+)*       # words w/ optional internal hyphens/apostrophe 
              |\.\.\.                # ellipsis 
              |(?:[.,;"'?():-_`])    # special characters with meanings 
            """
    t=nltk.regexp_tokenize(text, pattern)
    length=len(t)
    for i in range(length):
        t[i]=t[i].lower() 
    return t

def getridofsw(lis, swlist):  # 去除文章中的停用词
    afterswlis = []
    for i in lis:
        if str(i) in swlist:
            continue
        else:
            afterswlis.append(str(i).lower())
    return afterswlis

def fun(filepath):  # 遍历文件夹中的所有文件,返回文件list
    arr = []
    for root, dirs, files in os.walk(filepath):
        for fn in files:
            arr.append(root+"\\"+fn)
    return arr

def read(path):  # 读取txt文件,并返回list
        with codecs.open(path, 'r', 'ANSI') as f:
            data=f.read()
        return data
        
def readstop(path):  # 读取txt文件,并返回list
    f = open(path,encoding='ANSI' )
    data = []
    for line in f.readlines():
        data.append(line)
    return data
        
def getstopword(path):  # 获取停用词表
    swlis = []
    for i in readstop(path):
        outsw = str(i).replace('\n', '').lower()
        swlis.append(outsw)
    return swlis

def freqword(wordlis):  # 统计词频,并返回字典
    freword = {}
    for i in wordlis:
        if str(i) in freword:
            count = freword[str(i)]
            freword[str(i)] = count+1
        else:
            freword[str(i)] = 1
    return freword

def corpus(filelist, swlist):  # 建立语料库
    alllist = []
    for i in filelist:
        afterswlis = getridofsw(participles(read(str(i))), swlist)
        alllist.append(afterswlis)
    return alllist

def tf_idf(wordlis, filelist, corpuslist):  # 计算TF-IDF,并返回字典
    outdic = {}
    tf = 0
    idf = 0
    dic = freqword(wordlis)
    #outlis = []
    for i in set(wordlis):
        tf = dic[str(i)]/len(wordlis)  # 计算TF:某个词在文章中出现的次数/文章总词数
        # 计算IDF:log(语料库的文档总数/(包含该词的文档数+1))
        idf = math.log(len(filelist)/(wordinfilecount(str(i), corpuslist)+1))
        tfidf = tf*idf  # 计算TF-IDF
        outdic[str(i)] = tfidf
    orderdic = sorted(outdic.items(), key=operator.itemgetter(
        1), reverse=True)  # 给字典排序
    return orderdic

def wordinfilecount(word, corpuslist):  # 查出包含该词的文档数
    count = 0  # 计数器
    for i in corpuslist:
        for j in i:
            if word in set(j):  # 只要文档出现该词,这计数器加1,所以这里用集合
            #if j.__contains__(word):
                count = count+1
            else:
                continue
    return count

def befwry(lis):  # 写入预处理,将list转为string
    outall = ''
    for i in lis:
        ech = str(i).replace("('", '').replace("',", '\t').replace(')', '')
        outall = outall+'\t'+ech+'\n'
    return outall

def wry(txt, path):  # 写入txt文件
    f = codecs.open(path, 'a', 'ANSI')
    f.write(txt)
    f.close()
    return path

def main():
    swpath = r'D:\text\stop_words_eng.txt'#停用词表路径
    swlist = getstopword(swpath)  # 获取停用词表列表
    #print(swlist)
    filepath = r'D:\text\yuliao\1'
    filelist = fun(filepath)
    corpuslist = corpus(filelist, swlist)
    #print(corpuslist)
    outall = ''
    wrypath = r'D:\text\result\TFIDF2.txt'
    for i in filelist:
        afterswlis = getridofsw(participles(read(str(i))), swlist)  # 获取每一篇已经去除停用的词表
        tfidfdic = tf_idf(afterswlis, filelist, corpuslist) # 计算TF-IDF
        titleary = str(i).split('\\')
        title = str(titleary[-1]).replace('utf8.txt', '')
        echout = title+'\n'+befwry(tfidfdic)
        print(title+' is ok!')
        outall = outall+echout 
    print(wry(outall, wrypath)+' is ok!')
main()

    老规矩,先把代码贴出。上一周信息内容安全老师让我们应python实现英文文本的预处理、并通过计算TF-IDF的值来提取英文的特征词。接下来介绍一下每个子函数的功能。

一、函数功能

1、分词def participles():

    这个函数主要是用于英语语句的分词,思想是按照正则表达式,用到了nltk库函数,返回的是所有英文的小写形式,为了方便后面的词频统计。

2、去除停用词函数 def getridofsw():

    当我们把原始的英文文档分好词之后,返回的是所有单词的列表形式,在这里为了后面的计算结果更加接近文章的真实特征值,我们需要去除英语文本的停用词,停用词可以在CSDN上找的txt的文档,大家可以自行搜索一下。

3、返回目标文件夹下所有文档的地址列表 def fun()

    主要运用了os库的os.walk功能,遍历文件夹下的所有文件路径。因为后面所用到的语料库txt文件非常的多,所以要一一遍历。

4、read和readstop 

    两个函数功能一样,都是读取txt文件的文本信息,但是因为停用词的txt文件是一行一个词,所以写了readstop来专门读取停用词。不过后来想想,也就没用到。

5、获取停用词表def getstopword():

    按行将停用词txt文档的停用词转换为列表存储起来。

6、统计词频def freqword():

    返回字典形式,统计每一篇文章中进行处理后单词出现的频数。

7、建立语料库def corpus():

    将一篇文章作为列表的一个元素,然后将文件夹中所有的文章链接成一个列表。方便后面的统计单词出现的文档数。

8、计算TF-IDF的值tf-idf():

    

    最后按照TF-IDF的值将词按照降序排列。

9、统计出现的文档数def wordinfilecount():

     利用了两层循环,外层循环遍历所有的文档,内层循环遍历文档中的单词。利用了集合的方法,在这里还尝试使用了contain函数,但是效果不是特别的好,一方面对效率的提升作用不是特别大,另一方面部分结果出现了错误。

10、写入函数def befwry/wry():

     进行了一些写入的预处理,然后写入到txt文档中。

二、结果展示


使用了SCI.SPACE文件中的1000份语料,内容大部分与宇宙及空间技术有关。

TF-IDF提取英文文章特征词_第1张图片

TF-IDF提取英文文章特征词_第2张图片TF-IDF提取英文文章特征词_第3张图片TF-IDF提取英文文章特征词_第4张图片

这里选取了部分结果作为展示,可见特征词的提取是大致正确的。

你可能感兴趣的:(TF-IDF提取英文文章特征词)