亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

K-means聚類分析學(xué)生成績 Python實(shí)現(xiàn)

系統(tǒng) 2134 0

聲明 :本人小白,文章作為自己的學(xué)習(xí)參考資料,供大家學(xué)習(xí)交流
本文refer to

作者:csuldw
鏈接:https://github.com/csuldw/MachineLearning/tree/master/Kmeans
來源:Github

感謝此文章原創(chuàng)者
如有侵犯您的知識產(chǎn)權(quán)和版權(quán)問題,請通知本人,本人會即時做出處理并刪除文章

Email:louhergetup@gmail.com

理論部分

K-means原理

(這部分感覺 csuldw 大神寫的很好,所以直接拿來用了,想了解詳情請訪問上面 Github 的鏈接)
創(chuàng)建 k 個點(diǎn)作為 k 個簇的起始質(zhì)心(經(jīng)常隨機(jī)選擇)

  • 分別計算剩下的元素到k個簇中心的相異度(距離),將這些元素分別劃歸到相異度最低的簇。
  • 根據(jù)聚類結(jié)果,重新計算k個簇各自的中心,計算方法是取簇中所有元素各自維度的算術(shù)平均值。
  • 將 D 中全部元素按照新的中心重新聚類。
  • 重復(fù)第4步,直到聚類結(jié)果不再變化。
  • 最后,輸出聚類結(jié)果。

實(shí)現(xiàn)部分

實(shí)驗(yàn)環(huán)境

  • 操作系統(tǒng):win10 64
  • 編程語言:Python 3.7.3

K-means聚類實(shí)現(xiàn)

這部分也是 csuldw 大神的實(shí)現(xiàn)

            
              #  -*- coding: utf-8 -*-

import numpy as np


class KMeansClassifier():
    "this is a k-means classifier"

    def __init__(self, k=3, initCent='random', max_iter=500):

        self._k = k
        self._initCent = initCent
        self._max_iter = max_iter
        self._clusterAssment = None
        self._labels = None
        self._sse = None

    def _calEDist(self, arrA, arrB):
        """
        功能:歐拉距離距離計算
        輸入:兩個一維數(shù)組
        """
        return np.math.sqrt(sum(np.power(arrA - arrB, 2)))

    def _calMDist(self, arrA, arrB):
        """
        功能:曼哈頓距離距離計算
        輸入:兩個一維數(shù)組
        """
        return sum(np.abs(arrA - arrB))

    def _randCent(self, data_X, k):
        """
        功能:隨機(jī)選取k個質(zhì)心
        輸出:centroids # 返回一個m*n的質(zhì)心矩陣
        """
        n = data_X.shape[1]  # 獲取特征的維數(shù)
        centroids = np.empty((k, n))  # 使用numpy生成一個k*n的矩陣,用于存儲質(zhì)心
        for j in range(n):
            minJ = min(data_X[:, j])
            rangeJ = float(max(data_X[:, j] - minJ))
            # 使用flatten拉平嵌套列表(nested list)
            centroids[:, j] = (minJ + rangeJ * np.random.rand(k, 1)).flatten()
        return centroids

    def fit(self, data_X):
        """
        輸入:一個m*n維的矩陣
        """
        if not isinstance(data_X, np.ndarray) or \
               isinstance(data_X, np.matrixlib.defmatrix.matrix):
            try:
                data_X = np.asarray(data_X)
            except:
                raise TypeError("numpy.ndarray resuired for data_X")

        m = data_X.shape[0]  # 獲取樣本的個數(shù)
        # 一個m*2的二維矩陣,矩陣第一列存儲樣本點(diǎn)所屬的族的索引值,
        # 第二列存儲該點(diǎn)與所屬族的質(zhì)心的平方誤差
        self._clusterAssment = np.zeros((m, 2))

        if self._initCent == 'random':
            self._centroids = self._randCent(data_X, self._k)

        clusterChanged = True
        for _ in range(self._max_iter):  # 使用"_"主要是因?yàn)楹竺鏇]有用到這個值
            clusterChanged = False
            for i in range(m):  # 將每個樣本點(diǎn)分配到離它最近的質(zhì)心所屬的族
                minDist = np.inf  # 首先將minDist置為一個無窮大的數(shù)
                minIndex = -1  # 將最近質(zhì)心的下標(biāo)置為-1
                for j in range(self._k):  # 次迭代用于尋找最近的質(zhì)心
                    arrA = self._centroids[j, :]
                    arrB = data_X[i, :]
                    distJI = self._calEDist(arrA, arrB)  # 計算誤差值
                    if distJI < minDist:
                        minDist = distJI
                        minIndex = j
                if self._clusterAssment[i,
                                        0] != minIndex or self._clusterAssment[
                                            i, 1] > minDist**2:
                    clusterChanged = True
                    self._clusterAssment[i, :] = minIndex, minDist**2
            if not clusterChanged:  # 若所有樣本點(diǎn)所屬的族都不改變,則已收斂,結(jié)束迭代
                break
            for i in range(self._k):  # 更新質(zhì)心,將每個族中的點(diǎn)的均值作為質(zhì)心
                index_all = self._clusterAssment[:, 0]  # 取出樣本所屬簇的索引值
                value = np.nonzero(index_all == i)  # 取出所有屬于第i個簇的索引值
                ptsInClust = data_X[value[0]]  # 取出屬于第i個簇的所有樣本點(diǎn)
                self._centroids[i, :] = np.mean(ptsInClust, axis=0)  # 計算均值

        self._labels = self._clusterAssment[:, 0]
        self._sse = sum(self._clusterAssment[:, 1])

    def predict(self, X):  # 根據(jù)聚類結(jié)果,預(yù)測新輸入數(shù)據(jù)所屬的族
        # 類型檢查
        if not isinstance(X, np.ndarray):
            try:
                X = np.asarray(X)
            except:
                raise TypeError("numpy.ndarray required for X")

        m = X.shape[0]  # m代表樣本數(shù)量
        preds = np.empty((m, ))
        for i in range(m):  # 將每個樣本點(diǎn)分配到離它最近的質(zhì)心所屬的族
            minDist = np.inf
            for j in range(self._k):
                distJI = self._calEDist(self._centroids[j, :], X[i, :])
                if distJI < minDist:
                    minDist = distJI
                    preds[i] = j
        return preds

            
          

測試部分

導(dǎo)入 Python 庫

            
              import pandas as pd
import numpy as np
from kmeans import KMeansClassifier
import matplotlib.pyplot as plt
import csv

            
          

提取數(shù)據(jù)

讀取.csv 文件(學(xué)生成績文件)

            
              filename = './data/2017EngGrade.csv'
with open(filename) as f:
    reader = csv.reader(f)

            
          

創(chuàng)建兩個列表,分別用于存放.csv 文件中的數(shù)學(xué)成績和英語成績

            
                  gradeMaths = []
    gradeEnglishs = []

            
          

遍歷文件中數(shù)據(jù),將兩列數(shù)據(jù)分別存放至兩個列表

            
                  for row in reader:
        gradeMath = int(row[2])
        gradeMaths.append(gradeMath)
        gradeEnglish = int(row[1])
        gradeEnglishs.append(gradeEnglish)

            
          

合并兩列表

            
              	z = list(zip(gradeMaths, gradeEnglishs))

            
          

將合并后的兩列表轉(zhuǎn)為矩陣

            
              	matz = np.array(z)

            
          

提取數(shù)據(jù)部分完整代碼如下:

            
              #讀取.csv 文件
filename = './data/2017EngGrade.csv'
with open(filename) as f:
    reader = csv.reader(f)

    #創(chuàng)建兩個列表,分別用于存放.csv 文件中的數(shù)學(xué)成績和英語成績
    gradeMaths = []
    gradeEnglishs = []

    #遍歷文件中數(shù)據(jù),將兩列數(shù)據(jù)分別存放至兩個列表
    for row in reader:
        gradeMath = int(row[2])
        gradeMaths.append(gradeMath)
        gradeEnglish = int(row[1])
        gradeEnglishs.append(gradeEnglish)

    #合并兩列表
    z = list(zip(gradeMaths, gradeEnglishs))
    #將合并后的兩列表轉(zhuǎn)為矩陣
    matz = np.array(z)

            
          

使用 K-means 進(jìn)行測試

            
              if __name__=="__main__":
    data_X = matz
    k = 3
    clf = KMeansClassifier(k)
    clf.fit(data_X)
    cents = clf._centroids
    labels = clf._labels
    sse = clf._sse
    colors = ['b','g','r','k','c','m','y','#e24fff','#524C90','#845868']
    for i in range(k):
        index = np.nonzero(labels==i)[0]
        x0 = data_X[index, 0]
        x1 = data_X[index, 1]
        y_i = i
        for j in range(len(x0)):
            plt.text(x0[j], x1[j], str(y_i), color=colors[i], \
                        fontdict={'weight': 'bold', 'size': 6})
        plt.scatter(cents[i,0],cents[i,1],marker='x',color=colors[i],\
                    linewidths=7)
    
    plt.title("SSE={:.2f}".format(sse))
    plt.axis([40,100,40,100])
    outname = "./result/k_clusters" + str(k) + ".png"
    plt.savefig(outname)
    plt.show()

            
          

結(jié)果展示

k = 3 時,K-means 算法結(jié)果如圖:
K-means聚類分析學(xué)生成績 Python實(shí)現(xiàn)_第1張圖片
k = 4 時,K-means 算法結(jié)果如圖:
K-means聚類分析學(xué)生成績 Python實(shí)現(xiàn)_第2張圖片
k = 5 時,K-means 算法結(jié)果如圖:
K-means聚類分析學(xué)生成績 Python實(shí)現(xiàn)_第3張圖片


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 爱爱免费观看高清视频在线播放 | 女人十八毛片免费观 | 久久精品国产一区二区小说 | 国产自产视频 | 欧美一级二级aaa免费视频 | 日本网站在线 | 四虎新地址 | 欧美国产成人免费观看永久视频 | 日韩视频在线一区 | 操久在线 | 玖玖在线精品 | 国产精品亚洲国产三区 | 肉漫天堂| 成人免费视频国产 | 日韩一区三区 | 欧美一级二级aaa免费视频 | 最新中文字幕在线播放 | 97人人插| 久久综合狠狠综合久久97色 | 超清乱人伦中文视频在线 | 日本高中生一级乇片 | 啪啪免费网站入口链接 | 国产一区二区三区久久精品 | 欧美va亚洲va在线观看蝴蝶网 | 中文字幕福利 | 日韩在线视频一区二区三区 | 国产精品久久国产三级国不卡顿 | 亚洲综合一区二区 | 欧美美女被爆操 | 男人的天堂视频在线 | 九天玄帝诀王凡小说免费阅读 | 中文字幕人成乱码第一页 | 欧美级毛片 | 最新国产在线视频 | 婷婷网五月天天综合天天爱 | 91福利视频网站 | 天天爽夜夜爽天天做夜夜做 | 亚洲毛片免费在线观看 | 日本一级毛片视频在线看 | 99精品视频在线观看免费 | 91在线免费视频观看 |