besson_sylvain:etude_proprietes
Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente | ||
| besson_sylvain:etude_proprietes [2021/07/19 17:20] – sbesson | besson_sylvain:etude_proprietes [2021/07/19 18:32] (Version actuelle) – supprimée sbesson | ||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| - | Allez vers la [[traitements_statistiques| page précédente - traitements statistiques]] | ||
| - | ====== Étude des propriétés ====== | ||
| - | |||
| - | La première étape nécessaire à la réalisation de l' | ||
| - | |||
| - | ==== Requête SPARQL ==== | ||
| - | |||
| - | Pour cela, il est tout d' | ||
| - | |||
| - | Ensuite, il s'agit de créer une requête qui va prendre l' | ||
| - | |||
| - | Pour cela, nous avons créer un requête de la façon suivante: | ||
| - | |||
| - | <code sparql> | ||
| - | PREFIX | ||
| - | PREFIX | ||
| - | PREFIX rdfs: < | ||
| - | PREFIX rdf: < | ||
| - | |||
| - | PREFIX xsd: < | ||
| - | |||
| - | |||
| - | SELECT ?person ? | ||
| - | WHERE | ||
| - | {SELECT ?person ? | ||
| - | WHERE | ||
| - | {SELECT DISTINCT | ||
| - | WHERE { | ||
| - | {?person wdt:P569 ?bD} | ||
| - | OPTIONAL | ||
| - | {?person wdt:P69 ?edAt . | ||
| - | ?edAt rdfs:label ?educAt} | ||
| - | OPTIONAL | ||
| - | | ||
| - | ?na rdfs:label ?nat} | ||
| - | OPTIONAL | ||
| - | | ||
| - | ?g rdfs:label ?gend} | ||
| - | OPTIONAL | ||
| - | {?person wdt:P19 ?pB . | ||
| - | ?pB rdfs:label ? | ||
| - | OPTIONAL | ||
| - | {?person wdt:20 ?pD. | ||
| - | ?pD rdfs:label ? | ||
| - | OPTIONAL | ||
| - | {?person wdt:P184 ?dA . | ||
| - | ?dA rdfs:label ?docAdv} | ||
| - | | ||
| - | {?person wdt:P106 ?o . | ||
| - | ?o rdfs:label ?occ} | ||
| - | | ||
| - | {?person wdt:P39 ?pH. | ||
| - | ?pH rdfs:label ?posHeld} | ||
| - | | ||
| - | {?person wdt:P108 ?em . | ||
| - | ?em rdfs:label ?empl} | ||
| - | | ||
| - | {?person wdt:P185 ?dS . | ||
| - | ?dS rdfs:label ?docStu} | ||
| - | |||
| - | } | ||
| - | GROUP BY ?person ?bD | ||
| - | ORDER BY ?person | ||
| - | } | ||
| - | GROUP BY ?person ? | ||
| - | ORDER BY ?person | ||
| - | } | ||
| - | #LIMIT 100 | ||
| - | </ | ||
| - | |||
| - | C'est une requête qui semble assez complexe, mais on peut la comprendre assez facilement | ||
| - | |||
| - | Ensuite, dans ce même SELECT, nous avons utilisé la clause YEAR pour la date de naissance afin de ne garder que l' | ||
| - | |||
| - | Dans la clause SELECT supérieure, | ||
| - | |||
| - | Le dernier niveau de SELECT permet de s' | ||
| - | |||
| - | ====Étude des propriétés==== | ||
| - | |||
| - | Après avoir réalisé cette étape préliminaire, | ||
| - | |||
| - | Pour commencer, il est nécessaire de connaître le nombre de valeurs dans chaque propriété. Pour cela, il faut couper et compter les valeurs des propriétés : | ||
| - | |||
| - | <code python> | ||
| - | df_wiki[' | ||
| - | </ | ||
| - | |||
| - | La fonction découpe dans chaque cellule les valeurs concaténées (le découpage est fait par rapport à un caractère prédéfini, | ||
| - | |||
| - | Il est mieux d' | ||
| - | <code python> | ||
| - | df_wiki = df_wiki[[ ' | ||
| - | ' | ||
| - | ' | ||
| - | |||
| - | </ | ||
| - | |||
| - | Afin de ne pas réimporter les données à chaque fois, il est préférable de les exporter au format CSV. Et les réimporter par la suite. | ||
| - | Une fois fait, il est possible de calculer le nombre de valeurs pour chaque propriété en les additionnant. | ||
| - | |||
| - | <code python> | ||
| - | |||
| - | properties_persons = [] | ||
| - | for i,r in list(persons.iterrows()): | ||
| - | properties = [] | ||
| - | if r[' | ||
| - | properties.append(' | ||
| - | if r[' | ||
| - | properties.append(' | ||
| - | if r[' | ||
| - | properties.append(' | ||
| - | if r[' | ||
| - | properties.append(' | ||
| - | if r[' | ||
| - | properties.append(' | ||
| - | if r[' | ||
| - | properties.append(' | ||
| - | if r[' | ||
| - | properties.append(' | ||
| - | | ||
| - | properties_persons.append([i, | ||
| - | |||
| - | </ | ||
| - | |||
| - | Pour chaque propriété, | ||
| - | |||
| - | <code python> | ||
| - | frequencies_properties_per_person = df_properties_persons.groupby(' | ||
| - | </ | ||
| - | |||
| - | À partir de cela, une première visualisation de la distribution peut être faite. | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | Cette première visualisation permet déjà d' | ||
| - | |||
| - | Il est aussi possible d' | ||
| - | |||
| - | <code python> | ||
| - | |||
| - | freq_persons = 0 | ||
| - | nationality = 0 | ||
| - | gender = 0 | ||
| - | placeOfBirth = 0 | ||
| - | educatedAt = 0 | ||
| - | occupation = 0 | ||
| - | positionHeld = 0 | ||
| - | employer = 0 | ||
| - | for i,r in list(persons.iterrows()): | ||
| - | freq_persons += 1 | ||
| - | if r[' | ||
| - | nationality += 1 | ||
| - | if r[' | ||
| - | placeOfBirth += 1 | ||
| - | if r[' | ||
| - | gender += 1 | ||
| - | if r[' | ||
| - | educatedAt += 1 | ||
| - | if r[' | ||
| - | occupation += 1 | ||
| - | if r[' | ||
| - | positionHeld += 1 | ||
| - | if r[' | ||
| - | employer += 1 | ||
| - | | ||
| - | </ | ||
| - | Pour chaque personne, le code vérifie si une propriété est rentrée ou non et cela calcule leur nombre. On peut ensuite déterminer la distribution du nombre de propriétés disponibles. Ensuite, on met les propriétés et leur valeur en série : | ||
| - | <code python> | ||
| - | frequencies_properties = pd.Series({" | ||
| - | " | ||
| - | frequencies_properties | ||
| - | </ | ||
| - | |||
| - | On peut aussi l' | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | Cette visualisation nous renseigne que c'est la propriété " | ||
| - | On peut remarquer aussi que la propriété " | ||
| - | |||
| - | |||
| - | =====Étude des propriétés combinées===== | ||
| - | |||
| - | ====Réseaux de propriétés==== | ||
| - | |||
| - | À partir de ces analyses préliminaires, | ||
| - | |||
| - | La première étape est de créer les arrêtes du réseau entre les propriétés (c' | ||
| - | |||
| - | <code python> | ||
| - | properties_edges = [] | ||
| - | for pp in properties_persons: | ||
| - | local_properties = pp[1] | ||
| - | len_prop = len(local_properties) | ||
| - | # print(len_prop) | ||
| - | if len_prop > 1: | ||
| - | local_edges = [] | ||
| - | i = 0 | ||
| - | while i < (len_prop-1): | ||
| - | i_len = i + 1 | ||
| - | while i_len < (len_prop): | ||
| - | local_edges.append((local_properties[i], | ||
| - | i_len += 1 | ||
| - | i += 1 | ||
| - | # print(local_edges) | ||
| - | properties_edges += local_edges | ||
| - | </ | ||
| - | |||
| - | Puis il faut créer le graphe à proprement parler. Pour cela, il faut utiliser sur python la librairie [[https:// | ||
| - | |||
| - | <code python> | ||
| - | |||
| - | import networkx as nx | ||
| - | |||
| - | # cf. https:// | ||
| - | graph_properties = nx.MultiGraph() | ||
| - | graph_properties.add_edges_from(properties_edges) | ||
| - | print(nx.info(graph_properties)) | ||
| - | |||
| - | </ | ||
| - | |||
| - | Ensuite on créer un dictionnaire pour les effectifs et un dictionnaire pour les degrées de chaque propriété. | ||
| - | |||
| - | <code python> | ||
| - | frequency = dict([(i, {' | ||
| - | print(frequency) | ||
| - | </ | ||
| - | <code python> | ||
| - | degree = dict([(d[0], | ||
| - | print(degree) | ||
| - | </ | ||
| - | |||
| - | À partir de cela, il est possible donner les effectifs et les degrées aux nœuds. | ||
| - | |||
| - | <code python> | ||
| - | |||
| - | nx.set_node_attributes(graph_properties, | ||
| - | nx.set_node_attributes(graph_properties, | ||
| - | |||
| - | </ | ||
| - | |||
| - | Ensuite on peut calculer les poids entre chaque propriétés. | ||
| - | Pour cela, il faut créer une liste qui compte le poids qui existe entre deux propriétés. | ||
| - | De cette liste, on crée un dictionnaire: | ||
| - | |||
| - | <code python> | ||
| - | # Use the list of the previous command and create a dictionary of the weights | ||
| - | lll = [(l[0][0], l[0][1], {' | ||
| - | </ | ||
| - | |||
| - | Ensuite, on peut créer un graphe avec les poids mais il faut dans le même temps convertir ce qui est jusqu' | ||
| - | |||
| - | <code python> | ||
| - | weigth_graph_properties = nx.Graph() | ||
| - | weigth_graph_properties.add_edges_from(lll) | ||
| - | </ | ||
| - | |||
| - | <code python> | ||
| - | wgp = nx.Graph() | ||
| - | for u,v,data in graph_properties.edges.data(): | ||
| - | w = data[' | ||
| - | if wgp.has_edge(u, | ||
| - | wgp[u][v][' | ||
| - | else: | ||
| - | wgp.add_edge(u, | ||
| - | </ | ||
| - | |||
| - | Un moyen de vérifier que le graphe n'a de problème et notamment des // | ||
| - | |||
| - | <code python> | ||
| - | print(nx.number_of_selfloops(weigth_graph_properties)) | ||
| - | print(nx.is_weighted(weigth_graph_properties)) | ||
| - | </ | ||
| - | |||
| - | Enfin, on peut ajouter les effectifs et les degrées à ce graphe simple. | ||
| - | |||
| - | <code python> | ||
| - | nx.set_node_attributes(weigth_graph_properties, | ||
| - | nx.set_node_attributes(weigth_graph_properties, | ||
| - | </ | ||
| - | |||
| - | |||
| - | Une fois que le graphe est totalement créé, il est possible de le visualiser. Cela se présente de la façon suivante: | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | |||
| - | ==== Comparer les effectifs des autres caractéristiques pour chaque classe ==== | ||
| - | |||
| - | Tout d' | ||
| - | |||
| - | Dans notre casn nous avons retenu le "lieu de naissance, le " | ||
| - | |||
| - | On commence par les mettre sous forme de série : | ||
| - | |||
| - | <code python> | ||
| - | observed_variables = {" | ||
| - | for i,v in observed_variables.items(): | ||
| - | print(i,v) | ||
| - | </ | ||
| - | |||
| - | Dans ce filtre, si une propriété a une valeur supérieure à zéro, alors la fonction vérifie si les autres propriétés sont rentrées. Cela se présente de la façon suivante : | ||
| - | |||
| - | <code python> | ||
| - | |||
| - | plot_id = 1 | ||
| - | plot_left = 1 | ||
| - | for ix,v in observed_variables.items(): | ||
| - | | ||
| - | freq_persons = 0 | ||
| - | nationality = 0 | ||
| - | placeOfBirth = 0 | ||
| - | gender = 0 | ||
| - | educatedAt = 0 | ||
| - | occupation = 0 | ||
| - | positionHeld = 0 | ||
| - | employer = 0 | ||
| - | for i,r in list(persons.iterrows()): | ||
| - | if r[v] > 0: | ||
| - | freq_persons += 1 | ||
| - | if r[' | ||
| - | nationality += 1 | ||
| - | if r[' | ||
| - | placeOfBirth += 1 | ||
| - | if r[' | ||
| - | gender += 1 | ||
| - | if r[' | ||
| - | educatedAt += 1 | ||
| - | if r[' | ||
| - | occupation += 1 | ||
| - | if r[' | ||
| - | positionHeld += 1 | ||
| - | if r[' | ||
| - | employer += 1 | ||
| - | frequencies_properties = pd.Series({" | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | |||
| - | x = [l for l in frequencies_properties.index] | ||
| - | y = [l for l in frequencies_properties] | ||
| - | | ||
| - | |||
| - | plt.subplot(3, | ||
| - | |||
| - | plt.title(ix) | ||
| - | | ||
| - | plt.bar(x, y) | ||
| - | plt.gcf().set_size_inches(12, | ||
| - | plt.xticks(rotation=45) | ||
| - | |||
| - | plt.ylabel(' | ||
| - | |||
| - | | ||
| - | plot_id += 1 | ||
| - | | ||
| - | |||
| - | plt.subplots_adjust(# | ||
| - | | ||
| - | | ||
| - | | ||
| - | # wspace=0.4, | ||
| - | | ||
| - | ) | ||
| - | plt.show() | ||
| - | </ | ||
| - | |||
| - | La suite du code permet de créer une visualisation pour chaque propriété. Pour réaliser des sous-graphiques, | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | Dans ces représentations, | ||
| - | |||
| - | Une autre façon de faire qui permet d' | ||
| - | |||
| - | <code python> | ||
| - | freq_persons = 0 | ||
| - | nationality = 0 | ||
| - | placeOfBirth = 0 | ||
| - | gender = 0 | ||
| - | educatedAt = 0 | ||
| - | occupation = 0 | ||
| - | positionHeld = 0 | ||
| - | employer = 0 | ||
| - | |||
| - | for i,r in list(persons.iterrows()): | ||
| - | # if r[' | ||
| - | # if r[' | ||
| - | # r[' | ||
| - | # and r[' | ||
| - | if r[' | ||
| - | # if r[' | ||
| - | freq_persons += 1 | ||
| - | if r[' | ||
| - | nationality += 1 | ||
| - | if r[' | ||
| - | placeOfBirth += 1 | ||
| - | if r[' | ||
| - | gender += 1 | ||
| - | if r[' | ||
| - | educatedAt += 1 | ||
| - | if r[' | ||
| - | occupation += 1 | ||
| - | if r[' | ||
| - | positionHeld += 1 | ||
| - | if r[' | ||
| - | employer += 1 | ||
| - | if r[' | ||
| - | doctoralAdvisor += 1 | ||
| - | if r[' | ||
| - | doctoralStudent += 1 | ||
| - | | ||
| - | frequencies_properties_filter = pd.Series({ " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | " | ||
| - | }) | ||
| - | frequencies_properties_filter | ||
| - | </ | ||
| - | |||
| - | {{ : | ||
| - | |||
| - | |||
| - | ==== Filtrer les propriétés par individu ==== | ||
| - | |||
| - | Il est possible aussi de filtrer les propriétés par individu. Un moyen de le faire est d' | ||
| - | Il est tout d' | ||
| - | Ensuite il faut créer un // | ||
| - | |||
| - | <code python> | ||
| - | y20_list = pd.RangeIndex(start=1801, | ||
| - | y20_list | ||
| - | </ | ||
| - | |||
| - | Puis on agrège les individus suivant la génération dans laquelles ils se trouvent: | ||
| - | |||
| - | <code python> | ||
| - | merged[' | ||
| - | merged[' | ||
| - | </ | ||
| - | |||
| - | De ce découpage, on peut calculer la fréquence par génération: | ||
| - | <code python> | ||
| - | gb_generation = merged.groupby(' | ||
| - | gb_generation | ||
| - | </ | ||
| - | Enfin on peut créer une représentation de cette répartion dans dans le temps des propriétés filtrées: | ||
| - | |||
| - | {{ : | ||
besson_sylvain/etude_proprietes.1626708038.txt.gz · Dernière modification : de sbesson
