Master 2 DAC

Fouille de Donnée et Média Sociaux (FDMS)

Outils de gestion de fichier (tools.py)

def readAFile(nf):
    f = open(nf, 'rb')

    txt = f.readlines()
    txt = ' '.join(txt)

    f.close()
    return txt

def compteLignes(nf, fdl='\n', tbuf=16384):
    """Compte le nombre de lignes du fichier nf"""
    c = 0
    f = open(nf, 'rb')
    while True:
        buf = None
        buf = f.read(tbuf)
        if len(buf)==0:
            break
        c += buf.count(fdl)
    f.seek(-1, 2)
    car = f.read(1)
    if car != fdl:
        c += 1
    f.close()
    return c

Import des jeux de données sur le texte:

Obligation de savoir jouer (un peu) avec les expressions régulières:

  • Livre regular expresssion cookbook (dispo. gratuitement online)
  • Wikipedia regex

Code pour Chirac/Mitterrand

import codecs
import re
from tools import * # import du fichier défini plus haut

nblignes = compteLignes(fname)
print "nblignes = %d"%nblignes

alltxts = []
labs = np.ones(nblignes)
s=codecs.open(fname, 'r','utf-8') # pour régler le codage

cpt = 0
for i in range(nblignes):
    txt = s.readline()
    #print txt

    lab = re.sub(r"<[0-9]*:[0-9]*:(.)>.*","\\1",txt)
    txt = re.sub(r"<[0-9]*:[0-9]*:.>(.*)","\\1",txt)

    #assert(lab == "C" or lab == "M")

    if lab.count('M') >0:
        labs[cpt] = -1
    alltxts.append(txt)

    cpt += 1
    if cpt %1000 ==0:
        print cpt

A vous de charger les données de test pour vérifier que tout est OK;

Code pour movies


from tools import *
import os.path

path = "/Users/vguigue/Documents/Cours/AFD/projetTexteRessources/dataSent/movies1000/"

alltxts = [] # init vide
labs = []
cpt = 0
for cl in os.listdir(path): # parcours des fichiers d'un répertoire
    print cl
    for f in os.listdir(path+cl):
        txt = readAFile(path+cl+'/'+f)
        alltxts.append(txt)
        labs.append(cpt)

    cpt += 1
 

Passage aux sacs de mots

2 principales librairies permettent de manipuler aisément du texte:

  • gensim
  • nltk

Le tutoriel suivant est basé sur gensim. Vous êtes encouragé à jouer avec toutes les options pour évaluer les différences de performances.

stoplist = set('le la les de des à un une en au ne ce d l c s je tu il que qui mais quand'.split())
stoplist.add('')

## DICO
splitters = u'; |, |\*|\. | |\'|'

dictionary = corpora.Dictionary(re.split(splitters, doc.lower()) for doc in alltxts)

print len(dictionary)

stop_ids = [dictionary.token2id[stopword] for stopword in stoplist   if stopword in dictionary.token2id]
once_ids = [tokenid for tokenid, docfreq in dictionary.dfs.iteritems() if docfreq < 10 ]
dictionary.filter_tokens(stop_ids + once_ids) # remove stop words and words that appear only once
dictionary.compactify() # remove gaps in id sequence after words that were removed

print len(dictionary)

## PROJ

texts = [[word for word in re.split(splitters, document.lower()) if word not in stoplist]  for document in alltxts]
corpus = [dictionary.doc2bow(text) for text in texts]

## exemple de doc
# corpus[0]
# avec les mots
print [dictionary[i] for i,tmp in corpus[0]]

Passage dans numpy et traitements usuels

# Transformation pour passer en matrice numpy
dataSparse = gensim.matutils.corpus2csc(corpus)

#### tfidf

import sklearn.feature_extraction.text as txtTools #.TfidfTransformer

t = txtTools.TfidfTransformer()
t.fit(dataSparse.T)
data2 = t.transform(dataSparse.T)
 

Pour les bigrammes

Génération des bigrammes (version efficace)


# remplacement de la ligne:
# dictionary = corpora.Dictionary(re.split(splitters, doc.lower()) for doc in alltxts)

liste = (re.split(splitters, doc.lower()) for doc in alltxts) # generator = pas de place en memoire
dictionary = corpora.Dictionary([u"{0}_{1}".format(l[i],l[i+1]) for i in xrange(len(l)-1)] for l in liste) # bigrams

# projection des documents:
liste = (re.split(splitters, doc.lower()) for doc in alltxts) # ATTENTION: quand le générator a déjà servi, il ne se remet pas au début => le re-créer pour plus de sécurité
alltxtsBig = ([u"{0}_{1}".format(l[i],l[i+1]) for i in xrange(len(l)-1)] for l in liste)
corpusBig = [dictionary.doc2bow(text) for text in alltxtsBig]