在機器學習流程中,資料探索和向量化是至關重要的步驟。資料探索旨在理解資料的結構、趨勢和潛在問題,為後續的模型選擇和訓練提供依據。向量化則是將不同型別的資料轉換為機器學習模型可處理的數值向量形式。透過計算特徵的統計摘要,如直方圖,可以初步瞭解資料分佈。更進一步,可以利用聚類別等無監督學習方法揭示資料中的隱含結構,並提高資料探索的效率。針對不同資料型別,需要採用不同的向量化策略。
表格資料通常包含數值特徵和類別特徵,需要分別進行標準化和獨熱編碼處理。日期時間特徵則需要提取年、月、日、時等數值資訊。文字資料的向量化方法包括詞袋模型、TF-IDF 和詞向量等。影像資料可以直接使用畫素值,或利用預訓練的卷積神經網路模型提取更具語義資訊的向量表示。在實際應用中,遷移學習可以利用預訓練模型的知識提升新任務的效能,尤其在資料量有限的情況下效果顯著。高維資料的向量表示可以使用 UMAP 等降維技術進行視覺化,以便更好地理解資料結構和分佈。
探索資料集的趨勢與結構
在確認資料集的品質後,下一步是深入探索資料,以瞭解其內在結構和趨勢。這不僅有助於評估資料品質,還能為後續的建模策略提供依據。
標籤與資料趨勢分析
識別資料集中的趨勢,不僅關乎資料品質,更是站在模型的角度,預測它將捕捉到的結構。我們將透過將資料分成不同的叢集,並嘗試提取每個叢集中的共同特徵來實作這一點。
統計摘要
在開始探索資料集時,計算每個特徵的統計摘要是一個良好的開端。這有助於瞭解資料集中的特徵,並識別出任何容易區分類別的方法。
例項:計算問題長度的直方圖
以下是一個使用pandas繪製問題長度直方圖的例子,區分高分和低分問題:
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
# 篩選條件
high_score = df["Score"] > df["Score"].median()
normal_length = df["text_len"] < 2000
# 繪製直方圖
ax = df[df["is_question"] & high_score & normal_length]["text_len"].hist(
bins=60,
density=True,
histtype="step",
color="orange",
linewidth=3,
grid=False,
figsize=(16, 10),
)
df[df["is_question"] & ~high_score & normal_length]["text_len"].hist(
bins=60,
density=True,
histtype="step",
color="purple",
linewidth=3,
grid=False,
)
# 新增圖例
handles = [Rectangle((0, 0), 1, 1, color=c, ec="k") for c in ["orange", "purple"]]
labels = ["High score", "Low score"]
plt.legend(handles, labels)
ax.set_xlabel("Sentence length (characters)")
ax.set_ylabel("Percentage of sentences")
內容解密:
- 使用
df["Score"] > df["Score"].median()將問題分為高分和低分兩組。 - 使用
df["text_len"] < 2000篩選掉過長的問題,以簡化視覺化。 - 分別繪製高分和低分問題的文字長度直方圖,觀察其分佈差異。
- 高分問題的文字長度在某些區間(如800字元附近)略長於低分問題,這可能是模型預測問題得分的一個有用特徵。
高效探索與標註資料
僅僅依靠描述性統計和直方圖是有限的。為了更好地理解資料,我們需要花時間檢視個別資料點。然而,隨機瀏覽資料集效率很低。本文將介紹如何透過聚類別等方法提高探索效率。
聚類別的作用
聚類別是一種無監督學習方法,透過將相似的資料點分組到一起,幫助我們識別資料集中的結構。由於聚類別依賴於計算資料點之間的距離,因此資料的數值表示方式對聚類別結果有很大影響。
圖表翻譯:
此圖示展示瞭如何透過聚類別演算法將資料集分成三個不同的叢集。叢集內部的資料點比不同叢集之間的資料點更相似。
在探索資料集時,我們需要關注以下幾點:
- 資料集可以分為多少個叢集?
- 每個叢集之間有何不同?
透過這些步驟,我們可以更深入地瞭解資料集的內在結構,為後續的建模和分析奠定基礎。
資料向量化的重要性與實作方法
在機器學習(Machine Learning, ML)領域中,資料的品質與表示方式對於模型的表現至關重要。機器學習演算法通常需要將原始資料轉換為向量形式,以便進行後續的處理和分析。這種將資料轉換為向量表示的過程,被稱為向量化(Vectorizing)。
為何需要向量化?
機器學習模型,尤其是深度學習模型,需要輸入資料以數值向量的形式呈現。然而,現實世界中的資料往往以多種形式存在,例如文字、表格資料、影像等。為了使這些資料能夠被模型有效處理,我們需要將它們轉換為適當的向量表示。
向量化的方法
1. 表格資料的向量化
對於包含類別特徵(Categorical Features)和連續特徵(Continuous Features)的表格資料,一種常見的向量化方法是將每個特徵的向量表示串聯起來。
- 連續特徵應進行標準化處理,以避免某些特徵因尺度較大而主導模型的訓練。通常的做法是將特徵進行標準化,使其均值為0,方差為1。
- 類別特徵則可以採用獨熱編碼(One-Hot Encoding)。例如,對於顏色這個特徵,如果可能的取值有紅、藍、綠三種,那麼紅色可以編碼為
[1, 0, 0],藍色可以編碼為[0, 1, 0]。這種編碼方式避免了類別之間的人為排序問題。
2. 日期特徵的處理
對於日期時間類別特徵,可以提取出年、月、日、時等數值特徵,以供模型使用。
實作範例:表格資料的向量化
以下是一個實際的範例,展示如何對包含標籤、評論數和建立日期的表格資料進行向量化處理。
import pandas as pd
# 假設tabular_df是我們的DataFrame
# 對數值欄位進行標準化
def get_norm(df, col):
return (df[col] - df[col].mean()) / df[col].std()
tabular_df["NormComment"] = get_norm(tabular_df, "CommentCount")
tabular_df["NormScore"] = get_norm(tabular_df, "Score")
# 將日期轉換為pandas datetime格式
tabular_df["date"] = pd.to_datetime(tabular_df["CreationDate"])
# 從datetime物件中提取有意義的特徵
tabular_df["year"] = tabular_df["date"].dt.year
tabular_df["month"] = tabular_df["date"].dt.month
tabular_df["day"] = tabular_df["date"].dt.day
tabular_df["hour"] = tabular_df["date"].dt.hour
# 對標籤進行獨熱編碼
tags = tabular_df["Tags"]
clean_tags = tags.str.split("><").apply(lambda x: [a.strip("<").strip(">") for a in x])
# 使用pandas的get_dummies進行獨熱編碼,並篩選出現次數超過500的標籤
tag_columns = pd.get_dummies(clean_tags.apply(pd.Series).stack()).sum(level=0)
all_tags = tag_columns.astype(bool).sum(axis=0).sort_values(ascending=False)
top_tags = all_tags[all_tags > 500]
top_tag_columns = tag_columns[top_tags.index]
# 將處理好的標籤特徵與原始DataFrame合併
final = pd.concat([tabular_df, top_tag_columns], axis=1)
# 篩選出向量化後的特徵
col_to_keep = ["year", "month", "day", "hour", "NormComment", "NormScore"] + list(top_tags.index)
final_features = final[col_to_keep]
內容解密:
- 標準化數值欄位:使用
get_norm函式對CommentCount和Score進行標準化,使其均值為0,方差為1,有助於模型訓練。 - 日期時間特徵提取:將
CreationDate轉換為datetime格式,並提取年、月、日、時等特徵,供模型使用。 - 獨熱編碼處理標籤:對
Tags進行獨熱編碼,並篩選出出現次數超過500的標籤,以避免維度過高。 - 合併特徵:將處理好的標籤特徵與其他數值特徵合併,形成最終的向量化特徵集合。
圖表呈現向量化流程
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title 資料探索與向量化技術實踐
package "資料探索與向量化" {
package "資料探索" {
component [統計摘要] as stat
component [趨勢分析] as trend
component [聚類探索] as cluster
}
package "向量化方法" {
component [數值標準化] as norm
component [獨熱編碼] as onehot
component [TF-IDF] as tfidf
}
package "進階技術" {
component [詞向量] as word2vec
component [遷移學習] as transfer
component [UMAP 降維] as umap
}
}
stat --> trend : 分佈分析
trend --> cluster : 結構發現
norm --> onehot : 特徵轉換
onehot --> tfidf : 文字向量
word2vec --> transfer : 預訓練嵌入
transfer --> umap : 高維視覺化
note right of stat : 直方圖\n特徵分佈
note right of transfer : CNN 特徵提取\n語義向量
@enduml
圖表翻譯: 此圖示呈現了將原始資料轉換為向量化資料的流程。首先從原始資料中提取相關特徵,接著對數值特徵進行標準化處理,對類別特徵進行獨熱編碼,並提取日期中的有用資訊。最後,將這些處理好的特徵合併,形成可供機器學習模型使用的向量化資料。
向量化與資料外洩(VECTORIZATION AND DATA LEAKAGE)
在將資料輸入模型之前,向量化是至關重要的步驟。通常,用於視覺化的資料向量化技術與輸入模型的向量化技術相同,但有一個重要的區別。當向量化資料以輸入模型時,應對訓練資料進行向量化並儲存所使用的引數。然後,對驗證集和測試集使用相同的引數。
資料標準化與外洩
在標準化資料時,例如計算平均值和標準差,只應使用訓練集的統計資料,並使用相同的值來標準化驗證資料和生產環境中的推斷資料。如果使用驗證集和訓練集進行標準化,或者決定哪些類別保留在獨熱編碼中,就會導致資料外洩,因為會利用訓練集以外的資訊來建立訓練特徵。這樣會人為地提高模型的效能,但在生產環境中表現會更差。
不同型別的資料向量化
不同的資料型別需要不同的向量化方法。特別是,文字資料通常需要更具創意的方法。
文字資料
向量化文字最簡單的方法是使用計數向量(count vector),這相當於詞級別的獨熱編碼。首先,建立一個由資料集中唯一詞彙組成的詞彙表。將詞彙表中的每個詞與一個索引(從0到詞彙表的大小)相關聯。然後,可以透過一個與詞彙表長度相同的列表來表示每個句子或段落。對於每個句子,索引處的數字表示給定句子中相關詞的出現次數。
這種方法忽略了句子中詞的順序,因此被稱為詞袋(bag of words)。圖4-5顯示了兩個句子及其詞袋錶示。兩個句子都被轉換為向量,其中包含有關單詞在句子中出現次數的資訊,但不包含單詞在句子中的順序資訊。
# 建立TfidfVectorizer例項
# 我們可以使用CountVectorizer獲得非標準化版本
vectorizer = TfidfVectorizer()
# 將向量器擬合到資料集中的問題
# 傳回向量化文字的陣列
bag_of_words = vectorizer.fit_transform(df[df["is_question"]]["Text"])
#### 內容解密:
此程式碼示範如何使用TfidfVectorizer將文字資料轉換為TF-IDF表示。首先,建立一個TfidfVectorizer例項,然後使用fit_transform方法將向量器擬合到篩選出的問題文字資料,並傳回向量化結果。這種方法能夠捕捉詞語在檔案中的重要性。
近年來,人們開發了多種新穎的文字向量化方法,從2013年的Word2Vec開始,以及最近的方法如fastText。這些向量化技術產生的詞向量試圖學習一種表示,能夠比TF-IDF編碼更好地捕捉概念之間的相似性。它們透過學習哪些詞傾向於出現在大型文字語料函式庫(如維基百科)中的相似上下文中來實作這一點。這種方法是根據分佈假設,該假設主張具有相似分佈的語言專案具有相似的含義。
具體來說,這是透過為每個詞學習一個向量,並訓練模型使用周圍詞的詞向量來預測句子中的缺失詞來實作的。要考慮的鄰近詞的數量稱為視窗大小。在圖4-6中,您可以看到視窗大小為2時此任務的描述。在左側,將目標前後兩個詞的詞向量輸入到一個簡單模型中。然後最佳化這個簡單模型和詞向量的值,使輸出與缺失詞的詞向量相匹配。
import spacy
# 載入大型模型,並停用對我們任務不必要的管道部分
# 這顯著加快了向量化過程
nlp = spacy.load('en_core_web_lg', disable=["parser", "tagger", "ner", "textcat"])
# 然後簡單地取得每個問題的向量
# 預設情況下,傳回的向量是句子中所有向量的平均值
spacy_emb = df[df["is_question"]]["Text"].apply(lambda x: nlp(x).vector)
#### 內容解密:
此程式碼使用spaCy函式庫載入預訓練的詞向量,並將它們應用於問題文字資料。首先,載入大型英語模型en_core_web_lg,並停用不必要的處理元件以加快處理速度。然後,使用apply方法將每個問題文字傳遞給spaCy模型,並提取其向量表示。這種方法能夠獲得語義上有意義的句子向量。
影像資料
影像資料已經是向量化的,因為影像不過是一個多維的數字陣列,通常在機器學習社群中被稱為張量。大多數標準的三通道RGB影像,例如,只是儲存為一個長度等於影像高度(以畫素為單位)乘以寬度再乘以三(對於紅、綠和藍通道)的數字列表。在圖4-7中,您可以看到我們如何將影像表示為表示每個主要顏色強度的數字張量。
雖然我們可以直接使用這種表示,但我們希望我們的張量能夠捕捉更多關於影像語義含義的資訊。為此,我們可以使用類別似於文字的方法,利用大型預訓練神經網路。
在大型分類別資料集(如ImageNet)上訓練的模型,如VGG或Inception,最終會學習非常具表現力的表示,以便進行良好的分類別。這些模型大多遵循類別似的高階結構。輸入是一個影像,該影像透過許多連續的計算層,每個層生成該影像的不同表示。最後,將倒數第二層傳遞給一個函式,該函式為每個類別生成分類別機率。因此,倒數第二層包含足夠對影像進行分類別的表示,這使得它成為其他任務的有用表示。
# 使用預訓練模型提取影像特徵向量的範例程式碼片段
# 假設使用的是Keras API
from tensorflow.keras.applications import VGG16
from tensorflow.keras.preprocessing import image
from tensorflow.keras.applications.vgg16 import preprocess_input
# 載入VGG16模型,不包含頂層分類別層
model = VGG16(weights='imagenet', include_top=False)
# 假設img_path是影像檔案的路徑
img_path = 'path/to/image.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
# 使用模型提取特徵
features = model.predict(x)
#### 內容解密:
此程式碼範例展示如何使用預訓練的VGG16模型提取影像特徵。首先,載入不包含頂層分類別層的VGG16模型。然後,載入一張影像,將其調整為模型所需的輸入尺寸,並將其轉換為陣列格式。最後,使用模型的predict方法提取影像特徵。這種方法能夠獲得對影像內容有意義的向量表示。
影像向量化與遷移學習的實踐應用
在現代人工智慧領域,將影像轉換為具有語義意義的向量表示(vector representation)是許多應用的基礎。藉助預訓練模型(pretrained models),我們可以輕鬆實作這一過程。本文將介紹如何利用 Keras 函式庫中的預訓練模型 VGG16 將影像轉換為向量,並探討遷移學習(transfer learning)、維度縮減(dimensionality reduction)及叢集分析(clustering)在實際資料分析中的應用。
使用預訓練模型進行影像向量化
現代函式庫如 Keras 大大簡化了影像向量化的任務。以下是一個範例函式,用於載入指定資料夾中的影像,並將它們轉換為可用於下游分析的語義向量:
import numpy as np
from keras.preprocessing import image
from keras.models import Model
from keras.applications.vgg16 import VGG16
from keras.applications.vgg16 import preprocess_input
def generate_features(image_paths):
"""
載入影像路徑陣列,傳回每個影像的預訓練特徵。
:param image_paths: 影像路徑陣列
:return: 最後一層啟用值的陣列,以及陣列索引到檔案路徑的對映
"""
images = np.zeros(shape=(len(image_paths), 224, 224, 3))
# 載入預訓練的 VGG16 模型
pretrained_vgg16 = VGG16(weights='imagenet', include_top=True)
# 使用倒數第二層的輸出,藉此利用學習到的特徵
model = Model(inputs=pretrained_vgg16.input,
outputs=pretrained_vgg16.get_layer('fc2').output)
# 將所有資料集載入記憶體(適用於小型資料集)
for i, f in enumerate(image_paths):
img = image.load_img(f, target_size=(224, 224))
x_raw = image.img_to_array(img)
x_expand = np.expand_dims(x_raw, axis=0)
images[i, :, :, :] = x_expand
# 將所有影像傳遞給模型
inputs = preprocess_input(images)
images_features = model.predict(inputs)
return images_features
#### 內容解密:
此函式首先初始化一個零矩陣來儲存影像資料,然後載入預訓練的 VGG16 模型。透過設定 `include_top=True`,我們保留了模型的完整架構,包括最後的分類別層。我們選擇倒數第二層 (`'fc2'`) 的輸出作為影像的向量表示,這樣可以捕捉到影像的高層語義特徵。接著,將所有影像載入並進行預處理後,輸入到模型中,最終獲得每個影像的向量表示。
### 遷移學習:利用預訓練模型提升新任務的表現
遷移學習是指利用在一個資料集或任務上預訓練的模型,來改進在另一個資料集或任務上的表現。這種方法尤其在資料量有限的情況下頗為有效,因為它能夠利用在大規模資料集(如 ImageNet)上學習到的豐富特徵。
遷移學習不僅能提升模型效能,也可能引入額外的偏差。因此,在使用預訓練模型時,需要注意其原始訓練資料可能存在的偏差。
### 維度縮減:視覺化高維資料
獲得向量表示後,我們可以利用維度縮減技術將高維資料投影到二維平面,以便視覺化。常見的維度縮減技術包括 t-SNE 和 UMAP。
#### 使用 UMAP 進行維度縮減和視覺化
```python
import umap
import matplotlib.pyplot as plt
# 對嵌入向量進行 UMAP 維度縮減
umap_emb = umap.UMAP().fit_transform(embeddings)
fig = plt.figure(figsize=(16, 10))
color_map = {
True: '#ff7f0e',
False:'#1f77b4'
}
plt.scatter(umap_emb[:, 0], umap_emb[:, 1],
c=[color_map[x] for x in sent_labels],
s=40, alpha=0.4)
#### 內容解密:
這段程式碼使用 UMAP 對嵌入向量進行維度縮減,並將結果視覺化。透過為不同的標籤分配不同的顏色,我們可以觀察到資料的分佈情況和可能的叢集結構。這有助於我們識別哪些區域可能容易或難以被模型正確分類別。
圖表翻譯:
此圖示展示了經過 UMAP 維度縮減後的資料分佈,其中不同顏色代表不同的標籤(如是否被正確回答的問題)。從圖中可以觀察到一些密集的區域,這些區域可能對應於具有某些共同特徵的資料點。
叢集分析:探索資料中的隱含結構
叢集分析是一種無監督學習方法,用於發現資料中的自然群組。透過將相似的資料點分組,我們可以更好地理解資料的分佈和潛在模式。
結合 UMAP 和叢集分析進行深入探索
藉助 UMAP 和叢集分析,我們可以系統地識別和探索資料中的群組,從而發現潛在的有價值資訊。