利用無監督學習技術中的分群和主成分分析方法,可以有效地對產品進行分群。首先,對原始資料進行預處理,包括處理缺失值、異常值以及無關欄位。接著,進行特徵工程,提取關鍵特徵,例如產品描述文字,並將其轉換為數值向量表示,例如 TF-IDF 向量。然後,應用 K-means 分群演算法將產品分組,並使用肘部法或輪廓分數等方法確定最佳的簇數。最後,利用主成分分析(PCA)技術降低資料維度,並將分群結果在二維或三維空間中視覺化,以便更直觀地理解產品分群的結構和模式。
# 載入必要的函式庫
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
# 載入資料集
data = pd.read_csv('online_retail.csv', encoding='latin1')
# 資料預處理
data = data.dropna(subset=['CustomerID'])
data = data[(data['Quantity'] >= 0) & (data['UnitPrice'] >= 0)]
data['Amount'] = data['Quantity'] * data['UnitPrice']
data = data.groupby('CustomerID')['Amount'].sum().reset_index()
# 特徵工程 (簡化範例,使用 TotalAmount 作為單一特徵)
X = data[['Amount']]
# 使用 StandardScaler 進行資料標準化
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# K-means 分群
kmeans = KMeans(n_clusters=5, random_state=0) # 設定簇數為 5
kmeans.fit(X_scaled)
# PCA 降維
pca = PCA(n_components=2) # 降維至 2 維
X_pca = pca.fit_transform(X_scaled)
# 視覺化分群結果
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=kmeans.labels_)
plt.xlabel('PCA Component 1')
plt.ylabel('PCA Component 2')
plt.title('Customer Segmentation with K-means and PCA')
plt.show()
無監督學習:分群與主成分分析
在機器學習領域中,無監督學習模型能夠在未標註的資料中發現模式。分群是一種用於找出相似物件群組的技術,而主成分分析(PCA)則是一種用於降低資料維度的技術。本章將探討這兩種技術在產品分群中的應用,產品分群利用文字化的產品描述將相似產品分組。
在本章中,我們將:
- 討論兩種無監督學習技術:分群和主成分分析。
- 使用 K-means 分群演算法。
將問題分解為特徵
要將問題分解為特徵,需要考慮以下步驟:
- 資料準備:載入資料集並檢查資料結構、缺失值和整體特性。預處理資料,可能涉及處理缺失值、資料型別轉換和資料清理。
- 特徵工程:選擇相關特徵,從文字中提取特徵,並衍生新的特徵。
- 文字資料預處理:對文字進行分詞,移除標點符號和停用詞。使用詞頻-逆檔案頻率(TF-IDF)技術將文字轉換為數值格式。
- 應用分群演算法:建立 K-means 分群模型,並使用適當的技術(如肘部法和輪廓分數)確定最佳簇數。
- 評估和視覺化分群結果:評估分群效能,並使用 PCA 在降維空間中視覺化結果。
提示策略
本章使用 TAG 模式(任務-行動-指導),如第 2 章所述。我們知道以下要解決的問題:
- 任務:建立客戶分群模型。
- 行動:要求提供步驟和使用的技術。
- 指導:要求逐步學習。
客戶分群
分群可以根據客戶的購買行為、偏好或人口統計資訊對客戶進行分段。透過分析客戶資料(如瀏覽歷史、購買歷史、位置和人口統計資訊),可以應用分群演算法來識別不同的客戶分段。這些資訊可用於個人化行銷活動、推薦相關產品或根據不同客戶群體定製使用者經驗。
資料集
我們將使用電子商務資料集,可以從 UCI 機器學習倉函式庫下載 CSV 檔案:https://archive.ics.uci.edu/dataset/352/online+retail。它包含 2010 年 12 月 1 日至 2011 年 12 月 9 日期間英國註冊的非實體店線上零售商的所有交易資料。
資料集包含以下欄位:
- InvoiceNo:每個交易唯一分配的 6 位整數
- StockCode:每個不同產品唯一分配的 5 位整數
- Description:每個產品名稱的文字描述
- Quantity:每個交易中每個產品(專案)的數量
- InvoiceDate:每個交易生成的日期和時間
- UnitPrice:每個單位產品的價格(英鎊)
- CustomerID:每個客戶唯一分配的 5 位整數
- Country:每個客戶所在國家/地區的名稱
將 AI 助手新增到無監督學習模型開發過程
讓我們利用 ChatGPT 為無監督學習模型開發過程新增 AI 助手。首先,我們向 ChatGPT 輪廓我們的任務。讓我們看看如何使用 TAG 模式:
- 任務:我們的任務是建立一個分群模型。
# 載入必要的函式庫
import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
# 載入資料集
data = pd.read_csv('online_retail.csv')
# 檢視資料集的前幾行
print(data.head())
#### 內容解密:
這段程式碼首先載入了必要的 Python 函式庫,包括 `pandas` 用於資料處理、`TfidfVectorizer` 用於將文字轉換為 TF-IDF 特徵、`KMeans` 用於執行 K-means 分群、`PCA` 用於降維,以及 `matplotlib.pyplot` 用於視覺化。然後,它載入了電子商務資料集,並查看了資料集的前幾行以瞭解其結構。
載入與理解客戶細分聚類別模型的資料集
在進行客戶細分聚類別分析時,第一步是載入並理解所使用的資料集。以下將介紹如何使用Python在Jupyter Notebook中完成這項任務。
載入資料集
首先,需要從GitHub倉函式庫中載入名為data.csv的資料集。該資料集包含了客戶交易的詳細資訊,包括發票號、商品程式碼、描述、數量、發票日期、單價、客戶ID以及國家等欄位。
# 匯入必要的函式庫
import pandas as pd
# GitHub上原始CSV檔案的URL
data_url = "https://raw.githubusercontent.com/yourusername/yourrepository/master/data.csv"
# 使用latin1編碼讀取資料集到pandas DataFrame
df = pd.read_csv(data_url, encoding='latin1')
# 顯示DataFrame的形狀(行數,列數)
print("DataFrame的形狀:", df.shape)
# 顯示DataFrame的前幾行
print("DataFrame的前幾行:")
print(df.head())
內容解密:
- 匯入函式庫:使用
import pandas as pd匯入pandas函式庫,這是Python中用於資料操作和分析的主要工具。 - 定義資料URL:將
data_url變數設定為GitHub上data.csv檔案的原始URL。 - 讀取資料:使用
pd.read_csv函式讀取CSV檔案到DataFramedf中,並指定encoding='latin1'以正確處理字元編碼。 - 顯示DataFrame資訊:透過
df.shape和df.head()分別顯示DataFrame的行列數和前幾行的內容,以便初步瞭解資料。
檢查資料
接下來,需要檢查資料的欄位名稱、資料型別以及是否存在缺失值。
# 顯示欄位名稱和資料型別
print("欄位名稱和資料型別:")
print(df.dtypes)
# 檢查每個欄位的缺失值數量
print("\n每個欄位的缺失值數量:")
print(df.isnull().sum())
內容解密:
- 欄位名稱和資料型別:使用
df.dtypes檢視每個欄位的資料型別,有助於瞭解資料的儲存格式。 - 檢查缺失值:透過
df.isnull().sum()計算每個欄位的缺失值數量,這對於後續的資料預處理非常重要。
內容解密:
- 計算總結統計:使用
df.describe(include='all')計算所有欄位的總結統計,包括數值和非數值欄位。 - 轉置總結統計:透過
summary_stats.transpose()將總結統計轉置,使其更易於閱讀。 - 顯示總結統計:最後,列印預出轉置後的總結統計結果。
後續步驟
完成上述步驟後,將對資料集有初步的瞭解。接下來,需要進行資料預處理,以便將資料用於客戶細分聚類別模型。具體的預處理步驟將在下一小節中介紹。
資料載入與理解流程
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title 無監督學習產品分群與主成分分析應用
package "無監督學習分群" {
package "資料預處理" {
component [缺失值處理] as missing
component [異常值處理] as outlier
component [TF-IDF 向量化] as tfidf
}
package "分群演算法" {
component [K-means] as kmeans
component [肘部法] as elbow
component [輪廓分數] as silhouette
}
package "降維視覺化" {
component [PCA 降維] as pca
component [2D/3D 視覺化] as viz
component [分群解讀] as interpret
}
}
missing --> outlier : 資料清洗
outlier --> tfidf : 欄位篩選
tfidf --> kmeans : 文字向量
kmeans --> elbow : 分群執行
elbow --> silhouette : 簇數選擇
silhouette --> pca : 品質評估
pca --> viz : 維度壓縮
viz --> interpret : 結果呈現
note right of tfidf
特徵工程:
- TF-IDF 文字向量
- 資料標準化
- 產品描述提取
end note
note right of silhouette
評估方法:
- 肘部法則
- 輪廓分數
- 群內/群間距離
end note
@enduml
此圖示展示了從載入資料集到進行客戶細分聚類別分析的整個流程。
無監督學習:客戶分群與主成分分析(PCA)
資料預處理
在檢視資料後,我們發現CustomerID欄位存在缺失值。為了使用這些資料進行客戶分群聚類別模型的訓練,我們需要移除這些缺失值。此外,Quantity和UnitPrice等數值欄位也包含一些負值,這些同樣需要被移除。我們將捨棄一些對客戶分群聚類別模型無用的欄位,包括StockCode、InvoiceDate、Description和Country。
預處理步驟實作
# 步驟 4:資料預處理
# 1. 移除CustomerID欄位中的缺失值
df_cleaned = df.dropna(subset=['CustomerID'])
# 2. 移除Quantity和UnitPrice欄位中的負值
df_cleaned = df_cleaned[(df_cleaned['Quantity'] >= 0) & (df_cleaned['UnitPrice'] >= 0)]
# 3. 移除未使用的欄位:'StockCode', 'InvoiceDate', 'Description', 'Country'
columns_to_drop = ['StockCode', 'InvoiceDate', 'Description', 'Country']
df_cleaned = df_cleaned.drop(columns=columns_to_drop)
# 顯示清理後的DataFrame形狀
print("清理後的DataFrame形狀:", df_cleaned.shape)
# 顯示清理後的DataFrame前幾行
print("\n清理後的DataFrame前幾行:")
print(df_cleaned.head())
程式碼解說:
- 使用
dropna()函式移除CustomerID欄位中缺失值對應的列,以確保客戶ID的有效性。 - 使用布林索引過濾掉
Quantity和UnitPrice欄位中為負值的列,僅保留非負值的交易記錄。 - 使用
drop()函式移除無用的欄位,如StockCode、InvoiceDate、Description和Country。
特徵工程
為了幫助客戶分群聚類別模型的訓練,我們需要進行特徵工程,建立新的特徵。首先,透過將Quantity和UnitPrice欄位相乘來建立一個名為Amount的新欄位。然後,根據CustomerID對Amount進行匯總,建立一個名為TotalAmount的欄位。同時,計算每個客戶的交易次數,建立一個名為TotalTransactions的欄位。用於客戶分群的資料集將包含兩個欄位:TotalAmount和TotalTransactions。
特徵工程實作
# 步驟 5:特徵工程
# 1. 建立Amount欄位:將Quantity和UnitPrice欄位相乘
df_cleaned['Amount'] = df_cleaned['Quantity'] * df_cleaned['UnitPrice']
# 2. 建立TotalAmount欄位:根據CustomerID匯總Amount
df_total_amount = df_cleaned.groupby('CustomerID')['Amount'].sum().reset_index()
df_total_amount.rename(columns={'Amount': 'TotalAmount'}, inplace=True)
# 3. 建立TotalTransactions欄位:計算每個CustomerID的發票數量
df_total_transactions = df_cleaned.groupby('CustomerID')['InvoiceNo'].nunique().reset_index()
df_total_transactions.rename(columns={'InvoiceNo': 'TotalTransactions'}, inplace=True)
# 4. 建立客戶分群資料集:合併TotalAmount和TotalTransactions
df_segmentation = pd.merge(df_total_amount, df_total_transactions, on='CustomerID')
# 顯示客戶分群DataFrame的前幾行
print("客戶分群DataFrame:")
print(df_segmentation.head())
程式碼解說:
- 透過將
Quantity和UnitPrice欄位相乘來建立新的Amount欄位,以計算每筆交易的總金額。 - 使用
groupby()和sum()函式根據CustomerID匯總所有交易的Amount,計算每個客戶的總消費金額(TotalAmount)。 - 使用
groupby()和nunique()函式計算每個客戶的唯一發票數量,以代表客戶的交易次數(TotalTransactions)。 - 將包含TotalAmount和TotalTransactions的DataFrame合併,建立最終的客戶分群資料集。
重點分析與未來趨勢
透過資料預處理和特徵工程,我們成功地準備了用於客戶分群的資料集。這種方法不僅能夠幫助企業更好地瞭解其客戶群體,還可以為精準行銷提供有力的資料支援。未來,可以考慮結合更多的特徵,例如客戶的人口統計資訊或行為資料,以進一步提高客戶分群的準確性。隨著機器學習技術的不斷進步,客戶分群的應用將更加廣泛和深入。
客戶分群分析中的離群值處理與資料標準化
在進行客戶分群分析時,資料的品質與預處理步驟對於最終的分群結果具有決定性的影響。本章節將探討如何檢查與移除離群值,以及如何透過資料標準化來提升分群分析的準確性。
建立客戶分群特徵
首先,我們需要建立用於客戶分群的特徵。在此案例中,我們關注兩個主要的特徵:客戶的總消費金額(TotalAmount)與總交易次數(TotalTransactions)。這兩個特徵能夠有效地反映客戶的消費行為與忠誠度。
# 建立客戶分群特徵
df_segmentation = df_total_amount.merge(df_total_transactions, on='CustomerID')
內容解密:
df_total_amount與df_total_transactions分別代表客戶的總消費金額與總交易次數,這些是透過對原始資料進行分組與匯總計算得到的。merge函式用於根據CustomerID將兩個資料集合併為一個新的 DataFramedf_segmentation。
檢查離群值
在進行分群分析之前,檢查資料中的離群值是非常重要的步驟。離群值可能會對分群結果產生不利影響,因此需要仔細檢查並適當處理。
# 刪除 CustomerID 列
df_segmentation.drop('CustomerID', axis=1, inplace=True)
# 使用箱型圖檢查離群值
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 5))
plt.boxplot([df_segmentation['TotalAmount'], df_segmentation['TotalTransactions']], labels=['TotalAmount', 'TotalTransactions'])
plt.title('TotalAmount 與 TotalTransactions 的箱型圖')
plt.ylabel('數值')
plt.show()
內容解密:
drop函式用於刪除CustomerID列,因為該列不參與分群分析。- 箱型圖是一種有效的視覺化工具,用於識別資料中的離群值。箱型圖中的「箱子」代表了資料的四分位距(IQR),而「鬍鬚」以外的點則被視為潛在的離群值。
- 透過視覺化檢查,可以直觀地判斷是否存在離群值,並根據具體情況決定如何處理這些離群值。
移除離群值
一旦發現離群值,就需要決定是否移除或以其他方式處理這些資料。在本案例中,我們選擇使用 IQR 方法來檢測並移除離群值。
# 計算 TotalAmount 列的 IQR
Q1 = df_segmentation['TotalAmount'].quantile(0.25)
Q3 = df_segmentation['TotalAmount'].quantile(0.75)
IQR = Q3 - Q1
# 定義離群值檢測的上下限
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# 移除 TotalAmount 列中的離群值
df_segmentation = df_segmentation[(df_segmentation['TotalAmount'] >= lower_bound) & (df_segmentation['TotalAmount'] <= upper_bound)]
# 輸出移除離群值後的 DataFrame 大小
print("移除離群值後的 DataFrame 大小:", df_segmentation.shape)
內容解密:
- IQR 方法是一種常見的離群值檢測方法,透過計算第一四分位數(Q1)與第三四分位數(Q3)之間的差值來定義資料的正常範圍。
- 將超出
Q1 - 1.5*IQR與Q3 + 1.5*IQR範圍的資料視為離群值,並將其移除。 - 移除離群值後,DataFrame 的大小會發生變化,這可以透過比較
shape屬性的變化來觀察。
資料標準化
在進行分群分析時,資料標準化是至關重要的步驟。標準化可以確保不同特徵在相同的尺度上,避免某些特徵因尺度差異而主導分群結果。
# 使用 StandardScaler 進行資料標準化
from sklearn.preprocessing import StandardScaler
# 初始化 StandardScaler
scaler = StandardScaler()
# 對 TotalAmount 與 TotalTransactions 進行標準化
df_scaled = scaler.fit_transform(df_segmentation)
# 將標準化後的陣列轉換回 DataFrame
內容解密:
StandardScaler是 scikit-learn 提供的一種標準化工具,可以將資料轉換為均值為 0、標準差為 1 的分佈。- 標準化的過程包括了對原始資料進行擬合(fit)與轉換(transform),確保所有特徵在相同的尺度上。
- 將標準化後的結果轉換回 DataFrame,以便於後續的分群分析。