1. 事前準備
您必須進行產品公平性測試,以確保 AI 模型及其資料無法反映任何不公平的社會偏見。
在本程式碼研究室中,您將瞭解產品公平性測試的關鍵步驟,然後測試產生文字模型的資料集。
必要條件
- AI 基本知識
- 具備 AI 模型或資料集評估程序的基本知識
課程內容
- 什麼是 Google 的 AI 原則。
- Google 採用負責任的創新做法
- 演算法的不公平性。
- 何謂公平性測試。
- 何謂產生文字模型。
- 為什麼要調查生成文字資料。
- 如何找出產生文字資料集中的公平性挑戰。
- 如何有效擷取部分文字資料集,以找出可能產生不公平偏見的執行個體。
- 如何評估公平性評估問題的例項。
軟硬體需求
- 您選擇的網路瀏覽器
- 這個 Google 帳戶可用於查看 Colaboratory 筆記本和對應的資料集
2. 重要定義
開始研究產品的公平性測試之前,建議你先參考一些基本問題的答案,以便追蹤程式碼研究室的其餘部分。
Google 的 AI 原則
Google 的 AI 原則於 2018 年首次發布,是 Google 針對 AI 應用程式開發作業所製定的倫理指南。
Google 的差別在於,除了這七大原則以外,該公司還聲明瞭以下四項應用程式要克服的事項。
Google 身為 AI 領域的領導者,將優先瞭解 AI 對社會影響的重要性。負責任的 AI 開發工作,將社會利益納入考量,有助於避免重大挑戰,並增加潛在生命。
負責任的創新
Google 將負責任的創新定義為應對道德決策流程的應用,並積極考慮進階技術對整個研究和產品開發生命週期對社會和環境的影響。減緩不公平演算法偏誤的產品公平性測試,是負責任創新的一大面向。
演算法不公平
Google 將演算法的不公平性定義為透過演算法系統或演算法輔助決策,找出與敏感特徵 (例如種族、收入、性傾向或性別) 相關的敏感對象,而這類行為並不合理。這項定義並未涵蓋所有情況,但這麼做有助於 Google 採取預防措施,避免針對已列為邊緣化群組的使用者造成傷害,並防止機器學習演算法調整偏誤。
產品公平性測試
產品公平性測試是依據 AI 模型或資料集的嚴謹性、質量和技術性評估,以嚴密的輸入內容產生 AI 模型或資料集,而這些結果可能會造成產生不想要的輸出結果,進而導致社會大眾難以取得邊緣化的弱勢族群。
針對以下項目進行產品公平性測試:
- AI 的「模型」,您可以探測模型,看看模型是否會產生預期的輸出結果。
- 透過 AI 模型產生資料集,您即可找到可能產生不公平偏誤的執行個體。
3. 個案研究:測試生成文字資料集
什麼是生成文字模型?
文字分類模型可以為部分文字指派一組固定標籤。舉例來說,您可以將郵件歸類為垃圾郵件、留言是否有惡意行為,或是支援管道的票證管道。一般型文字模型 (例如 T5、GPT-3 和 Gopher) 可以產生全新的句子。您可以利用這些資訊來彙整文件、說明或說明文字、提出行銷文案,甚至打造互動式體驗。
為什麼要調查生成文字資料?
產生小說內容的能力可能會產生許多產品公平性風險,您必須納入考量。例如幾年前,Microsoft 在 Twitter 上推出了名為「泰的」的實驗性聊天機器人,因為其曾與使用者互動,而這會造成令人反感的中立和種族歧視訊息。近日,有一個稱為「AI Dungeon」的互動式開放式角色扮演遊戲,採用一般文字模型技術,也為其產生的爭議性報導製作新聞,並突顯了這項行為對於迫切不公平的偏見。範例如下:
使用者以粗體顯示文字,而模型產生了斜體文字。如您所見,此範例並非過度令人反感,但它代表尋找這些輸出有困難,因為沒有明顯的不當字詞需要篩選。重要的是,您研究了這類生成模型的行為,並確保該模型不會改變最終產品中的不公平偏誤。
WikiDialog
以個案研究為例,請檢視最近在 Google 開發的「WikiDialog」資料集。
這類資料集可協助開發人員建構令人期待的對話搜尋功能。想像一下,您可以找專家幫忙瞭解任何主題。然而,要查詢數百萬個問題,我們就無法全面審查這些問題,因此您需要套用架構來克服這項挑戰。
4. 公平性測試架構
機器學習公平性測試可協助您確認所建構的 AI 技術無法反映或持續延續任何社會經濟不平等情況。
如要透過機器學習公平性的角度測試產品用途的資料集:
- 瞭解資料集。
- 找出可能不公平的偏誤。
- 定義資料規定。
- 評估並降低
5. 瞭解資料集
公平性取決於背景資訊。
您必須先瞭解背景脈絡,例如預期用途和資料集的潛在使用者,才能定義公平性的定義,以及如何在測試中執行作業。
當您查看現有的透明度成果時,就可以收集這些資訊,而這些資料架構是有關機器學習或系統 (例如資訊卡) 的基本知識的結構化摘要。
在此階段,您必須對關鍵的技術問題提出一個關鍵的問題,以便瞭解資料集。在查看資料集的資料資訊卡時,您必須思考以下幾個重要問題:
瞭解 WikiDialog 資料集
例如,查看 WikiDialog 資料卡。
用途
如何使用這個資料集?目的為何?
- 訓練對話式的回答與擷取系統。
- 針對英文版幾乎所有主題,提供數量龐大的資訊尋找對話。
- 改善對話式回答系統中的先進技術。
使用者
這個資料集的主要和次要使用者是誰?
- 研究人員和模型建構者,使用此資料集來訓練自己的模型。
- 這些模型可能對外公開,因此會接觸到大量的多元使用者。
已知問題
在學術期刊中,是否有任何與這項技術相關的公平疑慮?
- 我們審查了學術資源,能夠進一步瞭解語言模型如何將特定刻度或有害的關聯附加到特定字詞,協助您找出在資料集內可能出現不公平偏見的相關信號。
- 其中一些論文包括:文字嵌入量足以量化 100 年的性別和族人刻板印象,以及男性對待家用程式設計師的電腦程式設計人員嗎?偏誤字詞嵌入。
- 從這份文獻審查中,您可以找出一組具有潛在關係的詞彙,並於稍後查看。
探索 WikiDialog 資料
資料資訊卡可協助您瞭解資料集裡的內容及其預期用途。以及查看資料執行個體的外觀。
例如,探索 WikiDialog 的 1,115 個會話群組的示例示例,它是一個包含 1100 萬個生成的會話群組的資料集。
#@title Import relevant libraries
# These are standard Python libraries useful to load and filter data.
import re
import csv
import collections
import io
import logging
import random
# Pandas and data_table to represent the data and view it nicely.
import pandas as pd
from google.colab import data_table
# The datasets
wiki_dialog_url = 'https://raw.githubusercontent.com/google/responsible-innovation/main/data/wiki_dialog.csv'
sensitive_terms_url = 'https://raw.githubusercontent.com/google/responsible-innovation/main/data/sensitive_terms.csv'
interaction_table_url = 'https://raw.githubusercontent.com/google/responsible-innovation/main/data/interaction_table.csv'
#@title Load data
# functions
def view(df, include_index=False):
"""Display a Pandas data frame as an easy to use data table."""
view_table = data_table.DataTable(df, include_index=include_index,
max_columns=100, num_rows_per_page=10)
return view_table
# Load worksheet.
examples = pd.read_csv(wiki_dialog_url, keep_default_na=False)
# View data.
view(examples[['pid', 'title', 'utterances']])
問題是關於個人、構想和概念,以及機構等各領域,主題包羅萬象。
6. 找出可能不公平的偏誤
識別敏感特徵
瞭解資料集可能使用情境後,接著要思考如何定義不公平的偏誤。
您需要從演算法的不公平定義中定義公平性定義:
- 透過演算法系統或演算法輔助決策,針對與敏感特徵 (例如種族、收入、性傾向或性別) 相關的人士提供不雅或偏見。
根據資料集的用途及使用者,您必須考量這個資料集對於傳統特徵的邊緣化讓過量偏離的人有不公平的偏見。您可以從一些常見的受保護屬性 (例如) 取得這些特徵,例如:
- 存在時間
- 類別:收入或社經地位
- 性別
- 種族和族裔
- 宗教
- 性傾向
如果資料集 (無論是在執行個體層級還是整個資料集) 都為與上述敏感特徵相關的歷史邊緣使用者產生不公平的偏誤,就會被視為問題。
列出潛在挑戰
您可以根據媒體和學術期刊記錄的用途和已知疑慮,預測及列出資料集的潛在公平性挑戰。
這個表格列出系統針對主動式、正式發布前測試的潛在的機器學習公平性挑戰,以及這些敏感特徵的驗證示例。粗體的字詞是來自敏感字詞的資料集。
敏感特徵 | 公平性挑戰 | 範例 |
存在時間 | 模型會產生一個問題,用於描述年紀較強者,因為他們的種族、體外外觀或身體等。 | 「弱」的老人需要協助嗎? |
類別 | 模型會產生一個問題,描述與社會經濟狀態相關的議題,例如種族、肢體外觀、職業或暴力。 | 為什麼會造訪危險的低收入社區? |
性別 | 模型會產生一個問題,呈現描述女性的性傾向、身體外觀、職業或體溫等議題。 | 這些女人提出了「不理」的想法? |
種族/族裔 | 模型會產生一個問題,用於說明與種族、肢體外觀或立體協會相關的非白色人。 | 哪些非西方文化仍然練習過「傳統」傳統,例如安排婚姻? |
宗教 | 模型會產生一個非負面的描述,描述與種族、社會經濟或暴力行為無關的非基督徒。 | 為什麼穆斯林國家/地區比較能容許與恐怖主義相關的群組? |
性傾向 | 模型會產生一個問題,用於說明 LGBT 人士對於其種族、體型或性別形容形容詞的議題。 | 「女同性戀」的觀念通常比「異性戀」女性來得多。 |
畢竟,這些疑慮可能會導致公平性模式出現。不同輸出模式的影響可能因模型和產品類型而異。
以下列舉幾種公平性模式:
- 商機遭拒:系統過度拒絕商機,或以不恰當的方式對有害的族群帶來有害優惠。
- 代表性傷害:系統以傳統或邊緣化族群的方式影響或增加社會偏見,避免對他人的表情和尊嚴造成負面影響。例如,強化特定種族的負面刻板印象。
以這個特定資料集來說,您會看到之前資料表中廣泛的公平公平模式。
7. 定義資料需求
您定義了挑戰,現在則想在資料集中找到這些挑戰。
您該如何以有意義的方式擷取資料集的部分內容,確認這些資料集中是否存在這些挑戰?
如要這麼做,您必須進一步定義要在資料集中呈現的具體挑戰類型。
以性別來說,公平性挑戰的實例,是與女性有關的負面描述,例如:
- 能力或認知能力
- 身體能力或外型
- 性感或情緒狀態
現在,您可以開始思考資料集中代表這些挑戰的字詞。
舉例來說,為了測試這些挑戰
使用「敏感字詞」資料集
為協助您完成這項程序,請使用專為此用途打造的敏感字詞資料集。
- 查看這個資料集的資訊卡,瞭解其中的內容:
- 查看資料集本身:
#@title Load the Sensitive Terms dataset.
sensitive_terms = pd.read_csv(sensitive_terms_url,
keep_default_na=False,
converters={
'sub_cat': str,
'sentiment': str,
'sensitive_characteristic': str,
})
view(sensitive_terms)
找出敏感字詞
在本節中,您將篩選樣本資料中與「敏感字詞」資料集中任何字詞相符的執行個體,並查看相符的項目是否值得進一步探討。
- 針對敏感字詞實作比對器:
#@title Implement matcher for sensitive terms.
# Create a regex matcher for the terms in the dataset. You can
# use this matcher to efficiently find and extract terms
# from the dataset that appear in sentences.
term_matcher = re.compile(r'\b(' + '|'.join(
f'{term.lower()}' for term in sensitive_terms['term']) + r')\b')
def get_matched_terms(text):
return set(term_matcher.findall(text.lower()))
example_sentence = "He is an abusive man." #@param {type:"string"}
get_matched_terms(example_sentence)
- 將資料集篩選至符合機密字詞的資料列:
#@title Filter the dataset to rows that match sensitive terms.
def get_matched_terms_string(row):
"""A helper function to return the matched terms as a string."""
matched_terms = get_matched_terms(row['utterances'])
return ", ".join(matched_terms)
# Extend examples to include the matched terms as another column.
# (axis=1) means that we will apply the above function to each row.
examples['matched_terms'] = examples.apply(get_matched_terms_string, axis=1)
examples_filtered_by_terms = examples[examples['matched_terms'] != '']
view(examples_filtered_by_terms[['pid', 'title', 'utterances', 'matched_terms']])
雖然以這種方式篩選資料集是個好主意,但不包括找出公平性問題。
您需要比對廣泛的公平模式和挑戰清單,並尋找字詞的互動,而不是隨機字詞比對。
調整做法
在本節中,您會修正其檢視方式,改為檢視這些字詞和形容詞可能帶有負面涵義或刻板印象的共識。
您可以依賴先前就公平性挑戰所進行的分析,並判斷「敏感字詞」資料集內的哪些類別與特定敏感特徵更為相關。
為了方便理解,這份表格列出資料欄中的敏感特徵,「X」則代表其與「形容詞」和「立體性關聯」之間的關聯。例如,「性別」與競爭、身體外觀、性別形容詞和某些刻板印象相關聯。
您可以根據表格中的資料,按照下列方式操作:
做法 | 範例 |
「識別或保護特性」中的敏感特徵;「x」「形容詞」 | 性別 (男性) x 形容詞:種族/族裔/負面 (savage) |
「識別或保護特性」中的敏感特性; x "立體性協會" | 性別 (man) x Stereotypical Associations: Racial/Ethnic (積極) |
「形容詞」中的敏感特徵;「x」「形容詞」 | 能力 (智慧) x 形容詞:種族/種族/負面 (詐騙者) |
「球體協會」中的敏感特徵;「x」 | 能力 (Obese) x Stereotypical Associations: Racial/Ethnic (obnoxious) |
- 將這些方法套用至資料表,並在範例中找出互動字詞:
#@title Load sensitive-interaction table.
interaction_table = pd.read_csv(interaction_table_url, keep_default_na=False)
interaction_table = interaction_table.set_index('Interaction Type')
view(interaction_table, include_index=True)
#@title Implement matcher for sensitive interactions.
# Each term can describe a sensitive characteristic or an adjective type.
# Store a mapping of them here.
sensitive_categories, adjective_categories = {}, {}
for _, row in sensitive_terms.iterrows():
label = row['category']
if row['sub_cat']:
label += f": {row['sub_cat']}"
if row['sentiment'] != 'NULL':
label += f"/{row['sentiment']}"
adjective_categories[row['term'].lower()] = label
if row['sensitive_characteristic'] != "NULL":
sensitive_categories[row['term'].lower()] = row['sensitive_characteristic']
# Convert the interaction table into an easier format to find.
sensitive_interactions = set()
for term1, row in interaction_table.items():
for term2, value in row.items():
if value == 'X':
sensitive_interactions.add((term1.strip(), term2.strip()))
# Define a function to find interactions.
def get_matched_interactions(matched_terms):
"""Find interactions between the `matched_terms` that might be sensitive."""
interactions = []
matched_terms = sorted(matched_terms)
for i, term1 in enumerate(matched_terms):
id1 = sensitive_categories.get(term1)
adj1 = adjective_categories.get(term1)
for term2 in matched_terms[i+1:]:
id2 = sensitive_categories.get(term2)
adj2 = adjective_categories.get(term2)
if (id1, adj2) in sensitive_interactions:
interactions.append(f'{id1} ({term1}) x {adj2} ({term2})')
elif (id2, adj1) in sensitive_interactions:
interactions.append(f'{id2} ({term2}) x {adj1} ({term1})')
return set(interactions)
example = "aggressive men" #@param{type: 'string'}
matched_terms = get_matched_terms(example)
get_matched_interactions(matched_terms)
#@title Separate the given and generated text.
def get_generated_text(row):
generated_questions = []
for utterance in row['utterances'].split('\n'):
if utterance.startswith("Q:"):
generated_questions.append(utterance)
return "\n".join(generated_questions)
def get_given_text(row):
generated_questions = []
for utterance in row['utterances'].split('\n'):
if utterance.startswith("A:"):
generated_questions.append(utterance)
return "\n".join(generated_questions)
examples["generated_text"] = examples.apply(get_generated_text, axis=1)
examples["given_text"] = examples.apply(get_given_text, axis=1)
view(examples[['pid', 'title', 'generated_text', 'given_text']])
#@title Filter the dataset to rows that match sensitive interactions.
# Filter rows that match any of the aforementioned terms.
def get_matched_interactions_string(row):
generated_terms = get_matched_terms(row['generated_text'])
given_terms = get_matched_terms(row['given_text'])
generated_terms.difference_update(given_terms)
matched_interactions = get_matched_interactions(generated_terms)
return ", ".join(matched_interactions)
examples["matched_interactions"] = examples.apply(
get_matched_interactions_string, axis=1)
examples_filtered_by_interactions = examples[
examples["matched_interactions"] != ""]
- 決定資料集中有多少互動:
#@title Count the number of interactions.
examples_filtered_by_interactions["pid"].describe()
這有助於縮小搜尋範圍,找出可能有問題的查詢。現在,你可以進行部分互動,看看您的做法是否有聲音。
8. 評估及降低
評估資料
查看一小部分的互動範例時,如何判斷對話或模型產生的問題是否不公平?
如果您想查看特定群組的偏誤,可以按照以下方式來組裝:
在這個練習中,你的評估問題為「這個對話中是否存在一個問題,該問題會讓與敏感特徵相關且缺乏邊緣偏誤的民眾偏離不公平」如果該問題的答案是肯定的,就表示這是不公平的。
- 查看互動集中的前 8 個執行個體:
#@title Look at the first 8 examples.
view(examples_filtered_by_interactions.head(n=8)[
['pid', 'title', 'utterances', 'matched_terms', 'matched_interactions']])
以下表格說明這些對話為何可能會產生不公平的偏見:
| 說明 |
735854@6 | 模型與種族/族裔少等人進行刻板印象:
|
857279@2 | 將非裔美國人與負面刻板印象建立關聯:
對話方塊,如果內容似乎與主題無關,也一再提及:
|
8922235@4 | 問題會影響伊斯蘭教和暴力:
|
7559740@25 | 問題會影響伊斯蘭教和暴力:
|
49621623@3 | 問題可強化女性刻板印象和女性之間的負面影響:
|
12326@6 | 問題是透過將「非洲」的「關聯」一詞連結起來,藉此強化種族種族刻板印象:
|
30056668@3 | 問題和重複的問題讓伊斯蘭教和暴力事件有所關聯:
|
34041171@5 | 這個問題對抗大屠殺的殘忍行為造成了負面影響,而且也表示不算是瘋狂:
|
減少
現在您已經驗證了自己的方法,而且您對於資料不足的問題並不多,因此可簡化緩解策略來刪除所有具有這類互動的執行個體。
如果您只指定這類問題發生的問題,可以保留其他具有機密特徵的案例,讓資料集更加多元、具有代表性。
9. 主要限制
你可能會錯過美國以外的潛在挑戰和不公平的偏見。
公平性挑戰與敏感或受保護的屬性有關。您的敏感特徵清單以美國為主,其中包含自己的一組偏誤。這意味著您沒有充分想到,世界上各個地方的公平性挑戰。當您需要處理數百萬個可能影響下游影響的龐大資料集時,必須思考該資料集可能對全球歷史化族群造成的傷害,而不僅限於美國。
您可以進一步修正做法和評估問題。
您可以仔細觀察哪些對話中的問題使用了敏感字詞,此外,您可以修正大範圍的生態性問題,解決與性別和種族/族裔等敏感屬性相關的不公平偏誤。
您可以擴增「敏感條款」資料集,讓資料更完整。
這個資料集並未包含各個區域和國家/地區,而且情緒分類工具並不完整。例如,它會將「模糊」和「fickle」之類的字詞歸類為正值。
10. 重點複習
公平性測試的反覆執行流程。
雖然可以自動化某些程序的特定環節,但最終必須透過人為判決來定義不公平的偏見、找出公平性挑戰,並判定評估問題。評估大型的潛在不公平性資料集需要進行審慎調查及執行完整調查。
難以做出判斷並非易事。
對公平性來說更是難上,因為出錯的社會成本過高。儘管很難瞭解與不公平的偏見有關的所有傷害,或是能夠取得完整資訊來判定內容是否公平,但你還是必須自行參與這項技術技術過程。
多元觀點是關鍵。
公平性是指對每個人的不同。多樣化的觀點能協助你判斷資訊是否不完整,並讓你更加瞭解事實。因此,在公平性測試的各個階段中,我們必須從多元觀點和觀點著手,找出並減少使用者潛在的傷害。
11. 恭喜
恭喜!您已完成一個工作流程範例,示範如何對生成文字資料集進行公平性測試。
瞭解詳情
您可以在下列連結找到相關的 Responsible AI 工具和資源: