Summary of test0
- data : source data
- source code : in test0 file
- reference : - Reference Website / - Article in English Website
- attention : the link of reference used python 2.x ,i use python 3.x ,there are some difference
Overview
- import data and visualization (導入文件和數據可視化)
- classification (分類)
- cluster (聚類)
- regression (回歸)
- correlation (相關)
- dimensionality reduction (降維)
- web mining (uncompleted) (網絡挖掘)
import data and visualization
下載伯克利大學網站的一個文件。
數據是一個關於iris(鳶尾花)數據集,包含三種iris:setosa(山鳶尾),virginica(維吉尼亞鳶尾)和versicolor(變色鳶尾)各50個的多元樣本。每個包含四個feature(特征),sepal(花萼)的長,petal(花瓣)的長,sepal(花萼)的寬petal(花瓣)的寬。
import urllib
url = 'http://aima.cs.berkeley.edu/data/iris.csv'
u = urllib.request.urlopen(url)
localFile = open('iris.csv', 'wb+')
localFile.write(u.read())
localFile.close()
用csv文件保存到自己的硬盤上,csv文件方便被numpy類庫的getfromtxt方法解析。
from numpy import genfromtxt, zeros
# read the first 4 columns
data = genfromtxt('iris.csv',delimiter=',',usecols=(0,1,2,3))
# read the fifth column
target = genfromtxt('iris.csv',delimiter=',',usecols=(4),dtype=str)
解析完之后,創建了一個包含特征值的矩陣以及一個包含樣本類型的向量,可以通過shape方法確認數據集的大小。
#查看兩個數據集的大小
print (data.shape) #(150, 4)
print (target.shape) #(150, 4)
也可以用set查看我們有多少種樣本類型以及它們的名字:
#用set統計總共有及中類型
print (set(target)) # build a collection of unique elements
# {'setosa', 'versicolor', 'virginica'}
pylab類庫(matplotlib的接口) 的plot() 方法可以建一個二維散點圖讓我們在兩個維度上分析數據集的兩個特征值,繪制了關於sepal的長為橫軸,寬為y軸的二維散點圖:
#繪制二維散點圖
from pylab import plot, show
plot(data[target=='setosa',0],data[target=='setosa',2],'bo')
plot(data[target=='versicolor',0],data[target=='versicolor',2],'ro')
plot(data[target=='virginica',0],data[target=='virginica',2],'go')
show()
另一種常用的查看數據的方法是分特性繪制直方圖,可以用hist 方法。在本例中,既然數據被分為三類,我們就可以比較每一類的分布特征。下面這個代碼可以繪制數據中每一類型的第一個特性(sepal的長度):
#繪制直方圖
from pylab import figure, subplot, hist, xlim, show
xmin = min(data[:,0])
xmax = max(data[:,0])
figure()
subplot(411) # distribution of the setosa class (1st, on the top)
hist(data[target=='setosa',0],color='b',alpha=.7)
xlim(xmin,xmax)
subplot(412) # distribution of the versicolor class (2nd)
hist(data[target=='versicolor',0],color='r',alpha=.7)
xlim(xmin,xmax)
subplot(413) # distribution of the virginica class (3rd)
hist(data[target=='virginica',0],color='g',alpha=.7)
xlim(xmin,xmax)
subplot(414) # global histogram (4th, on the bottom)
hist(data[:,0],color='y',alpha=.7)
xlim(xmin,xmax)
show()
根據上圖的直方圖,我們可以根據數據類型區分理解數據的特征。例如,我們可以觀察到,山鳶尾的平均花萼長度小於維吉尼亞鳶尾。
classification
分類是一個數據挖掘方法,有兩個過程訓練和分類。訓練是指采集已知其特定類歸屬的數據並基於這些數據創建分類器。 分類是指使用通過這些已知數據建立的分類器來處理未知的數據,以判斷未知數據的分類情況。
Sklearn類庫 包含很多分類器的實現,我們將會使用高斯朴素貝葉斯來分析我們在第一章載入的鳶尾花數據,包含setosa(山鳶尾),virginica(維吉尼亞鳶尾)和versicolor(變色鳶尾)。最后我們把字符串數組轉型成整型數據,方便處理:
#把字符串數組轉型成整型數據
t = zeros(len(target))
t[target == 'setosa'] = 1
t[target == 'versicolor'] = 2
t[target == 'virginica'] = 3
然后准備實例化和訓練分類器:
from sklearn.naive_bayes import GaussianNB
classifier = GaussianNB()
classifier.fit(data,t) # training on the iris dataset
分類器可以由predict方法完成,輸出預測的結果和實際結果進行對比,做一個檢測
print (classifier.predict(data[0])) #[ 1.]
print (t[0]) #1.0
上例中predicted類包含了一個正確的樣本(山鳶尾),但是在廣泛的樣本上評估分類器並且使用非訓練環節的數據測試是很重要的。最終我們通過從源數據集中隨機抽取樣本把數據分為訓練集和測試集。我們將會使用訓練集的數據來訓練分類器,並使用測試集的數據來測試分類器。train_test_split方法正是實現此功能的:
from sklearn import cross_validation
train, test, t_train, t_test = cross_validation.train_test_split(data, t,test_size=0.4, random_state=0)
數據集被分一分為二,測試集被指定為源數據的40%(命名為test_size),我們用它反復訓練我們的分類器並輸出精確度:
classifier.fit(train,t_train) # train
print (classifier.score(test,t_test)) # test
#0.933333333333
在此例中,我們的精確度為93%。一個分類器的精確度是通過正確分類樣本的數量除以總樣本的數量得出的。也就是說,它意味着我們正確預測的比例。
另一個估計分類器表現的工具叫做混淆矩陣。在此矩陣中每列代表一個預測類的實例,每行代表一個實際類的實例。使用它可以很容易的計算和打印矩陣:
from sklearn.metrics import confusion_matrix
print confusion_matrix(classifier.predict(test),t_test)
#[[16 0 0]
# [ 0 23 4]
# [ 0 0 17]]
在這個混淆矩陣中我們可以看到所有山鳶尾和維吉尼亞鳶尾都被正確的分類了,但是實際上應該是26個的變色鳶尾,系統卻預測其中三個是維吉尼亞鳶尾。如果我們牢記所有正確的猜測都在表格的對角線上,那么觀測表格的錯誤就很容易了,即對角線以外的非零值。
可以展示分類器性能的報告Precision:正確預測的比例,Recall(或者叫真陽性率):正確識別的比例,F1-Score:precision和recall的調和平均數 :
from sklearn.metrics import classification_report
print (classification_report(classifier.predict(test), t_test, target_names=['setosa', 'versicolor', 'virginica']))
返回結果如下表格(表格0,0為空):
(return:) | precision | recall | f1-score | support |
---|---|---|---|---|
setosa | 1.00 | 1.00 | 1.00 | 16 |
versicolor | 1.00 | 0.85 | 0.92 | 27 |
virginica | 0.81 | 1.00 | 0.89 | 17 |
avg / total | 0.95 | 0.93 | 0.93 | 60 |
當然,分割數據、減少用於訓練的樣本數以及評估結果等操作都依賴於配對的訓練集和測試集的隨機選擇。如果要切實評估一個分類器並與其它的分類器作比較的話,我們需要使用一個更加精確的評估模型,例如Cross Validation。該模型背后的思想很簡單:多次將數據分為不同的訓練集和測試集,最終分類器評估選取多次預測的平均值。這次,sklearn為我們提供了運行模型的方法:
from sklearn.cross_validation import cross_val_score
# cross validation with 6 iterations
scores = cross_val_score(classifier, data, t, cv=6)
print(scores)
#[ 0.92592593 1. 0.91666667 0.91666667 0.95833333 1. ]
輸出是每次模型迭代產生的精確度的數組。我們可以很容易計算出平均精確度
from numpy import mean
print (mean(scores)) #0.952932098765
cluster
通常我們的數據上不會有標簽告訴我們它的樣本類型;我們需要分析數據,把數據按照它們的相似度標准分成不同的群組,群組(或者群集)指的是相似樣本的集合。這種分析被稱為無監督數據分析。最著名的聚類工具之一叫做k-means算法,如下所示:
from sklearn.cluster import KMeans
kmeans=KMeans(init='k-means++', n_clusters=3, n_init=10).fit(data) # initialization
上述片段運行k-measn算法並把數據分為三個群集(參數k所指定的)。現在我們可以使用模型把每一個樣本分配到三個群集中:
c = kmeans.predict(data)
我們可以估計群集的結果,與使用完整性得分和同質性得分計算而得的標簽作比較:
from sklearn.metrics import completeness_score, homogeneity_score
print (completeness_score(t,c)) #0.764986151449
print (homogeneity_score(t,c)) #0.751485402199
當大部分數據點屬於一個給定的類並且屬於同一個群集,那么完整性得分就趨向於1。當所有群集都幾乎只包含某個單一類的數據點時同質性得分就趨向於1.
當然我們可以把集群可視化並和帶有真實標簽的做可視化比較:
figure()
subplot(211) # top figure with the real classes
plot(data[t==1,0],data[t==1,2],'bo')
plot(data[t==2,0],data[t==2,2],'ro')
plot(data[t==3,0],data[t==3,2],'go')
subplot(212) # bottom figure with classes assigned automatically
plot(data[c==1,0],data[c==1,2],'bo',alpha=.7)
plot(data[c==2,0],data[c==2,2],'go',alpha=.7)
plot(data[c==0,0],data[c==0,2],'mo',alpha=.7)
show()
觀察此圖我們可以看到,底部左側的群集可以被k-means完全識別,然而頂部的兩個群集有部分識別錯誤。
regression
回歸是一個用於預測變量之間函數關系調查的方法。例如,我們有兩個變量,一個被認為是解釋,一個被認為是依賴。我們希望使用模型描述兩者的關系。當這種關系是一條線的時候就稱為線性回歸。
為了應用線性回歸我們建立一個由上所述的綜合數據集:
from numpy.random import rand
#rand() :Random values in a given shape.
x = rand(40,1) # explanatory variable
y = x*x*x+rand(40,1)/5 # depentent variable
我們可以使用在sklear.linear_model模塊中發現的LinearRegression模型。該模型可以通過計算每個數據點到擬合線的垂直差的平方和,找到平方和最小的最佳擬合線。使用方法和我們之前遇到的實現sklearn的模型類似:
from sklearn.linear_model import LinearRegression
linreg = LinearRegression()
linreg.fit(x,y)
我們可以通過把擬合線和實際數據點畫在同一幅圖上來評估結果:
from numpy import linspace, matrix
xx = linspace(0,1,40)
plot(x,y,'o',xx,linreg.predict(matrix(xx).T),'--r')
show()
觀察該圖我們可以得出結論:擬合線從數據點中心穿過,並可以確定是增長的趨勢。
我們還可以使用均方誤差來量化模型和原始數據的擬合度:
from sklearn.metrics import mean_squared_error
print (mean_squared_error(linreg.predict(x),y)) #0.0133012180196
該指標度量了預期的擬合線和真實數據之間的距離平方。當擬合線很完美時該值為0。
correlation
我們通過研究相關性來理解成對的變量之間是否相關,相關性的強弱。此類分析幫助我們精確定位被依賴的重要變量。最好的相關方法是皮爾遜積矩相關系數。它是由兩個變量的協方差除以它們的標准差的乘積計算而來。我們將鳶尾花數據集的變量兩兩組合計算出其系數如下所示:
from numpy import corrcoef
corr = corrcoef(data.T) # .T gives the transpose
print (corr)
#[[ 1. -0.10936925 0.87175416 0.81795363]
# [-0.10936925 1. -0.4205161 -0.35654409]
# [ 0.87175416 -0.4205161 1. 0.9627571 ]
# [ 0.81795363 -0.35654409 0.9627571 1. ]]
corrcoef方法通過輸入行為變量列為觀察值的矩陣,計算返回相關系數的對稱矩陣。該矩陣的每個元素代表着兩個變量的相關性。
當值一起增長時相關性為正。當一個值減少而另一個只增加時相關性為負。特別說明,1代表完美的正相關,0代表不相關,-1代表完美的負相關。
當變量數增長時我們可以使用偽彩色點很方便的可視化相關矩陣:
from pylab import pcolor, colorbar, xticks, yticks
from numpy import arange
pcolor(corr)
colorbar() # add
# arranging the names of the variables on the axis
xticks(arange(0.5,4.5),['sepal length', 'sepal width', 'petal length', 'petal width'],rotation=-20)
yticks(arange(0.5,4.5),['sepal length', 'sepal width', 'petal length', 'petal width'],rotation=-20)
show()
看圖中的彩條,我們可以把顏色點關聯到數值上。
我們可以看出我們數據集的最強相關是“petal width(花瓣寬度)”和“sepal length(花瓣長度)”這兩個變量。
dimensionality reduction
在第一章中我們了解了如何將鳶尾花數據集的兩個維度可視化。單獨使用該方法,我們只能看到數據集的部分數據視圖。既然我們可以同時繪制的最高維度數為3,將整個數據集嵌入一系列維度並建立一個整體可視化視圖是很有必要的。這個嵌入過程就被稱作降維。最著名的降維技術之一就是主成分分析(PCA)。該技術把數據變量轉換為等量或更少的不相關變量,稱為主成分(PCs)。
這次,sklearn滿足我們本次分析的所有需求:
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
上述片段中我們實例化了一個PCA對象,用於計算前兩個主成分。轉換計算如下:
pcad = pca.fit_transform(data)
然后如往常一樣繪制結果:
plot(pcad[target=='setosa',0],pcad[target=='setosa',1],'bo')
plot(pcad[target=='versicolor',0],pcad[target=='versicolor',1],'ro')
plot(pcad[target=='virginica',0],pcad[target=='virginica',1],'go')
show()
可以注意到上圖和第一章提到的有些相似,不過這次變色鳶尾(紅色的)和維吉尼亞鳶尾(綠色的)的間隔更清晰了。
PCA將空間數據方差最大化,我們可以通過方差比判斷PCs包含的信息量:
print (pca.explained_variance_ratio_)
#[ 0.92461621 0.05301557]
現在我們知道第一個PC占原始數據的92%的信息量而第二個占剩下的5%。我們還可以輸出在轉化過程中丟失的信息量:
print (1-sum(pca.explained_variance_ratio_))
#0.0223682249752
在本例中我們損失了2%的信息量。
此時,我們可以是應用逆變換還原原始數據,
可以證明的是,由於信息丟失逆變換不能給出准確的原始數據。我們可以估算逆變換的結果和原始數據的相似度:
data_inv = pca.inverse_transform(pcad)
print (abs(sum(sum(data - data_inv))))
#5.10702591328e-15
可以看出原始數據和逆變換計算出的近似值之間的差異接近於零。通過改變主成分的數值來計算我們能夠覆蓋多少信息量是很有趣的:
for i in range(1,5):
pca = PCA(n_components=i)
pca.fit(data)
print (sum(pca.explained_variance_ratio_) * 100,'%' )
#92.4616207174 %
#97.7631775025 %
#99.481691455 %
#100.0 %
PCs用得越多,信息覆蓋就越全,不過這段分析有助於我們理解保存一段特定的信息需要哪些組件。例如,從上述片段可以看出,只要使用三個PCs就可以覆蓋鳶尾花數據集的幾乎100%的信息。