承接上一篇有關如何處理數據的文章,這一篇,我們來一次實戰,讓大家感受一下這個過程。
Iris數據集是一個比較特別的數據集,早在1936年Ronald Fisher就將此數據集用于了數據挖掘實驗。Fisher是一位非常出名的遺傳統計學家,其用他所擅長的統計利器揭開了一個又一個有關生命的奧秘。
Iris數據集的地位就相當于遺傳學家眼中的果蠅,其花朵的性狀分明,用來學習數據挖掘再好不過。因此python的sklearn庫中內置了此數據集,大家不用下載,一行代碼就可以獲得該數據集。
導入,清洗
因為數據規范,該數據不存在清洗的過程,導入也非常簡單。
他的數據集里包含了150個個體,包含三種鳶尾花,分別是山鳶尾、變色鳶尾、維吉尼亞鳶尾。每一個個體有四個特征,分別是花萼的長寬和花瓣的長寬。同時還有標簽變量target,表示了花朵的種類,用0、1、2表示。
存在csv文件中是這樣的。
下面是處理數據的代碼。代碼中涉及了如何將花個體與標簽兩個表格合并的過程。
from sklearn import datasets
import matplotlib.pyplot as plt
from pandas import DataFrame
import pandas as pd
import os
path = 'C:/python/python code/scikit-learn/'
iris = datasets.load_iris()
data = iris.data
target = iris.target
data_information = DataFrame(data, columns=['bcalyx', 'scalyx', 'length', 'width'])
data_target = DataFrame(target, columns = ['target'])
data_csv = pd.concat([data_information, data_target], axis = 1)
if not os.path.exists(path):
os.makedirs(path)
filename = path + 'data.csv'
data_csv.to_csv(filename)
單變量探索
下面是單變量探索的代碼。
import matplotlib.pyplot as plt
from pandas import DataFrame
import pandas as pd
def drawing(nature):
data = pd.read_csv('data.csv')
data1 = data[data['target'] == 0]
data2 = data[data['target'] == 1]
data3 = data[data['target'] == 2]
breed1_bcalyx = []
for i in data1[nature]:
breed1_bcalyx.append(i)
breed2_bcalyx = []
for i in data2[nature]:
breed2_bcalyx.append(i)
breed3_bcalyx = []
for i in data3[nature]:
breed3_bcalyx.append(i)
breed = []
breed.append(breed1_bcalyx)
breed.append(breed2_bcalyx)
breed.append(breed3_bcalyx)
pd1 = DataFrame(breed, index = ['breed1', 'breed2', 'breed3'])
pd1 = pd1.T
pd1.plot()
plt.show()
drawing('width')
從這幾張圖中我們就可以看出來,相比于花萼的長寬,這三種花在花瓣的長寬上差異更加明顯。
多變量探索
接下來我們探索并比較,花萼長寬和花瓣長寬這兩組因子組合分別對花朵種類的影響。
import matplotlib.pyplot as plt
from sklearn import datasets
import matplotlib.patches as mpatches
iris = datasets.load_iris()
x = iris.data[:, 2]
y = iris.data[:, 3]
species = iris.target
x_min, x_max = x.min()-.5, x.max() + .5
y_min, y_max = y.min()-.5, y.max() + .5
plt.figure()
plt.scatter(x, y, c = species)
plt.title('Iris Dataset - Classification By Petal Sizes', size = 14)
plt.xlabel('Petal length')
plt.ylabel('Petal width')
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.xticks(())
plt.yticks(())
plt.show()
如果說單變量探索的可視化結果還不夠明顯,那么多變量探索就更加說明這個問題。三種花在花瓣上的區別遠遠大于花萼。如果更細致的分析,在花萼寬的區別不如在花萼長上的區別。
在花萼寬的區別上后兩種花性狀表現幾乎是互相交錯的,不過這個性狀表現仍然可以清晰的分出第一種與后兩種花。因此我們四個因素都要用,不排除任何因子。
但是我們也發現,貌似花萼長寬之間是有相關關系的,花瓣長度也是如此。所以我們要進行降維。
import matplotlib.pyplot as plt
from sklearn import datasets
from mpl_toolkits.mplot3d import Axes3D
from sklearn.decomposition import PCA
iris = datasets.load_iris()
x_reduced = PCA(n_components = 3).fit_transform(iris.data)
species = iris.target
fig = plt.figure()
ax = Axes3D(fig)
ax.set_title('Iris Dataset by PCA', size = 14)
ax.scatter(x_reduced[:, 0], x_reduced[:, 1], x_reduced[:, 2], c = species)
ax.set_xlabel('eigenvector1')
ax.set_ylabel('eigenvector2')
ax.set_zlabel('eigenvector3')
ax.w_xaxis.set_ticklabels(())
ax.w_yaxis.set_ticklabels(())
ax.w_zaxis.set_ticklabels(())
plt.show()
我們設置降維成三維,并在3D圖上可以直觀的感受到降維成三個解釋變量后的花朵分布情況。
K-means預測
我們只有150個個體,這里我們先將數據順序打亂,然后取前140個作為訓練集,最后10個做測試集。
import numpy as np
from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier
np.random.seed(0)
iris = datasets.load_iris()
x = iris.data
y = iris.target
i = np.random.permutation(len(iris.data))
x_train, y_train = x[i[:-10]], y[i[:-10]]
x_test, y_test = x[i[-10:]], y[i[-10:]]
knn = KNeighborsClassifier()
knn.fit(x_train, y_train)
y_pre_test = knn.predict(x_test)
print(y_pre_test)
print(y_test)
運行后發現,我們的識別錯誤率為10%。
分類情況可視化
我們現在將K-means方法的分類情況用散點圖可視化出來,讓大家更直觀的感受到算法分類結果。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn import datasets
from sklearn.neighbors import KNeighborsClassifier
iris = datasets.load_iris()
x = iris.data[:, :2]
y = iris.target
x_min, x_max = x[:, 0].min() - .5, x[:, 0].max() + .5
y_min, y_max = x[:, 1].min() - .5, x[:, 1].max() + .5
cmap_light = ListedColormap(['#AAAAFF', '#AAFFAA', '#FFAAAA'])
h = .02
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
knn = KNeighborsClassifier()
knn.fit(x, y)
Z = knn.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
plt.figure()
plt.pcolormesh(xx, yy, Z, cmap = cmap_light)
plt.scatter(x[:, 0], x[:, 1], c = y)
#plt.xlim(xx.min(), xx.max())
#plt.ylim(yy.min(). yy.max())
plt.show()
我們可以很容易發現。第一類花和后面兩種花的分類情況是非常好的,但是后面兩種花就有點難分難解了。這在我們之前的單變量和多變量分析中其實也是有體現,埋下伏筆了的。不過沒辦法,我們只有四個特征。
從這里也可以體現,從單變量分析與多變量分析中確定大致的分析策略也是很重要的一步。
不要只重視模型的選擇,而忽略了數據的選擇!