nltk-コーパスの構築と使用-小説に使用できる推奨-完全なインスタンス


手順1:コーパスの構築:
#!/usr/bin/env python
#-*-coding=utf-8-*-


#     (    )
sourceDataDir='data'

#       
fileLists = []

import os
from gensim import corpora, models, similarities
            
def getSourceFileLists(sourceDataDir):  
    fileLists = []
    subDirList = os.listdir(sourceDataDir)
    for subDir in subDirList:
        subList = os.listdir(sourceDataDir + '/' + subDir)
        fileList = [ sourceDataDir+'/'+subDir+'/'+ x for x in subList if os.path.isfile(sourceDataDir+'/'+subDir+'/'+x)]
        fileLists += fileList

    return  fileLists   
        
        
fileLists = getSourceFileLists(sourceDataDir)  
  
  
if 0 < len(fileLists): 
    import codecs
    import jieba
    punctuations = ['','
','\t',',', '.', ':', ';', '?', '(', ')', '[', ']', '&', '!', '*', '@', '#', '$', '%']           if not os.path.exists('dict'):         os.mkdir("dict")      if not os.path.exists('corpus'):         os.mkdir("corpus")      for fileName in fileLists:         print fileName         hFile = None         content = None         try:             hFile = codecs.open(fileName,'r','gb18030')             content = hFile.readlines()         except Exception,e:             print e         finally:             if hFile:                 hFile.close()                  if content:             fileFenci = [ x for x in jieba.cut(' '.join(content),cut_all=True)]             fileFenci2 = [word for word in fileFenci if not word in punctuations]                            texts = [fileFenci2]             all_tokens = sum(texts, [])             tokens_once = set(word for word in set(all_tokens) if all_tokens.count(word) == 1)             texts = [[word for word in text if word not in tokens_once] for text in texts]             sFileDir, sFileName = os.path.split(fileName)             dictFileName = 'dict/'+sFileName+'.dict'             corpusFileName = 'corpus/'+sFileName+'.mm'                          dictionary = corpora.Dictionary(texts)             dictionary.save_as_text(dictFileName)             corpus = ([dictionary.doc2bow(text) for text in texts])             corpora.MmCorpus.serialize(corpusFileName, corpus)  print 'Build corpus done'

データソース:
からhttp://d1.txthj.com/newrar/txthj_264.rarの83編の小説をカタログに保存する./data/下.
ロード時に二層ディレクトリとして処理
出力:
./dictおよび./corpus
対応ディレクトリの下でxxxを生成する.dictとxxx.mm,xxxは元のファイルのフルネーム(パスを含まない、接尾辞を含む)
手順2:コーパスのロード、類似性分析
#!/usr/bin/env python
#-*-coding=utf-8-*-


import os
from gensim import corpora, models, similarities
            
def getFileList(dir):            
    return [ dir + x for x in os.listdir(dir)]
dictLists =  getFileList('./dict/')
 

class LoadDictionary(object):
    def __init__(self, dictionary):
        self.dictionary = dictionary

    def __iter__(self):
        for dictFile in dictLists:
            sFileRaw, sFilePostfix = os.path.splitext(dictFile)
            sFileDir, sFileName = os.path.split(sFileRaw)
            (dictFile, corpusFile) = ( './dict/' + sFileName + '.dict',  './corpus/'+sFileName + '.mm')
            yield self.dictionary.load_from_text(dictFile)
            
class LoadCorpus(object):

    def __iter__(self):
        for dictFile in dictLists:
            sFileRaw, sFilePostfix = os.path.splitext(dictFile)
            sFileDir, sFileName = os.path.split(sFileRaw)
            (dictFile, corpusFile) = ( './dict/' + sFileName + '.dict',  './corpus/'+sFileName + '.mm')
            yield corpora.MmCorpus(corpusFile)
            
  
"""
       (easy_install nltk)
"""
#      +      
def pre_process_cn(inputs, low_freq_filter = True):
    """
        1.     
        2.      
        3.     
        4.     

    """
    import nltk
    import jieba.analyse
    from nltk.tokenize import word_tokenize
    
    texts_tokenized = []
    for document in inputs:
        texts_tokenized_tmp = []
        for word in word_tokenize(document):
            texts_tokenized_tmp += jieba.analyse.extract_tags(word,10)
        texts_tokenized.append(texts_tokenized_tmp)    
    
    texts_filtered_stopwords = texts_tokenized

    #      
    english_punctuations = [',', '.', ':', ';', '?', '(', ')', '[', ']', '&', '!', '*', '@', '#', '$', '%']
    texts_filtered = [[word for word in document if not word in english_punctuations] for document in texts_filtered_stopwords]

    #   
    from nltk.stem.lancaster import LancasterStemmer
    st = LancasterStemmer()
    texts_stemmed = [[st.stem(word) for word in docment] for docment in texts_filtered]
    
    #      
    if low_freq_filter:
        all_stems = sum(texts_stemmed, [])
        stems_once = set(stem for stem in set(all_stems) if all_stems.count(stem) == 1)
        texts = [[stem for stem in text if stem not in stems_once] for text in texts_stemmed]
    else:
        texts = texts_stemmed
    return texts

dictionary = corpora.dictionary.Dictionary()
dictionary_memory_friendly = LoadDictionary(dictionary)
for vector in dictionary_memory_friendly: 
    dictionary = vector

corpus = []
corpus_memory_friendly = LoadCorpus()
for vector in corpus_memory_friendly: 
    corpus.append(vector[0])
    
if 0 < len(corpus):
    tfidf = models.TfidfModel(corpus)
    corpus_tfidf = tfidf[corpus]

    model = models.LsiModel(corpus_tfidf, id2word=None, num_topics=20,  chunksize=2000000) #    id2word=dictionary  ,LsiModel      corpus    dictionary
    index = similarities.Similarity('./novel_', model[corpus], num_features=len(corpus)) 

    #        ,              
    target_courses = ['           ,                    ,           ,           。']
    target_text = pre_process_cn(target_courses, low_freq_filter=False)

    """
              
    """
    #        
    ml_course = target_text[0]
    #    
    ml_bow = dictionary.doc2bow(ml_course)   

    #           lsi model  ,            
    ml_lsi = model[ml_bow]     #ml_lsi     (topic_id, topic_value)
    sims = index[ml_lsi]     #sims       , index[xxx]        __getitem__()    ml_lsi

    #  ,     
    sort_sims = sorted(enumerate(sims), key=lambda item: -item[1])

    #    
    print sort_sims[0:10]   
    print len(dictLists)
    print dictLists[sort_sims[1][0]] 
    print dictLists[sort_sims[2][0]] 
    print dictLists[sort_sims[3][0]]

説明:
yieldの使用は、より良いメモリ効率のためです.
残された問題:
手順2でヒントが表示されます.
     /usr/lib/python2.7/dist-packages/scipy/sparse/compressed.py:122: UserWarning: indices array has non-integer dtype (float64)
プロセスに影響しない