如何使用K-Means對用戶進行分群

2021-02-20 CPDA數據說

K-Means 定義

K-Means 算法是聚類算法的一種,所以先了解聚類算法。

聚類分析是在沒有給定劃分類別情況下,根據數據相似度進行樣本分組的一種方法。是一種無監督的學習算法。劃分依據主要是自身的距離或相似度將他們劃分為若干組,劃分原則是組內樣本最小化而組間(外部)距離最大化。聚類多數場景下用在「數據探索」環節,也就是用來了解數據。它無法提供明確的行動指向,更多是為後期挖掘和分析提供參考,無法回答「為什麼」和「怎麼辦」的問題。

聚類分析和分類區別:分類是從特定的數據中挖掘模式,作出分類判斷;聚類是根據數據本身特點,按照不同的模型來判斷數據之間的相似性、相似性高的一組數據聚成一簇。

K-Means 算法是基於距離的聚類方法,在最小誤差函數的基礎上將數據劃分為預定的類數 K,採用距離作為相似性的評價指標,認為兩個對象的距離越近,其相似度越高。適用於連續型數據。使用場景可以是:用戶分群分析。

算法過程

從 n 個樣本數據中隨機選取 K 個對象作為初始的聚類中心(在一開始確定 K 值上,憑業務經驗劃分,所以K值的選定不一定合理);

分別計算每個樣本到各個聚類中心的距離,將對象分配到距離最近的聚類中;

所有對象分配完成後,重新計算 K 個聚類的中心(類似重新計算虛擬中心);

與前一次計算得到的 K 個聚類中心比較,如果聚類中心發生變化,轉至步驟 2,否則轉至步驟 5;

度量距離:度量樣本之間的相似性最常用的是歐幾裡得距離、曼哈頓距離和閔可夫斯基距離(Python 中目前支持歐氏距離)。

偽代碼如圖所示

初始質心如何確定比較好

所以可以看到,在 K-Means 中有一個重要的環節,那就是如何放置初始質心,初始質心放置的位置不同,聚類的結果很可能不一樣。一個好的初始質心可以避免更多的計算,讓算法收斂穩定且更快。算法的第一步是在 n 個樣本中隨機抽取 K 個對象作為初始聚類中心,在初始的時候可能會生成在一起,導致算法運算慢且不收斂,對於此類問題可以採用 K-means++ 作為優化,其核心就是選擇離已選中心點最遠的點,初始質心相互間離得儘可能遠。

如何確定K值

在 K-Means 中,K 值是人為確定的,如果有業務經驗,可以根據業務經驗來判斷,如果此類數據沒有先驗知識,也不知道如何聚類,劃分的依據就依賴於組間差異最大化,組內差異最小化的評估指標。對於這個問題可以採用輪廓係數來判定,輪廓係數的取值為(-1,1),輪廓係數越接近於 1 越好,負數則表示聚類效果非常差。單個樣本的輪廓係數計算公式如下:

a:樣本與其自身所在的簇中的其他樣本的相似度,等於樣本與同一簇中所有其他點之間的平均距離;

b:樣本與其他簇中的樣本的相似度,等於樣本與下一個最近的簇中的所有點之間的平均距離。

值越接近 1 表示樣本與自己所在的簇中的樣本很相似,並且與其他簇中的樣本不相似;越接近 -1 說明樣本點與簇外的樣本更相似,與簇內樣本不相似;當輪廓係數接近 0 時,則代表簇類差異和簇外差異的樣本相似度一致,無明顯分界。

K-Means 案例演示

數據集:航空公司客戶特徵欄位。

分析流程為:

import pandas as pd
import numpy as np
import os
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.family'] = ['Arial Unicode MS'] 
pd.set_option('display.max_columns', None)
# sns.set_style("darkgrid",{"font.sans-serif":['simhei','Droid Sans Fallback']})

os.chdir('/data')
df = pd.read_csv('air_data.csv')
df.head()

描述性統計分析查看整體數據描述性分析

explore = df.describe(percentiles=[], include='all').T
explore


explore['null'] = len(df) - explore['count']
df_check = explore[['null', 'max', 'min']]
df_check.columns = [['空值記錄數', '最大值', '最小值']]
df_check

查看單個主體變量會員逐年增長情況

df['FFP_DATE_year'] = pd.to_datetime(df['FFP_DATE']).dt.year

# 獲取每個年份的合計數量。方式一
count = df['FFP_DATE_year'].value_counts(sort=False).reset_index()

# 獲取每個年份的合計數量。方式二
# count = df.groupby('FFP_DATE')['FFP_DATE'].count()

count.columns = ['入會時間', '入會人數']
count.plot(kind='bar', x='入會時間', y='入會人數', figsize=(12,8))


查看單個分類型變量比例變化情況(直方堆積圖)

# 使用數據交叉表,計算每個年度時間節點,出現男女分類的數量情況
cross_table = pd.crosstab(index=df['FFP_DATE_year'],columns=df['GENDER'])
cross_table


# 通過div函數,讓分組每行合計等於1,用來看每個分組佔比
cross_table = cross_table.div(cross_table.sum(1), axis=0)
cross_table


cross_table.plot(kind='bar', stacked=True)


查看單個分類型變量佔比情況(直方圖&餅圖)

# 男女分別數量合計佔比
sns.countplot(x='GENDER',data=df)


# 男女會員分別所有數量。方式一
# male_count = df.groupby('GENDER')['GENDER'].count()[0]
# female_count = df.groupby('GENDER')['GENDER'].count()[1]

# 方式二
male_count = pd.value_counts(df['GENDER'])['男']
female_count = pd.value_counts(df['GENDER'])['女']

plt.pie([male_count, female_count], 
        labels=['男', '女'], 
        colors=['lightskyblue', 'lightcoral'],
        autopct='%1.1f%%',
       )
plt.show

查看單個分類型變量頻數情況(直方圖)

# 方式一: 直接使用sns.countplot 查看單個變量的分類情況
# sns.countplot(x='FFP_TIER',data=df)

# 方式二:
FFP_TIER_Level4 = pd.value_counts(df['FFP_TIER'])[4]
FFP_TIER_Level5 = pd.value_counts(df['FFP_TIER'])[5]
FFP_TIER_Level6 = pd.value_counts(df['FFP_TIER'])[6]

plt.bar(x=range(3), 
        height=[FFP_TIER_Level4, FFP_TIER_Level5, FFP_TIER_Level6],
        width=0.4,
        alpha=0.8,
        color='skyblue')
plt.xticks([index for index in range(3)], [4, 5, 6])
plt.show()


查看單個數值型變量分布情況(箱型圖)

# 會員年齡分布箱型圖

plt.figaspect
plt.boxplot(df['AGE'].dropna(),
           patch_artist=True,
           vert=False,
           boxprops = {'facecolor': 'lightblue'},
           labels=['會員年齡'])
plt.grid(linestyle=":", color="r")
plt.title('會員年齡分布箱型圖')
plt.show()

相關性分析

# 'FFP_TIER','FLIGHT_COUNT','LAST_TO_END','SEG_KM_SUM','EXCHANGE_COUNT','Points_Sum','FFP_DATE'的相關係數分析
df_corr = df.loc[:, ['FFP_TIER','FLIGHT_COUNT','LAST_TO_END','SEG_KM_SUM','EXCHANGE_COUNT','Points_Sum','FFP_DATE']]
age1 = df['AGE'].fillna(0)
df_corr['AGE'] = age1.astype('int64')

# df的相關係數
df_corr = df_corr.corr()
df_corr


# 設置圖形大小
plt.subplots(figsize=(10,10))

# 特徵數據熱力圖
ax = sns.heatmap(df_corr, annot=True, cmap='Blues')
ax.set_ylim([8, 0])
ax


數據預處理數據清洗

# 去除票價為空的行 
airline_notnull = df.loc[df['SUM_YR_1'].notnull() & df['SUM_YR_2'].notnull(), :]

# 保留票價非零數據,或者平均折扣率不為零且總飛行數大於0的記錄;AGE去除大於100的記錄
index1 = airline_notnull['SUM_YR_1'] != 0
index2 = airline_notnull['SUM_YR_2'] != 0
index3 = (airline_notnull['SEG_KM_SUM'] > 0) & (airline_notnull['avg_discount'] != 0)
index4 = airline_notnull['AGE'] > 100
airline = airline_notnull[(index1 | index2) & index3 & ~index4]
airline.head()

部分數據欄位

屬性歸約

airline = airline[['FFP_DATE', 'LOAD_TIME', 'LAST_TO_END','FLIGHT_COUNT','SEG_KM_SUM','avg_discount' ]]
airline['FFP_DATE'], airline['LOAD_TIME'] = pd.to_datetime(airline['FFP_DATE']), pd.to_datetime(airline['LOAD_TIME'])
airline['L'] = (airline['LOAD_TIME'] - airline['FFP_DATE']).dt.days
airline = airline.drop(['FFP_DATE', 'LOAD_TIME'], axis=1)
airline.columns = ['R', 'F', 'M', 'C', 'L']
airline.head()


數據標準化

from sklearn.preprocessing import StandardScaler
data = StandardScaler().fit_transform(airline)
data[:5, :]

array([[-0.94493902, 14.03402401, 26.76115699,  1.29554188,  1.43579256],
       [-0.91188564,  9.07321595, 13.12686436,  2.86817777,  1.30723219],
       [-0.88985006,  8.71887252, 12.65348144,  2.88095186,  1.32846234],
       [-0.41608504,  0.78157962, 12.54062193,  1.99471546,  0.65853304],
       [-0.92290343,  9.92364019, 13.89873597,  1.34433641,  0.3860794 ]])


聚類分析

from sklearn.cluster import KMeans

# 構建模型,隨機種子設為123
kmeans_model = KMeans(n_clusters=5, n_jobs=4, random_state=123)

# 模型訓練
fit_kmeans = kmeans_model.fit(data)

# 查看聚類結果
kmeans_cc = kmeans_model.cluster_centers_
kmeans_cc

# 樣本的類別標籤
kmeans_lable = kmeans_model.labels_

# 統計不同類別樣本數目
pd.Series(kmeans_model.labels_).value_counts()

cluster_center = pd.DataFrame(kmeans_model.cluster_centers_, columns=['ZR','ZF','ZM','ZC','ZL'])
# cluster_center.index = pd.DataFrame(kmeans_model.labels_).drop_duplicates().iloc[:,0]
cluster_center


聚類分析可視化(雷達圖)

#標籤
labels = cluster_center.columns 

#數據個數
k = 5 
plot_data = kmeans_model.cluster_centers_

#指定顏色
color = ['b', 'g', 'r', 'c', 'y'] 

angles = np.linspace(0, 2*np.pi, k, endpoint=False)

# 閉合
plot_data = np.concatenate((plot_data, plot_data[:,[0]]), axis=1) 

# 閉合
angles = np.concatenate((angles, [angles[0]])) 

fig = plt.figure(figsize=(8,6))

#polar參數
ax = fig.add_subplot(111, polar=True) 
for i in range(len(plot_data)):
  ax.plot(angles, plot_data[i], 'o-', color = color[i], label = u'客戶群'+str(i), linewidth=2)# 畫線

ax.set_rgrids(np.arange(0.01, 3.5, 0.5), np.arange(-1, 2.5, 0.5), fontproperties="SimHei")
ax.set_thetagrids(angles * 180/np.pi, labels, fontproperties="SimHei")
plt.legend(loc = 4)
plt.show()


相關焦點

  • 使用K-means 算法進行客戶分類
    在本部分中,你將理解並學習到如何實現K-Means聚類。部分使用案例如下:  k - means聚類算法步驟1對於python,我使用的是Spyder Editor。下面,我們將展示K-means算法如何處理客戶費用和發票數據的例子。我們有500個客戶數據,我們關注兩個客戶特徵: 客戶發票,客戶費用。
  • 騰訊QQ大數據:用戶增長分析——用戶分群分析 - 大數據 - IT商業網...
    類型四:根據用戶行為進行分群,此階段會在畫像分群的基礎上關注用戶的行為特徵, 如根據用戶的註冊渠道和活躍習慣,制定不同的營銷推廣策略。三、常見的用戶分群維度1. 統計指標:年齡,性別,地域2. 付費狀態:免費,試用,付費用戶3. 購買歷史:未付費用戶,一次付費用戶,多次付費用戶4. 訪問位置:用戶使用產品的區域位置5. 使用頻率:用戶使用產品的頻率6. 使用深度:輕度,中度,重度用戶7.
  • 如何用聚類模型(k-means)做數據分析?
    例如我們想探尋我們產品站內都有哪些社交行為群體,剛開始拍腦門想可能並不會很容易,這時候可以根據用戶屬性、行為對用戶進行聚類,根據結果將每個簇定義為一類社交群體,基於這些類訓練後續的分類模型,給用戶打標籤後進行個性化推薦、運營。
  • k-means聚類簡介
    這篇K-means聚類算法涵蓋了:使用K-means的常見商業案例運行該算法所涉及的步驟使用一個配送車隊數據的Python示例商業用途K-means聚類算法用來查找那些包含沒有明確標記數據的組。這可以用於確定商業假設,存在什麼類型的分組或為複雜的數據集確定未知組。一旦該算法已運行並定義分組,任何新數據可以很容易地分配到正確的組。
  • k-means算法
    k-means算法流程1.選擇聚類的個數k(kmeans算法傳遞超參數的時候,只需設置最大的K值)2.任意產生k個聚類,然後確定聚類中心,或者直接生成k個中心。3.對每個點確定其聚類中心點。4.再計算其聚類新中心。5.重複以上步驟直到滿足收斂要求。(通常就是確定的中心點不再改變。)
  • K-means(聚類)
    比如Gmail郵箱裡有垃圾郵件分類器,一開始的時候可能什麼都不過濾,在日常使用過程中,我人工對於每一封郵件點選「垃圾」或「不是垃圾」,過一段時間,Gmail就體現出一定的智能,能夠自動過濾掉一些垃圾郵件了。
  • 基本的k-means算法流程
    打開APP 基本的k-means算法流程 李倩 發表於 2018-07-24 17:44:21 1、引言 k-means
  • 聚類算法之Kmeans
    但是為何這篇只提Kmeans,是因為Kmeans是算法理解簡單,而又使用最多,並且從原理上來說,其它的聚類算法只是其算法或求解思路有些差別,但是其核心思路還是一致,具體做的事也是有著同一個目標,故而這篇我們重點詳細單獨闡述Kmeans算法。對於其它聚類算法,如果必要,我們在下一篇再進行展開。
  • 如何使用K-MEANS聚類算法解決分類問題
    首先說一下質心,質心可以認為就是一個樣本點,或者可以認為是數據集中的一個數據點P,它是具有相似性的一組數據的中心,即該組中每個數據點到P的距離都比到其他質心的距離近。k個初始類聚類質心的選取對聚類結果具有較大的影響,因為在該算法第一步中是隨機的選取任意k個對象作為初始聚類的質心,初始地代表一個聚類結果,當然這個結果一般情況不是合理的,只是隨便地將數據集進行了一次隨機的劃分,具體進行修正這個質心還需要進行多輪的計算,來一步步逼近我們期望的聚類結果:具有相似性的對象聚集到一個組中,它們都具有共同的一個質心。
  • 詳解 kmeans 聚類算法
    下圖展示了對n個樣本點進行K-means聚類的效果,這裡k取2。     K-means面對的第一個問題是如何保證收斂,前面的算法中強調結束條件就是收斂,可以證明的是K-means完全可以保證收斂性。由於畸變函數J是非凸函數,意味著我們不能保證取得的最小值是全局最小值,也就是說k-means對質心初始位置的選取比較感冒,但一般情況下k-means達到的局部最優已經滿足需求。但如果你怕陷入局部最優,那麼可以選取不同的初始值跑多遍k-means,然後取其中最小的J對應的
  • K-Means聚類算法詳解
    通過今天的學習,掌握KMeans算法的工作原理,然後會使用sklearn實現KMeans聚類,最後我們來做一個實戰項目:如何使用KMeans對圖像進行分割? 下面我們開始吧。這個就是KMeans進行聚類的過程了。簡單點,就是反覆兩個過程:上面這個也可以使用sklearn中的K-Means進行實戰一下子,作為圖像分割圖像的準備期。4. KMeans聚類實戰:如何使用KMeans對圖像進行分割?
  • 數據分析入門系列教程-K-Means原理
    聚類的應用場景是非常多的,比如給用戶群分類,對用戶行為劃分等待,特別是在沒有標籤的情況下,只能只用聚類的方式做分析。那麼該如何更好的選擇初始化數據呢,一般可以採用 k-means++ 的方式來處理k-means++它的工作流程大致如下:1、從輸入的數據點集合中隨機選擇一個點作為第一個聚類中心2、對於數據集中的每一個點 x,計算它與最近聚類中心(指已選擇的聚類中心)的距離 D(x)3、選擇一個新的數據點作為新的聚類中心,選擇的原則是:D(x) 較大的點
  • 機器學習算法之K-means算法
    K-means舉例shi'li1 K-means算法簡介k-means算法是一種聚類算法,所謂聚類,即根據相似性原則2 K-means算法原理k-means算法中的k代表類簇個數,means代表類簇內數據對象的均值(這種均值是一種對類簇中心的描述),因此,k-means算法又稱為k-均值算法。
  • K-Means聚類算法
    簡單來說,之前的算法中我們是利用特徵 x 和類別 y 來進行訓練、分類的,而無監督學習是指不需要我們提供具體的類別 y ,而讓數據自己聚在一起,形成 k 個簇,以實現分類的目的。具體方法是通過對給定的樣本進行劃分,分為 k 個簇,使得簇內的點儘量緊密的連在一起,而簇間的距離儘量大,評判的標準就是通過歐氏距離。
  • 你需要的最全面的K-means聚類指南
    介紹每當我在網站上遇到推薦引擎時,我都迫不及待地將其分解並理解它的底層是如何工作的。我想這是成為數據科學家的最重要的品質之一!這些系統真正令我著迷的是我們如何將類似的物品,產品和用戶組合在一起。這種分組或分段適用於各個行業。這就是聚類概念在數據科學中如此重要的原因。
  • 數據分析入門系列教程-K-Means實戰
    這裡sklearn 會自動為我們進行迭代運算,找出合適的初始中心點。init初始值的選擇方式。默認就是採用 k-means++ 的方式,或者還可以採用 random 完全隨機的方式。 [0.42352941 0.42352941 0.43137255] [0.48235294 0.48235294 0.49019608] [0.42745098 0.42352941 0.44313725]]現在開始使用 K-Means 做聚類kmeans = KMeans(n_clusters=2)kmeans.fit
  • 使用K-Means算法將圖像壓縮6倍!
    此外,我們還將討論如何使用K-Means來壓縮圖像。在深入研究K-Means算法的細節之前,讓我們先了解一下無監督的機器學習是什麼,以及它的實際應用是什麼。與有標記數據的監督機器學習不同,,無監督機器學習處理未標記數據的問題。如果你熟悉經典的有監督機器學習,你可能會問,如何從未標記的數據集中學習任何有用的東西?成本函數是否不需要輸出標籤來計算算法的執行方式?
  • K-means實戰:618來了,你屬於剁手族中的哪一「簇」?
    比如淘寶要上新產品了,天貓精靈4.0,它需要知道哪些用戶更有可能去購買這款產品。所以,對不同的用戶進行分析並從中找到一些共同規律並歸類,對於它們預測用戶的購買行為非常重要。下面的內容我們將結合實例告訴你這些電商是如何利用大數據來對用戶進行聚類分析的。別慌,先來分析下數據。
  • 機器學習之分類算法K-Means介紹與代碼分析(篇四)
    一般情況下,都使用效率比較高的啟發式算法,它們能夠快速收斂於一個局部最優解。這些算法通常類似於通過迭代優化方法處理高斯混合分布的最大期望算法(EM算法)。而且,它們都使用聚類中心來為數據建模;然而k-平均聚類傾向於在可比較的空間範圍內尋找聚類,期望-最大化技術卻允許聚類有不同的形狀。
  • 聚類算法入門:k-means
    二、劃分聚類方法: K-means:對於給定的樣本集,按照樣本之間的距離(也就是相似程度)大小,將樣本集劃分為K個簇(即類別)。讓簇內的點儘量緊密的連在一起,而讓簇間的距離儘量的大。根據裡面的所有樣本點重新計算得到一個新的中心點,如果中心點發生變化回到步驟2,未發生變化轉到步驟4步驟4:得出結果就像這樣:缺點:初始值敏感、採用迭代方法,得到的結果只是局部最優、K值的選取不好把握、對於不是凸的數據集比較難收斂如何衡量