I created a model that combines two vector layers and outputs a single layer with aggregated data. I have a Python script that calculates the Chi-square, and I would like it to be executed at the end of the model's execution.
How do I incorporate the Chi-square code into the modeler?
script Chi-square:
import numpy as np
from scipy.stats import chisquare, norm
from qgis.gui import QgsFieldComboBox, QgsDoubleSpinBox
from qgis.PyQt.QtWidgets import QInputDialog, QMessageBox
# Função para calcular os valores críticos com base no novo valor de alfa corrigido
def calcular_valores_criticos(alfa_corrigido):
# Calcular os valores críticos da distribuição normal padrão
limite_superior = norm.ppf(1 - alfa_corrigido / 2)
limite_inferior = norm.ppf(alfa_corrigido / 2)
return limite_superior, limite_inferior
# Função para realizar o teste qui-quadrado de aderência com correção de Bonferroni
def qui_quadrado_aderencia_qgis(camada, campo_esperado, campo_observado, alfa):
# Verificar se a camada está carregada
if not camada:
print("Camada inválida. Verifique se uma camada está ativa.")
return
# Inicializar listas para valores esperados e observados
valores_esperados = []
valores_observados = []
# Acessar os dados da camada e extrair os valores esperados e observados
for feature in camada.getFeatures():
valor_esperado = feature[campo_esperado]
valor_observado = feature[campo_observado]
if isinstance(valor_esperado, (int, float)) and isinstance(valor_observado, (int, float)):
valores_esperados.append(float(valor_esperado))
valores_observados.append(float(valor_observado))
# Executar o teste qui-quadrado de aderência
chi2, p_valor = chisquare(valores_observados, f_exp=valores_esperados)
# Calcular os resíduos padronizados ajustados
res_padronizados = (np.array(valores_observados) - np.array(valores_esperados)) / np.sqrt(valores_esperados)
# Aplicar a correção de Bonferroni ao valor de alfa
p_valor_corrigido = p_valor * len(valores_esperados) # Número de testes multiplicado pelo p-valor original
alfa_corrigido = alfa / len(valores_esperados)
# Calcular os valores críticos com base no novo valor de alfa corrigido
limite_superior, limite_inferior = calcular_valores_criticos(alfa_corrigido)
# Imprimir os resultados
print("Estatística qui-quadrado:", chi2)
print("Valor-p:", p_valor)
print("Valor-p corrigido (Bonferroni):", p_valor_corrigido)
print("Resíduos Padronizados:")
print(res_padronizados)
print(f"Valores críticos para alfa corrigido ({alfa_corrigido}):")
print(f"Limite Superior: {limite_superior}")
print(f"Limite Inferior: {limite_inferior}")
# Interpretar o resultado com a correção de Bonferroni
if p_valor_corrigido < alfa_corrigido:
print("Rejeitar a hipótese nula: A distribuição do fenômeno analisado não possui carácter aleatório (com correção de Bonferroni).")
else:
print("Falha em rejeitar a hipótese nula: A distribuição do fenômeno analisado possui carácter aleatório (com correção de Bonferroni).")
# Obter a camada ativa no QGIS
camada_ativa = iface.activeLayer()
# Usar QInputDialog para obter os campos de atributos e o valor de alfa
campo_esperado, ok = QInputDialog.getItem(None, "Campo de Valores Esperados", "Selecione o campo de valores esperados:",
[field.name() for field in camada_ativa.fields()])
if not ok:
QMessageBox.critical(None, "Erro", "Seleção de campo de valores esperados cancelada.")
else:
campo_observado, ok = QInputDialog.getItem(None, "Campo de Valores Observados", "Selecione o campo de valores observados:",
[field.name() for field in camada_ativa.fields()])
if not ok:
QMessageBox.critical(None, "Erro", "Seleção de campo de valores observados cancelada.")
else:
alfa, ok = QInputDialog.getDouble(None, "Valor de Alfa", "Digite o valor de alfa (nível de significância):", 0.05, 0, 1, 6)
if ok:
# Chamar a função qui_quadrado_aderencia_qgis
qui_quadrado_aderencia_qgis(camada_ativa, campo_esperado, campo_observado, alfa)