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
En primer lugar, gracias a Kaggle y THE LEARNING AGENCY LAB por organizar esta competencia, y gracias a todos en el equipo por sus esfuerzos. Aunque el resultado no fue perfecto, todavía aprendimos mucho y continuaremos avanzando. ¡Felicitaciones a todos los ganadores!
Aquí está el GitHub Repo para esta competencia, donde puede encontrar casi todos los códigos: https://github.com/lizhecheng02/kaggle-pii_data_detection
AWP (Adversarial Weight Perturbation) Mejore la robustez del modelo mediante el uso de una clase AWP personalizada y escriba propia CustomTrainer . Este es un método que nuestro equipo a menudo usa en las competiciones de PNL, y tiene algunos buenos resultados. (El código correspondiente se puede encontrar en mi github en el directorio models ).
Wandb Sweep Con esta herramienta, podemos probar varias combinaciones de diferentes hiperparámetros para seleccionar los que producen los mejores resultados de ajuste. (El código correspondiente se puede encontrar en mi github en el directorio models ).
Replace nn with | in all documentsEn este caso, entrenamos un conjunto de modelos con puntajes de 4 veces y validación cruzada y LB de 0.977. Aunque hubo cierta mejora en el LB, los resultados no mostraron mejoras en el PB.
n aparición en direcciones, que deben etiquetarse con la etiqueta I.Dr. con la etiqueta B. ( Sin mejoras significativas ) 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 el método de tomar el promedio de probabilidades para obtener el resultado final. Dado que el recuerdo es más importante que la precisión en esta competencia, establecí el umbral en 0.0 para evitar perderse cualquier posible retiro correcto.
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 EnsembleEn nuestra presentación final, conjunamos 7 modelos, y aceptamos una etiqueta como la predicción correcta si al menos dos de los modelos predijeron esa misma etiqueta.
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 Usando T4*2 GPU duplica la velocidad de inferencia en comparación con una sola GPU. Para ensamblar 8 modelos, el máximo max_length es 896 ; Si los modelos Ensemble 7, el max_length se puede establecer en 1024 , que es un valor más ideal. (El código correspondiente se puede encontrar en mi GitHub en el directorio submissions ).
Convert Non-English Characters (reduzca el LB) 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)
Hemos anotado aproximadamente 10,000 nombres no estudiantes del conjunto de datos utilizando la API GPT-4 , ya que los nombres de los estudiantes son el tipo de etiqueta más común. Esperamos mejorar la precisión del modelo para predecir este tipo particular de etiqueta.
Intenté ajustar el modelo Mistral-7b en las etiquetas relacionadas con el nombre, pero los puntajes en el LB mostraron una disminución significativa.
Por lo tanto, intenté usar Mistral-7b para un aprendizaje de pocos disparos para determinar si el contenido previsto que sea el name student de la etiqueta es en realidad un nombre. (Aquí no podemos esperar que el modelo distinga si es el nombre de un estudiante o no, sino solo para excluir las predicciones que claramente no son nombres).
El aviso está en el siguiente, haciendo esto produjo una mejora muy ligera en el 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 | Lb | PB | Elegir |
|---|---|---|---|
Seven single models that exceed 0.974 on the LB | 0.978 | 0.964 | Sí |
Two 4-fold cross-validation models, with LB scores of 0.977 and 0.974 respectively. | 0.978 | 0.961 | Sí |
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 | Sí |
Two single models ensemble | 0.972 | 0.967 | No |
Four single models ensemble | 0.979 | 0.967 | No |
LB 0.978 PB 0.964
LB 0.978 PB 0.961
LB 0.979 PB 0.963
Gracias a mis compañeros de equipo, nos conocemos a través de Kaggle por más de medio año. Me siento afortunado de poder aprender y progresar junto con todos ustedes. @rdxsun, @bianshengtao, @xuanmingzhang777, @tonyarobertson.
Ir más allá es tan equivocado como no ir lo suficientemente lejos. --Confucio