摘要:項目介紹某用戶一直使用在線約會軟件尋找適合自己的約會對象。盡管約會網站會推薦不同的人選但她并不是喜歡每一個人。
1 項目介紹
某APP用戶一直使用在線約會軟件尋找適合自己的約會對象。盡管約會網站會推薦不同的人選,但她并不是喜歡每一個人。經過一番總結,她發現曾交往過三種類型的人:
不喜歡的人(3)
魅力一般的人(2)
極具魅力的人(1)
某APP用戶希望分類軟件可以更好地幫助她將匹配對象劃分到確切的分類中。此外還可以收集了約會軟件未曾記錄的數據信息,她認為這些數據更有助于匹配對象的歸類。收集的部分信息如下圖所示:
數據集下載
樣本主要包含以下3種特征:
每年獲得的飛行??屠锍虜?/p>
玩視頻游戲所耗時間百分比
每周消費的冰淇淋公升數
2 準備數據:從文本文件中解析數據在將上述特征數據輸入到分類器之前,必須將待處理數據的格式改變為分類器可以接受的格式。
import numpy as np def file2matrix(filename): """ :param filename: APP用戶收集的約會數據的文件名 :return: returnMat: 用戶提供的每行數據信息,三列, 分別是每年獲得的飛行??屠锍虜?, 玩視頻游戲所耗時間百分比, 每周消費的冰淇淋公升數 classLabelVetor: 用戶的評價信息, 一般分為3類(1,2,3) """ fr = open(filename) arrayOfLines = fr.readlines() # print(arrayOfLines) # 獲得文件行數; numerOfLines = len(arrayOfLines) # 創建要返回的Numpy矩陣; returnMat = np.zeros((numerOfLines, 3)) # 解析文件數據到矩陣中; classLabelVetor = [] index = 0 for line in arrayOfLines: line = line.strip() listFromLine = line.split(" ") returnMat[index, :] = listFromLine[0:3] classLabelVetor.append(listFromLine[-1]) index += 1 return returnMat, classLabelVetor print(file2matrix("data/datingTestSet2"))
返回的值顯示:
3 分析數據:使用 Matplotlib 創建散點圖使用Matplotlib庫圖形化清晰地標識了三個不同的樣本分類區域,具有不同愛好的人其類別區域也不同。
def draw_pic(datingDataMat, datingLabels): """ 每年獲取的飛行常客里程數與每周所消費的冰淇淋公升數”構成的散點圖。 :param datingDataMat: :param datingLabels: :return: """ # 中文顯示亂碼問題; myfont = font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc", size=12) # 創建畫布 fig = plt.figure() ax = fig.add_subplot(111) ax.scatter(datingDataMat[:, 0], datingDataMat[:, 2], 15 * datingLabels, datingLabels) plt.xlabel("每年的飛行里程數", fontproperties=myfont) plt.ylabel("每周消費的冰淇淋公升數", fontproperties=myfont) plt.grid(alpha=0.5) plt.show()
效果展示
4 準備數據:歸一化數值計算樣本3和樣本4之間的距離:
問題:
飛行常客里程數對于計算結果的影響將遠遠大于其他兩個特征的影響
解決方式:
處理不同取值范圍的特征值時,通常采用的方法是將數值歸一化,如將取值范圍處理為0到1或者-1到1之間。
歸一化公式: newValue = oldValue / max
def autoNorm(dataSet): """ 歸一化數值, :param dataSet:用戶提供的每行數據信息,三列; :return: normDataSet: 歸一化的特征信息; maxVals:每個特征數據的最大值; """ # 獲取每個特征數據的最大值; maxVals = dataSet.max(0) # 獲取樣本個數; m = dataSet.shape[0] # 根據公式生成歸一化的特征信息; normDataSet = dataSet / np.tile(maxVals, (m, 1)) return normDataSet, maxVals4 實施 kNN 算法
對未知類別屬性的數據集中的每個點依次執行以下操作, 與上一個案例代碼相同:
(1) 計算已知類別數據集中的點與當前點之間的距離;
(2) 按照距離遞增次序排序;
(3) 選取與當前點距離最小的k個點;
(4) 確定前k個點所在類別的出現頻率;
(5) 返回前k個點出現頻率最高的類別作為當前點的預測分類。
def classify(inX, dataSet, labels, k): """ :param inX: 要預測的數據 :param dataSet: 我們要傳入的已知數據集 :param labels: 我們要傳入的標簽 :param k: KNN里的k, 也就是說我們要選幾個近鄰 :return: 排序的結果 """ dataSetSize = dataSet.shape[0] # (6,2) 6 # tile會重復inX, 把他重復成(datasetsize, 1)型的矩陣 # print(inX) # (x1 - y1), (x2- y2) diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet # 平方 sqDiffMat = diffMat ** 2 # 相加, axis=1 行相加 sqDistance = sqDiffMat.sum(axis=1) # 開根號 distances = sqDistance ** 0.5 # print(distances) # 排序 輸出的是序列號index,并不是值 sortedDistIndicies = distances.argsort() # print(sortedDistIndicies) classCount = {} for i in range(k): voteLabel = labels[sortedDistIndicies[i]] classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 # print(classCount) sortedClassCount = sorted(classCount.items(), key=lambda d: float(d[1]), reverse=True) return sortedClassCount[0]5 測試算法:作為完整程序驗證分類器
如果分類器的正確率滿足要求,就可以使用這個軟件來處理約會網站提供的約會名單了。機器學習算法一個很重要的工作就是評估算法的正確率,通常我們只提供已有數據的90%作為訓練樣本來訓練分類器,而使用其余的10%數據去測試分類器,檢測分類器的正確率。
def datingClassTest(): """ 分類器針對約會網站的測試代碼, 獲取錯誤率; :return: """ hoRatio = 0.10 datingDataMat, datingLabels = file2matrix("data/datingTestSet2") normDataSet, maxVals = autoNorm(datingDataMat) # 樣本個數 m = normDataSet.shape[0] # 測試集個數; numTestVecs = int(m*hoRatio) errorCount = 0.0 for i in range(numTestVecs): classiferResult = classify(normDataSet[i, :], normDataSet[numTestVecs:m, :], datingLabels[numTestVecs:m], 3) # print(classiferResult) if classiferResult != datingLabels[i]: errorCount += 1 print("正確結果:", datingLabels[i]) print("預測結果:", classiferResult) # print("錯誤個數:", errorCount) return errorCount
執行效果展示:
6 使用算法:構建完整可用的預測系統def classifyPerson(Person): """ 使用這個分類器為某APP用戶來對人們分類。 :param Person: :return: """ datingDataMat, datingLabels = file2matrix("data/datingTestSet2") normDataSet, maxVals = autoNorm(datingDataMat) classiferResult = classify(Person / maxVals, normDataSet, datingLabels, 3) if classiferResult == "1": print("不喜歡") elif classiferResult == "2": print("有一點喜歡") else: print("非常喜歡")完整代碼
# encoding:utf-8 """ KNN實現,基于KNN分類的約會網站配對改進算法 """ import numpy as np import matplotlib.pyplot as plt from matplotlib import font_manager def file2matrix(filename): """ :param filename: APP用戶收集的約會數據的文件名 :return: returnMat: 用戶提供的每行數據信息,三列, 分別是每年獲得的飛行常客里程數, 玩視頻游戲所耗時間百分比, 每周消費的冰淇淋公升數 classLabelVetor: 用戶的評價信息, 一般分為3類(1,2,3) """ fr = open(filename) arrayOfLines = fr.readlines() # print(arrayOfLines) # 獲得文件行數; numerOfLines = len(arrayOfLines) # 創建要返回的Numpy矩陣; returnMat = np.zeros((numerOfLines, 3)) # 解析文件數據到矩陣中; classLabelVetor = [] index = 0 for line in arrayOfLines: line = line.strip() listFromLine = line.split(" ") returnMat[index, :] = listFromLine[0:3] classLabelVetor.append(listFromLine[-1]) index += 1 return returnMat, classLabelVetor def autoNorm(dataSet): """ 歸一化數值, 計算樣本3和樣本4之間的距離: [(0-67)**2 + (20000 - 32 000)**2 + (1.1 - 0.1)**2]**0.5 問題: 飛行??屠锍虜祵τ谟嬎憬Y果的影響將遠遠大于其他兩個特征的影響 解決方式: 處理不同取值范圍的特征值時, 通常采用的方法是將數值歸一化,如將取值范圍處理為0到1或者-1到1之間。 歸一化公式: newValue = oldValue / max :param dataSet:用戶提供的每行數據信息,三列; :return: normDataSet: 歸一化的特征信息; maxVals:每個特征數據的最大值; """ # 獲取每個特征數據的最大值; maxVals = dataSet.max(0) # 獲取樣本個數; m = dataSet.shape[0] # 根據公式生成歸一化的特征信息; normDataSet = dataSet / np.tile(maxVals, (m, 1)) return normDataSet, maxVals def draw_pic(datingDataMat, datingLabels): """ 每年獲取的飛行??屠锍虜蹬c每周所消費的冰淇淋公升數”構成的散點圖。 :param datingDataMat: :param datingLabels: :return: """ # 中文顯示亂碼問題; myfont = font_manager.FontProperties(fname="/usr/share/fonts/cjkuni-uming/uming.ttc", size=12) # 創建畫布 fig = plt.figure() ax = fig.add_subplot(111) ax.scatter(datingDataMat[:, 0], datingDataMat[:, 2], 15 * datingLabels, datingLabels) plt.xlabel("每年的飛行里程數", fontproperties=myfont) plt.ylabel("每周消費的冰淇淋公升數", fontproperties=myfont) plt.grid(alpha=0.5) plt.show() def classify(inX, dataSet, labels, k): """ :param inX: 要預測的數據 :param dataSet: 我們要傳入的已知數據集 :param labels: 我們要傳入的標簽 :param k: KNN里的k, 也就是說我們要選幾個近鄰 :return: 排序的結果 """ dataSetSize = dataSet.shape[0] # (6,2) 6 # tile會重復inX, 把他重復成(datasetsize, 1)型的矩陣 # print(inX) # (x1 - y1), (x2- y2) diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet # 平方 sqDiffMat = diffMat ** 2 # 相加, axis=1 行相加 sqDistance = sqDiffMat.sum(axis=1) # 開根號 distances = sqDistance ** 0.5 # print(distances) # 排序 輸出的是序列號index,并不是值 sortedDistIndicies = distances.argsort() # print(sortedDistIndicies) classCount = {} for i in range(k): voteLabel = labels[sortedDistIndicies[i]] classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 # print(classCount) sortedClassCount = sorted(classCount.items(), key=lambda d: float(d[1]), reverse=True) return sortedClassCount[0][0] def datingClassTest(): """ 分類器針對約會網站的測試代碼, 獲取錯誤率; :return: """ hoRatio = 0.10 datingDataMat, datingLabels = file2matrix("data/datingTestSet2") normDataSet, maxVals = autoNorm(datingDataMat) # 樣本個數 m = normDataSet.shape[0] # 測試集個數; numTestVecs = int(m*hoRatio) errorCount = 0.0 for i in range(numTestVecs): classiferResult = classify(normDataSet[i, :], normDataSet[numTestVecs:m, :], datingLabels[numTestVecs:m], 3) # print(classiferResult) if classiferResult != datingLabels[i]: errorCount += 1 print("正確結果:", datingLabels[i]) print("預測結果:", classiferResult) # print("錯誤個數:", errorCount) return errorCount def classifyPerson(Person): """ 使用這個分類器為某APP用戶來對人們分類。 :param Person: :return: """ datingDataMat, datingLabels = file2matrix("data/datingTestSet2") normDataSet, maxVals = autoNorm(datingDataMat) classiferResult = classify(Person / maxVals, normDataSet, datingLabels, 3) if classiferResult == "1": print("不喜歡") elif classiferResult == "2": print("有一點喜歡") else: print("非常喜歡") if __name__ == "__main__": # personData = [30000, 10, 1.3] personData = [40920, 8.326976, 0.953952] classifyPerson(personData)
執行結果
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/19982.html
摘要:項目介紹某用戶一直使用在線約會軟件尋找適合自己的約會對象。盡管約會網站會推薦不同的人選但她并不是喜歡每一個人。 1 項目介紹 某APP用戶一直使用在線約會軟件尋找適合自己的約會對象。盡管約會網站會推薦不同的人選,但她并不是喜歡每一個人。經過一番總結,她發現曾交往過三種類型的人: 不喜歡的人(3) 魅力一般的人(2) 極具魅力的人(1) 某APP用戶希望分類軟件可以更好地幫助她將匹...
摘要:鄰近算法實例額一改進約會網站的配對效果應用背景某約會網站收集了一些數據放在中,每個樣本數據占據一行,總共有行。在中創建名為的函數,以此來處理輸人格式問題。該函數的輸人為文件名字符串輸出為訓練樣本矩陣和類標簽向量。 k鄰近算法實例額(一) 改進約會網站的配對效果 應用背景: 某約會網站收集了一些數據放在datingTestSet.txt中,每個樣本數據占據一行,總共有1000行。樣本主要...
k近鄰(k-Nearest Neighbor,kNN)算法是經典的帶監督的分類算法,核心思想是如果一個樣本在特征空間中的k個最相鄰的樣本中的大多數屬于某一個類別,則針對該樣本的劃分結果也屬于這個類別。 1. 算法步驟 準備訓練數據和測試數據; 確定參數 k; 計算測試數據與各個訓練數據之間的距離,距離的遞增關系進行排序; 選取距離最小的 k 個點; 確定前 k 個點所在類別的出現頻率; 返回前 ...
摘要:背景近鄰算法的概述近鄰算法的簡介近鄰算法是屬于一個非常有效且易于掌握的機器學習算法,簡單的說就是采用測量不同特征值之間距離的方法對數據進行分類的一個算法。完美的分類器的錯誤率為,而最差的分類器的錯誤率則為。 1 背景 1.1 k近鄰算法的概述 (1)k近鄰算法的簡介 k-近鄰算法是屬于一個非...
閱讀 1211·2023-04-25 20:31
閱讀 3718·2021-10-14 09:42
閱讀 1485·2021-09-22 16:06
閱讀 2636·2021-09-10 10:50
閱讀 3524·2021-09-07 10:19
閱讀 1772·2019-08-30 15:53
閱讀 1170·2019-08-29 15:13
閱讀 2818·2019-08-29 13:20