哪些網站可以做調查賺錢廣告關鍵詞有哪些類型
KNN(K近鄰)算法實現紅酒聚類
K近鄰算法,是有監(jiān)督學習中的分類算法,可以用于分類和回歸,本篇主要講解其在分類上的用途。
文章目錄
- KNN(K近鄰)算法實現紅酒聚類
- 算法原理
- 數據下載
- 數據讀取與處理
- 模型構建--計算距離
- 模型預測
算法原理
KNN算法雖然是機器學習算法,但是他不學習,他的原理是把所有的訓練集都存儲下來,在測試的時候把測試集放到原圖里面,根據測試點和訓練集的距離判定屬于的類別。如下圖示例,假設我們現在有兩個類別,分別是A和B,用三角和圓圈(不太圓見諒)表示,我們把這兩種類別都畫在坐標系中。此時載入一個未知類別方框,我們的KNN算法就開始了。
首先我們要指定一個K值,K值就是距離值,比如我們先指定K=2,就可以在這個位置類別周圍畫一個圓(可以理解為半徑為2),如下圖:
此時我們這個圓框進去了兩個A類別,根據算法原理,此時就會把這個未知類別判斷為A類別。而如果我們擴大K值呢
當我們把K值從2擴大到4時(小圓外面的大圓),可以看到,此時包進來了4個B類別值,A類別值仍然只有2個,此時就會判斷為B類別。這個算法有一點劃地盤的意思,畫個圈,這圈里誰人多,你就跟誰走,是這意思。歪理原理就這么結束了,下面讓我們看看正經的解釋。
K近鄰算法(K-Nearest-Neighbor, KNN)是一種用于分類和回歸的非參數統(tǒng)計方法,最初由 Cover和Hart于1968年提出(Cover等人,1967),是機器學習最基礎的算法之一。它正是基于以上思想:要確定一個樣本的類別,可以計算它與所有訓練樣本的距離,然后找出和該樣本最接近的k個樣本,統(tǒng)計出這些樣本的類別并進行投票,票數最多的那個類就是分類的結果。KNN的三個基本要素:
- K值,一個樣本的分類是由K個鄰居的“多數表決”確定的。K值越小,容易受噪聲影響,反之,會使類別之間的界限變得模糊。
- 距離度量,反映了特征空間中兩個樣本間的相似度,距離越小,越相似。常用的有Lp距離(p=2時,即為歐式距離)、曼哈頓距離、海明距離等。
- 分類決策規(guī)則,通常是多數表決,或者基于距離加權的多數表決(權值與距離成反比)。
預測算法(分類)的流程如下:
(1)在訓練樣本集中找出距離待測樣本x_test最近的k個樣本,并保存至集合N中;
(2)統(tǒng)計集合N中每一類樣本的個數𝐶𝑖,𝑖=1,2,3,…,𝑐𝐶𝑖,𝑖=1,2,3,…,𝑐;
(3)最終的分類結果為argmax𝐶𝑖𝐶𝑖 (最大的對應的𝐶𝑖𝐶𝑖)那個類。
在上述實現過程中,k的取值尤為重要。它可以根據問題和數據特點來確定。在具體實現時,可以考慮樣本的權重,即每個樣本有不同的投票權重,這種方法稱為帶權重的k近鄰算法,它是一種變種的k近鄰算法。
數據下載
我們使用Wine數據集進行展示,Wine數據集的官網:Wine Data Set,這個數據集是對同一地區(qū)三個不同品種的葡萄酒進行化學分析后記錄的結果。數據集分析了三種葡萄酒中每種所含13種成分的量。這些13種屬性是
- Alcohol,酒精
- Malic acid,蘋果酸
- Ash,灰
- Alcalinity of ash,灰的堿度
- Magnesium,鎂
- Total phenols,總酚
- Flavanoids,類黃酮
- Nonflavanoid phenols,非黃酮酚
- Proanthocyanins,原花青素
- Color intensity,色彩強度
- Hue,色調
- OD280/OD315 of diluted wines,稀釋酒的OD280/OD315
- Proline,脯氨酸
可以采用兩種下載方式:
- 方式一,從Wine數據集官網下載wine.data文件。
- 方式二,從華為云OBS中下載wine.data文件。
此時我們默認已經安裝了Mindspore環(huán)境,采用從華為云OBS中下載數據集
from download import download# 下載紅酒數據集
url = "https://ascend-professional-construction-dataset.obs.cn-north-4.myhuaweicloud.com:443/MachineLearning/wine.zip"
path = download(url, "./", kind="zip", replace=True)
數據讀取與處理
數據下載下來了,我們就進行讀取和預處理唄。
%matplotlib inline
import os
import csv
import numpy as np
import matplotlib.pyplot as pltimport mindspore as ms
from mindspore import nn, opsms.set_context(device_target="CPU")
with open('wine.data') as csv_file:data = list(csv.reader(csv_file, delimiter=','))
print(data[56:62]+data[130:133])
執(zhí)行完這幾行代碼后我們會打印出來部分數據進行查看,比如我這里打印出這樣的數據
此時最開始的每個list最開始的第一個數都是1或2或3,這就是葡萄酒的三種類別,后面緊跟著的13個參數就是他的13種化學成分。
取三類樣本(共178條),將數據集的13個屬性作為自變量X,將數據集的3個類別作為因變量Y。此時X和Y的值可以自行打印查看
X = np.array([[float(x) for x in s[1:]] for s in data[:178]], np.float32)
Y = np.array([s[0] for s in data[:178]], np.int32)
取樣本的某兩個屬性進行2維可視化,可以看到在某兩個屬性上樣本的分布情況以及可分性。
attrs = ['Alcohol', 'Malic acid', 'Ash', 'Alcalinity of ash', 'Magnesium', 'Total phenols','Flavanoids', 'Nonflavanoid phenols', 'Proanthocyanins', 'Color intensity', 'Hue','OD280/OD315 of diluted wines', 'Proline']
plt.figure(figsize=(10, 8))
for i in range(0, 4):plt.subplot(2, 2, i+1)# 選擇的化學成分由循環(huán)輪數i決定a1, a2 = 2 * i, 2 * i + 1# 選擇前59個類別為1的數據,化學成分選a1和a2類plt.scatter(X[:59, a1], X[:59, a2], label='1')plt.scatter(X[59:130, a1], X[59:130, a2], label='2')plt.scatter(X[130:, a1], X[130:, a2], label='3')plt.xlabel(attrs[a1])plt.ylabel(attrs[a2])plt.legend()
plt.show()
這里執(zhí)行完了就可以看到四張打印出來的圖,就體現了每一類葡萄酒其中兩種化學成分的關系
將數據集按128:50劃分為訓練集(已知類別樣本)和驗證集(待驗證樣本):
train_idx = np.random.choice(178, 128, replace=False)
test_idx = np.array(list(set(range(178)) - set(train_idx)))
X_train, Y_train = X[train_idx], Y[train_idx]
X_test, Y_test = X[test_idx], Y[test_idx]
模型構建–計算距離
利用MindSpore提供的tile, square, ReduceSum, sqrt, TopK
等算子,通過矩陣運算的方式同時計算輸入樣本x和已明確分類的其他樣本X_train的距離,并計算出top k近鄰
class KnnNet(nn.Cell):def __init__(self, k):super(KnnNet, self).__init__()self.k = kdef construct(self, x, X_train):#平鋪輸入x以匹配X_train中的樣本數x_tile = ops.tile(x, (128, 1))square_diff = ops.square(x_tile - X_train)square_dist = ops.sum(square_diff, 1)dist = ops.sqrt(square_dist)#-dist表示值越大,樣本就越接近values, indices = ops.topk(-dist, self.k)return indicesdef knn(knn_net, x, X_train, Y_train):x, X_train = ms.Tensor(x), ms.Tensor(X_train)indices = knn_net(x, X_train)topk_cls = [0]*len(indices.asnumpy())for idx in indices.asnumpy():topk_cls[Y_train[idx]] += 1cls = np.argmax(topk_cls)return cls
模型預測
在驗證集上驗證KNN算法的有效性,取𝑘=5𝑘=5,驗證精度接近80%,說明KNN算法在該3分類任務上有效,能根據酒的13種屬性判斷出酒的品種。
acc = 0
knn_net = KnnNet(5)
for x, y in zip(X_test, Y_test):pred = knn(knn_net, x, X_train, Y_train)acc += (pred == y)print('label: %d, prediction: %s' % (y, pred))
print('Validation accuracy is %f' % (acc/len(Y_test)))
打卡圖片: