pip install - r requirements . txt export KAGGLE_USERNAME= " your_kaggle_username "
export KAGGLE_KEY= " your_api_key " cd kaggle_dataset
kaggle datasets download -d lizhecheng/pii-data-detection-dataset
unzip pii-data-detection-dataset.zip
kaggle datasets download -d lizhecheng/piidd-reliable-cv
unzip piidd-reliable-cv.zip cd kaggle_dataset
cd competition
kaggle competitions download -c pii-detection-removal-from-educational-data
unzip pii-detection-removal-from-educational-data.zip cd kaggle_notebook
run train-0.3-validation.ipynb cd models
wandb sweep --project PII config.yamlwandb agent xxx/PII/xxxxxxxx cd kfold
wandb login --relogin
(input your wandb api key)
wandb init -e (input your wandb username)
export KFOLD=0/1/2/3
wandb sweep --project PII hypertuning_kfold.yaml
wandb agent xxx/PII/xxxxxxxx
Primeiro de tudo, obrigado a Kaggle e THE LEARNING AGENCY LAB por sediar esta competição e, obrigado a todos da equipe por seus esforços. Embora o resultado não tenha sido perfeito, ainda aprendemos muito e continuaremos avançando. Parabéns a todos os vencedores!
Aqui está o GitHub Repo para esta competição, onde você pode encontrar quase todos os códigos: https://github.com/lizhecheng02/kaggle-pii_data_detecção
AWP (Adversarial Weight Perturbation) Aprimore a robustez do modelo usando uma classe AWP personalizada e escreva o próprio CustomTrainer . Esse é um método que nossa equipe costuma usar nas competições de PNL e tem alguns bons resultados. (O código correspondente pode ser encontrado no meu diretório GitHub no models ).
Wandb Sweep Com essa ferramenta, podemos tentar várias combinações de diferentes hiperparâmetros para selecionar os que produzem os melhores resultados de ajuste fino. (O código correspondente pode ser encontrado no meu diretório GitHub no models ).
Replace nn with | in all documentsNesse caso, treinamos um conjunto de modelos com validação cruzada 4 vezes e escores LB de 0,977. Embora tenha havido alguma melhoria no LB, os resultados não mostraram melhora no PB.
n aparecer em endereços, que devem ser rotulados com a etiqueta i .Dr. são previstos com o rótulo B. ( Sem melhora significativa ) def pp(new_pred_df):
df = new_pred_df.copy()
i = 0
while i < len(df):
st = i
doc = df.loc[st, "document"]
tok = df.loc[st, "token"]
pred_tok = df.loc[st, "label"]
if pred_tok == 'O':
i += 1
continue
lab = pred_tok.split('-')[1]
cur_doc = doc
cur_lab = lab
last_tok = tok
cur_tok = last_tok
while i < len(df) and cur_doc == doc and cur_lab == lab and last_tok == cur_tok:
last_tok = cur_tok + 1
i += 1
cur_doc = df.loc[i, "document"]
cur_tok = df.loc[i, "token"]
if i >= len(df) or df.loc[i, "label"] == 'O':
break
cur_lab = df.loc[i, "label"].split('-')[1]
if st - 2 >= 0 and df.loc[st - 2, "document"] == df.loc[st, "document"] and df.loc[st - 1, "token_str"] == 'n' and df.loc[st - 2, "label"] != 'O' and df.loc[st - 2, "label"].split('-')[1] == lab:
df.loc[st - 1, "label"] = 'I-' + lab
df.loc[st - 1, "score"] = 1
for j in range(st, i):
if df.loc[j, "label"] != 'I-' + lab:
df.loc[j, "score"] = 1
df.loc[j, "label"] = 'I-' + lab
continue
for j in range(st, i):
if j == st:
if df.loc[j, "label"] != 'B-' + lab:
df.loc[j, "score"] = 1
df.loc[j, "label"] = 'B-' + lab
else:
if df.loc[j, "label"] != 'I-' + lab:
df.loc[j, "score"] = 1
df.loc[j, "label"] = 'I-' + lab
if lab == 'NAME_STUDENT' and any(len(item) == 2 and item[0].isupper() and item[1] == "." for item in df.loc[st:i-1, 'token_str']):
for j in range(st, i):
df.loc[j, "score"] = 0
df.loc[j, "label"] = 'O'
return df
Average EnsembleUse o método de tomar a média de probabilidades para obter o resultado final. Como o recall é mais importante que a precisão nesta competição, defina o limite para 0,0 para evitar perder qualquer possível recall correto.
for text_id in final_token_pred:
for word_idx in final_token_pred[text_id]:
pred = final_token_pred[text_id][word_idx].argmax(-1)
pred_without_O = final_token_pred[text_id][word_idx][:12].argmax(-1)
if final_token_pred[text_id][word_idx][12] < 0.0:
final_pred = pred_without_O
tmp_score = final_token_pred[text_id][word_idx][final_pred]
else:
final_pred = pred
tmp_score = final_token_pred[text_id][word_idx][final_pred]
Vote EnsembleEm nosso envio final, reunimos 7 modelos e aceitamos um rótulo como a previsão correta se pelo menos dois dos modelos previam o mesmo rótulo.
for tmp_pred in single_pred:
for text_id in tmp_pred:
max_id = 0
for word_idx in tmp_pred[text_id]:
max_id = tmp_pred[text_id][word_idx].argmax(-1)
tmp_pred[text_id][word_idx] = np.zeros(tmp_pred[text_id][word_idx].shape)
tmp_pred[text_id][word_idx][max_id] = 1.0
for word_idx in tmp_pred[text_id]:
final_token_pred[text_id][word_idx] += tmp_pred[text_id][word_idx]
for text_id in final_token_pred:
for word_idx in final_token_pred[text_id]:
pred = final_token_pred[text_id][word_idx].argmax(-1)
pred_without_O = final_token_pred[text_id][word_idx][:12].argmax(-1)
if final_token_pred[text_id][word_idx][pred] >= 2:
final_pred = pred
tmp_score = final_token_pred[text_id][word_idx][final_pred]
else:
final_pred = 12
tmp_score = final_token_pred[text_id][word_idx][final_pred]
Two GPU Inference O uso de GPUs T4*2 dobra a velocidade de inferência em comparação com uma única GPU. Para proteger 8 modelos, o máximo max_length é 896 ; Se o Ensemble 7 modelos, o max_length pode ser definido como 1024 , que é um valor mais ideal. (O código correspondente pode ser encontrado no meu GitHub no diretório submissions ).
Convert Non-English Characters (torne o LB mais baixo) def replace_non_english_chars(text):
mapping = {
'à': 'a', 'á': 'a', 'â': 'a', 'ã': 'a', 'ä': 'a', 'å': 'a',
'è': 'e', 'é': 'e', 'ê': 'e', 'ë': 'e',
'ì': 'i', 'í': 'i', 'î': 'i', 'ï': 'i',
'ò': 'o', 'ó': 'o', 'ô': 'o', 'õ': 'o', 'ö': 'o', 'ø': 'o',
'ù': 'u', 'ú': 'u', 'û': 'u', 'ü': 'u',
'ÿ': 'y',
'ç': 'c',
'ñ': 'n',
'ß': 'ss'
}
result = []
for char in text:
if char not in string.ascii_letters:
replacement = mapping.get(char.lower())
if replacement:
result.append(replacement)
else:
result.append(char)
else:
result.append(char)
return ''.join(result)
Anotamos aproximadamente 10.000 nomes não estudantes do conjunto de dados usando a API GPT-4 , pois os nomes dos alunos são o tipo de etiqueta mais comum. Esperamos aprimorar a precisão do modelo na previsão desse tipo específico de etiqueta.
Tentei ajustar o modelo Mistral-7b em rótulos relacionados a nomes, mas as pontuações no LB mostraram uma diminuição significativa.
Portanto, tentei usar Mistral-7b para aprendizado de poucos anos para determinar se o conteúdo previsto para ser o name student é realmente um nome. (Aqui não podemos esperar que o modelo distingue se é o nome de um aluno ou não, mas apenas para excluir previsões que claramente não são nomes).
O prompt está abaixo, fazendo isso produzindo uma pequena melhoria no LB, menos de 0,001.
f"I'll give you a name, and you need to tell me if it's a normal person name, cited name or even not a name. Do not consider other factors.nExample:n- Is Matt Johnson a normal person name? Answer: Yesn- Is Johnson. T a normal person name? Answer: No, this is likely a cited name.n- Is Andsgjdu a normal person name? Answer: No, it is even not a name.nNow the question is:n- Is {name} a normal person name? Answer:"
| Modelos | LIBRA | PB | Escolher |
|---|---|---|---|
Seven single models that exceed 0.974 on the LB | 0.978 | 0.964 | Sim |
Two 4-fold cross-validation models, with LB scores of 0.977 and 0.974 respectively. | 0.978 | 0.961 | Sim |
Three single models with ensemble LB score of 0.979, plus one set of 4-fold cross-validation models with an LB score of 0.977. (Use vote ensemble) | 0.979 | 0.963 | Sim |
Two single models ensemble | 0.972 | 0.967 | Não |
Four single models ensemble | 0.979 | 0.967 | Não |
Lb 0,978 PB 0,964
Lb 0,978 PB 0,961
Lb 0,979 PB 0,963
Graças aos meus companheiros de equipe, nos conhecemos através de Kaggle há mais de meio ano. Sinto -me afortunado por poder aprender e progredir junto com todos vocês. @rdxsun, @bianshengtao, @xuanmingzhang777, @tonyarobertson.
Ir além é tão errado quanto não ir longe o suficiente. - Confucius