承接上一篇有關(guān)如何處理數(shù)據(jù)的文章,這一篇,我們來(lái)一次實(shí)戰(zhàn),讓大家感受一下這個(gè)過(guò)程。
Iris數(shù)據(jù)集是一個(gè)比較特別的數(shù)據(jù)集,早在1936年Ronald Fisher就將此數(shù)據(jù)集用于了數(shù)據(jù)挖掘?qū)嶒?yàn)。Fisher是一位非常出名的遺傳統(tǒng)計(jì)學(xué)家,其用他所擅長(zhǎng)的統(tǒng)計(jì)利器揭開(kāi)了一個(gè)又一個(gè)有關(guān)生命的奧秘。
Iris數(shù)據(jù)集的地位就相當(dāng)于遺傳學(xué)家眼中的果蠅,其花朵的性狀分明,用來(lái)學(xué)習(xí)數(shù)據(jù)挖掘再好不過(guò)。因此python的sklearn庫(kù)中內(nèi)置了此數(shù)據(jù)集,大家不用下載,一行代碼就可以獲得該數(shù)據(jù)集。
導(dǎo)入,清洗
因?yàn)閿?shù)據(jù)規(guī)范,該數(shù)據(jù)不存在清洗的過(guò)程,導(dǎo)入也非常簡(jiǎn)單。
他的數(shù)據(jù)集里包含了150個(gè)個(gè)體,包含三種鳶尾花,分別是山鳶尾、變色鳶尾、維吉尼亞鳶尾。每一個(gè)個(gè)體有四個(gè)特征,分別是花萼的長(zhǎng)寬和花瓣的長(zhǎng)寬。同時(shí)還有標(biāo)簽變量target,表示了花朵的種類,用0、1、2表示。
存在csv文件中是這樣的。

下面是處理數(shù)據(jù)的代碼。代碼中涉及了如何將花個(gè)體與標(biāo)簽兩個(gè)表格合并的過(guò)程。
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')





從這幾張圖中我們就可以看出來(lái),相比于花萼的長(zhǎng)寬,這三種花在花瓣的長(zhǎng)寬上差異更加明顯。
多變量探索
接下來(lái)我們探索并比較,花萼長(zhǎng)寬和花瓣長(zhǎng)寬這兩組因子組合分別對(duì)花朵種類的影響。
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()


如果說(shuō)單變量探索的可視化結(jié)果還不夠明顯,那么多變量探索就更加說(shuō)明這個(gè)問(wèn)題。三種花在花瓣上的區(qū)別遠(yuǎn)遠(yuǎn)大于花萼。如果更細(xì)致的分析,在花萼寬的區(qū)別不如在花萼長(zhǎng)上的區(qū)別。
在花萼寬的區(qū)別上后兩種花性狀表現(xiàn)幾乎是互相交錯(cuò)的,不過(guò)這個(gè)性狀表現(xiàn)仍然可以清晰的分出第一種與后兩種花。因此我們四個(gè)因素都要用,不排除任何因子。
但是我們也發(fā)現(xiàn),貌似花萼長(zhǎng)寬之間是有相關(guān)關(guān)系的,花瓣長(zhǎng)度也是如此。所以我們要進(jìn)行降維。
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()
我們?cè)O(shè)置降維成三維,并在3D圖上可以直觀的感受到降維成三個(gè)解釋變量后的花朵分布情況。

K-means預(yù)測(cè)
我們只有150個(gè)個(gè)體,這里我們先將數(shù)據(jù)順序打亂,然后取前140個(gè)作為訓(xùn)練集,最后10個(gè)做測(cè)試集。
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)
運(yùn)行后發(fā)現(xiàn),我們的識(shí)別錯(cuò)誤率為10%。
分類情況可視化
我們現(xiàn)在將K-means方法的分類情況用散點(diǎn)圖可視化出來(lái),讓大家更直觀的感受到算法分類結(jié)果。

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()
我們可以很容易發(fā)現(xiàn)。第一類花和后面兩種花的分類情況是非常好的,但是后面兩種花就有點(diǎn)難分難解了。這在我們之前的單變量和多變量分析中其實(shí)也是有體現(xiàn),埋下伏筆了的。不過(guò)沒(méi)辦法,我們只有四個(gè)特征。
從這里也可以體現(xiàn),從單變量分析與多變量分析中確定大致的分析策略也是很重要的一步。
不要只重視模型的選擇,而忽略了數(shù)據(jù)的選擇!