如何在圖片上添加文字做網(wǎng)站小紅書(shū)推廣方案
、
目? ? 錄
前情說(shuō)明
問(wèn)題陳述
數(shù)據(jù)說(shuō)明
KNN算法流程概述
代碼實(shí)現(xiàn)
運(yùn)行結(jié)果
基于可視化的改進(jìn)
可視化代碼
全部數(shù)據(jù)可視化總覽
分類(lèi)投票結(jié)果
?改進(jìn)后最終代碼
前情說(shuō)明
本書(shū)基于《特征工程入門(mén)與入門(mén)與實(shí)踐》莊家盛 譯版P53頁(yè)K最近鄰(KNN)算法進(jìn)行講解
問(wèn)題陳述
Iris 鳶尾花數(shù)據(jù)集內(nèi)包含 3 類(lèi)分別為山鳶尾(Iris-setosa)、變色鳶尾(Iris-versicolor)和維吉尼亞鳶尾(Iris-virginica),共 150 條記錄,每類(lèi)各 50 個(gè)數(shù)據(jù),每條記錄都有 4 項(xiàng)特征:花萼長(zhǎng)度、花萼寬度、花瓣長(zhǎng)度、花瓣寬度。
sepallength:萼片長(zhǎng)度
sepalwidth:萼片寬度
petallength:花瓣長(zhǎng)度
petalwidth:花瓣寬度
我們的任務(wù)就是:給定一組記錄(包含sepallength,sepalwidth,petallength,petalwidth),使用KNN算法給出該組記錄的分類(lèi) (使用0,1,2表示)
數(shù)據(jù)說(shuō)明
本文使用數(shù)據(jù)源從機(jī)器學(xué)習(xí)庫(kù)sklearn的datasets包中獲取
# 導(dǎo)入iris數(shù)據(jù)
iris = datasets.load_iris()
可支持的數(shù)據(jù)集如下:
"load_digits","load_files","load_iris","load_breast_cancer","load_linnerud","load_sample_image","load_sample_images","load_svmlight_file","load_svmlight_files","load_wine",
#不知道為什么我的機(jī)器學(xué)習(xí)庫(kù)只有這些數(shù)據(jù)集
參考鏈接:?sklearn中的datasets數(shù)據(jù)集 - 知乎 (zhihu.com)
KNN算法流程概述
1.數(shù)據(jù)獲取。要進(jìn)行KNN,我們需要樣本的部分屬性完整數(shù)據(jù)以及在各種屬性不同值的組合情況下的對(duì)應(yīng)分類(lèi)結(jié)果
2.數(shù)據(jù)清洗。獲取數(shù)據(jù)后使用numpy整理缺失值,可視化查看是否有異常值(比如偏正態(tài)分布樣本出現(xiàn)的極端值或者空值)
3.數(shù)據(jù)切分。將數(shù)據(jù)按照一定比例,從特定位置切分成訓(xùn)練集和測(cè)試集,必要情況還需要切割分一部分?jǐn)?shù)據(jù)作為驗(yàn)證集
4.選取k個(gè)近鄰點(diǎn)。使用某種數(shù)據(jù)結(jié)構(gòu)或者庫(kù)函數(shù),獲取邏輯距離最近的k個(gè)點(diǎn)位
5.獲取結(jié)果。對(duì)k個(gè)點(diǎn)位進(jìn)行統(tǒng)計(jì),獲取票數(shù)最多的結(jié)果進(jìn)行分類(lèi)。但是存在票數(shù)一致的情況,可以使用某種排序方式對(duì)數(shù)據(jù)進(jìn)行排序,隱式的賦予某些特定的數(shù)據(jù)具有更高的優(yōu)先級(jí)(即返回首位即可)
6.可視化(補(bǔ)充)。雖然使用KNN算法對(duì)結(jié)果進(jìn)行展示了,但是整個(gè)過(guò)程的投票情況不夠直觀,于是我們接下來(lái)將對(duì)整體分類(lèi)和循環(huán)內(nèi)當(dāng)前投票情況進(jìn)行展示。
代碼實(shí)現(xiàn)
from sklearn import datasets
from collections import Counter # 為了做投票計(jì)數(shù)
from sklearn.model_selection import train_test_split
import random
import numpy as np###############數(shù)據(jù)定義區(qū)
# 數(shù)據(jù)集劃分隨機(jī)數(shù)種子
randomNums=random.randint(1,9999)
print("隨機(jī)數(shù){}".format(randomNums))
# 最短投票對(duì)象數(shù)量
k=3
###############數(shù)據(jù)定義區(qū)END
# 計(jì)算同類(lèi)屬性的歐氏距離 假設(shè)能這樣計(jì)算歐式距離代表樣本之間的差距
def calcDistance(toBeMeasuredDataSet,DataSet):# print("打印歐氏距離")# print(toBeMeasuredDataSet,'\n',DataSet)# **2的妙用result=np.sqrt(np.sum((toBeMeasuredDataSet - DataSet)**2 ))# print("打印歐氏距離",result)return result# 原始特征數(shù)據(jù)集 原始分類(lèi)數(shù)據(jù)集 選取個(gè)數(shù) 待分類(lèi)對(duì)象(一條記錄)
def KNNSelect(X,Y,k,testObject):# 獲取歐氏距離列表 計(jì)算待測(cè)數(shù)據(jù)與特征數(shù)據(jù)集的歐數(shù)據(jù)集distanceList=[calcDistance(testObject,singleData) for singleData in X ]# 排序后 切片獲取邏輯距離最短的k個(gè)對(duì)記錄的下標(biāo)(維護(hù)前k個(gè)最值)theShortestIndex=np.argsort(distanceList)[:k]# 獲取這k個(gè)結(jié)果resultList=Y[theShortestIndex]# 返回頻率最高的結(jié)果 作為樣本的類(lèi)別return Counter(resultList).most_common(1)[0][0]def printTopLineA():print(r"/\/\/\/\/\/\/\/\/\/\/\/\/")def printTopLineB():print(r"\/\/\/\/\/\/\/\/\/\/\/\/\ ")# 導(dǎo)入鸞尾花數(shù)據(jù)集
irisDataSet=datasets.load_iris()#獲取特征數(shù)據(jù)集
characteristicData=irisDataSet.data
# 獲取分類(lèi)數(shù)據(jù)集
categoricalData=irisDataSet.target
# 訓(xùn)練用特征數(shù)據(jù)集
# 測(cè)試用特征數(shù)據(jù)集
# 訓(xùn)練用分類(lèi)數(shù)據(jù)集
# 測(cè)試用分類(lèi)數(shù)據(jù)集
trainCharDataSet,testCharDataSet,trainCateDataSet,testCateDaSet\=train_test_split(characteristicData,categoricalData,random_state=randomNums)for index,i in enumerate(testCharDataSet):print("第{}個(gè)數(shù)據(jù)\n特征數(shù)據(jù)是:{}\n數(shù)據(jù)的類(lèi)別是:{}".format(index+1,i,KNNSelect(trainCharDataSet,trainCateDataSet,k,i)))if (index&1):printTopLineA()else:printTopLineB()
運(yùn)行結(jié)果
基于可視化的改進(jìn)
我們還是從源數(shù)據(jù)入手,將源數(shù)據(jù)轉(zhuǎn)換成key-value聚合的形式,
具體點(diǎn)就是將同一類(lèi)數(shù)據(jù)打成列表,作為以列名為key的對(duì)應(yīng)的value
運(yùn)行網(wǎng)址:Replit: the collaborative browser based IDE - Replit
可視化代碼
from collections import Counter # 為了做投票計(jì)數(shù)
from sklearn import datasets
from sklearn.model_selection import train_test_split
import random
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
###############說(shuō)明
# 1.本地sns畫(huà)圖環(huán)境炸了,具體原因不詳,運(yùn)行平臺(tái)為Replit,復(fù)制即可運(yùn)行
# 2.參考了許多可視化案例,但大部分都沒(méi)有理論支撐,就自己做了###############數(shù)據(jù)定義區(qū)
# 數(shù)據(jù)集劃分隨機(jī)數(shù)種子
randomNums=random.randint(1,9999)
print("隨機(jī)數(shù){}".format(randomNums))
# 最小投票對(duì)象數(shù)量
k=9
###############數(shù)據(jù)定義區(qū)END
# 計(jì)算同類(lèi)屬性的歐氏距離 假設(shè)能這樣計(jì)算歐式距離代表樣本之間的差距
def calcDistance(toBeMeasuredDataSet,DataSet):# print("打印歐氏距離")# print(toBeMeasuredDataSet,'\n',DataSet)# **2的妙用result=np.sqrt(np.sum((toBeMeasuredDataSet - DataSet)**2 ))# print("打印歐氏距離",result)return result#這個(gè)方法會(huì)傳來(lái)收集好的k個(gè)數(shù)據(jù)以及分類(lèi)結(jié)果 然后返回成key-value的形式調(diào)用進(jìn)行可視化
def showVisual(irisData,irisTarget):#數(shù)據(jù)處理irisDictData = {'sepalLength': [],'sepalWidth': [],'petalLength': [],'petalWidth': []}for index, i in enumerate(irisDictData):# print(index,i,irisDictData[i])#將每一列數(shù)據(jù)剝離出來(lái)irisDictData[i] = [data[index] for indexs, data in enumerate(irisData)]#將分類(lèi)結(jié)果添加進(jìn)來(lái)irisDictData['species']=irisTarget# 進(jìn)行可視化visual(irisDictData)# 原始特征數(shù)據(jù)集 原始分類(lèi)數(shù)據(jù)集 選取個(gè)數(shù) 待分類(lèi)對(duì)象(一條記錄)
def KNNSelect(X,Y,k,testObject):# 獲取歐氏距離列表 計(jì)算待測(cè)數(shù)據(jù)與特征數(shù)據(jù)集的歐數(shù)據(jù)集distanceList=[calcDistance(testObject,singleData) for singleData in X ]# 排序后 切片獲取邏輯距離最短的k個(gè)對(duì)記錄的下標(biāo)(維護(hù)前k個(gè)最值)theShortestIndex=np.argsort(distanceList)[:k]# 獲取這k個(gè)源數(shù)據(jù)和結(jié)果dataList=X[theShortestIndex]resultList=Y[theShortestIndex]print("投票結(jié)果:{}".format(resultList))##########可視化出最近的k個(gè)點(diǎn)showVisual(dataList,resultList)# 返回頻率最高的結(jié)果 作為樣本的類(lèi)別return Counter(resultList).most_common(1)[0][0]def showNcolsData():# 導(dǎo)入鸞尾花數(shù)據(jù)集irisDataSet = datasets.load_iris()# 分析花瓣與花萼的相關(guān)性# 寬度的相關(guān)性# 高度的相關(guān)性# data是采集數(shù)據(jù) target是人工分好的類(lèi)別數(shù)據(jù)irisData = irisDataSet["data"]# print(irisData[0][0])irisDictData = {'sepalLength': [],'sepalWidth': [],'petalLength': [],'petalWidth': []}for index, i in enumerate(irisDictData):# print(index,i,irisDictData[i])#將每一列數(shù)據(jù)剝離出來(lái) 注意這里用的下標(biāo)是index 而不是indexs哈哈#感覺(jué)寫(xiě)的時(shí)候自己挺聰明,過(guò)兩天就看不懂了qwq irisDictData[i] = [data[index] for indexs, data in enumerate(irisData)]# k2, p = stats.normaltest(irisDictData[i])# print(k2,p)# 添加預(yù)測(cè)結(jié)果數(shù)據(jù)irisDictData['species']=irisDataSet['target']return irisDictData# 裝飾打印語(yǔ)句
def printTopLineA():print(r"/\/\/\/\/\/\/\/\/\/\/\/\/")def printTopLineB():print(r"\/\/\/\/\/\/\/\/\/\/\/\/\ ")#可視化函數(shù)
def visual(rawData):# 傳入一個(gè)沒(méi)有被DataFrame的dfData=pd.DataFrame(rawData)# x X軸展示數(shù)據(jù)# y Y軸展示數(shù)據(jù)# data 數(shù)據(jù)源# hub 顏色分類(lèi)依據(jù)列# 分類(lèi)總覽sns.relplot(x='sepalLength',y='sepalWidth',data=dfData,hue='species')plt.show()# 導(dǎo)入鸞尾花數(shù)據(jù)集
irisDataSet=datasets.load_iris()
#獲取特征數(shù)據(jù)集
characteristicData=irisDataSet.data
# 獲取分類(lèi)數(shù)據(jù)集
categoricalData=irisDataSet.target
# print("打印分類(lèi)結(jié)果",categoricalData)
# 訓(xùn)練用特征數(shù)據(jù)集,測(cè)試用特征數(shù)據(jù)集,訓(xùn)練用分類(lèi)數(shù)據(jù)集,測(cè)試用分類(lèi)數(shù)據(jù)集
trainCharDataSet,testCharDataSet,trainCateDataSet,testCateDaSet\=train_test_split(characteristicData,categoricalData,random_state=randomNums)
# 可視化需求分析
# 1.對(duì)訓(xùn)練集數(shù)據(jù)進(jìn)行可視化
# 2.對(duì)每個(gè)測(cè)試對(duì)象展示一個(gè)獨(dú)特的點(diǎn)
# 3.標(biāo)出待測(cè)對(duì)象最近的k個(gè)點(diǎn)# 每一列key的字典 對(duì)應(yīng)值是該列數(shù)據(jù)
irisDictData=showNcolsData()# sepalLength sepalWidth petalLength petalWidth
# print(dfData)
visual(irisDictData) #對(duì)整體進(jìn)行可視化###使用循環(huán)處理待測(cè)數(shù)據(jù) 并給出結(jié)果
for index,i in enumerate(testCharDataSet):print("第{}個(gè)數(shù)據(jù)\n特征數(shù)據(jù)是:{}\n數(shù)據(jù)的類(lèi)別是:{}"\.format(index+1,i,KNNSelect(trainCharDataSet,trainCateDataSet,k,i)))printTopLineA() if index&1 else printTopLineB()
全部數(shù)據(jù)可視化總覽
分類(lèi)投票結(jié)果
?改進(jìn)后最終代碼
我們對(duì)代碼進(jìn)行優(yōu)化,整理后最終代碼如下,可在如上在線平臺(tái)直接運(yùn)行
from collections import Counter # 為了做投票計(jì)數(shù)
from sklearn import datasets
from sklearn.model_selection import train_test_split
import random
import numpy as np
import pandas as pd
import seaborn as sns #流行可視化工具
import matplotlib.pyplot as plt #sns的底層基于這個(gè)。。。需要用plt.show()###############說(shuō)明
# 1.本地sns畫(huà)圖環(huán)境炸了,具體原因不詳,運(yùn)行平臺(tái)為Replit,復(fù)制即可運(yùn)行
# 2.參考了許多可視化案例,但大部分都沒(méi)有理論支撐,就自己做了
###############數(shù)據(jù)定義區(qū)
# 數(shù)據(jù)集劃分隨機(jī)數(shù)種子
randomNums = random.randint(1, 9999)
print("隨機(jī)數(shù){}".format(randomNums))
# 最小投票對(duì)象數(shù)量
k = 9
# 定義空字典 增加復(fù)用率
irisDictEmptyData = {'sepalLength': [],'sepalWidth': [],'petalLength': [],'petalWidth': []
}###############數(shù)據(jù)定義區(qū)END
# 計(jì)算同類(lèi)屬性的歐氏距離 假設(shè)能這樣計(jì)算歐式距離代表樣本之間的差距
def calcDistance(toBeMeasuredDataSet, DataSet):# print("打印歐氏距離")# print(toBeMeasuredDataSet,'\n',DataSet)# **2的妙用result = np.sqrt(np.sum((toBeMeasuredDataSet - DataSet) ** 2))# print("打印歐氏距離",result)return resultdef dealRawDataToDict(irisDictData, irisData):for index, i in enumerate(irisDictData):# print(index,i,irisDictData[i])# 將每一列數(shù)據(jù)剝離出來(lái) 注意這里用的下標(biāo)是index 而不是indexs哈哈# 感覺(jué)寫(xiě)的時(shí)候自己挺聰明,過(guò)兩天就看不懂了qwq irisDictData[i] = [data[index] for indexs, data in enumerate(irisData)]return irisDictData# 這個(gè)方法會(huì)傳來(lái)收集好的k個(gè)數(shù)據(jù)以及分類(lèi)結(jié)果 然后返回成key-value的形式調(diào)用進(jìn)行可視化
def showVisual(irisData, irisTarget):# 數(shù)據(jù)處理irisDictData = dealRawDataToDict(irisDictEmptyData, irisData)# 將分類(lèi)結(jié)果添加進(jìn)來(lái)irisDictData['species'] = irisTarget# 進(jìn)行可視化visual(irisDictData)# 原始特征數(shù)據(jù)集 原始分類(lèi)數(shù)據(jù)集 選取個(gè)數(shù) 待分類(lèi)對(duì)象(一條記錄)
def KNNSelect(X, Y, k, testObject):# 獲取歐氏距離列表 計(jì)算待測(cè)數(shù)據(jù)與特征數(shù)據(jù)集的歐數(shù)據(jù)集distanceList = [calcDistance(testObject, singleData) for singleData in X]# 排序后 切片獲取邏輯距離最短的k個(gè)對(duì)記錄的下標(biāo)(維護(hù)前k個(gè)最值)theShortestIndex = np.argsort(distanceList)[:k]# 獲取這k個(gè)源數(shù)據(jù)和結(jié)果dataList = X[theShortestIndex]resultList = Y[theShortestIndex]print("投票結(jié)果:{}".format(resultList))##########可視化出最近的k個(gè)點(diǎn)showVisual(dataList, resultList)# 返回頻率最高的結(jié)果 作為樣本的類(lèi)別return Counter(resultList).most_common(1)[0][0]#拼裝全部原始數(shù)據(jù) 然后送還字典
def showNcolsData():# 導(dǎo)入鸞尾花數(shù)據(jù)集irisDataSet = datasets.load_iris()# 分析花瓣與花萼的相關(guān)性# 寬度的相關(guān)性# 高度的相關(guān)性# data是采集數(shù)據(jù) target是人工分好的類(lèi)別數(shù)據(jù)irisData = irisDataSet["data"]# print(irisData[0][0])irisDictData = dealRawDataToDict(irisDictEmptyData, irisData)# 添加預(yù)測(cè)結(jié)果數(shù)據(jù)irisDictData['species'] = irisDataSet['target']return irisDictData# 裝飾打印語(yǔ)句
def printTopLineA():print(r"/\/\/\/\/\/\/\/\/\/\/\/\/")def printTopLineB():print(r"\/\/\/\/\/\/\/\/\/\/\/\/\ ")# 可視化函數(shù)
def visual(rawData):# 傳入一個(gè)沒(méi)有被DataFrame的dfData = pd.DataFrame(rawData)# x X軸展示數(shù)據(jù)# y Y軸展示數(shù)據(jù)# data 數(shù)據(jù)源# hub 顏色分類(lèi)依據(jù)列# 分類(lèi)總覽sns.relplot(x='sepalLength', y='sepalWidth', data=dfData, hue='species')plt.show()# 導(dǎo)入鸞尾花數(shù)據(jù)集
irisDataSet = datasets.load_iris()
# 獲取特征數(shù)據(jù)集
characteristicData = irisDataSet.data
# 獲取分類(lèi)數(shù)據(jù)集
categoricalData = irisDataSet.target
# print("打印分類(lèi)結(jié)果",categoricalData)
# 訓(xùn)練用特征數(shù)據(jù)集,測(cè)試用特征數(shù)據(jù)集,訓(xùn)練用分類(lèi)數(shù)據(jù)集,測(cè)試用分類(lèi)數(shù)據(jù)集
trainCharDataSet, testCharDataSet, trainCateDataSet, testCateDaSet \= train_test_split(characteristicData, categoricalData, random_state=randomNums)
# 可視化需求分析
# 1.對(duì)訓(xùn)練集數(shù)據(jù)進(jìn)行可視化
# 2.對(duì)每個(gè)測(cè)試對(duì)象展示一個(gè)獨(dú)特的點(diǎn)
# 3.標(biāo)出待測(cè)對(duì)象最近的k個(gè)點(diǎn)# 每一列key的字典 對(duì)應(yīng)值是該列數(shù)據(jù)
irisDictData = showNcolsData()# sepalLength sepalWidth petalLength petalWidth
# print(dfData)
visual(irisDictData) # 進(jìn)行可視化###使用循環(huán)處理待測(cè)數(shù)據(jù) 并給出結(jié)果
for index, i in enumerate(testCharDataSet):print("第{}個(gè)數(shù)據(jù)\n特征數(shù)據(jù)是:{}\n數(shù)據(jù)的類(lèi)別是:{}" \.format(index + 1, i, KNNSelect(trainCharDataSet, trainCateDataSet, k, i)))printTopLineA() if index & 1 else printTopLineB()
部分參考鏈接:
1.sklearn數(shù)據(jù)集——iris鳶尾花數(shù)據(jù)集_iris 數(shù)據(jù)_lyb06的博客-CSDN博客
2.【機(jī)器學(xué)習(xí)實(shí)戰(zhàn)】科學(xué)處理鳶尾花數(shù)據(jù)集_鳶尾花數(shù)據(jù)標(biāo)準(zhǔn)化處理-CSDN博客
3.數(shù)據(jù)分析——鳶尾花數(shù)據(jù)集-CSDN博客
4.Python collections模塊之Counter()詳解_python counter-CSDN博客
5.Python基本函數(shù):np.argsort()-CSDN博客
6.Python中的Counter.most_common()方法-CSDN博客
7.史上最全面K近鄰算法/KNN算法詳解+python實(shí)現(xiàn) - 知乎 (zhihu.com)
8.什么是KNN算法? - 知乎 (zhihu.com)
9.sklearn中的datasets數(shù)據(jù)集 - 知乎 (zhihu.com)