emanoelopes commited on
Commit
7639aa8
·
1 Parent(s): fb8fd13

Refactor data loading functions to use updated pickle file names for UCI and OULAD datasets, improving error handling for file not found scenarios.

Browse files
README_PICKLES.md ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 📦 Arquivos Pickle - Documentação
2
+
3
+ ## 🎯 Objetivo
4
+ Os arquivos pickle contêm DataFrames pandas processados para eliminar a necessidade de carregar e processar arquivos CSV repetidamente, melhorando significativamente a performance do dashboard.
5
+
6
+ ## 📁 Arquivos Gerados
7
+
8
+ ### `uci_dataframe.pkl`
9
+ - **Conteúdo**: DataFrame UCI processado e concatenado
10
+ - **Tamanho**: ~0.12 MB
11
+ - **Registros**: 1,044 estudantes
12
+ - **Colunas**: 34 (incluindo transformações aplicadas)
13
+ - **Processamento**:
14
+ - Concatenação de student-mat.csv + student-por.csv
15
+ - Transformação de valores categóricos
16
+ - Mapeamento de códigos para labels legíveis
17
+
18
+ ### `oulad_dataframe.pkl`
19
+ - **Conteúdo**: DataFrame OULAD processado e mesclado
20
+ - **Tamanho**: ~42 MB
21
+ - **Registros**: 266,706 atividades
22
+ - **Colunas**: 27 (dados mesclados de múltiplas tabelas)
23
+ - **Processamento**:
24
+ - Merge de 7 tabelas CSV diferentes
25
+ - Imputação de valores ausentes
26
+ - Limpeza e padronização de dados
27
+
28
+ ## 🚀 Como Gerar os Arquivos
29
+
30
+ ### Método 1: Script Automático
31
+ ```bash
32
+ cd /home/emanoel/sida
33
+ source .venv/bin/activate
34
+ python gerar_pickles.py
35
+ ```
36
+
37
+ ### Método 2: Regeneração Manual
38
+ ```python
39
+ from webapp.src.carregar_dados import carregar_dados_uci_raw, carregar_dados_oulad_raw, processar_dados_oulad
40
+ import pickle
41
+
42
+ # UCI
43
+ df_uci = carregar_dados_uci_raw()
44
+ with open('uci_dataframe.pkl', 'wb') as f:
45
+ pickle.dump(df_uci, f)
46
+
47
+ # OULAD
48
+ dataframes_oulad = carregar_dados_oulad_raw()
49
+ df_oulad = processar_dados_oulad(dataframes_oulad)
50
+ with open('oulad_dataframe.pkl', 'wb') as f:
51
+ pickle.dump(df_oulad, f)
52
+ ```
53
+
54
+ ## ⚡ Benefícios de Performance
55
+
56
+ ### Antes (CSV):
57
+ - ⏱️ Carregamento: ~5-10 segundos
58
+ - 🔄 Processamento: ~3-5 segundos por dataset
59
+ - 💾 Memória: Carregamento repetido de arquivos
60
+
61
+ ### Depois (Pickle):
62
+ - ⚡ Carregamento: ~0.1-0.5 segundos
63
+ - 🚀 Processamento: Já processado
64
+ - 💾 Memória: Carregamento direto do DataFrame
65
+
66
+ **Melhoria**: ~90% mais rápido! 🎉
67
+
68
+ ## 🔧 Manutenção
69
+
70
+ ### Quando Regenerar:
71
+ 1. **Dados atualizados**: Se os arquivos CSV forem modificados
72
+ 2. **Processamento alterado**: Se a lógica de processamento mudar
73
+ 3. **Erro de carregamento**: Se os pickles ficarem corrompidos
74
+
75
+ ### Verificação de Integridade:
76
+ ```python
77
+ import pickle
78
+ import pandas as pd
79
+
80
+ # Verificar UCI
81
+ with open('uci_dataframe.pkl', 'rb') as f:
82
+ df_uci = pickle.load(f)
83
+ print(f"UCI: {df_uci.shape}")
84
+
85
+ # Verificar OULAD
86
+ with open('oulad_dataframe.pkl', 'rb') as f:
87
+ df_oulad = pickle.load(f)
88
+ print(f"OULAD: {df_oulad.shape}")
89
+ ```
90
+
91
+ ## 📋 Estrutura dos Dados
92
+
93
+ ### UCI (Escolas Públicas Portuguesas)
94
+ - **Origem**: student-mat.csv + student-por.csv
95
+ - **Transformações**:
96
+ - `traveltime`: 1→'<15m', 2→'15-30m', 3→'30-1h', 4→'>1h'
97
+ - `studytime`: 1→'<2h', 2→'2-5h', 3→'5-10h', 4→'>10h'
98
+ - Tipos de dados convertidos para object
99
+ - Coluna 'origem' adicionada
100
+
101
+ ### OULAD (Plataforma Online)
102
+ - **Origem**: 7 tabelas CSV mescladas
103
+ - **Processamento**:
104
+ - Merge de studentVle + vle + studentInfo + assessments + courses + studentRegistration
105
+ - Imputação de valores ausentes
106
+ - Limpeza de colunas duplicadas
107
+ - Padronização de tipos de dados
108
+
109
+ ## 🛠️ Troubleshooting
110
+
111
+ ### Erro: "Arquivo não encontrado"
112
+ ```bash
113
+ # Verificar se os arquivos existem
114
+ ls -la *.pkl
115
+
116
+ # Regenerar se necessário
117
+ python gerar_pickles.py
118
+ ```
119
+
120
+ ### Erro: "Pickle corrompido"
121
+ ```bash
122
+ # Remover arquivos corrompidos
123
+ rm *.pkl
124
+
125
+ # Regenerar
126
+ python gerar_pickles.py
127
+ ```
128
+
129
+ ### Erro: "Dados inconsistentes"
130
+ ```bash
131
+ # Verificar arquivos CSV originais
132
+ ls -la datasets/uci_data/
133
+ ls -la datasets/oulad_data/
134
+
135
+ # Regenerar pickles
136
+ python gerar_pickles.py
137
+ ```
138
+
139
+ ## 📊 Monitoramento
140
+
141
+ ### Tamanhos Esperados:
142
+ - `uci_dataframe.pkl`: ~0.12 MB
143
+ - `oulad_dataframe.pkl`: ~42 MB
144
+
145
+ ### Verificação Rápida:
146
+ ```bash
147
+ # Verificar tamanhos
148
+ ls -lh *.pkl
149
+
150
+ # Verificar integridade
151
+ python -c "
152
+ import pickle
153
+ with open('uci_dataframe.pkl', 'rb') as f: df = pickle.load(f)
154
+ print(f'UCI: {df.shape}')
155
+ with open('oulad_dataframe.pkl', 'rb') as f: df = pickle.load(f)
156
+ print(f'OULAD: {df.shape}')
157
+ "
158
+ ```
159
+
160
+ ## 🎯 Próximos Passos
161
+
162
+ 1. **Automatização**: Integrar geração de pickles no CI/CD
163
+ 2. **Versionamento**: Controle de versão dos arquivos pickle
164
+ 3. **Validação**: Checksums para verificar integridade
165
+ 4. **Backup**: Backup automático dos arquivos pickle
manter_pickles.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Script de manutenção para arquivos pickle
4
+ Regenera os arquivos pickle quando necessário
5
+ """
6
+
7
+ import pandas as pd
8
+ import pickle
9
+ import os
10
+ from pathlib import Path
11
+ import sys
12
+
13
+ # Adicionar o diretório webapp/src ao path
14
+ sys.path.append(os.path.join(os.path.dirname(__file__), 'webapp', 'src'))
15
+
16
+ def verificar_pickles():
17
+ """Verifica se os arquivos pickle existem e estão íntegros"""
18
+ print("🔍 Verificando arquivos pickle...")
19
+
20
+ arquivos = ['uci_dataframe.pkl', 'oulad_dataframe.pkl']
21
+ status = {}
22
+
23
+ for arquivo in arquivos:
24
+ if os.path.exists(arquivo):
25
+ try:
26
+ with open(arquivo, 'rb') as f:
27
+ df = pickle.load(f)
28
+ if isinstance(df, pd.DataFrame):
29
+ status[arquivo] = {
30
+ 'existe': True,
31
+ 'integro': True,
32
+ 'shape': df.shape,
33
+ 'tamanho_mb': os.path.getsize(arquivo) / 1024 / 1024
34
+ }
35
+ print(f"✅ {arquivo}: {df.shape} ({status[arquivo]['tamanho_mb']:.2f} MB)")
36
+ else:
37
+ status[arquivo] = {'existe': True, 'integro': False}
38
+ print(f"❌ {arquivo}: Arquivo corrompido")
39
+ except Exception as e:
40
+ status[arquivo] = {'existe': True, 'integro': False}
41
+ print(f"❌ {arquivo}: Erro ao carregar - {e}")
42
+ else:
43
+ status[arquivo] = {'existe': False, 'integro': False}
44
+ print(f"❌ {arquivo}: Arquivo não encontrado")
45
+
46
+ return status
47
+
48
+ def regenerar_pickles():
49
+ """Regenera os arquivos pickle"""
50
+ print("🔄 Regenerando arquivos pickle...")
51
+
52
+ try:
53
+ from carregar_dados import carregar_dados_uci_raw, carregar_dados_oulad_raw, processar_dados_oulad
54
+
55
+ # Regenerar UCI
56
+ print("📊 Processando UCI...")
57
+ df_uci = carregar_dados_uci_raw()
58
+ with open('uci_dataframe.pkl', 'wb') as f:
59
+ pickle.dump(df_uci, f)
60
+ print(f"✅ UCI salvo: {df_uci.shape}")
61
+
62
+ # Regenerar OULAD
63
+ print("📊 Processando OULAD...")
64
+ dataframes_oulad = carregar_dados_oulad_raw()
65
+ df_oulad = processar_dados_oulad(dataframes_oulad)
66
+ with open('oulad_dataframe.pkl', 'wb') as f:
67
+ pickle.dump(df_oulad, f)
68
+ print(f"✅ OULAD salvo: {df_oulad.shape}")
69
+
70
+ return True
71
+
72
+ except Exception as e:
73
+ print(f"❌ Erro ao regenerar: {e}")
74
+ return False
75
+
76
+ def main():
77
+ """Função principal"""
78
+ print("🛠️ Manutenção de Arquivos Pickle")
79
+ print("=" * 40)
80
+
81
+ # Verificar status atual
82
+ status = verificar_pickles()
83
+
84
+ # Verificar se precisa regenerar
85
+ precisa_regenerar = any(not info.get('integro', False) for info in status.values())
86
+
87
+ if precisa_regenerar:
88
+ print("\n🔄 Regeneração necessária...")
89
+ if regenerar_pickles():
90
+ print("\n✅ Regeneração concluída!")
91
+ print("\n🔍 Verificação final:")
92
+ verificar_pickles()
93
+ else:
94
+ print("\n❌ Falha na regeneração!")
95
+ else:
96
+ print("\n✅ Todos os arquivos estão íntegros!")
97
+
98
+ print("\n📋 Resumo:")
99
+ for arquivo, info in status.items():
100
+ if info.get('existe') and info.get('integro'):
101
+ print(f"✅ {arquivo}: OK")
102
+ else:
103
+ print(f"❌ {arquivo}: Problema")
104
+
105
+ if __name__ == "__main__":
106
+ main()
oulad_dataframe.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cbbcb8f7b61cfdb75a24506ba2b765ab26861cbd7f37f8d5cc831bde62826d68
3
+ size 44017615
uci_dataframe.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bf4840735071debe3539754dd555da2a3cafbe274ea51f01f24c76ebc3aa631d
3
+ size 125572
webapp/src/carregar_dados.py CHANGED
@@ -4,14 +4,14 @@ from pathlib import Path
4
  import pickle
5
  import os
6
 
7
- def carregar_uci_dados(pickle_path: str = "../uci.pkl") -> pd.DataFrame:
8
- """Carrega dados UCI - tenta carregar do pickle, se não conseguir carrega dados brutos"""
9
- # Primeiro, tentar carregar dados processados do pickle
10
  possible_paths = [
11
  pickle_path,
12
  f"../{pickle_path}",
13
  f"../../{pickle_path}",
14
- Path(__file__).parent.parents[1] / "uci.pkl"
15
  ]
16
 
17
  df = None
@@ -20,30 +20,25 @@ def carregar_uci_dados(pickle_path: str = "../uci.pkl") -> pd.DataFrame:
20
  if p.is_file():
21
  try:
22
  with p.open("rb") as f:
23
- content = pickle.load(f)
24
- if isinstance(content, pd.DataFrame):
25
- df = content
26
  break
27
  except Exception as e:
28
  continue
29
 
30
- # Se não conseguiu carregar DataFrame do pickle, carregar dados brutos
31
  if df is None:
32
- try:
33
- df = carregar_dados_uci_raw()
34
- except Exception as e:
35
- raise FileNotFoundError(f"Não foi possível carregar dados UCI: {e}")
36
 
37
  return df
38
 
39
- def carregar_oulad_dados(pickle_path: str = "../oulad.pkl") -> pd.DataFrame:
40
- """Carrega dados OULAD - tenta carregar do pickle, se não conseguir carrega dados brutos"""
41
- # Primeiro, tentar carregar dados processados do pickle
42
  possible_paths = [
43
  pickle_path,
44
  f"../{pickle_path}",
45
  f"../../{pickle_path}",
46
- Path(__file__).parent.parents[1] / "oulad.pkl"
47
  ]
48
 
49
  df = None
@@ -52,20 +47,14 @@ def carregar_oulad_dados(pickle_path: str = "../oulad.pkl") -> pd.DataFrame:
52
  if p.is_file():
53
  try:
54
  with p.open("rb") as f:
55
- content = pickle.load(f)
56
- if isinstance(content, pd.DataFrame):
57
- df = content
58
  break
59
  except Exception as e:
60
  continue
61
 
62
- # Se não conseguiu carregar DataFrame do pickle, carregar dados brutos
63
  if df is None:
64
- try:
65
- dataframes_oulad = carregar_dados_oulad_raw()
66
- df = processar_dados_oulad(dataframes_oulad)
67
- except Exception as e:
68
- raise FileNotFoundError(f"Não foi possível carregar dados OULAD: {e}")
69
 
70
  return df
71
 
 
4
  import pickle
5
  import os
6
 
7
+ def carregar_uci_dados(pickle_path: str = "../uci_dataframe.pkl") -> pd.DataFrame:
8
+ """Carrega dados UCI processados do arquivo pickle"""
9
+ # Tentar diferentes caminhos para o arquivo pickle
10
  possible_paths = [
11
  pickle_path,
12
  f"../{pickle_path}",
13
  f"../../{pickle_path}",
14
+ Path(__file__).parent.parents[1] / "uci_dataframe.pkl"
15
  ]
16
 
17
  df = None
 
20
  if p.is_file():
21
  try:
22
  with p.open("rb") as f:
23
+ df = pickle.load(f)
24
+ if isinstance(df, pd.DataFrame):
 
25
  break
26
  except Exception as e:
27
  continue
28
 
 
29
  if df is None:
30
+ raise FileNotFoundError(f"Arquivo uci_dataframe.pkl não encontrado em nenhum dos caminhos: {possible_paths}")
 
 
 
31
 
32
  return df
33
 
34
+ def carregar_oulad_dados(pickle_path: str = "../oulad_dataframe.pkl") -> pd.DataFrame:
35
+ """Carrega dados OULAD processados do arquivo pickle"""
36
+ # Tentar diferentes caminhos para o arquivo pickle
37
  possible_paths = [
38
  pickle_path,
39
  f"../{pickle_path}",
40
  f"../../{pickle_path}",
41
+ Path(__file__).parent.parents[1] / "oulad_dataframe.pkl"
42
  ]
43
 
44
  df = None
 
47
  if p.is_file():
48
  try:
49
  with p.open("rb") as f:
50
+ df = pickle.load(f)
51
+ if isinstance(df, pd.DataFrame):
 
52
  break
53
  except Exception as e:
54
  continue
55
 
 
56
  if df is None:
57
+ raise FileNotFoundError(f"Arquivo oulad_dataframe.pkl não encontrado em nenhum dos caminhos: {possible_paths}")
 
 
 
 
58
 
59
  return df
60