File size: 4,853 Bytes
668588c
 
e15ae83
b497d4c
d8bf9f4
b497d4c
6340bc3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import os
os.system('pip install nltk')
os.system('pip install wordcloud')
os.system('pip install spacy')
os.system('python -m spacy download es_core_news_sm')


import  streamlit as st
from collections import Counter
import pandas as pd
import numpy as np
import re 
import json
import matplotlib.pyplot as plt
import nltk
nltk.download('stopwords')
from wordcloud import WordCloud
from nltk.corpus import stopwords
import spacy
nlp = spacy.load("es_core_news_sm")

def lemmatize_text(text):
    doc = nlp(text)
    lemmatized = ' '.join([token.lemma_ for token in doc if not token.is_stop])
    return lemmatized

def clean_text(series):
    # Convertir la serie a una sola cadena de texto
    text = ' '.join(series.dropna().astype(str))
    # Eliminar caracteres no deseados (opcional, pero recomendado)
    text = re.sub(r'[^\w\s]', '', text.lower())
    # Lematizar el texto
    lemmatized_text = lemmatize_text(text)
    # Eliminar stopwords adicionales que no fueron removidas por spaCy
    stop_words = set(stopwords.words('spanish'))
    stop_words.update(["maestro", "clase", "profesor", "doctor", "profe", "alumno", "dr", "doctora", "material", "maestra", "ms", "mejor"])
    words = [word for word in lemmatized_text.split() if word not in stop_words]
    cleaned_text = ' '.join(words)
    return cleaned_text

    # Crear la nube de palabras
def create_wordcloud_from_series(cleaned_text, escuela):
    wordcloud = WordCloud(width=800, height=400, background_color='white').generate(cleaned_text)
    # Mostrar la nube de palabras
    plt.figure(figsize=(10, 5))
    plt.imshow(wordcloud, interpolation='bilinear')
    plt.axis('off')
    plt.show()
    #st.write(f"Palabras mas utilizadas por los alumnos de {escuela}")
    st.pyplot(plt)
    


def plot_top_words(words, top_n=20):
    words = words.split(" ")
    word_counts = Counter(words)
    common_words = word_counts.most_common(top_n)
    words, counts = zip(*common_words)
    fig, ax = plt.subplots(figsize=(10, 5))
    ax.bar(words, counts)
    plt.xticks(rotation=90)
    plt.xlabel('Palabras')
    plt.ylabel('Frecuencia')
    plt.title(f'Top {top_n} palabras más usadas')
    st.pyplot(fig)


# cargamos información de Escuelas
escuelas = pd.read_json('./escuelas.json', orient='records', lines=True).drop(columns = "Unnamed: 0")
categories = escuelas["Escuela"].unique()

# cargamos datos
datos = pd.read_json('./datos.json', orient='records', lines=True)
print(datos.columns)

def tabla_materias(df):
    # seleccionamos las materias con más comentarios
    materias = df["Class Name"].value_counts().index[:12]
    df_f = df[df["Class Name"].isin(materias)].groupby("Class Name").sentimiento.value_counts(normalize = True).fillna(0).unstack(-1).style.format('{:.2%}')
    return df_f

def tabla_anio(df):
    # seleccionamos las materias con más comentarios
    df["year"] = df.Date.dt.year
    df_f = df.groupby(["year"]).sentimiento.value_counts(normalize = True).fillna(0.0).unstack(0).T.reset_index() # .style.format('{:.2%}')
    fig, ax = plt.subplots(figsize=(10, 5))
    for column in ["postivo", "negativo"]:
        ax.plot(df_f['year'], df_f[column], label=column)
    ax.set_xlabel('Year')
    ax.set_ylabel('%')
    ax.set_title('Sentimiento anual por años')
    ax.legend()
    return st.pyplot(fig)
    


def main():
    st.title('Análisis de Sentimiento a comentarios Realizados en MisProfesores.com')
    selected_category = st.selectbox("Seleccionar una Escuela para hacer Web Scrapping", categories)
    datos_f= datos[datos.escuela == selected_category] 
    # eliminar al cambiar el dato
    # generamos dos conjuntos de datos para comparar
    datos_positivos = datos_f[datos_f.sentimiento == "postivo"]
    # generamos dos conjuntos de datos para comparar
    datos_negativos = datos_f[datos_f.sentimiento == "negativo"]


    for key, dat in {"positivas": datos_positivos , "negativas": datos_negativos}.items():
        st.header(f"Palabras mas utilizadas por los alumnos con calificaciones {key}")
        # generamos nube de palabras
        cleaned_text = clean_text(dat.Comments)
        create_wordcloud_from_series(cleaned_text, selected_category)
        plot_top_words(cleaned_text, top_n=20)
    
    # desplegamos los resultados de las 5 materias mas comunes 
    st.header(f"Así es cómo los alumnos de la {selected_category} se sienten a lo largo de los años")
    tabla_anio(datos_f)
    st.write(f"curioso como el porcentaje de sentimientos positivos baja por culpa de la pandemia")

    st.header(f"estas fueron las calificaciones de las materias más comentadas de {selected_category}")
    st.dataframe( tabla_materias(datos_f))

    st.write(f"aqui puedes observar los datos por si tienes curiosidad de lo que dicen los usuarios!")
    st.dataframe( datos_positivos)

if __name__ == "__main__":
    main()