<jupyter_start><jupyter_text>Label Sentence<jupyter_code>class LabeledLineSentence(object):
	def __init__(self, doc_list, labels_list):
		self.labels_list = labels_list
		self.doc_list = doc_list
	def __iter__(self):
		for idx, doc in enumerate(self.doc_list):
			yield gensim.models.doc2vec.LabeledSentence(doc,[self.labels_list[idx]])<jupyter_output><empty_output><jupyter_text>create stopword list<jupyter_code>#from nltk.corpus import stopwords
# stopwords_french = stopwords.words("french")
# print(stopwords_french)
#création de la liste de stopwords
stopwords_base = ['là','si','ça','aussi','au','aux','avec','ce','ces','dans','de','des','du','elle','en','et','eux','il','je','la','le','leur','leurs','lui','ma','mais','me','même','mes','moi','mon','ne','nos','notre','nous','on','ou','où','par','pas','pour','qu','que','qui','sa','se','ses','son','sur','ta','te','tes','toi','ton','tu','un','une','vos','votre','vous','ceci','cela','celà','cet','cette','ici','ils','les','leurs','quel','quels','quelle','quelles','sans','soi', 'tout', 'toutes', 'toute', 'tous']
stopwords_ponctuation = [',','"',';',':','.','?','!','*','—']
stopwords_lettres_seules = ['c','d','j','l','à','m','n','s','t','y',"c’","d’","j’","l’","m’","n’","s’","t’","qu’"]
stopwords_verbeterne_etre = ['être','été','étée','étées','étés','étant','suis','es','est','sommes','êtes','sont','serai','seras','sera','serons','serez','seront','serais','serait','serions','seriez','seraient','étais','était','étions','étiez','étaient','fus','fut','fûmes','fûtes','furent','sois','soit','soyons','soyez','soient','fusse','fusses','fût','fussions','fussiez','fussent']
stopwords_verbeterne_avoir = ['a','avoir','ayant','eu','eue','eues','eus','ai','as','avons','avez','ont','aurai','auras','aura','aurons','aurez','auront','aurais','aurait','aurions','auriez','auraient','avais','avait','avions','aviez','avaient','eut','eûmes','eûtes','eurent','aie','aies','ait','ayons','ayez','aient','eusse','eusses','eût','eussions','eussiez','eussent']

#création du stopset
stopset = stopwords_base
for w in stopwords_ponctuation:
    stopset.append(w)

for w in stopwords_lettres_seules:
    stopset.append(w)

for w in stopwords_verbeterne_avoir:
    stopset.append(w)

for w in stopwords_verbeterne_etre:
    stopset.append(w)
    
print(stopset)<jupyter_output>['là', 'si', 'ça', 'aussi', 'au', 'aux', 'avec', 'ce', 'ces', 'dans', 'de', 'des', 'du', 'elle', 'en', 'et', 'eux', 'il', 'je', 'la', 'le', 'leur', 'leurs', 'lui', 'ma', 'mais', 'me', 'même', 'mes', 'moi', 'mon', 'ne', 'nos', 'notre', 'nous', 'on', 'ou', 'où', 'par', 'pas', 'pour', 'qu', 'que', 'qui', 'sa', 'se', 'ses', 'son', 'sur', 'ta', 'te', 'tes', 'toi', 'ton', 'tu', 'un', 'une', 'vos', 'votre', 'vous', 'ceci', 'cela', 'celà', 'cet', 'cette', 'ici', 'ils', 'les', 'leurs', 'quel', 'quels', 'quelle', 'quelles', 'sans', 'soi', 'tout', 'toutes', 'toute', 'tous', ',', '"', ';', ':', '.', '?', '!', '*', '—', 'c', 'd', 'j', 'l', 'à', 'm', 'n', 's', 't', 'y', 'c’', 'd’', 'j’', 'l’', 'm’', 'n’', 's’', 't’', 'qu’', 'a', 'avoir', 'ayant', 'eu', 'eue', 'eues', 'eus', 'ai', 'as', 'avons', 'avez', 'ont', 'aurai', 'auras', 'aura', 'aurons', 'aurez', 'auront', 'aurais', 'aurait', 'aurions', 'auriez', 'auraient', 'avais', 'avait', 'avions', 'aviez', 'avaient', 'eut', 'eûmes', 'eûtes', 'eurent', 'a[...]<jupyter_text>Other functions Clean text<jupyter_code>def nlp_clean(data):
    tokenizer = RegexpTokenizer(r'\w+')
    new_str = data.lower()
    dlist = tokenizer.tokenize(new_str)
    #stopwords_french_1 = set(line.strip() for line in open('../dictionaries/stopwords_fr1'))
    #stopwords_french_1 =  stopwords.words("french") + ['les', 'a', 'à', 'où', 'plus', 'moins']
    stopwords_french_1 =  stopset    
    cleanList = [word for word in dlist if word not in stopwords_french_1]
    #print(cleanList)
    return cleanList<jupyter_output><empty_output><jupyter_text>Load JSON<jupyter_code>def loadjson(json_file) :
    try :
        if os.path.exists(json_file) :
            with open(json_file) as f:
                return json.load(f)
        else :
            return {}
    except :
            return {}<jupyter_output><empty_output><jupyter_text>Build datasetSelect only french text<jupyter_code>def build_dataset(json_files):
    docLabels = []
    data = []

    for jfile in json_files:
        j = loadjson(jfile)
        for news in j :
            if news != "statistics" :
                #print(news)
                for t in j[news] :
                    if t['lang'] == 'fr' :
                        # Create uniq title label
                        docLabels.append(news+" - "+t['title'])
                        data.append(nlp_clean(t['text']))
                        #data.append(t['text'])
    return data, docLabels<jupyter_output><empty_output><jupyter_text>train model function<jupyter_code>def train_model(json_files) :
    startime = time.time()

    data, docLabels = build_dataset(json_files)
    
    print("{0} articles loaded for model".format(len(data)))

    it = LabeledLineSentence(data, docLabels)

    model = gensim.models.Doc2Vec(size=300, window=10, min_count=0, workers=8,alpha=0.025, min_alpha=0.025) # use fixed learning rate
    model.build_vocab(it)
    for epoch in range(10):
        print("Training epoch {}".format(epoch))
        model.train(it,total_examples=model.corpus_count,epochs=model.iter)
        model.alpha -= 0.002 # decrease the learning rate
        model.min_alpha = model.alpha # fix the learning rate, no deca
        model.train(it,total_examples=model.corpus_count,epochs=model.iter)

    #saving the created model
    model.save(os.path.join('/tmp/doc2vec.w2v'))
    print('model saved')<jupyter_output><empty_output><jupyter_text>TRAINING open JSON for articles<jupyter_code># this finds our json files
path_to_json = 'articles/'
json_files = [path_to_json + pos_json for pos_json in os.listdir(path_to_json) if pos_json.endswith('.json')]<jupyter_output><empty_output><jupyter_text>train the model<jupyter_code># avec http://www.iero.org/beatcrunch/20171025.json
#json_files = sorted(glob.glob('20171025.json'))
train_model(json_files)<jupyter_output>9956 articles loaded for model
Training epoch 0
Training epoch 1
Training epoch 2
Training epoch 3
Training epoch 4
Training epoch 5
Training epoch 6
Training epoch 7
Training epoch 8
Training epoch 9
model saved<jupyter_text>TEST MODEL<jupyter_code>#load the model
d2v_model = gensim.models.doc2vec.Doc2Vec.load('/tmp/doc2vec.w2v')<jupyter_output><empty_output><jupyter_text>test with text existing in training set<jupyter_code>sims = d2v_model.docvecs.most_similar(positive=['1500584801776 - Sega débarque du passé sur les mobiles'])
print(sims)<jupyter_output>[('1500574901070 - Sega débarque du passé sur les mobiles', 0.9839634895324707), ('1500579404472 - Sega débarque du passé sur les mobiles', 0.983874499797821), ('1500581201923 - Sega débarque du passé sur les mobiles', 0.9825841188430786), ('1500563204267 - Sega débarque du passé sur les mobiles', 0.9823078513145447), ('1500559608655 - Sega débarque du passé sur les mobiles', 0.9822750687599182), ('1500567702617 - Sega débarque du passé sur les mobiles', 0.9822436571121216), ('1500568612144 - Sega débarque du passé sur les mobiles', 0.9821775555610657), ('1500570407277 - Sega débarque du passé sur les mobiles', 0.9821608662605286), ('1500565001898 - Sega débarque du passé sur les mobiles', 0.9820943474769592), ('1500583902187 - Sega débarque du passé sur les mobiles', 0.9820334911346436)]<jupyter_text>test with text outside training textinfer_vector function have to be carefully set, especially if the text is not long.- steps have to be big (default is really not enough)- alpha should close to the one used to train the model<jupyter_code>newdoc="Dévoilée pendant le dernier CES, la nouvelle smartwatch de Misfit embarque un écran AMOLED rond de 1,39 pouces et d'une résolution de 326ppp, ainsi qu'un processeur Snapdragon Wear 2100, un accéléromètre, un altimètre, un gyroscope, un cardiofréquencemètre, un GPS et un micro. Tous ces capteurs permettront à la Vapor de surveiller la plupart des activités sportives sans dépendre d'un smartphone, et même de diffuser dans un casque bluetooth la musique stockée dans sa mémoire de 4Go. La smartwatch se démarquera par ailleurs par sa lunette tactile, laquelle pourra par exemple être utilisée pour naviguer dans les applications en faisant glisser son doigt autour de l'écran et en cliquant sur le bouton latéral. Misfit promet enfin une autonomie d'environ deux jours entre deux charges. La Vapor sera en vente le 31 octobre au prix de 199$ sur le site du constructeur."

print('Devrait afficher 1508966362314 - Misfit lancera finalement sa Vapor le 31 octobre')
new_vector = d2v_model.infer_vector(nlp_clean(newdoc), steps=5000, alpha=0.025)
sims = d2v_model.docvecs.most_similar(positive=[new_vector])
print(sims)<jupyter_output>Devrait afficher 1508966362314 - Misfit lancera finalement sa Vapor le 31 octobre
[('1502395811350 - La montre connectée de Fitbit encore en fuite', 0.30221953988075256), ("1504085722164 - Fitbit fait équipe avec Adidas dans sa course contre l'Apple Watch", 0.3014877736568451), ('1502953811827 - Hyundai prévoit un véhicule électrique de 500 km après 2021', 0.2901829779148102), ("1502875211745 - La corde à sauter connectée Smart Rope Pure est sur l'Apple\xa0Store", 0.28938812017440796), ("1503398121591 - La start-up chinoise HiScene lève 12,75 millions d'euros", 0.27898749709129333), ('1503987315978 - Apple s’occupe du support de Beddit', 0.27834364771842957), ('1500884710927 - Razer prépare un smartphone pour les utilisateurs mobiles les plus joueurs', 0.2773747444152832), ('1504367438943 - Samsung persiste et signe dans les montres connectées', 0.2750348150730133), ("1501149930414 - Assistant connecté : Xiaomi lance son clone d'Echo... à 40 euros", 0.2681073248386383), ("1506368133246[...]
{'fraction_non_alphanumeric': 0.1768501714055253, 'fraction_numerical': 0.07420850978019762, 'mean_word_length': 5.599467731204258, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '129379', 'license': 'Apache-2.0', 'n_tokens_mistral': 4122, 'n_tokens_neox': 3636, 'n_words': 837, 'path': 'beatcrunch/.ipynb_checkpoints/testdocmodel-2-checkpoint.ipynb', 'repo_name': 'iero/BeatCrunch', 'size': '9918'}