使用python3.5重新驗證《python機器學習經典實例》中的代碼時,經常碰到各種警告與錯誤。
一般來說警告來自於函數庫的更新,原書使用python2.x,且函數庫古老,一些模塊被合併了,在調取對應方法時要記得更新名字,不然紅色警告傷眼。
拋出的異常錯誤集中在P40頁的對單一數據示例進行編碼測試中的這一句代碼:
input_data_encoded[i]=int(label_encoder[i].transform([input_data[i]]))
異常是:
raise ValueError("bad input shape {0}".format(shape))
ValueError: bad input shape ()
經過逐步分析,發現:input_data[i] 的值是單一字符串,但是transform方法中的參數需要列表格式,所以改成:[input_data[i]]
解決完這個問題後,第二個問題是:
output_class=classifier.predict(input_data_encoded)
報錯爲:
ValueError: Expected 2D array, got 1D array instead:
array=[ 3. 3. 0. 0. 2. 1.].
Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.
這個問題與第一個問題類似,要將 input_data_encoded 重塑成一維數組。
在重塑前 input_data_encoded的值是 :[0 0 1 1 2 0]
重塑代碼爲:
input_data_encoded=input_data_encoded.reshape(1,6)
重塑後是:[[0 0 1 1 2 0]]
以上就是本節的難點了,全部修正後代碼如下:
import numpy as np
from sklearn import preprocessing
from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt
from sklearn import model_selection
from sklearn.model_selection import validation_curve
from sklearn.model_selection import learning_curve
#畫圖時顯示中文字體
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
input_file=r'D:\python\AI\2\car.data.txt'
x=[]
count=0
with open(input_file,'r') as f:
for line in f.readlines():
data=line[:-1].split(',')
x.append(data)
x=np.array(x)
#字符串轉數值
label_encoder=[]
x_encoded=np.empty(x.shape)
for i,item in enumerate(x[0]):
label_encoder.append(preprocessing.LabelEncoder())
label_encoder[-1].fit(x[:,i])
x_encoded[:,i]=label_encoder[-1].transform(x[:,i])
x=x_encoded[:, :-1].astype(int)
y=x_encoded[:,-1].astype(int)
#訓練分類器
params={'n_estimators':200,'max_depth':8,'random_state':7}
classifier=RandomForestClassifier(**params)
classifier.fit(x,y)
#交叉驗證
accuracy=model_selection.cross_val_score(classifier,x,y,scoring='accuracy',cv=3)
print('Accuracy of the classifier(訓練器精度):'+str(round(100*accuracy.mean(),2))+'%')
#對單一數據示例進行編碼測試
input_data=['high','high','3','4','small','high']
input_data_encoded=[-1]*len(input_data)
for i,item in enumerate(input_data):
input_data_encoded[i]=int(label_encoder[i].transform([input_data[i]]))
input_data_encoded=np.array(input_data_encoded)
print('數組重塑前:',input_data_encoded)
#預測並打印數據點的輸出
#重塑數組
input_data_encoded=input_data_encoded.reshape(1,6)
print('數組重塑後:',input_data_encoded)
output_class=classifier.predict(input_data_encoded)
print('Output class(輸出類型):',label_encoder[-1].inverse_transform(output_class)[0])
#定義隨機森林迴歸器的超參數
#測試評估器數量參數對分類器的影響
classifier = RandomForestClassifier(max_depth=4, random_state=7)
parameter_grid = np.linspace(25, 200, 8).astype(int)
train_scores, validation_scores = validation_curve(classifier, x, y,
'n_estimators', parameter_grid, cv=5)
print('\n##### 驗證曲線 #####')
print('\nParam: n_estimators\nTraining scores:\n', train_scores)
print('\nParam: n_estimators\nValidation scores:\n', validation_scores)
#畫圖
plt.figure()
plt.plot(parameter_grid, 100*np.average(train_scores, axis=1), color='black')
plt.title(u'Training curve(訓練曲線)')
plt.xlabel(u'Number of estimators(評估器數量)')
plt.ylabel(u'Accuracy(準確度)')
plt.show()
#測試最大深度參數對分類器的影響
classifier = RandomForestClassifier(n_estimators=20, random_state=7)
parameter_grid = np.linspace(2, 10, 5).astype(int)
train_scores, valid_scores = validation_curve(classifier, x, y,
'max_depth', parameter_grid, cv=5)
print(u'\nParam: max_depth\nTraining scores:\n', train_scores)
print(u'\nParam: max_depth\nValidation scores:\n', validation_scores)
#畫圖
plt.figure()
plt.plot(parameter_grid, 100*np.average(train_scores, axis=1), color='black')
plt.title(u'Validation curve(驗證曲線)')
plt.xlabel(u'Maximum depth of the tree(樹的最大深度)')
plt.ylabel(u'Accuracy(準確度)')
plt.show()
#生成學習曲線
classifier = RandomForestClassifier(random_state=7)
parameter_grid = np.array([200, 500, 800, 1100])
train_sizes, train_scores, validation_scores = learning_curve(classifier,
x, y, train_sizes=parameter_grid, cv=5)
print('\n##### 學習曲線 #####')
print('\nTraining scores:\n', train_scores)
print('\nValidation scores:\n', validation_scores)
#畫圖
plt.figure()
plt.plot(parameter_grid, 100*np.average(train_scores, axis=1), color='black')
plt.title(u'Learning curve(學習曲線)')
plt.xlabel(u'Number of training samples(訓練樣本的數量)')
plt.ylabel(u'Accuracy(準確度)')
plt.show()