ajout de plusieurs graphiques et métriques dans le rapport
This commit is contained in:
parent
5b7ff3ac85
commit
c8c4c2b137
5 changed files with 624 additions and 84 deletions
|
@ -8,7 +8,7 @@
|
|||
"\n",
|
||||
"## Lecture des fichiers de données et affichage d'un échantillon de données\n",
|
||||
"\n",
|
||||
"### Articles"
|
||||
"### Lecture des données des articles"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -17,7 +17,27 @@
|
|||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import pickle"
|
||||
"import pickle\n",
|
||||
"import pandas as pd\n",
|
||||
"import wn_pos_from_ud_pos as wnud\n",
|
||||
"from nltk.corpus import wordnet as wn\n",
|
||||
"from french_lefff_lemmatizer.french_lefff_lemmatizer import FrenchLefffLemmatizer\n",
|
||||
"import seaborn as sns\n",
|
||||
"import numpy as np\n",
|
||||
"import emoji\n",
|
||||
"import ast\n",
|
||||
"from nltk.tokenize import TweetTokenizer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from nltk.parse.corenlp import CoreNLPServer\n",
|
||||
"from nltk.parse.corenlp import CoreNLPParser\n",
|
||||
"parser = CoreNLPParser()"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -31,6 +51,13 @@
|
|||
"f.close()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Aperçu des données"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
|
@ -44,7 +71,7 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Commentaires"
|
||||
"### Lecture des données des commentaires"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -61,12 +88,23 @@
|
|||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"metadata": {
|
||||
"jupyter": {
|
||||
"source_hidden": true
|
||||
}
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"commentaires_df = commentaires_df[commentaires_df[\"media\"]!='CNN']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Aperçu des données"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
|
@ -148,7 +186,7 @@
|
|||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"decompte_commentaires.to_latex(\"decompte_comm_medias.tex\",)"
|
||||
"decompte_commentaires.to_latex(\"decompte_comm_medias.tex\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -181,8 +219,9 @@
|
|||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Niveau de langage\n",
|
||||
"## Nombre de jetons dans WordNet\n",
|
||||
"# Analyse des commentaires\n",
|
||||
"## Niveau de langage\n",
|
||||
"### Nombre de jetons dans WordNet\n",
|
||||
"\n",
|
||||
"On utilise le POS tag identifié depuis Stanford POS Tagger, puis on le convertis en tag compatible pour Wordnet. On recherche ensuite le mot lemmatisé dans Wordnet en français, puis on filtre les résultats avec le POS. Ceci permet d'identifier tous les synsets réalistes pour les mots du commentaire."
|
||||
]
|
||||
|
@ -193,37 +232,9 @@
|
|||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from nltk.corpus import wordnet as wn\n",
|
||||
"from french_lefff_lemmatizer.french_lefff_lemmatizer import FrenchLefffLemmatizer\n",
|
||||
"lemmatizer = FrenchLefffLemmatizer()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Conversion du tag de Stanford POS vers Wordnet POS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def wn_tag_from_ud(tag):\n",
|
||||
" if tag=='ADJ':\n",
|
||||
" return wn.ADJ\n",
|
||||
" if tag=='NOUN':\n",
|
||||
" return wn.NOUN\n",
|
||||
" if tag=='VERB':\n",
|
||||
" return wn.VERB\n",
|
||||
" if tag=='ADV':\n",
|
||||
" return wn.ADV\n",
|
||||
" else:\n",
|
||||
" return None"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
|
@ -240,7 +251,7 @@
|
|||
"def lem_fr(tokens):\n",
|
||||
" list_tokens = []\n",
|
||||
" for token in tokens:\n",
|
||||
" wn_pos = wn_tag_from_ud(token[1])\n",
|
||||
" wn_pos = wnud.wn_pos_from_ud_pos(token[1]) # conversion de Universal Dependancies vers WordNet\n",
|
||||
" if wn_pos is not None:\n",
|
||||
" lem_token = lemmatizer.lemmatize(token[0],pos=wn_pos)\n",
|
||||
" else:\n",
|
||||
|
@ -274,7 +285,7 @@
|
|||
"def synsets_fr(tokens):\n",
|
||||
" list_synsets = []\n",
|
||||
" for token in tokens:\n",
|
||||
" wn_pos = wn_tag_from_ud(token[1])\n",
|
||||
" wn_pos = wnud.wn_pos_from_ud_pos(token[1])\n",
|
||||
" if wn_pos is not None:\n",
|
||||
" synset = wn.synsets(token[0], lang='fra', pos=wn_pos)\n",
|
||||
" list_synsets.append(synset)\n",
|
||||
|
@ -290,6 +301,515 @@
|
|||
"commentaires_df[\"synsets\"] = commentaires_df.apply(lambda x: synsets_fr(x[\"pos_dict_lem\"]), axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"Nombre de mots ayant au moins un synset associé"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"commentaires_df[\"nb_synsets\"]=commentaires_df.apply(lambda y: sum([len(x)>0 for x in y[\"synsets\"]]), axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"commentaires_df[\"nb_pos\"]=commentaires_df.apply(lambda y: len(y[\"pos_dict\"]), axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"commentaires_df[\"prop_synsets_pos\"]=commentaires_df.apply(lambda y: y[\"nb_synsets\"]/max(y[\"nb_pos\"],1), axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d000 = commentaires_df[[\"media\",\"nb_synsets\"]].copy()\n",
|
||||
"d000[\"nb_synsets_tronq\"] = d000.apply(lambda x: min(20,x[\"nb_synsets\"]), axis=1)\n",
|
||||
"g000 = sns.catplot(x=\"media\", y=\"nb_synsets_tronq\",\n",
|
||||
" kind=\"boxen\",\n",
|
||||
" data=d000);\n",
|
||||
"g000.set_axis_labels(\"Média\", \"Nombre de POS ayant un synset\\n(tronqué à 20)\")\n",
|
||||
"g000.despine(offset=10, trim=True)\n",
|
||||
"g000.savefig(\"g000.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d001 = commentaires_df[[\"media\",\"prop_synsets_pos\"]].copy()\n",
|
||||
"g001 = sns.catplot(x=\"media\", y=\"prop_synsets_pos\",\n",
|
||||
" kind=\"boxen\",\n",
|
||||
" data=d001);\n",
|
||||
"g001.set_axis_labels(\"Média\", \"Proportion de POS ayant un synset\")\n",
|
||||
"g001.despine(offset=10, trim=True)\n",
|
||||
"g001.savefig(\"g001.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Nombre de types de POS dans le commentaire"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"commentaires_df[\"nb_type_pos\"] = commentaires_df.apply(lambda y: len(set([x[1] for x in y[\"pos_dict\"]])), axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d002 = commentaires_df[[\"media\",\"nb_type_pos\"]].copy()\n",
|
||||
"g002 = sns.catplot(x=\"media\", y=\"nb_type_pos\",\n",
|
||||
" kind=\"boxen\",\n",
|
||||
" data=d002);\n",
|
||||
"g002.set_axis_labels(\"Média\", \"Nombre de types de POS\")\n",
|
||||
"g002.despine(offset=10, trim=True)\n",
|
||||
"g002.savefig(\"g002.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Marqueurs d'emphase\n",
|
||||
"\n",
|
||||
"### Nombre d'emojis"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def dict_emojis_to_list(emoji_dict):\n",
|
||||
" emojis = []\n",
|
||||
" for key in emoji_dict:\n",
|
||||
" for value in emoji_dict[key]:\n",
|
||||
" emojis.append(key)\n",
|
||||
" return emojis"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"commentaires_df[\"emoji_list\"] = commentaires_df.apply(lambda x: dict_emojis_to_list(x[\"emoji_dict\"]), axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d003 = commentaires_df[[\"media\",\"emoji_list\"]].copy()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d003df = pd.DataFrame({'media':np.repeat(d003.media.values, d003.emoji_list.str.len()),\n",
|
||||
" 'emoji':np.concatenate(d003.emoji_list.values),\n",
|
||||
" 'value':1})"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d003cnt1 = d003df.groupby([\"media\",\"emoji\"]).agg(['sum']).reset_index(['media','emoji'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d003cnt1.columns = [\"media\",\"emoji\",\"media_count\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d003cnt2 = d003df.groupby(\"emoji\").agg(['count']).reset_index(\"emoji\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d003cnt2 = d003cnt2[[\"emoji\",\"media\"]]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d003cnt2.columns = [\"emoji\",\"total_count\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d003cntx = d003cnt1[d003cnt1.emoji != \":\"].merge(d003cnt2,on=\"emoji\").sort_values(\"total_count\",ascending=False).head(30)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"del d003cntx[\"total_count\"]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"g003 = sns.catplot(y=\"emoji\", x=\"media_count\", hue=\"media\", \n",
|
||||
" kind=\"bar\",\n",
|
||||
" palette=\"pastel\", edgecolor=\".6\",\n",
|
||||
" data=d003cntx)\n",
|
||||
"g003.set_axis_labels(\"Fréquence\", \"Forme textuelle des emojis\")\n",
|
||||
"g003.despine(offset=10, trim=True)\n",
|
||||
"g003.savefig(\"g003.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Mots en majuscules"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"commentaires_df['nb_mots_majuscules'] = commentaires_df.apply(lambda x: len([word for word,_ in x[\"pos_dict\"] if word.isupper()]), axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d004 = commentaires_df[['media','nb_mots_majuscules']].copy()\n",
|
||||
"g004 = sns.catplot(x=\"media\", y=\"nb_mots_majuscules\",\n",
|
||||
" kind=\"boxen\",\n",
|
||||
" data=d004);\n",
|
||||
"g004.set_axis_labels(\"Média\", \"Nombre de mots en majuscules\")\n",
|
||||
"g004.despine(offset=10, trim=True)\n",
|
||||
"g004.savefig(\"g004.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Ponctuations successives"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import re\n",
|
||||
"punct_re = re.compile(r'([^\\w\\s\\:]{2,})')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"demo = emoji.demojize(commentaires_df['comment_clean'][37765])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"### Ponctuations successives\n",
|
||||
"def nb_punct_succ(x):\n",
|
||||
" seq_punct = re.findall(punct_re,x)\n",
|
||||
" return sum([len(s) for s in seq_punct])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"commentaires_df['nb_punct_succ'] = commentaires_df.apply(lambda x: nb_punct_succ(x['comment_clean']), axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d005 = commentaires_df[commentaires_df.nb_punct_succ > 0][['media','nb_punct_succ']].copy()\n",
|
||||
"g005 = sns.catplot(x=\"media\", y=\"nb_punct_succ\",\n",
|
||||
" kind=\"boxen\",\n",
|
||||
" data=d005);\n",
|
||||
"g005.set_axis_labels(\"Média\", \"Nombre ponctuations successives totales\")\n",
|
||||
"g005.despine(offset=10, trim=True)\n",
|
||||
"g005.savefig(\"g005.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Intertextualité\n",
|
||||
"\n",
|
||||
"### Mention de l'auteur d'un autre commentaire"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"commentaires_df['ind_auteurs_referes'] = commentaires_df.apply(lambda x: len(ast.literal_eval(x['auteurs_referes']))>0, axis=1) # j'avais sauvegardé une représentation littérale de la liste ..."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"decompte_auteur_refere = commentaires_df[['media','ind_auteurs_referes']].groupby('media').agg('mean').reset_index('media')\n",
|
||||
"decompte_auteur_refere.columns = ['Media','Proportion']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"decompte_auteur_refere.to_latex(\"decompte_auteur_refere.tex\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Pronoms et articles possessifs à la deuxième personne"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"tok = TweetTokenizer(preserve_case=False)\n",
|
||||
"mots_2epers = ['ton','ta','tes','toi','te','tu','t\\'','vous','votre','vos']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"commentaires_df['ind_2e_pers'] = commentaires_df.apply(lambda x: len([token for token in tok.tokenize(x['comment_clean']) if token in mots_2epers])>0, axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"decompte_2e_pers = commentaires_df[['media','ind_2e_pers']].groupby('media').agg('mean').reset_index('media')\n",
|
||||
"decompte_2e_pers.columns = ['Media','Proportion']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"decompte_2e_pers.to_latex(\"decompte_2e_pers.tex\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# Analyse des liens entre les commentaires et les articles\n",
|
||||
"\n",
|
||||
"## Entités nommées"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d006a = commentaires_df[commentaires_df['ner_dict'] != {}][['media','id','post_id','ner_dict']].copy()\n",
|
||||
"d006a['ner_list_comm'] = commentaires_df.apply(lambda x: list(x['ner_dict'].keys()), axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"del d006a['ner_dict']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d006b = textes_articles_df[textes_articles_df['ner_dict'] != {}][['media','post_id','ner_dict']].copy()\n",
|
||||
"d006b['ner_list_art'] = textes_articles_df.apply(lambda x: list(x['ner_dict'].keys()), axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"del d006b['ner_dict']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d006 = d006a.merge(d006b, on=['post_id','media'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def intersection(lst1, lst2): \n",
|
||||
" lst3 = [value for value in lst1 if value in lst2] \n",
|
||||
" return lst3 "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"d006['ner_list_inter'] = d006.apply(lambda x: len(intersection(x['ner_list_comm'],x['ner_list_art'])), axis=1)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"prop_ner_inter_post = d006[['media','post_id','ner_list_inter']].groupby(['media','post_id']).agg('mean').reset_index(['media','post_id'])"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"prop_ner_inter_post.columns = ['media','post_id','prop_ner_list_inter']"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"g006 = sns.catplot(x=\"media\", y=\"prop_ner_list_inter\",\n",
|
||||
" kind=\"boxen\",\n",
|
||||
" data=prop_ner_inter_post);\n",
|
||||
"g006.set_axis_labels(\"Média\", \"Nombre moyen d'entités nommées communes par commentaire\")\n",
|
||||
"g006.despine(offset=10, trim=True)\n",
|
||||
"g006.savefig(\"g006.pdf\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,2 +1,2 @@
|
|||
build: rapport.md
|
||||
pandoc --filter=pandoc-citeproc -f markdown+raw_tex+latex_macros rapport.md -o rapport.pdf
|
||||
pandoc --filter=pandoc-citeproc --dpi=180 -f markdown+raw_tex+latex_macros rapport.md -o rapport.pdf
|
||||
|
|
17
NLP-TP3.bib
17
NLP-TP3.bib
File diff suppressed because one or more lines are too long
|
@ -118,7 +118,7 @@
|
|||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.7.3"
|
||||
"version": "3.7.4"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
|
93
rapport.md
93
rapport.md
|
@ -8,7 +8,7 @@ toc: yes
|
|||
toc-depth: 1
|
||||
lang: fr-FR
|
||||
documentclass: "article"
|
||||
fontsize: 12pt
|
||||
fontsize: 11pt
|
||||
geometry: margin=1in
|
||||
bibliography: NLP-TP3.bib
|
||||
csl: transactions-on-speech-and-language-processing.csl
|
||||
|
@ -107,7 +107,7 @@ Cette expertise est illustrée par un choix de vocabulaire spécifique au domain
|
|||
|
||||
La prise de position relie le commentaire aux réalités socio-culturelles traitées dans l'article journalistique. Ces positions sont exprimées par des adjectifs et des adverbes évaluatifs, des verbes affectifs et cognitifs, des modalités, des pronoms génériques, de l'ironie, des questions rhétoriques, des citations et des paroles de chansons ainsi que l'utilisations de mécanismes d'emphase. On notera aussi l'usage de nombreuses images, notamment les *memes*, quoique ce n'est pas le sujet de ce rapport.
|
||||
|
||||
**Observations**: On remarque ici que l'on devra utiliser des étiquettes plus détaillés que celles qu'on retrouve notamment dans Universal Dependancies [@zeman_universal_2019] pour identifier les parties du discours impliquées dans la prise de position. Pour ce faire, il sera nécessaire d'utiliser conjointement les parties du discours et une base sémantique telle que WordNet pour augmenter le niveau de détail contenu dans les étiquettes.
|
||||
**Observations**: On remarque ici que l'on devra utiliser des étiquettes plus détaillés que celles qu'on retrouve notamment dans Universal Dependancies [@noauthor_universal_2019] pour identifier les parties du discours impliquées dans la prise de position. Pour ce faire, il sera nécessaire d'utiliser conjointement les parties du discours et une base sémantique telle que WordNet pour augmenter le niveau de détail contenu dans les étiquettes.
|
||||
|
||||
# Relations entre les commentaires
|
||||
|
||||
|
@ -147,16 +147,16 @@ Nous analyserons les articles provenant des pages Facebook de trois médias écr
|
|||
|
||||
\begin{figure}
|
||||
\centering
|
||||
\caption{Décompte des articles par médias}
|
||||
\input{decompte_articles_medias}
|
||||
\caption{Décompte des articles par médias}
|
||||
\end{figure}
|
||||
|
||||
Le premier corpus étudié est constitué du texte de chacun des articles qui sont liés dans les publications (l'utilisateur de Facebook devant cliquer sur le lien pour y accéder). Le titre de l'article n'est pas inclus dans ce corpus. Le second corpus est constitué d'un ensemble de commentaires publiés par des utilisateurs du réseau social et associés à chacune des publications précédentes.
|
||||
|
||||
\begin{figure}
|
||||
\centering
|
||||
\caption{Décompte des commentaires par médias}
|
||||
\input{decompte_comm_medias}
|
||||
\caption{Décompte des commentaires par médias}
|
||||
\end{figure}
|
||||
|
||||
Ces deux corpus ont été créés à l'aide des données de commentaires extraites depuis l'application en ligne exportcomments.com @noauthor_exportcomments.com_2019 dans des fichiers XLSX. Les fichiers ont par la suite été utilisés par les programmes Python suivants :
|
||||
|
@ -164,42 +164,63 @@ Ces deux corpus ont été créés à l'aide des données de commentaires extrait
|
|||
- `commentaires.ipynb` pour extraire les commentaires depuis les fichiers téléchargés à l'aide de Pandas @mckinney_data_2010.
|
||||
- `textes_articles.ipynb` pour extraire les textes depuis les URL disponibles dans les fichiers, par récupération de données (*web scraping*), en utilisant la librairie Python `newspaper` @ou-yang_newspaper3k:_2019. Du même coup, cette librairie permet d'extraction d'entités nommées et l'étiquetage des parties du discours.
|
||||
|
||||
## Métriques considérées
|
||||
|
||||
Niveau de langage:
|
||||
|
||||
- Nombre de jetons dans WordNet
|
||||
- Est-ce que le commentaire contient une phrase validée par une analyse syntaxique
|
||||
- Nombre de POS par type
|
||||
|
||||
Marqueurs d'emphase
|
||||
|
||||
- Nombre d'emojis
|
||||
- Présence de mots tout en majuscules
|
||||
- Présence de ponctuations successives
|
||||
|
||||
Entités
|
||||
|
||||
- Correspondance du lieu avec l'article
|
||||
- Correspondance des personnes avec l'article
|
||||
- Nombre d'entités en commun avec l'article
|
||||
|
||||
Expertise et prise de position
|
||||
|
||||
- Correspondance du sujet
|
||||
- Interrogation
|
||||
- Mots-clés
|
||||
|
||||
Intertextualité
|
||||
|
||||
- Mention de l'auteur d'un autre commentaire
|
||||
- Présence de pronoms à la deuxième personne
|
||||
|
||||
## Méthodologie et algorithmes
|
||||
|
||||
J'ai effectué la lemmatisation en français à l'aide du French LEFFF Lemmatizer de Claude Coulombe [@coulombe_french_2019], qui est compatible avec la syntaxe utilisée dans la librairie NLTK et les étiquettes POS utilisées dans WordNet.
|
||||
|
||||
## Quelques résultats
|
||||
## Analyse statistique des commentaires
|
||||
|
||||
### Distribution du niveau de langage
|
||||
|
||||
![Nombre de jetons avec POS dans WordNet, par commentaire, par média](g000.pdf)
|
||||
|
||||
![Proportion de jetons avec POS dans WordNet, par commentaire, par média](g001.pdf)
|
||||
|
||||
![Nombre de types de POS avec classes fermées, par commentaire, par média](g002.pdf)
|
||||
|
||||
### Distribution des marqueurs d'emphase
|
||||
|
||||
![Emojis les plus fréquents, par médias](g003.pdf)
|
||||
|
||||
![Nombre de mots en majuscules, par commentaire, par média](g004.pdf)
|
||||
|
||||
![Nombre de ponctuations successives totales, par commentaire, par média](g005.pdf)
|
||||
|
||||
### Indicateurs d'intertextualité
|
||||
|
||||
Le principal indicateur de l'intertextualité est la référence directe à l'auteur d'un commentaire précédent.
|
||||
|
||||
\begin{figure}
|
||||
\centering
|
||||
\input{decompte_auteur_refere}
|
||||
\caption{Proportion de références d'auteurs de commentaires par médias}
|
||||
\end{figure}
|
||||
|
||||
On remarque ici que la proportion de commentaires qui contiennent de telles références est constante et est aussi relativement élevée, peu importe le média. On pourrait donc conclure qu'il s'agit d'un attribut possédant de bonnes caractéristiques pour un modèle de classification binaire.
|
||||
|
||||
Un autre indicateur de l'intertextualité est l'usage de la deuxième personne, autant pour les pronoms que pous les articles possessifs. Cependant, ici, il n'est pas possible de savoir, sans devoir faire une analyse des coréférences, si la personne référée est l'auteur d'un commentaire ou une personne mentionnée dans l'article.
|
||||
|
||||
\begin{figure}
|
||||
\centering
|
||||
\input{decompte_2e_pers}
|
||||
\caption{Proportion de commentaires avec des pronoms ou articles à la 2e personne, par médias}
|
||||
\end{figure}
|
||||
|
||||
Cet indicateur possède aussi de bonnes caractéristiques pour être un attribut dans un modèle de classification.
|
||||
|
||||
## Analyse statistique des relations entre commentaires et articles
|
||||
|
||||
### Entités nommées en commun
|
||||
|
||||
Une façon d'évaluer la pertinence d'un commentaire est de dénombrer le nombre d'entités nommées communes entre ce commentaire et l'article auquel il réfère. Ici, on calcule, pour chaque commentaire, le nombre d'entités en commun avec l'article, puis on effectue la moyenne par article. C'est cette statistique qui est représentée sur la figure qui suit.
|
||||
|
||||
![Nombre moyen d'entités nommées en commun entre le commentaire et l'article, par article et par média](g006.pdf)
|
||||
|
||||
On remarque que le nombre moyen d'entités référées par commentaire est d'environ 1/5. On peut donc dire qu'en moyenne, 20% des commentaires réfèrent à une entité nommée de l'article. Afin d'augmenter potentiellement ce nombre, on pourrait étendre la liste des entités nommées à l'aide de relations sémantiques de méronymie.
|
||||
|
||||
### Groupes sémantiques en commun
|
||||
|
||||
- Synsets
|
||||
|
||||
# Conclusion
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue