神經網絡在多分類上的應用——數據預處理部分
標簽: 神經網絡 多分類
- 首先建立思路,然后在實行過程中根據需求找方法和工具。
- 本文以
用三層神經網絡識別給定的圖片是人,貓還是狗項目為例,記錄實現過程中的思路,遇到的難點和多次的調整。
數據預處理
主要工具:pandas matplotlib seaborn numpy sklearn
- 項目已給定經過預處理后較小的數據集data.csv,數據集中僅含提取的圖像的特征結果。數據集部分如下面表格形式:
| feature1 | feature2 | feature3 | feature4 | class |
|---|---|---|---|---|
| 5.1 | 1400 | 1.4 | 2 | 0 |
| 4.9 | 1200 | 1.4 | 2 | 0 |
| 4.7 | 1280 | 1.3 | 2 | 0 |
[數據集描述]
數據集含有4個特征每個輸入的x向量有4個坐標;每行代表一個圖像;class代表圖像的類別:有三種情況——0代表是人,1代表是貓,2代表是狗
[加載數據]
使用pandas包讀取data文件為DataFrame格式。
dataset = pd.read_csv('data.csv')
[數據集隨機化]
由表格可以看出,數據集仍需要進一步處理:
數據集是按類別分類后按順序依次排列的,需要將其打亂。
已知python自帶有shuffle方法,這里dataset為DataFrame格式,可以使用pandas中設定抽取比例為1時的sample方法。
# 打亂后索引仍按照正常的排序
dataset = dataset.sample(frac=1).reset_index(drop=True)
[數據分析——數據可視化]
使用matplotlib包和seaborn工具繪制數據圖,直觀分析它們之間的關系和數據的特點。
matplotlib
- 選取feature1和feature2作為二維圖像的橫縱坐標;
- 分別取出類別為人,貓和狗時的二維特征數組;
- 分別繪制不同顏色的散點圖,注意這三種類別的數據點應該體現在一張二維圖像上。
代碼如下:
def plot_points(dataset):
X = np.array(dataset[["feature1", "feature2"]]) # X保存特征,先繪制二維圖(選取feature1和feature2)
y = np.array(dataset["class"]) # y保存類別
people = X[np.argwhere(y == 0)] # 取出圖片為人時的特征值數組
cat = X[np.argwhere(y == 1)] # 取出圖片為貓時的特征值數組
dog = X[np.argwhere(y == 2)] # 取出圖片為狗時的特征值數組
# 對於類別為人,貓,狗,分別繪制不同顏色的數據點——對應於同一張二維坐標圖
plt.scatter([s[0][0] for s in people], [s[0][1] for s in people], s=25, color='red', edgecolor='k')
plt.scatter([s[0][0] for s in cat], [s[0][1] for s in cat], s=25, color='cyan', edgecolor='k')
plt.scatter([s[0][0] for s in dog], [s[0][1] for s in dog], s=25, color='yellow', edgecolor='k')
plt.xlabel('Feature_1')
plt.ylabel('Feature_2')
plot_points(dataset)
plt.show() # 繪制散點圖
繪制圖像如下:

- 由上圖可以看出僅依據兩個特征並不能很好地分離圖片類別。
seaborn
- 使用seaborn中的pairplot函數繪制多變量圖——如本項目中特征有四個維度;
- 若pairplot的變量參數有n個,則會繪制n*n的方格。當i=j時,為直方圖;i≠j時,為散點圖;
- 仍然使用matplotlib的顯示函數來顯示圖像。
代碼如下:
import seaborn as sns # seaborn作為matplotlib的補充,導入后會覆蓋matplotlib的默認作圖風格
sns.pairplot(dataset, hue='class', vars=["feature1", "feature2", "feature3", "feature4"]) # hue : 使用指定變量為分類變量畫圖;vars : 與data使用,否則使用data的全部變量
plt.show() # 仍然使用matplotlib的顯示函數
繪制圖像如下:

- 根據四個特征維度,圖像的類別得到了很好地分離
[數據分離——將數據集拆分為輸入和標簽]
在訓練神經網絡時,訓練集的數據要分開使用:輸入每個數據的n維特征,得到神經網絡的輸出結果,並將該結果與訓練集中的類別[標簽]來對比,構造誤差函數等,從而利用梯度下降算法對神經網絡的模型進行優化。
可以使用pandas包中的iloc和loc屬性,其中
- loc是根據DataFrame的行、列標簽名來進行選取,可以選取單個元素,也可以選取一個區域
- iloc是根據DataFrame的行、列索引來進行選取,可以選取單個元素,也可以選取一個區域
代碼如下:
data = dataset.iloc[0: 150, 0: 4] # 輸入
# print(data)
label = dataset.iloc[0: 150, 4] # 標簽
# print(label)
[數據標准化]
有時輸入數據的幾個特征(維度)所在的數值范圍是不一致的,這意味着數據存在偏差,不利於神經網絡的處理,需要將所有特征的值規划到同一數值范圍內。
處理方法:一般將大的特征值縮小,可使用(x-min)/(max-min)規划到[0,1]的范圍內。
本例代碼:
data['feature2'] = (data['feature2'] - data['feature2'].min()) / (data['feature2'].max() - data['feature2'].min())
data['feature4'] = (data['feature4'] - data['feature4'].min()) / (data['feature4'].max() - data['feature4'].min())
[將類別(標簽)進行One-hot編碼]
- 原始訓練集的類別為0,1,2,不容易進行神經網絡的訓練,需要對標簽進行One-hot編碼;即有n種類別便將每個圖像的標簽轉化為n維向量,只有其對應正確類別的索引下的值為1,其余為0。
- 本項目是一個三分類問題,類別(離散特征)的取值之間沒有大小關系,可以使用One-hot編碼。[若有大小關系則采用數值映射的方式]
- 將標簽進行One-hot編碼后,可以對應softmax函數的概率分布意義,得到神經網絡的預測結果並進行誤差分析。
使用pandas庫中的get_dummies方法進行One-hot編碼:
one_hot_label = pd.get_dummies(label)
得到編碼后的部分標簽如下:

訓練數據集和測試數據集的划分
- 為防止過擬合,需要將給定的數據集按一定的比例划分為訓練集和測試集:訓練集用於得到優秀的神經網絡模型,測試集用於測試神經網絡的泛化能力。
- 數據集划分的比例和組成不同也會對神經網絡模型產生一定的影響
有很多方式可以進行數據集的隨機划分:
- 使用
numpy.random.choice - 使用
sklearn.model_selection.train_test_split或sklearn.cross_validation.train_test_split,其中cross_validation指交叉驗證。
這里使用第2種方式:
from sklearn.cross_validation import train_test_split
# 使用sklearn.cross_validation.train_test_split方法,暫取隨機數種子為1,以在重復試驗時,得到相同的隨機數組
train_data, test_data, train_label, test_label = train_test_split(data, label, test_size=0.3, random_state=1)
