機(jī)器學(xué)習(xí)開(kāi)發(fā),與Mail.Ru Search數(shù)據(jù)分析負(fù)責(zé)人Egor Polusmak和Mail.Ru Group數(shù)據(jù)科學(xué)家Yury Kashnitsky一起探索如何使用Python可視化數(shù)據(jù)。
在機(jī)器學(xué)習(xí)領(lǐng)域中,可視化并不僅僅用來(lái)制作漂亮的報(bào)表。項(xiàng)目的各個(gè)階段都大量使用可視化技術(shù)。
在開(kāi)始一項(xiàng)新任務(wù)時(shí),通過(guò)可視化手段探索數(shù)據(jù)往往是任務(wù)的第一步。我們通過(guò)圖表匯總數(shù)據(jù),放棄無(wú)關(guān)緊要的細(xì)節(jié)。相比直接閱讀許多行原始數(shù)據(jù),可視化能更好地幫助人類把握數(shù)據(jù)的要點(diǎn)。令人驚嘆的是,僅僅通過(guò)可視化工具創(chuàng)建一些看上去再簡(jiǎn)單不過(guò)的圖表,就能獲得大量洞見(jiàn)。
接著,在分析模型表現(xiàn)和模型報(bào)告的結(jié)果時(shí),我們也常常使用可視化。有時(shí)候,為了理解復(fù)雜的模型,我們需要將高維空間映射為視覺(jué)上更直觀的二維或三維圖形。
總而言之,可視化是一個(gè)相對(duì)快捷的從數(shù)據(jù)中獲取新知的手段。因此,學(xué)習(xí)這一極為重要的技術(shù),并將其納入你的日常機(jī)器學(xué)習(xí)工具箱,是至關(guān)重要的。
本文將使用pandas、matplotlib和seaborn等流行的庫(kù),帶你上手可視化。
概覽
數(shù)據(jù)集
單變量可視化數(shù)量和類型分布
多變量可視化變量間的相互作用
全數(shù)據(jù)集一窺高維空間
作業(yè)二
相關(guān)資源
下面的材料以Jupyter notebook的形式查看效果最佳。如果你克隆了本教程的代碼倉(cāng)庫(kù),你也可以在本地運(yùn)行。
1. 數(shù)據(jù)集
首先初始化環(huán)境:
import numpy as np
import pandas as pd
pd.options.display.max_columns = 12
# 禁用Anaconda警告
import warnings
warnings.simplefilter('ignore')
# 在Jupyter Notebook內(nèi)部顯示圖形
%matplotlib inline
import matplotlib.pyplot as plt
# 我們將使用Seaborn庫(kù)
import seaborn as sns
sns.set()
# SVG格式的圖像更清晰
%config InlineBackend.figure_format = 'svg'
# 增加默認(rèn)的繪圖尺寸
from pylab import rcParams
rcParams['figure.figsize'] = 5, 4
在第一篇文章中,我們使用的是某電信運(yùn)營(yíng)商的客戶離網(wǎng)率數(shù)據(jù)。這里我們?nèi)耘f使用這個(gè)數(shù)據(jù)集。
df = pd.read_csv('../../data/telecom_churn.csv')
df.head()
數(shù)據(jù)集的特征:
2. 單變量可視化
單變量(univariate)分析一次只關(guān)注一個(gè)變量。當(dāng)我們獨(dú)立地分析一個(gè)特征時(shí),我們通常最關(guān)心的是該特征的值的分布,而忽略數(shù)據(jù)集中的其他變量。
下面我們將考慮不同統(tǒng)計(jì)類型的變量,以及相應(yīng)的可視化工具。
2.1 數(shù)量特征
數(shù)量特征(quantitative feature)的值為有序數(shù)值。這些值可能是離散的,例如整數(shù),也可能是連續(xù)的,例如實(shí)數(shù),通常用于表示技術(shù)和度量。
直方圖和密度圖
最簡(jiǎn)單的查看數(shù)值變量分布的方法是使用DataFrame的hist()方法繪制它的直方圖(histogram)。
features = ['Total day minutes', 'Total intl calls']
df[features].hist(figsize=(12, 4));
直方圖依照相等的范圍將值分組為柱。直方圖的形狀可能包含了數(shù)據(jù)分布的線索:高斯、指數(shù),等等。當(dāng)分布基本上很有規(guī)律,但有一些異常值時(shí),你也可以通過(guò)直方圖辨認(rèn)出形狀的歪斜之處。當(dāng)你使用預(yù)設(shè)某一特定分布類型(通常是高斯)的機(jī)器學(xué)習(xí)方法時(shí),知道特征值的分布是非常重要的。
在以上圖形中,我們看到變量Total day minutes(每日通話時(shí)長(zhǎng))呈正態(tài)分布(譯者注:正態(tài)分布即高斯分布),而Total intl calls(總國(guó)際呼叫數(shù))顯著右傾(它右側(cè)的尾巴更長(zhǎng))。
除了直方圖,理解分布的另一個(gè)(經(jīng)常更清楚的)方法是密度圖(density plots),也叫(更正式的名稱)核密度圖(Kernel Density Plots)。它們可以看成是直方圖平滑過(guò)的版本。相比直方圖,它們的主要優(yōu)勢(shì)是不依賴于柱的尺寸。讓我們?yōu)樯厦鎯蓚€(gè)變量創(chuàng)建密度圖:
df[features].plot(kind='density', subplots=True,
layout=(1, 2), sharex=False, figsize=(12, 4));
我們也可以使用seaborn的distplot()方法繪制觀測(cè)數(shù)據(jù)的分布。例如,Total day minutes(每日通話時(shí)長(zhǎng))的分布。默認(rèn)情況下,圖形將同時(shí)顯示直方圖和核密度估計(jì)(kernel density estimation,KDE)。
sns.distplot(df['Total intl calls']);
這里直方圖的柱形的高度已經(jīng)歸一過(guò)了,表示的是密度而不是樣本數(shù)。
箱形圖
箱形圖(box plot)是另一種有用的可視化圖形。使用seaborn繪制箱形圖:
_, ax = plt.subplots(figsize=(3, 4))
sns.boxplot(data=df['Total intl calls'], ax=ax);
箱形圖的主要組成部分是箱子(box)(顯然,這是它被稱為箱形圖的原因),須(whisker)和一些單獨(dú)的數(shù)據(jù)點(diǎn)(離群值)。
箱子顯示了分布的四分位距;它的長(zhǎng)度由25%(Q1,下四分位數(shù))和75%(Q3,上司分位數(shù))決定。箱中的水平線表示中位數(shù)(50%)。
從箱子處延伸出來(lái)的線被稱為須。它們表示數(shù)據(jù)點(diǎn)的總體散布,具體而言,是位于區(qū)間(Q1 - 1.5xIQR, Q3 + 1.5xIQR)的數(shù)據(jù)點(diǎn),其中IQR = Q3 - Q1,也就是四分位距。
離群值是須之外的數(shù)據(jù)點(diǎn),它們作為單獨(dú)的數(shù)據(jù)點(diǎn),沿著中軸繪制。
我們可以看到,在我們的數(shù)據(jù)中,大量的國(guó)際呼叫是相當(dāng)少見(jiàn)的。
提琴形圖
我們最后考慮的分布圖形是提琴形圖(violin plot)。
下圖左側(cè)是箱形圖,右側(cè)是提琴形圖。
_, axes = plt.subplots(1, 2, sharey=True, figsize=(6, 4))
sns.boxplot(data=df['Total intl calls'], ax=axes[0]); sns.violinplot(data=df['Total intl calls'], ax=axes[1]);
箱形圖和提琴形圖的區(qū)別是,箱形圖顯示了單獨(dú)樣本的特定統(tǒng)計(jì)數(shù)據(jù),而提琴形圖聚焦于平滑后的整體分布。
describe()
圖形工具之外,我們可以使用DataFrame的describe()方法來(lái)獲取分布的精確數(shù)值統(tǒng)計(jì):
df[features].describe()
describe()的輸出基本上是自解釋性的。
2.2 類別和二元特征
類別特征(categorical features take)具有固定數(shù)目的值。每個(gè)值將一個(gè)觀測(cè)數(shù)據(jù)分配到相應(yīng)的組,這些組稱為類別(category)。類別反映了樣本的某個(gè)定性屬性。二元(binary)變量是一個(gè)重要的類別變量的特例,其中類別的可能值正好為2. 如果類別變量的值具有順序,稱為有序(ordinal)類別變量。
頻率表
讓我們查看下數(shù)據(jù)集的分類平滑:目標(biāo)變量離網(wǎng)率的分布。首先,我們使用value_counts()得到一張頻率表:
df['Churn'].value_counts()
False 2850
True 483
Name: Churn, dtype: int64
默認(rèn)情況下,頻率由高到低排列。
在我們的例子中,數(shù)據(jù)是失衡的,也就是說(shuō),數(shù)據(jù)集中忠實(shí)客戶和不忠實(shí)客戶的比例并不相等。只有一小部分的客戶取消了他們的電信服務(wù)訂閱。我們將在以后的文章中看到,這一事實(shí)可能暗示衡量分類表現(xiàn)時(shí)存在一些限制,以后我們可能額外懲罰我們的模型在預(yù)測(cè)少數(shù)“離網(wǎng)”分類時(shí)所犯的錯(cuò)誤。
條形圖
頻率表的圖形化表示是條形圖。創(chuàng)建條形圖最簡(jiǎn)單的方法是使用seaborn的countplot()函數(shù)。seaborn中還有一個(gè)函數(shù),起了一個(gè)令人困惑的名字(barplot()),barplot()絕大部分情況下用于表示以某個(gè)類別特征分組的數(shù)值變量的一些基本統(tǒng)計(jì)數(shù)據(jù)。
_, axes = plt.subplots(nrows=1, ncols=2, figsize=(12, 4))
sns.countplot(x='Churn', data=df, ax=axes[0]);
sns.countplot(x='Customer service calls', data=df, ax=axes[1]);
盡管條形圖和上面提到的直方圖看起來(lái)很像,它們是不一樣的:
直方圖用于查看數(shù)值變量的分布,而條形圖用于類別特征。
直方圖的X軸是數(shù)值;條形圖的X軸可能是任何類型:數(shù)字、字符串、布爾值。
直方圖的X軸是一根笛卡爾坐標(biāo)軸;條形的順序沒(méi)有事先定義。不過(guò),值得注意的是,條形經(jīng)常按照高度排序,也就是值的頻率。同時(shí),當(dāng)我們考慮有序變量(例如Customer service calls(客服呼叫數(shù)))時(shí),條形通常按照變量的值排序。
左側(cè)的圖形生動(dòng)地顯示了目標(biāo)變量的失衡性。右側(cè)Customer service calls(客服呼叫數(shù))的條形圖暗示了大部分客戶最多打了2-3個(gè)客服電話就解決了他們的問(wèn)題。不過(guò),既然我們想要預(yù)測(cè)少數(shù)分類,我們可能對(duì)少數(shù)不滿意的客戶的表現(xiàn)更感興趣。很可能條形圖的尾巴包含了大部分的離網(wǎng)客戶。目前這只是假想,讓我們來(lái)看一些更有趣、更強(qiáng)大的可視化技術(shù)。
3. 多變量可視化
多變量(multivariate)圖形讓我們得以在單張圖像中查看兩個(gè)以上變量的聯(lián)系。和單變量圖形一樣,可視化的類型取決于將要分析的變量的類型。
3.1 數(shù)量——數(shù)量
我們先來(lái)看看數(shù)量變量之間的相互作用。
相關(guān)矩陣
讓我們看下數(shù)據(jù)集中的數(shù)值變量的相關(guān)性。這一信息很重要,因?yàn)橛幸恍C(jī)器學(xué)習(xí)算法(比如,線性回歸和邏輯回歸)不能很好地處理高度相關(guān)的輸入變量。
首先,我們使用DataFrame的corr()方法計(jì)算出每對(duì)特征間的相關(guān)性。接著,我們將所得的相關(guān)矩陣(correlation matrix)傳給seaborn的heatmap()方法,該方法根據(jù)提供的數(shù)值,渲染出一個(gè)基于色彩編碼的矩陣:
# 丟棄非數(shù)值變量
numerical = list(set(df.columns) -
set(['State', 'International plan',
'Voice mail plan', 'Area code', 'Churn',
'Customer service calls']))
# 計(jì)算和繪圖
corr_matrix = df[numerical].corr()
sns.heatmap(corr_matrix);
從上圖我們可以看到,Total day charge(日話費(fèi)總額)直接基于電話的分鐘數(shù)計(jì)算得到(Total day minutes),這樣的變量有4個(gè)。這4個(gè)變量稱為因變量(dependent variable),可以直接去除,因?yàn)樗鼈儾⒉回暙I(xiàn)任何額外信息。讓我們?nèi)サ羲鼈儯?/p>
numerical = list(set(numerical) -
set(['Total day charge', 'Total eve charge',
'Total night charge', 'Total intl charge']))
散點(diǎn)圖
散點(diǎn)圖(scatter plot)將兩個(gè)數(shù)值變量的值顯示為二位空間中的笛卡爾坐標(biāo)(Cartesian coordinate)。還有三維的散點(diǎn)圖。
讓我們?cè)囅耺atplotlib庫(kù)的scatter()方法:
plt.scatter(df['Total day minutes'], df['Total night minutes']);
我們得到了兩個(gè)正態(tài)分布變量的散點(diǎn)圖,這張圖沒(méi)什么意思??雌饋?lái)這兩個(gè)變量并不相關(guān),因?yàn)轭愃茩E圓的形狀和軸是對(duì)齊的。
seaborn庫(kù)創(chuàng)建的散點(diǎn)圖有一個(gè)略微奇特的選項(xiàng):
sns.jointplot(x='Total day minutes', y='Total night minutes',
data=df, kind='scatter');
jointplot()函數(shù)繪制了兩張直方圖,某些情形下它們可能會(huì)有用。這一函數(shù)還可以讓我們繪制平滑過(guò)的joint plot:
sns.jointplot('Total day minutes', 'Total night minutes',
data=df, kind="kde", color="g");
這個(gè)基本上是我們之前討論過(guò)的核密度圖的雙變量版本。
散點(diǎn)圖矩陣
在某些情形下,我們可能想要繪制如下所示的散點(diǎn)圖矩陣(scatterplot matrix)。它的對(duì)角線包含變量的分布,而每對(duì)變量的散點(diǎn)圖填充了矩陣的其余部分。
# 使用SVG格式可能導(dǎo)致pairplot變得非常慢
%config InlineBackend.figure_format = 'png'
sns.pairplot(df[numerical]);
有時(shí)候,這樣的可視化可能幫我們從數(shù)據(jù)中得出一些結(jié)論。
3.2 數(shù)量——類別
在這一小節(jié)中,讓我們的圖形更有趣一點(diǎn)。我們將嘗試從數(shù)值和類別特征的相互作用中得到離網(wǎng)預(yù)測(cè)的新洞見(jiàn)。
更具體地,讓我看看輸入變量和目標(biāo)變量離網(wǎng)的關(guān)系。
先前我們了解了散點(diǎn)圖。散點(diǎn)圖中的數(shù)據(jù)點(diǎn)可以通過(guò)色彩或尺寸進(jìn)行編碼,以便在同一張圖像中包括第三個(gè)類別變量的值。我們可以通過(guò)之前的scatter()函數(shù)達(dá)成這一點(diǎn),不過(guò),這次讓我們換換花樣,用lmplot()函數(shù)的hue參數(shù)來(lái)指定感興趣的類別特征:
sns.lmplot('Total day minutes', 'Total night minutes', data=df,
hue='Churn', fit_reg=False);
看起來(lái)占少數(shù)的不忠實(shí)客戶偏向右上角;也就是傾向于在白天和夜間打更多電話的客戶。但這不是非常明顯,我們也不會(huì)基于這一圖形下任何確定的結(jié)論。
現(xiàn)在,讓我們創(chuàng)建箱形圖,以可視化兩個(gè)互斥分組中的數(shù)值變量分布的統(tǒng)計(jì)數(shù)據(jù):忠實(shí)客戶(Churn=False)和離網(wǎng)客戶(Churn=True)。
# 有時(shí)我們可以將有序變量作為數(shù)值變量分析
numerical.append('Customer service calls')
fig, axes = plt.subplots(nrows=3, ncols=4, figsize=(10, 7))
for idx, feat in enumerate(numerical):
ax = axes[int(idx / 4), idx % 4]
sns.boxplot(x='Churn', y=feat, data=df, ax=ax)
ax.set_xlabel('')
ax.set_ylabel(feat)
fig.tight_layout();
從這一圖表中,我們可以看到,兩組之間分歧最大的分布是這三個(gè)變量:Total day minutes(日通話分鐘數(shù))、Customer service calls(客服呼叫數(shù))、Number vmail messages(語(yǔ)音郵件數(shù))。在后續(xù)的課程中,我們將學(xué)習(xí)如何使用隨機(jī)森林(Random Forest)或梯度提升(Gradient Boosting)來(lái)判定特征對(duì)分類的重要性;那時(shí)我們將看到,前兩個(gè)特征對(duì)于離網(wǎng)預(yù)測(cè)而言確實(shí)非常重要。
讓我們分別看下忠實(shí)客戶和不忠實(shí)客戶的日通話分鐘數(shù)。我們將創(chuàng)建箱形圖和提琴形圖。
_, axes = plt.subplots(1, 2, sharey=True, figsize=(10, 4))
sns.boxplot(x='Churn', y='Total day minutes',
data=df, ax=axes[0]);
sns.violinplot(x='Churn', y='Total day minutes',
data=df, ax=axes[1]);
在這一情形下,提琴形圖并沒(méi)有提供關(guān)于數(shù)據(jù)的額外信息,因?yàn)橄湫螆D已經(jīng)告訴了我們一切:不忠實(shí)客戶傾向于打更多的電話。
一個(gè)有趣的觀察:平均而言,終止他們的協(xié)議的客戶是通訊服務(wù)更活躍的用戶。也許他們對(duì)話費(fèi)不滿意,所以預(yù)防離網(wǎng)的一個(gè)可能措施是降低通話費(fèi)率。公司需要進(jìn)行額外的經(jīng)濟(jì)分析,以查明這樣的措施是否有利。
當(dāng)我們想要一次分析兩個(gè)類別維度下的數(shù)量變量時(shí),可以用seaborn庫(kù)的factorplot()函數(shù)。例如,在同一圖形中可視化Total day minutes(日通話分鐘數(shù))和兩個(gè)類別變量的相互作用:
sns.factorplot(x='Churn', y='Total day minutes',
col='Customer service calls',
data=df[df['Customer service calls'] < 8],
kind="box", col_wrap=4, size=3, aspect=.8);
從上圖我們可以總結(jié)出,從4次呼叫開(kāi)始,Total day minutes(日通話分鐘數(shù))可能不再是客戶離網(wǎng)的主要因素。也許,除了我們之前猜測(cè)的話費(fèi),有些客戶因?yàn)槠渌麊?wèn)題對(duì)服務(wù)不滿意,或許這導(dǎo)致了日通話分鐘數(shù)較少。
3.3 類別——類別
正如我們之前提到的,變量Customer service calls(客服呼叫數(shù))的唯一值極少,因此,既可以看成數(shù)值變量,也可以看成有序類別變量。我們已經(jīng)通過(guò)計(jì)數(shù)圖(countc plot)查看過(guò)它的分布了?,F(xiàn)在我們感興趣的是這一有序特征和目標(biāo)變量Churn(離網(wǎng))之間的關(guān)系。
讓我們?cè)僖淮问褂糜?jì)數(shù)圖看下客服呼叫數(shù)的分布。這次,我們同時(shí)傳入hue=Churn參數(shù),以便在圖形中加入類別維度:
sns.countplot(x='Customer service calls', hue='Churn', data=df);
觀察:呼叫客服達(dá)到4次以上后,離網(wǎng)率顯著增加了。
現(xiàn)在讓我們看下Churn(離網(wǎng))和二元特征International plan(國(guó)際套餐)、Voice mail plan(語(yǔ)音郵件套餐)的關(guān)系。
_, axes = plt.subplots(1, 2, sharey=True, figsize=(10, 4))
sns.countplot(x='International plan', hue='Churn',
data=df, ax=axes[0]);
sns.countplot(x='Voice mail plan', hue='Churn',
data=df, ax=axes[1]);
觀察:開(kāi)通國(guó)際套餐后,離網(wǎng)率會(huì)高很多;使用國(guó)際套餐是一個(gè)強(qiáng)烈的特征。我們?cè)谡Z(yǔ)音郵件套餐上沒(méi)有觀察到相同的效應(yīng)。
列聯(lián)表
除了使用圖形進(jìn)行類別分析之外,還可以使用統(tǒng)計(jì)學(xué)的傳統(tǒng)工具:列聯(lián)表(contingency table),又稱為交叉制表(cross tabulation),使用表格形式表示多個(gè)類別變量的頻率分布。特別地,它讓我們可以通過(guò)查看一列或一行來(lái)得知某個(gè)變量在另一變量的作用下的分布。
讓我們通過(guò)交叉制表看看Churn(離網(wǎng))和類別變量State(州)的關(guān)系:
pd.crosstab(df['State'], df['Churn']).T
State(州)的不同值很多:51. 我們看到每個(gè)周只有少量數(shù)據(jù)點(diǎn)——每個(gè)州只有3到17個(gè)客戶拋棄了運(yùn)營(yíng)商。讓我們暫時(shí)忽略這一點(diǎn),計(jì)算每個(gè)州的離網(wǎng)率,由高到低排列:
df.groupby(['State'])['Churn'].
agg([np.mean]).
sort_values(by='mean', ascending=False).T
乍看起來(lái),新澤西和加利福尼亞的離網(wǎng)率超過(guò)了25%,夏威夷和阿拉斯加的離網(wǎng)率則不到6%. 然而,這些結(jié)論是基于極少的樣本得出的,我們的觀察可能僅僅是這一特定數(shù)據(jù)集的性質(zhì)。我們可以通過(guò)Matthews和Cramer相關(guān)性假說(shuō)確認(rèn)這一點(diǎn),不過(guò)這個(gè)超出了這篇文章的范圍。
4. 全數(shù)據(jù)集
4.1 幼稚方法
上面我們查看了數(shù)據(jù)集的不同刻面(facet),猜測(cè)感興趣的特征,每次選擇其中的一小部分進(jìn)行可視化。我們一次僅僅處理兩到三個(gè)變量,能比較容易地觀察到數(shù)據(jù)的結(jié)構(gòu)和關(guān)系。但是,如果我們想一下子顯示所有特征呢?如何確保最終的可視化仍然是可解釋的?
我們可以為整個(gè)數(shù)據(jù)集使用hist()或者pairplot()方法,同時(shí)查看所有的特征。不過(guò),當(dāng)特征數(shù)目足夠多的時(shí)候,這樣的可視化分析很快就變得緩慢和低效。另外,我們其實(shí)仍然可以成對(duì)地分析變量,而不用一下子分析所有變量。
4.2 降維
大多數(shù)現(xiàn)實(shí)世界的數(shù)據(jù)集有很多特征,有時(shí)有上萬(wàn)個(gè)特征。每一個(gè)特征都可以被看成數(shù)據(jù)點(diǎn)空間的一維。因此,我們經(jīng)常需要處理高維數(shù)據(jù)集,可視化整個(gè)高維數(shù)據(jù)集相當(dāng)難。
為了從整體上查看一個(gè)數(shù)據(jù)集,我們需要在不損失很多數(shù)據(jù)信息的前提下,降低用于可視化的維度。這一任務(wù)稱為降維(dimensionality reduction)。降維是一個(gè)無(wú)監(jiān)督學(xué)習(xí)(unsupervised learning)問(wèn)題,因?yàn)槲覀冃枰诓唤柚魏伪O(jiān)督輸入的前提下,從數(shù)據(jù)自身得到新的低維特征。
主成分分析(Principal Component Analysis, PCA)是一個(gè)著名的降維方法,我們會(huì)在之后的課程中討論它。主成分分析有一個(gè)限制,它是線性(linear)算法,因而對(duì)數(shù)據(jù)有某些特定的限制。
有許多非線性方法,統(tǒng)稱流形學(xué)習(xí)(Manifold Learning)。最著名的流形學(xué)習(xí)方法之一是t-SNE。
4.3 t-SNE
讓我們?yōu)殡x網(wǎng)數(shù)據(jù)創(chuàng)建一個(gè)t-SNE表示。
這一方法的名字看起來(lái)很復(fù)雜,有些嚇人:t分布隨機(jī)近鄰嵌入(t-distributed Stohastic Neighbor Embedding)。它的數(shù)學(xué)也很令人印象深刻(我們不會(huì)在這里深究數(shù)學(xué),勇敢的讀者可以閱讀Laurens van der Maaten和Geoffrey Hinton在JMLR上發(fā)表的原論文)。它的基本思路很簡(jiǎn)單:為高維特征空間在二維平面(或三維超平面,不過(guò)基本上總是使用二維空間)上尋找一個(gè)投影,使得在原本的n維空間中相距很遠(yuǎn)的數(shù)據(jù)點(diǎn)在屏幕上同樣相距較遠(yuǎn)。而原本相近的點(diǎn)在平面上仍然相近。
本質(zhì)上,近鄰嵌入尋找保留了樣本的鄰居關(guān)系的新的維度較低的數(shù)據(jù)表示。
現(xiàn)在讓我們做些練習(xí)。首先,加載類:
from sklearn.manifold import TSNE
from sklearn.preprocessing importStandardScaler
我們?nèi)コ齋tate(州)和離網(wǎng)(Churn)變量,然后用pandas.Series.map()方法將二元特征的“Yes”/“No”轉(zhuǎn)換成數(shù)值:
X = df.drop(['Churn', 'State'], axis=1)
X['International plan'] = X['International plan'].
map({'Yes': 1, 'No': 0})
X['Voice mail plan'] = X['Voice mail plan'].
map({'Yes': 1, 'No': 0})
我們同樣需要?dú)w一化數(shù)據(jù)。我們從每個(gè)變量中減去均值,然后除以標(biāo)準(zhǔn)差。這些都可以使用StandardScaler來(lái)完成。
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
現(xiàn)在可以構(gòu)建t-SNE表示了:
tsne = TSNE(random_state=17)
tsne_repr = tsne.fit_transform(X_scaled)
然后可視化它的圖形:
plt.scatter(tsne_repr[:, 0], tsne_repr[:, 1]);
讓我們根據(jù)離網(wǎng)情況給t-SNE表示加上色彩(綠色表示忠實(shí)用戶,紅色表示不忠實(shí)用戶)。
plt.scatter(tsne_repr[:, 0], tsne_repr[:, 1],
c=df['Churn'].map({False: 'green', True: 'red'}));
我們可以看到,離網(wǎng)的客戶集中在低維特征空間的一小部分區(qū)域。
為了更好地理解這一圖像,我們可以使用剩下的兩個(gè)二元特征給圖像著色:International plan(國(guó)際套餐)和Voice mail plan(語(yǔ)音郵件套餐)。綠色代表相應(yīng)的二元特征是正值。
_, axes = plt.subplots(1, 2, sharey=True, figsize=(12, 5))
for i, name in enumerate(['International plan', 'Voice mail plan']):
axes[i].scatter(tsne_repr[:, 0], tsne_repr[:, 1],
c=df[name].map({'Yes': 'green', 'No': 'red'}))
axes[i].set_title(name)
現(xiàn)在很清楚了,許多退訂的不滿意客戶集中在西南聚類(表示開(kāi)通了國(guó)際套餐但沒(méi)有開(kāi)通語(yǔ)音郵件套餐)。
最后,讓我們了解下t-SNE的缺陷:
高計(jì)算復(fù)雜度。scikit-learn的實(shí)現(xiàn)在真實(shí)任務(wù)中往往不太管用。如果你有大量樣本,你應(yīng)該轉(zhuǎn)而使用Multicore-TSNE(多核)。
隨機(jī)數(shù)種子的不同會(huì)導(dǎo)致圖形大不相同,這給解釋帶來(lái)了困難。請(qǐng)參考文末相關(guān)資源給出的t-SNE教程。通常而言,你不應(yīng)該基于這些圖像做出任何深遠(yuǎn)的結(jié)論,因?yàn)樗赡芎蛦渭兊牟聹y(cè)差不多。當(dāng)然,t-SNE圖像中的某些發(fā)現(xiàn)可能會(huì)啟發(fā)一個(gè)想法,這個(gè)想法可以通過(guò)更全面深入的研究得到確認(rèn),但這并不經(jīng)常發(fā)生。
偶爾,t-SNE可以讓你從數(shù)據(jù)中得到非常好的直覺(jué)。下面的論文展示了一個(gè)這樣的例子:Visualizing MNIST(可視化MNIST)。
有時(shí)t-SNE真的能夠幫助你更好地理解數(shù)據(jù),有時(shí)t-SNE能夠幫助你畫(huà)出圣誕樹(shù)玩具 :-)
用t-SNE)
-
機(jī)器人
+關(guān)注
關(guān)注
211文章
28566瀏覽量
207716 -
Google
+關(guān)注
關(guān)注
5文章
1769瀏覽量
57658 -
數(shù)據(jù)集
+關(guān)注
關(guān)注
4文章
1208瀏覽量
24749 -
開(kāi)發(fā)編程
+關(guān)注
關(guān)注
0文章
4瀏覽量
5788
原文標(biāo)題:機(jī)器學(xué)習(xí)開(kāi)放課程(二):使用Python可視化數(shù)據(jù)
文章出處:【微信號(hào):jqr_AI,微信公眾號(hào):論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論