機器學習實踐之手寫數字識別- 數據階段分析總結



機器學習實踐之手寫數字識別 - 數據初識
2. 機器學習實踐之手寫數字識別 - 初步特征選擇及線性識別
前面兩章對數據進行了簡單的特征提取及線性回歸分析。識別率已經達到了85%, 完成了數字識別的第一步:數據探測。 這一章要做的就各種常用機器學習算法來對數據進行測試,並總結規律,為后續進一步提供准確率作准備。 這單選取的算法有:(后面有時間再對每個算法單獨作分析總結介紹):
  1. 線性回歸
  2. 支持向量機
  3. 決策樹
  4. 朴素貝葉斯
  5. KNN算法
  6. 邏輯回歸
以測試樣本的最后一千個數作為測試樣例,其它的作為訓練樣例。 數據結果為測試樣例的識別結果。

使用到的統計概念有:precision,recall及f1-score(參見文章機器學習結果統計-准確率、召回率,F1-score 先看測試總結數據,后面會提供完整代碼及數據提供。使用的機器學習算法庫為:http://scikit-learn.org/
算法測試數據 對算法進行測試,測試數據如下:
測試算法 中文 precision recall f1-score 樣本數 所花時間(秒)
LinearRegression 線性回歸 0.84 0.84 0.84 1000 2.402
SVC 支持向量機 0.85 0.85 0.85 1000 22.72
DecisionTree 決策樹 0.81 0.81 0.81 1000 0.402
Bayes 朴素貝葉斯 0.78 0.77 0.77 1000 0.015
KNN KNN算法 0.86 0.86 0.86 1000 0.374
LogisticRegression 邏輯回歸 0.82 0.82 0.82 1000 2.419

總結: 算法識別結果想差不多,除了貝葉斯之外都在80%以上。  時間花銷上SVC算法花得最多。而貝葉斯花得最小。  在手寫識別上,如果樣本量夠多,相比之下KNN算法會更確。
分析: 由於貝葉期是基於概率統計的算法。 計算時間會很快。而由於缺乏對特征之間的關心的支持,識別率會弱一些。
各數字識別統計
  線性回歸 支持向量機 決策樹 基本貝葉斯算法 KNN算法 邏輯回歸    
數字 recall precision recall precision recall precision recall precision recall precision recall precision recall 平均 precision平均
0 0.93 0.83 0.93 0.88 0.92 0.9 0.92 0.88 0.95 0.87 0.95 0.89 0.933 0.875
1 0.96 0.91 0.97 0.97 0.96 0.96 0.97 0.84 0.99 0.98 0.94 0.94 0.965 0.933
2 0.82 0.82 0.84 0.76 0.8 0.74 0.59 0.73 0.81 0.81 0.73 0.76 0.765 0.770
3 0.79 0.72 0.75 0.74 0.71 0.74 0.71 0.61 0.81 0.71 0.73 0.67 0.750 0.698
4 0.68 0.87 0.73 0.84 0.7 0.77 0.64 0.83 0.75 0.85 0.68 0.78 0.697 0.823
5 0.73 0.78 0.75 0.8 0.66 0.73 0.67 0.63 0.78 0.84 0.8 0.8 0.732 0.763
6 0.93 0.93 0.92 0.88 0.89 0.88 0.91 0.84 0.92 0.91 0.89 0.91 0.910 0.892
7 0.89 0.83 0.88 0.85 0.78 0.72 0.74 0.78 0.87 0.88 0.86 0.82 0.837 0.813
8 0.83 0.83 0.83 0.85 0.78 0.79 0.82 0.77 0.81 0.9 0.83 0.8 0.817 0.823
9 0.82 0.86 0.82 0.85 0.86 0.83 0.72 0.8 0.84 0.81 0.79 0.8 0.808 0.825

數據總結:
  1. 整體數據中,1,6的識別率最高,而2, 3, 4, 5識別率最低。說明數據中比較難區分2, 3, 4, 5的屬性。
  2. 注意線性回歸中,0的recall 大於precision10個百分點,意味着把別的數據錯誤識別成0成的較多。
  3. 4中 recall小於precision 20%面分則說明識別4的特征不明顯。



終合上面分析結果得到后續計划:
  1. 繼續分析數據,尋找更有用的特征值。
  2. 使用KNN來作為數據分析算法。


測試代碼
import numpy as np
from sklearn.naive_bayes import GaussianNB
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.linear_model import LinearRegression
from sklearn.svm import SVC
import functools
from datetime import datetime
from time import clock

from sklearn import metrics
from tools import load_data, load_source, show_source


def log_time(fn):
@functools.wraps(fn)
def wrapper():
start = clock()
ret = fn()
end = clock()
print("{} use time: {:.3f} s" .format (fn.__name__, end-start))
return ret
return wrapper

#加載訓練數據
data_x, data_y = load_data("train.txt")

# 加載原始數據
source_data = load_source("train.csv")

# 打印數據長度
print("len", len(data_x), len(data_y))

# 設置測試數據數量
LEN = -1000
# 划分訓練數據和測試數據 注: 當前測試中用到測試數據訓練集(train.csv)的數據, 而暫時沒有用到測試數據集的數據(test.csv)
x_train, y_train = data_x[:LEN], data_y[:LEN]
x_test, y_test = data_x[LEN:], data_y[LEN:]

@log_time
def tran_LinearRegression():
# 定義45個線性分類器,並訓練數據,每個分類器只對兩個數字進行識別
RegressionDict = {}
for i in range(10):
for j in range(i+1, 10):
regr = LinearRegression()
RegressionDict["{}-{}".format(i, j)] = regr
x_train_tmp = np.array([x_train[index] for index, y in enumerate(y_train) if y in [i, j]])
y_train_tmp = np.array([0 if y == i else 1 for y in y_train if y in [i, j]])
regr.fit(x_train_tmp, y_train_tmp)

# 初始化計數器
ret_counter = []
for i in range(len(x_test)):
ret_counter.append({})
# 預測數據,並把結果放到計數器中
tmp_dict = {}
for key, regression in RegressionDict.items():
a, b = key.split('-')
y_test_predict = regression.predict(x_test)
tmp_dict[key] = [a if item <= 0.5 else b for item in y_test_predict]
for i, item in enumerate(tmp_dict[key]):
ret_counter[i][item] = ret_counter[i].get(item, 0) + 1

predict = []
for i, item in enumerate(y_test):
predict.append(int(sorted(ret_counter[i].items(), key=lambda x:x[1],reverse=True)[0][0]))

return predict


print("\nLinearRegression")
predicted = tran_LinearRegression()
print(metrics.classification_report(y_test, predicted))
print("count:", len(y_test), "ok:", sum([1 for item in range(len(y_test)) if y_test[item]== predicted[item]]))

# 其它常用分類器測試
map_predictor = {
"LogisticRegression":LogisticRegression(),
"bayes":GaussianNB(),
"KNN": KNeighborsClassifier(),
"DecisionTree":DecisionTreeClassifier(),
"SVC":SVC()
}

for key, model in map_predictor.items():

start = clock()
print("start: ",start, key, datetime.utcnow())
model.fit(x_train, y_train)
end = clock()
print("end: ",end, key, datetime.utcnow())
print("{} use time: {:.3f} s".format(key, end-start))
predicted = model.predict(x_test)
print(metrics.classification_report(y_test, predicted))
print("count:", len(y_test), "ok:", sum([1 for item in range(len(y_test)) if y_test[item]== predicted[item]]))

輸出結果

len 42000 42000

LinearRegression
/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/scipy/linalg/basic.py:884: RuntimeWarning: internal gelsd driver lwork query error, required iwork dimension not returned. This is likely the result of LAPACK bug 0038, fixed in LAPACK 3.2.2 (released July 21, 2010). Falling back to 'gelss' driver.
warnings.warn(mesg, RuntimeWarning)
tran_LinearRegression use time: 2.402 s
precision recall f1-score support

0.0 0.84 0.93 0.89 92
1.0 0.91 0.96 0.93 127
2.0 0.79 0.84 0.81 97
3.0 0.73 0.77 0.75 95
4.0 0.87 0.68 0.77 111
5.0 0.79 0.73 0.76 85
6.0 0.92 0.94 0.93 103
7.0 0.83 0.89 0.86 101
8.0 0.83 0.83 0.83 88
9.0 0.87 0.82 0.85 101

avg / total 0.84 0.84 0.84 1000

count: 1000 ok: 843
start: 3.398754 SVC 2016-06-30 11:06:01.412944
end: 26.118339 SVC 2016-06-30 11:06:24.145873
SVC use time: 22.720 s
precision recall f1-score support

0.0 0.88 0.93 0.91 92
1.0 0.97 0.97 0.97 127
2.0 0.76 0.84 0.80 97
3.0 0.74 0.75 0.74 95
4.0 0.84 0.73 0.78 111
5.0 0.80 0.75 0.78 85
6.0 0.88 0.92 0.90 103
7.0 0.85 0.88 0.86 101
8.0 0.85 0.83 0.84 88
9.0 0.85 0.82 0.83 101

avg / total 0.85 0.85 0.85 1000

count: 1000 ok: 846
start: 26.90291 KNN 2016-06-30 11:06:24.930844
end: 27.276969 KNN 2016-06-30 11:06:25.304922
KNN use time: 0.374 s
precision recall f1-score support

0.0 0.87 0.95 0.91 92
1.0 0.98 0.99 0.98 127
2.0 0.81 0.81 0.81 97
3.0 0.71 0.81 0.75 95
4.0 0.85 0.75 0.79 111
5.0 0.84 0.78 0.80 85
6.0 0.91 0.92 0.92 103
7.0 0.88 0.87 0.88 101
8.0 0.90 0.81 0.85 88
9.0 0.81 0.84 0.83 101

avg / total 0.86 0.86 0.86 1000

count: 1000 ok: 857
start: 27.368384 DecisionTree 2016-06-30 11:06:25.396350
end: 27.770018 DecisionTree 2016-06-30 11:06:25.798082
DecisionTree use time: 0.402 s
precision recall f1-score support

0.0 0.88 0.92 0.90 92
1.0 0.98 0.97 0.97 127
2.0 0.77 0.75 0.76 97
3.0 0.77 0.74 0.75 95
4.0 0.75 0.69 0.72 111
5.0 0.75 0.71 0.73 85
6.0 0.86 0.90 0.88 103
7.0 0.71 0.78 0.75 101
8.0 0.80 0.78 0.79 88
9.0 0.83 0.85 0.84 101

avg / total 0.81 0.81 0.81 1000

count: 1000 ok: 815
start: 27.772331 LogisticRegression 2016-06-30 11:06:25.800391
end: 30.191443 LogisticRegression 2016-06-30 11:06:28.219996
LogisticRegression use time: 2.419 s
precision recall f1-score support

0.0 0.89 0.95 0.92 92
1.0 0.94 0.94 0.94 127
2.0 0.76 0.73 0.75 97
3.0 0.67 0.73 0.70 95
4.0 0.78 0.68 0.73 111
5.0 0.80 0.80 0.80 85
6.0 0.91 0.89 0.90 103
7.0 0.82 0.86 0.84 101
8.0 0.80 0.83 0.82 88
9.0 0.80 0.79 0.80 101

avg / total 0.82 0.82 0.82 1000

count: 1000 ok: 822
start: 30.19377 bayes 2016-06-30 11:06:28.222098
end: 30.209151 bayes 2016-06-30 11:06:28.237481
bayes use time: 0.015 s
precision recall f1-score support

0.0 0.88 0.92 0.90 92
1.0 0.84 0.97 0.90 127
2.0 0.73 0.59 0.65 97
3.0 0.61 0.71 0.65 95
4.0 0.83 0.64 0.72 111
5.0 0.63 0.67 0.65 85
6.0 0.84 0.91 0.87 103
7.0 0.78 0.74 0.76 101
8.0 0.77 0.82 0.80 88
9.0 0.80 0.72 0.76 101

avg / total 0.78 0.77 0.77 1000

count: 1000 ok: 774


代碼及測試數據下載


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com