最近開始學習《機器學習實戰(zhàn)》這本書,以下是在學習過程中學到的一些python基礎(chǔ)知識以及算法思想袖外。
python版本:3.6
1奏甫、算法核心思想概述
算法思想:k-近鄰算法采用測量不同特征值之間的距離方法進行分類扶供。
優(yōu)點:精度高囤耳、對異常值不敏感、無數(shù)據(jù)輸入假定
缺點:計算復(fù)雜度高面褐、空間復(fù)雜度高
適用數(shù)據(jù)范圍:數(shù)值型拌禾、標稱型
一個樣本在特征空間里k個距離最短的樣本中,大多數(shù)樣本屬于A類展哭,則這個樣本也屬于A類湃窍。
1.1 k-近鄰算法的一般流程
(1)收集數(shù)據(jù):可以使用任何方法
(2)準備數(shù)據(jù):距離計算所需的數(shù)值,最好是結(jié)構(gòu)化的數(shù)據(jù)格式
(3)分析數(shù)據(jù):可以使用任何方法
(4)測試數(shù)據(jù):計算錯誤率
(5)使用算法:首先需要輸入樣本數(shù)據(jù)和結(jié)構(gòu)化的輸出結(jié)果匪傍,然后運行kNN算法判定輸入數(shù)據(jù)屬于哪個分類您市,最后應(yīng)用對計算出的分類執(zhí)行后續(xù)的處理。
1.2 分類函數(shù)
本函數(shù)的功能為:使用kNN算法將每組數(shù)據(jù)劃分到某個類別中役衡。首先計算出特征向量間的距離茵休,然后選取與當前距離最小的k個點,并通過這k個點類別出現(xiàn)的頻率來確定當前點的預(yù)測分類。
在最初的學習中遇到以下幾個python相關(guān)的基礎(chǔ)知識:
(1)shape
函數(shù)
a.shape[0]
計算行數(shù)
a.shape[1]
計算列數(shù)
(2)title
函數(shù)
>>>a = array([1,2])
>>>title(a, (3,2))
array([[1, 2, 1, 2],
[1, 2, 1, 2],
[1, 2, 1, 2]])
(3)axis=0
矩陣每一列相加榕莺, axis=1
矩陣每一行相加
(4)argsort
函數(shù):返回數(shù)組的索引值
(5)dict.get(key, default=None)
key:要查找的鍵俐芯;default:指定鍵的值不存在則返回默認值。
以下是算法詳細代碼:
from numpy import *
import operator
def createDataSet():
group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
labels = ['A', 'A', 'B', 'B']
return group, labels
def classify0(inK, dataSet, labels, k):
# 計算訓(xùn)練樣本的行數(shù)钉鸯,也就是有幾組訓(xùn)練樣本
dataSetSize = dataSet.shape[0]
# 將新樣本與每一個訓(xùn)練樣本相減
diffMat = tile(inK, (dataSetSize, 1)) - dataSet
sqDiffMat = diffMat ** 2
# 將結(jié)果每一行相加泼各,平方和
sqDistances = sqDiffMat.sum(axis=1)
# 求距離
distances = sqDistances ** 0.5
# 將距離按照從小到大順序排列
sortedDistIndicies = distances.argsort() # argsort返回的是索引值
classCount = {}
# 選取與當前點距離最小的K個點,確定前K個點所在類別的出現(xiàn)頻率
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
# 將前K個值按照出現(xiàn)頻率最高的類別進行逆序排序
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
執(zhí)行代碼如下
import kNN
input = [3, 0]
group, labels = kNN.createDataSet()
output = kNN.classify0(input, group, labels, 3)
print("分類結(jié)果為:", output)
2亏拉、改進約會網(wǎng)站配對效果
示例內(nèi)容:產(chǎn)生簡單的命令行程序,用戶可以輸入一些特征數(shù)據(jù)來判斷對方是否為自己喜歡的類型逆巍。
2.1準備數(shù)據(jù):從文本文件中解析數(shù)據(jù)
此時數(shù)據(jù)已經(jīng)存放在文本文件中及塘,在將數(shù)據(jù)輸入到分類器之前,需要將待處理的數(shù)據(jù)變成分類器可以接受的格式锐极。(數(shù)據(jù)為看數(shù)據(jù)所占時間數(shù)笙僚、每年的飛行里程數(shù)、每周消耗的冰淇淋公升數(shù))
創(chuàng)建一個file2matrix
的函數(shù)灵再,用來解析數(shù)據(jù)肋层。函數(shù)的輸入為文件名稱字符,輸出為訓(xùn)練樣本矩陣和類標簽向量翎迁。
以下是學到的一些小知識:
(1)readlines()
函數(shù)
使用方法:fileObject.readlines( );
返回值:返回列表栋猖,包含所有的行
(2)numpy
高維數(shù)組操作
本部分主要是想提一下以slice的方式來獲取數(shù)據(jù)
下圖來自博客園
以下是算法詳細代碼:
def file2matrix(filename):
# 得到文件的行數(shù)
fr = open(filename)
arrayOLines = fr.readlines()
numberOfLines = len(arrayOLines)
# 創(chuàng)建返回的numpy矩陣,矩陣使用0填充,numberOfLines行汪榔,3列
returnMat = zeros((numberOfLines, 3))
classLabelVector = []
index = 0
# 解析文件數(shù)據(jù)到列表蒲拉,循環(huán)處理文件中的每行數(shù)據(jù)
for line in arrayOLines:
# 去掉每行回車字符
line = line.strip()
# 將上一步得到的整行數(shù)據(jù)分割成一個元素列表
listFromLine = line.split('\t')
# 選取列表的前3個元素并存儲到特征向量中
returnMat[index, :] = listFromLine[0:3]
# 將列表的最后一列存儲到向量中
classLabelVector.append(int(listFromLine[-1]))
index += 1
return returnMat, classLabelVector
在測試結(jié)果時,需要重載kNN模塊痴腌,需要導(dǎo)入模塊importlib
然后輸入如下命令:
importlib.reload(kNN)
datingDataMat, datingLabels = kNN.file2matrix('datingTestSet2.txt')
2.2分析數(shù)據(jù):使用Matplotlib創(chuàng)建散點圖
本部分主要采用直觀的圖表來分析數(shù)據(jù)結(jié)構(gòu)雌团。
以下是算法詳細代碼:
import kNN
import numpy
import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(datingDataMat[:,0], datingDataMat[:,1], 15.0*numpy.array(datingLabels), 15.0*numpy.array(datingLabels))
plt.show()
2.3準備數(shù)據(jù):歸一化數(shù)值
由于kNN算法就是在求方差,數(shù)值偏大的屬性值的影響遠遠大于數(shù)值偏小的屬性值士聪。故需要將數(shù)據(jù)進行歸一化處理锦援,通常將取值范圍處理為0到1或-1到1之間。
以下是算法詳細代碼
def autoNorm(dataSet):
# 參數(shù)0指取列的最值
minVals = dataSet.min(0)
maxVals = dataSet.max(0)
ranges = maxVals - minVals
normDataSet = zeros(shape(dataSet))
m = dataSet.shape[0]
normDataSet = dataSet - tile(minVals, (m, 1))
normDataSet = normDataSet / tile(ranges, (m, 1))
return normDataSet, ranges, minVals
2.4測試算法:作為完整程序驗證分類器
機器學習一個非常重要的工作就是評估算法的正確率剥悟,通常使用已有數(shù)據(jù)的90%作為訓(xùn)練樣本來訓(xùn)練分類器灵寺,剩余10%的數(shù)據(jù)用于測試分類器∨嘲可以使用錯誤率來檢測分類器的性能替久。對于分類器而言,錯誤率就是分類器給出錯誤結(jié)果的次數(shù)除以測試數(shù)據(jù)的總數(shù)躏尉。
算法過程
此算法首先使用file2matrix
和autoNorm
函數(shù)從文件讀取數(shù)據(jù)并將數(shù)據(jù)歸一化處理蚯根。接著確定哪些數(shù)據(jù)用于測試,哪些數(shù)據(jù)用做訓(xùn)練樣本,然后將這兩部分數(shù)據(jù)輸入到分類器函數(shù)classify0
颅拦,最后輸出錯誤率蒂誉。
以下是算法詳細代碼
def datingClassTest() -> object:
# 選取多少數(shù)據(jù)測試分類器
hoRatio = 0.10
# 得到數(shù)據(jù)矩陣和標簽向量
datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
# 歸一化處理矩陣
normMat, ranges, minVals = autoNorm(datingDataMat)
# 獲取矩陣的行數(shù)
m = normMat.shape[0]
# 設(shè)置測試個數(shù)(10%)
numTestVecs = int(m * hoRatio)
errorCount = 0.0
for i in range(numTestVecs):
#第一個參數(shù):前10%的數(shù)據(jù)用于inX;第二個參數(shù):后90%用戶dataSet;第三個參數(shù):后90%的數(shù)據(jù)的標簽;k=3
classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)
print("分類后的結(jié)果為:,", classifierResult, "原結(jié)果為:", datingLabels[i])
if (classifierResult != datingLabels[i]):
errorCount += 1.0
print("錯誤率是:", (errorCount / float(numTestVecs)))
2.5使用算法:構(gòu)建完整可用系統(tǒng)
現(xiàn)在通過輸入看數(shù)據(jù)所占時間數(shù)距帅、每年的飛行里程數(shù)右锨、每周消耗的冰淇淋公升數(shù)這些數(shù)據(jù)來給出喜歡對方程度的預(yù)測值。
以下是算法詳細代碼
def classifyPerson():
resultList = ['一點也不喜歡', '有一點喜歡', '非常喜歡']
percentTats = float(input("看視頻所占的時間比:"))
miles = float(input("每年的飛行里程數(shù):"))
iceCream = float(input("每周消耗的冰淇淋公升數(shù):"))
datingDataMat, datingLabels = file2matrix('datingTestSet2.txt')
normMat, ranges, minVals = autoNorm(datingDataMat)
inArr = array([miles, percentTats, iceCream])
classifierResult = classify0((inArr - minVals) / ranges, normMat, datingLabels, 3)
print("你對這個人的喜歡程度:", resultList[classifierResult - 1])