Da Perda pro Custo: Somando o Erro de Todo Mundo
A perda logística mede o erro de um exemplo. O curso já define essa distinção: perda (loss) é sobre um exemplo só, custo (cost) é a perda somada (com a média) sobre o conjunto de treino inteiro. É o custo que gradiente descendente minimiza.
A função de custo completa
Parece complicada, mas é só a perda de um exemplo, a mesma fórmula de linha única do lab passado, dentro de um somatório dividido por m. Média da perda de todo mundo.
O código, linha a linha
def compute_cost_logistic(X, y, w, b):
m = X.shape[0]
cost = 0.0
for i in range(m):
z_i = np.dot(X[i],w) + b
f_wb_i = sigmoid(z_i)
cost += -y[i]*np.log(f_wb_i) - (1-y[i])*np.log(1-f_wb_i)
cost = cost / m
return cost
m = X.shape[0]: quantos exemplos tem no conjunto.- o
forpercorre cada pacientei. z_i = np.dot(X[i],w) + b: a parte linear, a mesma combinação de sempre, só que agoraX[i]pode ter várias variáveis, então é produto escalar em vez de multiplicação simples.f_wb_i = sigmoid(z_i): espreme pra virar probabilidade.- a linha do meio soma a perda desse paciente ao acumulador
cost, a mesma fórmula de linha única do lab passado. - no fim,
cost / mfaz a média.
Testando com dois valores de b diferentes
Mesmo dataset de sempre, duas fronteiras candidatas: b=-3 e b=-4 (mantendo w=[1,1] fixo nos dois).
print("Custo com b = -3:", compute_cost_logistic(X_train, y_train, np.array([1,1]), -3))
print("Custo com b = -4:", compute_cost_logistic(X_train, y_train, np.array([1,1]), -4))
Saída:
Custo com b = -3: 0.3669·Custo com b = -4: 0.5037
O custo já denuncia qual fronteira é pior, antes de eu precisar olhar gráfico nenhum. Mas o gráfico confirma:
A linha de b=-4 (tracejada) fica deslocada pra cima e pra direita em relação à de b=-3, e nesse deslocamento ela passa a deixar dois pacientes y=1 do lado errado (abaixo da linha, previstos como 0). Faz sentido o custo dela ser maior: custo alto é literalmente o modelo dizendo "essa fronteira explica pior os dados que eu vi".
Fechando
| O que eu já sabia | O que essa aula assentou |
|---|---|
| Perda mede o erro de um exemplo | Custo é a média da perda sobre todo o conjunto de treino, é isso que se minimiza |
| A fórmula da perda logística, de linha única | O mesmo código, dentro de um for com média no fim, vira a função de custo completa |
| Uma fronteira pior classifica mais gente errado | O custo mede essa piora numericamente, antes mesmo de eu plotar qualquer gráfico |
Aplicação Prática
Uso o modelo real de duas variáveis do lab da fronteira de decisão (worst concave points + worst perimeter, ambas normalizadas), com os pesos w=[2.5494, 4.0739] treinados por gradiente descendente, e comparo o custo do b treinado contra um b deliberadamente pior (deslocado em +2):
print("Custo com b treinado:", compute_cost_logistic(X_train_z, y_train, w, b))
print("Custo com b + 2:", compute_cost_logistic(X_train_z, y_train, w, b + 2))
Saída:
Custo com b treinado: 0.1461·Custo com b + 2: 0.2391
O custo mais que soma um terço a mais só por deslocar a fronteira em duas unidades. E a acurácia sente isso na prática: com o b treinado, acurácia de treino é 0.9319; com o b deslocado, cai pra 0.8989. Um b "quase certo" (a direção da fronteira, dada por w, continua a mesma) já perde 3 pontos percentuais de acurácia, e o custo denuncia exatamente essa piora, do jeito que gradiente descendente enxerga: como um número maior, que ele vai tentar diminuir de novo nos próximos passos.