Форум сайта python.su
Нужна помощь в объединении файлов о один проект. Скорее всего нужен ещё какой-то код (так называемый Main) для реализации идеи. Суть: определение являются ли два текста от одного автора.
import numpy as np import similarity_measures as sm from numba import jit @jit def get_score(x,y,imposters,sim): '''Compute for how many random feature sets out of 100 sim(x,y) is greater than sim(x,z) for all z in imposters''' score = 0 sim_xy = sim(x,y) for k in range(100): ran_el = np.sort(np.random.choice(range(len(x)), (1,round(len(x) / 2)), replace = False)) c_x = x[ran_el][0] c_y = y[ran_el][0] sim_xy = sim(c_x,c_y) for yi in imposters: if sim(c_x, np.take(yi,ran_el)[0]) > sim_xy: break else: score += 1 return score / 100.0 # def imposters(y, universe, m = 125, n = 25): '''Return n imposters. Compute the m most similar files in universe and randomly select n from them ''' minmax_vec = np.array([sm.cminmax(t,y) for t in universe]) pot_imp_ind = minmax_vec.argsort()[:-(m+1):-1] # Last m entries pot_imp_ind = np.sort(np.random.choice(pot_imp_ind, n)) return [universe[k] for k in pot_imp_ind[::-1]] # Have the most similar imposters first, to hope for a quicker break in the get_score algorithm def blog_same_author(x,y,text_corpus, threshold, nr_imposters = 25): '''Return true if x and y are by the same author according to the algorithm in the paper''' imposters_y = imposters(y, text_corpus.Y, n = nr_imposters) score_xy = get_score(x,y,imposters_y, sm.cminmax) imposters_x = imposters(x, text_corpus.X, n = nr_imposters) score_yx = get_score(y,x,imposters_x, sm.cminmax) if (score_xy + score_yx ) /2.0 > threshold: print("true") return True else: print("false") return False
Отредактировано vasyabylba (Апрель 15, 2019 13:26:56)
Прикреплённый файлы: imposter_meth.py (1,7 KБ)
Офлайн
from numba import jit import numpy as np def minmax(x,y): return np.sum(np.minimum(x,y)) / np.sum(np.maximum(x,y)) @jit def cminmax(x,y): nom = 0.0 denom = 0 for k in range(len(x)): if x[k] > y[k]: nom += y[k] denom += x[k] else: nom += x[k] denom += y[k] return nom / denom def cos(x,y): return x.dot(y) / (np.linalg.norm(x) * np.linalg.norm(y))
Отредактировано vasyabylba (Апрель 15, 2019 13:28:41)
Прикреплённый файлы: similarity_measures.py (439 байт)
Офлайн
import data_prep as dp import numpy as np class corpus: def __init__(self, start = '', end = '', authors = ''): self.start, self.end, self.authors = start, end, authors def build_by_xml(self, path, number_of_words=500, number_of_files = 500): self.start, self.end, self.authors = dp.open_xml(path, max_of_files = number_of_files, n_of_words = number_of_words) def build_pairs(self): self.pair = dp.pair_vec(len(self.start)) self.end = np.take(self.end, self.pair) def build_matrix(self): data = dp.build_matrix(np.concatenate((self.start, self.end))) self.X = data[:len(self.start)] self.Y = data[len(self.end):] def get_length(self): return len(self.authors) def same_author(self, k): return self.pair[k] == k def get_pair(self, k,num = True, text = False): if text and num: return [self.X[k], self.Y[k], self.start[k], self.end[k]] if text: return [self.start[k], self.end[k]] else: return [self.X[k], self.Y[k]]
Отредактировано vasyabylba (Апрель 15, 2019 13:28:03)
Прикреплённый файлы: corpus_class.py (1,1 KБ)
Офлайн
import re import string import numpy as np import pandas as pd import os import random import xml.etree.ElementTree as ET def get_n_words(text, number_of_words, name = None, report = False): '''Funktion to extract the first and last n words from a string long tells, if the file is too short to extract to distinct subsets of length number_of_words''' long = True words = text.split(' ') if len(words) < number_of_words*2: # Double because I dont want that first and last have 'common' elements if report == True: print('WARNING: ' + name + ' has fewer than ' + str(number_of_words*2) + ' words! ' + str(len(words))) long = False # Die ersten N Wörter: first_words = words[:number_of_words] start = ' '.join(first_words) # Letzten N Wörter: last_words = words[-number_of_words:] end = ' '.join(last_words) return (start, end, long) #### Test # Kurze Test-Texte text1 = 'Sprengstoffexperten des und Landeskriminalamtes haben den Sprengsatz untersucht. Sie gehen davon aus, dass die Ladung aus den Inhaltsstoffen sogenannter Polenböller gebaut und offenbar per Funk gezündet wurde. Die Beamten stufen den Vorfall als besorgniserregend ein, da man eine derartige Sprengkraft bei vergleichbaren Fällen noch nicht gesehen habe. Eine Spezialeinheit der Polizei zur Aufklärung extremistisch orientierter Straftaten ermittelt. Neben der Spur nach Berlin geht sie auch der These nach, dass womöglich eine bisher unbekannte Gruppe in dem Haus, das zum Abriss vorgesehen ist, einen Sprengversuch unternommen hat.' text2 = 'Und das, obwohl die und Sache mit der Krim eigentlich klar ist Die russische Annexion der ukrainischen Halbinsel im Jahr 2014 war völkerrechtswidrig. Das sagt die Bundesregierung, das sagt die EU das sagt sogar die Linkspartei, schon 2014 festgehalten per Parteitagsbeschluss. Und trotzdem wollen manche Linke am liebsten nicht darüber sprechen.' text3 = 'US-Präsident Donald Trump schließt eine militärische Reaktion auf die Krise in Venezuela nicht aus. Es gebe mehrere Möglichkeiten, "darunter eine militärische Option, falls nötig", sagte Trump am Freitag in New Jersey. Konkrete Pläne für ein militärisches Eingreifen in Venezuela gibt es aber offenbar nicht. Ein Pentagon-Sprecher erklärte, zum jetzigen Zeitpunkt gebe es keine entsprechenden Anweisungen aus dem Weißen Haus.' text4 = 'Als am Freitagmorgen vergangener und Woche die Eilmeldungen zum überraschenden Fraktionswechsel der niedersächsischen Grünen-Abgeordneten Elke Twesten über die Nachrichtenagenturen liefen, wusste die Bundeskanzlerin längst Bescheid. Angela Merkel (CDU) hat einem Medienbericht zufolge vorab von der Wechsel der niedersächsischen Landtagsabgeordneten von den Grünen zur CDU erfahren. Das gehe aus einem Schreiben von Kanzleramtsstaatsminister Helge Braun an die Geschäftsführerin der SPD-Bundestagsfraktion, Christine Lambrecht hervor, berichteten die Zeitungen des Redaktionsnetzwerks Deutschland (RND). Demnach informierte der niedersächsische CDU-Landesvorsitzende Bernd Althusmann die Kanzlerin am Vortag des Wechsels telefonisch.' vector_with_text = [text1, text2, text3, text4] b1 = 'This is a 12385 sample' b2 = 'this is ano>>ther $example!!!' vector_with_text = [b1, b2] # Takes a path and opens all txt-files in that directory and returns a vector with the n first # words, n last words from every text and a vector with the name of the authors, given that all # files have the format author_title.txt def open_text(path, number_of_words): vector_with_text = [] vector_text_end = [] authors = [] for t in os.listdir(path): # Überspringe Dateien, die keine Txt sind: if t[-4:] != '.txt': continue aut = re.match(r'(\w*)_', t).group(1) authors.append(aut) name = path +'/'+ t file = open(name, 'r') text = file.read() words = get_n_words(text, number_of_words, t) vector_with_text.append(words[0]) vector_text_end.append(words[1]) return vector_with_text, vector_text_end, authors def open_xml(path, max_of_files = 5000, n_of_words = 500): ''' Takes a path and opens max_of_files xml files in that directory. From each file it extracts the n first and last words and gives the author-ID, if the filename is formatted as authorid.[...].xml remove specifies if '&' Symboles are deleted in the files''' text_start = [] text_end = [] author_id = [] number_files = 0 for f_name in os.listdir(path): # Just xml-Files: #if f_name[-4:] != '.xml': if not f_name.endswith('xml'): continue if number_files >= max_of_files: break file_path = path + '/' + f_name try: text = '' file = open(file_path, 'r') for line in file: if line.startswith('<'): continue text += line.strip() start, end, long = get_n_words(text, n_of_words, f_name, False) # Gives start, end, long? (i.e. boolean if the file has fewer than n words) # If the document has to few words, skip this one if long == False: continue aut = re.match(r'(\d+).', f_name).group(1) author_id.append(aut) text_start.append(start) text_end.append(end) number_files += 1 #print(f_name) except UnicodeDecodeError: #print('Encoding Error: ', f_name) pass except ValueError: print('Parse: file: ', f_name) return text_start, text_end, author_id def old_open_xml(path, max_of_files = 5000, n_of_words = 500, remove = True): text_start = [] text_end = [] author_id = [] number_files = 0 for f_name in os.listdir(path): # Just xml-Files: #if f_name[-4:] != '.xml': if not f_name.endswith('xml'): continue if number_files >= max_of_files: break file = path + '/' + f_name # Remove &-Symbols (otherwise the xml Parser throws an error) if remove == True: f = open(file, 'r') text = f.read() f.close() text = text.translate({ord('&'): None}) f_o = open(file, 'w') f_o.write(text) f_o.close() with open(file, 'r') as xml_file: # Umständlich damit UTF8 codierung -> Reicht nicht tree = ET.parse(xml_file) # tree = ET.parse(file) root = tree.getroot() text = '' for p in root.findall('post'): # Find all <post> entries text += p.text.strip() # Build one long string without any newline characters and white spaces start, end, long = get_n_words(text, n_of_words, f_name, False) # Gives start, end, long? (i.e. boolean if the file has fewer than n words) # If the document has to few words, skip this one if long == False: continue aut = re.match(r'(\d+).', f_name).group(1) author_id.append(aut) text_start.append(start) text_end.append(end) number_files += 1 return text_start, text_end, author_id # Take a text and get all the n-grams with their freq as a dict def get_freq(text, n = 4): '''Take a string and get all the n-grams with their freq as a dict''' text1 = text.lower() # text1 = re.sub(r'[.,-?!+"_()/$§%<>]', '', text1) # Remove punctuation, RE slower than that: text1 = text1.translate({ord(char): None for char in string.punctuation + '0123456789'}) # Remove punctuation and digits text1 = re.sub(r'\s\s+',' ',text1) # Remove double spaces words = text1.split(' ') grams = [] # Identify all n-grams: for w in words: if len(w) < (n+1): grams.append(w.lower()) else: for k in range(len(w)-n + 1): grams.append(w[k:k+n].lower()) freq = {} for g in set(grams): c = grams.count(g) freq[g]= c return freq def build_matrix(vector_with_text, k_highest_freq = 100000): ''' Take a array of texts and return a matrix (as a numpy array) with the tf-idf values for all n grams in the texts. Each row represents a text''' # Matrix mit den Texten als Zeilen und den verschiedenen n-grams als Spalten. Die Einträge geben # dann für jedes n-grams den tf-idf Wert in Bezug auf den Text an # WICHTIG: # total_text braucht für später die selbe Reihenfolge wie vector_with_text total_text = [get_freq(text) for text in vector_with_text] # Vector with all dictionaries of freq # Total_freq ist ein dict was für jedes in irgendeinem Text vorkommenden n-gram die Gesamt- # Vorkommenshäufigkeit speichert total_freq = {} for cfreq in total_text: for f in cfreq: if f in total_freq: total_freq[f] += cfreq[f] else: total_freq[f] = cfreq[f] #print(total_freq) #print(len(total_freq)) # Get the n-grams with the k-hightest freq from all texts # If there are more n-grams than k_highest_freq, delate the least frequent ones if len(total_freq.keys()) > k_highest_freq: lowest_freq = sorted([x for x in total_freq.values()], reverse = True)[k_highest_freq] keys = total_freq.keys() for k in list(total_freq.keys()): if total_freq[k] < lowest_freq: del total_freq[k] # Data_m als matrix, die für jedes n-gram die absolute Häufigkeit enthält data_m = np.empty((len(vector_with_text), len(total_freq.keys()))) for t in enumerate(vector_with_text): freq_t = [] # Freq für alle n-grams für aktuellen Text, da vector erst um alle n-grams erweitert werden muss, die nicht in aktuellem Text sind for g in enumerate(total_freq.keys()): if g[1] in total_text[t[0]]: # Wenn n-gram in aktuellem Text (toatl_text sollte die selbe Reihenfolge haben wir v_text) freq_t.append(total_text[t[0]][g[1]]) # Nehme aus vektor mit allen Freq, den Eintrag der zum Text entspricht und suche die Freq für das aktuelle n gram else: freq_t.append(0.0) data_m[t[0]] = freq_t # Neue Reihe in Dataframe mit dem index # Berechen Vektor mit der idf für jedes n-gram idf_m = np.log(data_m.shape[0] /np.array([(data_m[:,column]!= 0).sum() for column in range(data_m.shape[1])])) # Berechne TF data_m = data_m / np.sum(data_m, axis = 1)[:,None] # Berechne TF-IDF data_m = np.multiply(data_m, idf_m) #print(data_m) return data_m def pair_vec(n): '''The index corresponds to the start index, the entry to the text in end A Pair is from the same author if index = entry. ATTENTION: By chance it can happen, that slithly more than 50% are from the same other, but never less ''' x = list(range(n)) #random.seed(0) rand_ind = random.sample(range(n), round(n / 2)) rand_match = rand_ind.copy() random.shuffle(rand_match) for ent in x: if ent in rand_ind: x[ent] = rand_match.pop() return x
Отредактировано vasyabylba (Апрель 15, 2019 13:27:37)
Прикреплённый файлы: data_prep.py (11,4 KБ)
Офлайн
{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Determining if two documents are written by the same author" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import pickle\n", "import numpy as np\n", "import data_prep as dp\n", "import similarity_measures as sm\n", "import imposter_meth as im\n", "import corpus_class as cp\n", "\n", "\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Corpus- Class" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[array([ 0. , 0. , 0. , 0.23104906, 0. ,\n", " 0. , 0. , 0. , 0.23104906, 0. ]), array([ 0. , 0. , 0. , 0. , 0. ,\n", " 0. , 0. , 0. , 0. , 0.27725887])]\n" ] } ], "source": [ "text1 = 'First example'\n", "text2 = 'Next example'\n", "text3 = 'Third example'\n", "text4 = 'Four example'\n", "\n", "cor = cp.corpus([text1, text3], [text2, text4])\n", "cor.build_matrix()\n", "print(cor.get_pair(0))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Gives back the tf-idf vector representations of text 1 and 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Imposters" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Because it takes a couple of minutes to compute the algorithm for 500 pairs, I just load the results:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "with open('/Users/alexandersauer/Anaconda_Projects/results/scores500_blog', 'rb') as f:\n", " scores_blog = pickle.load(f)\n", "with open('/Users/alexandersauer/Anaconda_Projects/results/scores500_minmax', 'rb') as f:\n", " scores_minmax = pickle.load(f)\n", "with open('/Users/alexandersauer/Anaconda_Projects/results/scores500_cosine', 'rb') as f:\n", " scores_cos = pickle.load(f)\n", " " ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "data": { "image/png": "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\n8yv2f8LMfkfSrZJukLRb0rUM6gAApBNjPQAAPlJxJB4AAAAAAIwuDUvMAQAAAACAMcjNJN7Mrjez\nx83skJk9aGaXj7L/b5pZt5m9YGY/NbNrJqutWTGeTM3srWZ2n5ntMbNnzex+M1s2me3NgvH+O614\nXquZHTEz1vuoEKPfTzOzT5nZE6W+v9PM3j1Jzc2EGJn+gZk9bGbPm9nPzWy9mZ01We1NMzO72szu\nNrOnzexFM2sfw3MYm0bBeO+Lsd4fY70vxnp/jPV+khrrczGJN7MVkj4r6WZJr5D0iKR7S9fe1dv/\nAknfkPRtSZdI+rykvzWz356M9mbBeDOV9EpJ9ymqJLxE0nck3WNml0xCczMhRqbl550u6SuSuA60\nQsw8/1HSqyWtlPQrkt4h6ScNbmpmxHgvbVX0b/NvJP2aoiJlV0j60qQ0OP1mKrru+32SRr12jbFp\ndIz3vhjr/THW+2Ks98dY7y6ZsT6EkPmbpAclfb7ivikqgHPTMPuvk/T9mm0bJf1b0q8lLbfxZjrM\n73hU0seSfi1pucXNtPRv8xOK3mx7kn4dabnF6Pevl/SMpDOSbntabzEy/TNJP6vZtlrSrqRfS9pu\nkl6U1D7KPoxNo+fIeJ9gnsP8DsZ6h0wZ633yZKxvSKaM9WPPdtLG+swfiTezkyW1KPo2Q5IUojS+\nJWnpME/7DQ39pvPeEfYvlJiZ1v4Ok9Sk6I208OJmamYrJV2oaGBHScw83yxpm6QPmdluM/uJmf2l\nmZ3S8AZnQMxMH5A038zeUPod50j6PUn/2tjW5hZj0wgY730x1vtjrPfFWO+PsT4VXMalzE/iJc2W\nNEVSX832PkXL1dRz7jD7n2Zm032bl0lxMq21RtHpJXc5tivLxp2pmb1E0qcl/UEI4cXGNi9z4vwb\nXSTpakkvl/QWSR9QdErYXzeojVkz7kxDCPdLepekTWZ2WFKvpAOKvqHH+DE2jYzx3hdjvT/Gel+M\n9f4Y65PnMi7lYRKPlDGzd0r6uKTfCyHsS7o9WWRmJ0n6mqSbQwg7ypsTbFIenKToNKd3hhC2hRD+\nXdIHJV3Dh/l4zOzXFF3LtVbR9bGvU3Q06c4EmwVgEjDWTxxjfUMw1jtjrE+nqUk3wME+SccknVOz\n/RxJvxjmOb8YZv/nQgiDvs3LpDiZSpLM7PcVFbp4WwjhO41pXiaNN9MmSZdJutTMyt8en6To7MXD\nkpaFEP6zQW3Ngjj/RnslPR1COFix7ceKPjDNk7Sj7rOKI06mH5a0JYTwudL9R83sfZK+a2YfDSHU\nftOMkTE2jYzx3hdjvT/Gel+M9f4Y65PnMi5l/kh8COGIpG5Jry1vK12j9VpJ9w/ztAcq9y9ZVtpe\neDEzlZm9Q9J6Sb9f+uYTJTEyfU7Sr0u6VFHlykskfVHS9tLPDzW4yakW89/oFknnmdmMim2/qugb\n+90NampmxMx0hqSjNdteVFSdlaNJ48fYNALGe1+M9f4Y630x1vtjrE8Fn3Ep6Sp+HjdJb5c0IOkP\nJb1U0ekd+yXNKT3+GUlfqdj/Akn9iqoD/qqiJQEOS/qtpF9LWm4xMn1nKcP3Kvo2qXw7LenXkpbb\neDOt83wq1k4gT0XXbT4paZOklylaKuknkr6Y9GtJyy1GptdIGiz1+wsltUraKun+pF9LGm6lf3OX\nKPqA/qKkPy3dnz9MnoxNo2fKeJ9snoz1zpnWeT5j/QTyZKxvSKaM9SPnmchYn/gLdwzwfZKekHRI\n0TcZl1U89neS/qNm/1cq+ibqkKSfSfofSb+GtN3Gk6mitWKP1bltSPp1pOk23n+nNc9lYJ9gnorW\ni71X0sHSIH+LpOlJv4403WJker2kH5Qy3a1oLdnmpF9HGm6SXlUa0Ou+LzI2xc6V8T6hPBnr/TOt\n81zG+gnmyVjfkEwZ64fPMpGx3kq/CAAAAAAApFzmr4kHAAAAAKAomMQDAAAAAJARTOIBAAAAAMgI\nJvEAAAAAAGQEk3gAAAAAADKCSTwAAAAAABnBJB4AAAAAgIxgEg8AAAAAQEYwiQcAAAAAICOYxANo\nKDN7lZm9aGanle5fY2YHkm4XAADwwVgPTC4m8QAmQxjlPgAAyDbGemCSMIkHCszMTk66DQAAoHEY\n64H8YRIPFIiZfcfMbjezW81sr6R/N7PTzexvzWyPmT1rZt8ys4trnvdmM9tqZofMbK+Z/e+Kx95l\nZt8zs+fMrNfMvmZmcyb9xQEAAMZ6oACYxAPF84eSBiVdJem9kv5R0tmSXidpiaQeSd8yszMkycx+\nR1KnpG9IulTSb0p6sOL3TZX0MUkXS/pdSQsl/d0kvA4AAFAfYz2QYxYCl6sARWFm35HUFEK4rHS/\nVdGAPTeEcKRiv59JWhdC+Fsz2yLpsRDCNWP8G5dJeqj0dwbM7FWS/kPSmSGE58zsGkm3hhDO8n11\nAACAsR7IP47EA8XTXfHzJZKaJD1jZv3lm6QLJC0q7XOpooG5LjNrMbO7zexJM/v/27l/Fj3KKIzD\nvwPBIqRKZWVIt41NIBY2FmITMFUstMonSBNYSBfBzyHYWNu5xRZqY5dAIIXtgoKYQgIhEAiTYt8i\nLLuwkXXDvHtdzQych5nTHe758zyvftmUPjrzzgGA0zDrYYtdet8NAOfuxVvnV6q/qs+qObLu383x\n5UkXmpnL1V71c/VN9U+Hn9jtVR+cUb8AwLsx62GLCfFwsT2qPqxeL8tycMKaJ9Xn1Q/H1Haqq9WD\nZVn+rJqZT/6PRgGA/8Sshy3jc3q4wJZl2a9+r36amS9m5trMfDoz383Mjc2yb6uvZ+bhzOzMzMcz\ns7upHVSvqnszc31mbne48c1RR5/8AwDnwKyH7SPEw8Vy3E6Wt6rfqu+rP6ofO/zH7e+qZVl+rb6q\nvqweV/vVzU3tWXW3ulM9rXar+6e8LwBw9sx62HJ2pwcAAICV8CYeAAAAVkKIBwAAgJUQ4gEAAGAl\nhHgAAABYCSEeAAAAVkKIBwAAgJUQ4gEAAGAlhHgAAABYCSEeAAAAVkKIBwAAgJUQ4gEAAGAlhHgA\nAABYiTeuL+hYXfgY1gAAAABJRU5ErkJggg==\n", "text/plain": [ "<matplotlib.figure.Figure at 0x1179c1780>" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "alg_dec = im.p_r_dic(scores_blog)\n", "min_dec = im.p_r_dic(scores_minmax)\n", "cos_dec = im.p_r_dic(scores_cos)\n", "\n", "bsame_prec = [alg_dec[sigma][0] for sigma in alg_dec.keys()]\n", "bsame_rec = [alg_dec[sigma][1] for sigma in alg_dec.keys()]\n", "bdiff_prec = [alg_dec[sigma][2] for sigma in alg_dec.keys()]\n", "bdiff_rec = [alg_dec[sigma][3] for sigma in alg_dec.keys()]\n", "\n", "\n", "msame_prec = [min_dec[sigma][0] for sigma in min_dec.keys()]\n", "msame_rec = [min_dec[sigma][1] for sigma in min_dec.keys()]\n", "mdiff_prec = [min_dec[sigma][2] for sigma in min_dec.keys()]\n", "mdiff_rec = [min_dec[sigma][3] for sigma in min_dec.keys()]\n", "\n", "csame_prec = [cos_dec[sigma][0] for sigma in cos_dec.keys()]\n", "csame_rec = [cos_dec[sigma][1] for sigma in cos_dec.keys()]\n", "cdiff_prec = [cos_dec[sigma][2] for sigma in cos_dec.keys()]\n", "cdiff_rec = [cos_dec[sigma][3] for sigma in cos_dec.keys()]\n", "\n", "plt.figure(1, figsize= (12,6))\n", "plt.subplot(1,2,1)\n", "plt.plot(bsame_rec, bsame_prec, '.', msame_rec, msame_prec, '.', csame_rec, csame_prec, '.')\n", "plt.legend(['blog', 'minmax', 'cosine'])\n", "plt.axis([0,1,0,1.1])\n", "plt.title('Same author')\n", "plt.xlabel('recall')\n", "plt.ylabel('precision')\n", "plt.grid()\n", "\n", "plt.subplot(1,2,2)\n", "plt.plot(bdiff_rec, bdiff_prec, '.', mdiff_rec, mdiff_prec, '.', cdiff_rec, cdiff_prec, '.')\n", "plt.legend(['blog', 'minmax', 'cosine'])\n", "plt.axis([0,1,0,1.1])\n", "plt.title('Different author')\n", "plt.xlabel('recall')\n", "plt.ylabel('precision')\n", "plt.grid()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## No difference! - WHY?!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Algorithms" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "1. Generate a set of impostors $Y_1, . . . , Y_m$.\n", "2. Compute $score_X(Y)$ = the number of choices of feature sets (out of 100) for which $sim(X, Y) > sim(X, Y_i)$, for all $i = 1, . . . , m$.\n", "3. Repeat the above with impostors $X_1, . . . , X_m$ and compute scoreY(X) in an analogous manner.\n", "4. If $average(score_X(Y), score_Y(X))$ is greater than a threshold $s*$, assign 〈X, Y〉 to same-author." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def blog_same_author(x,y,text_corpus, threshold, nr_imposters = 25, return_score = False):\n", " '''Return true if x and y are by the same author according to the algorithm in the paper'''\n", " imposters_y = imposters(y, text_corpus.Y, n = nr_imposters)\n", " score_xy = get_score(x,y,imposters_y, sm.cminmax)\n", " \n", " imposters_x = imposters(x, text_corpus.X, n = nr_imposters)\n", " score_yx = get_score(y,x,imposters_x, sm.cminmax)\n", " \n", " if return_score == True:\n", " return (score_xy + score_yx ) /2.0\n", "\n", " if (score_xy + score_yx ) /2.0 > threshold:\n", " return True\n", " else:\n", " return False" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "## Create Blog-universe\n", "1. Compute the min-max similarity to Y of each document in the universe. Select the m most similar documents as potential impostors.\n", "2. Randomly select n actual impostors from among the potential impostors." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def imposters(y, universe, m = 250, n = 25):\n", " '''Return n imposters. Compute the m most similar files in universe and randomly select n from them '''\n", " minmax_vec = np.array([sm.cminmax(t,y) for t in universe])\n", " pot_imp_ind = minmax_vec.argsort()[:-(m+1):-1] # Last m entries\n", " pot_imp_ind = np.sort(np.random.choice(pot_imp_ind, n))\n", " return [universe[k] for k in pot_imp_ind[::-1]] # Have the most similar imposters first, to hope for a quicker break in the get_score algorithm\n", " " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Compute Score\n", "\n", "Compute $score_X(Y)$ = the number of choices of feature sets (out of 100) for which $sim(X, Y) > sim(X, Y_i)$, for all $i = 1, . . . , m$." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "@jit\n", "def get_score(x,y,imposters,sim):\n", " '''Compute for how many random feature sets out of 100 sim(x,y) is greater than sim(x,z) for all z in imposters'''\t\n", " score = 0\n", " sim_xy = sim(x,y) \n", " for k in range(100):\n", " ran_el = np.sort(np.random.choice(range(len(x)), (1,round(len(x) / 2)), replace = False)) # Sorting makes the next steps faster \n", " c_x = x[ran_el][0]\n", " c_y = y[ran_el][0]\n", " sim_xy = sim(c_x,c_y)\n", "\n", "\n", " for yi in imposters:\n", " if sim(c_x, np.take(yi,ran_el)[0]) > sim_xy: # If there is one text in imposter with a greater score, there is no need to continue\n", " break\n", " else:\n", " score += 1\n", "\n", " return score / 100.0 # " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Algorithms to store the results and compute precision and recall:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def result_array(corp, sigma= None):\n", " '''\n", " Returns an array with tuples containing the average score given by the algorithms whether both\n", " texts are by the same author and a boolean whether the pair really is by the same author \n", " '''\n", " res = []\n", " for k in range(corp.get_length()):\n", " alg = blog_same_author(*corp.get_pair(k), corp, threshold = sigma, return_score = True)\n", " same_author = corp.same_author(k)\n", " res.append((alg, same_author))\n", " return res" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def pre_recall(result_array, threshold):\n", " ''' Return precision and recall values for the same-author and different-author classes'''\n", " same_same, same_dif, dif_same, dif_dif = 0,0,0,0\n", " for k in range(len(result_array)):\n", " res = (result_array[k][0] > threshold )\n", " same_author = result_array[k][1]\n", " \n", " if same_author and res:\n", " same_same += 1\n", " if same_author and not res:\n", " same_dif +=1\n", " if not same_author and res:\n", " dif_same +=1\n", " if not same_author and not res:\n", " dif_dif +=1\n", " try:\n", " precision_same = same_same / (same_same + dif_same)\n", " recall_same = same_same / (same_same + same_dif)\n", "\n", " precision_dif = dif_dif / (same_dif + dif_dif)\n", " recall_dif = dif_dif / (dif_dif + dif_same)\n", "\n", " acc = (same_same + dif_dif) / len(result_array)\n", " except ZeroDivisionError:\n", " return None\n", "\n", " return precision_same, recall_same, precision_dif, recall_dif, acc \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def p_r_dic(result_array):\n", " '''Create a dictionary with threshold values and the decisions based on this threshold'''\n", " s_range = np.linspace(0, 0.8, 1000)\n", " res = {}\n", " for sigma in s_range:\n", " pc = pre_recall(result_array, sigma)\n", " if pc == None:\n", " continue\n", " res[sigma] = pre_recall(result_array, sigma)\n", " return res" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python [default]", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.2" } }, "nbformat": 4, "nbformat_minor": 1 }
Отредактировано vasyabylba (Апрель 15, 2019 13:29:56)
Прикреплённый файлы: Presentation.ipynb (63,6 KБ)
Офлайн
vasyabylbaВ питоне нет понятия “проект”. Следовательно файлы объединить в один проект невозможно.
Нужна помощь в объединении файлов о один проект
Офлайн
doza_andЭто и так ясно было. Мне нужно чтобы кто-то сказал мне как это можно объединить.
Офлайн
vasyabylbaЯ помоему ясно выразился- никак. Не теряйте времени и ищите нормальную библиотеку.
кто-то сказал мне как это можно объединить.
Офлайн
vasyabylbaНу вот файл main.py делаешь и в нём импортируешь свои модули и в функции main() пишешь код, который использует из модулей функции.
Скорее всего нужен ещё какой-то код (так называемый Main) для реализации идеи.
#!/usr/bin/env python3 def main(): pass if __name__ == '__main__': main()
vasyabylbaСудя по кодам, они не очень грамотно сделаны. Так что, очень может быть, эти коды и не работают вовсе.
Суть: определение являются ли два текста от одного автора.
Отредактировано py.user.next (Апрель 16, 2019 01:30:02)
Офлайн