Kmeans聚类算法实战

根据计科18大类学生的成绩数据(选取两个特征:1、平均成绩GPA; 2、面向对象程序设计成绩),将计科18大类学生分成 3~4个类型。将其可视化显示出来。然后,根据18级物联网分流名单,计算物联1801、物联1802两个班的学生的学生类型占比,输出物联18两个班的学生类型分布饼图。

一、需要对所有学生的表进行kmeans聚类

1、Excel文件

在这里插入图片描述

2、代码如下所示(对于Excel文件最后几行无用的数据可以删除。我这里没有删除,我是在读取数据时没有读取最后几行)

from sklearn import datasets
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt1
from sklearn.cluster import KMeans
#导入
import pandas as pd
path=r'C:\Users\Administrator\Desktop\大三下课程\人工智能\18计算机类重庆交通大学专业成绩表_计算机类-new-0512.xls'

data=pd.read_excel(path,header=0)

data1=data.values[0:198,2:4]
#平均学分绩
x=data.values[0:198,2]
#面向对象成绩
y=data.values[0:198,3]

#这里已经知道了分4类,其他分类这里的参数需要调试
model = KMeans(n_clusters=3)
 
#训练模型
model.fit(data1)
 
#选取行标为100的那条数据,进行预测
prddicted_label= model.predict([[75.88,77]])
 
#预测全部203条数据
all_predictions = model.predict(data1)
#print(all_predictions)
#将名字与类别转化成字典进行一一对应
#全局字典
a={}
def one():
    aa=0
    bb=0
    cc=0
    print("18级所有学生信息!!!!!!!!!!!!")
    print('\n')
    print('每次预测结果为随机,即代表优生与差生的数字每次随机!')
    print('因此预测结果列表的前面几位数字就代表优秀学生,最后几位数字就代表差生!')
    print('请在明确优生与差生的代表数字过后再查看饼状图')
    print('\n')
    print('成绩预测分类结果:',all_predictions)
    for i in range(len(all_predictions)):
    	#循环给字典赋值	
        a[data.values[i,0]]=all_predictions[i]
        if all_predictions[i] ==0:
            aa+=1
        if all_predictions[i] ==1:
            bb+=1
        if all_predictions[i] ==2:
            cc+=1
    #print(a)
    aa1=aa/len(all_predictions)
    bb1=bb/len(all_predictions)
    cc1=cc/len(all_predictions)
    print('\n')
    print('所有学生中预测为0的概率',aa1)
    print('所有学生中预测为1的概率',bb1)
    print('所有学生中预测为2的概率',cc1)
    values1=[aa1,bb1,cc1]
    colors=['green','red','orange']


    plt1.title('18级所有学生的分类!')

    plt1.pie(values1,autopct='%3.1f %%',colors=colors)
    plt1.show()

    plt.scatter(x, y, c=all_predictions)
    plt.title('分成三类')
    plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
    plt.rcParams['axes.unicode_minus']=False
    plt.xlabel('平均学分成绩')
    plt.ylabel('面向对象成绩')
    plt.show()
one()

二、通过第二个表(分流名单)来确定学生类型

1、分流名单Excel文件

在这里插入图片描述

2、我的思路

我是用的字典来做,两个表中相同的元素有姓名和学号,因此第一个表可以将学号或者姓名作为字典的key,而分类出来的结果有三类(随机用0,1,2代替的),可将结果作为字典的value。而第二个表分类就可以使用key(学号或者姓名都行)去索引字典中的value,然后在计0,1,2的个数即可。但是第一个表中舍弃了部分数据,因此第二个表索引时有可能找不到对应的key,可用try except语句解决,同时将找不到的个数也可求出,求概率时用总长度减去找不到的个数。

3、代码

def two():
    print('--------------------------------------------------------------------------------------')
    path1=r'C:\Users\Administrator\Desktop\大三下课程\人工智能\物联网工程18级分流名单(公示).xlsx'
    data2=pd.read_excel(path1,header=1)
    #分别代表0,1,2的个数
    b=0
    c=0
    d=0
    #记录字典没有索引值的个数
    f=0
    #print(data2.values[1,2])

    for i in range(len(data2)):
        e=data2.values[i,1]
        try:
            if a[e]==0:
                b+=1
            if a[e]==1:
                c+=1
            if a[e]==2:
                d+=1
        except:
            f+=1
            #print('字典中没有这个索引值')
    b1=b/(len(data2)-f)
    c1=c/(len(data2)-f)
    d1=d/(len(data2)-f)


    print("18级物联网的分类情况!!!!!!!!!!!!!!!")
    print('\n')
    print('散点图上预测为0的概率:',b1)
    print('散点图上预测为1的概率:',c1)
    print('散点图上预测为2的概率:',d1)
    values=[b1,c1,d1]
    colors=['green','red','orange']
    print('\n')

    plt1.title('18物联网的分班情况!')
    plt1.pie(values,autopct='%3.1f %%',colors=colors)
    plt1.show()

三、总体代码

#from sklearn import datasets
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt1
from sklearn.cluster import KMeans
#导入
import pandas as pd
path=r'C:\Users\Administrator\Desktop\大三下课程\人工智能\18计算机类重庆交通大学专业成绩表_计算机类-new-0512.xls'

data=pd.read_excel(path,header=0)

data1=data.values[0:198,2:4]
#平均学分绩
x=data.values[0:198,2]
#面向对象成绩
y=data.values[0:198,3]

#这里已经知道了分4类,其他分类这里的参数需要调试
model = KMeans(n_clusters=3)
 
#训练模型
model.fit(data1)
 
#选取行标为100的那条数据,进行预测
prddicted_label= model.predict([[75.88,77]])
 
#预测全部203条数据
all_predictions = model.predict(data1)
#print(all_predictions)
#将名字与类别转化成字典进行一一对应
#全局
a={}
def one():
    aa=0
    bb=0
    cc=0
    print("18级所有学生信息!!!!!!!!!!!!")
    print('\n')
    print('每次预测结果为随机,即代表优生与差生的数字每次随机!')
    print('因此预测结果列表的前面几位数字就代表优秀学生,最后几位数字就代表差生!')
    print('请在明确优生与差生的代表数字过后再查看饼状图')
    print('\n')
    print('成绩预测分类结果:',all_predictions)
    for i in range(len(all_predictions)):
        a[data.values[i,0]]=all_predictions[i]
        if all_predictions[i] ==0:
            aa+=1
        if all_predictions[i] ==1:
            bb+=1
        if all_predictions[i] ==2:
            cc+=1
    #print(a)
    aa1=aa/len(all_predictions)
    bb1=bb/len(all_predictions)
    cc1=cc/len(all_predictions)
    print('\n')
    print('所有学生中预测为0的概率',aa1)
    print('所有学生中预测为1的概率',bb1)
    print('所有学生中预测为2的概率',cc1)
    values1=[aa1,bb1,cc1]
    colors=['green','red','orange']


    plt1.title('18级所有学生的分类!')

    plt1.pie(values1,autopct='%3.1f %%',colors=colors)
    plt1.show()

    plt.scatter(x, y, c=all_predictions)
    plt.title('分成三类')
    plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
    plt.rcParams['axes.unicode_minus']=False
    plt.xlabel('平均学分成绩')
    plt.ylabel('面向对象成绩')
    plt.show()
def two():
    print('--------------------------------------------------------------------------------------')
    path1=r'C:\Users\Administrator\Desktop\大三下课程\人工智能\物联网工程18级分流名单(公示).xlsx'
    data2=pd.read_excel(path1,header=1)
    #分别代表0,1,2的个数
    b=0
    c=0
    d=0
    #记录字典没有索引值的个数
    f=0
    #print(data2.values[1,2])

    for i in range(len(data2)):
        e=data2.values[i,1]
        try:
            if a[e]==0:
                b+=1
            if a[e]==1:
                c+=1
            if a[e]==2:
                d+=1
        except:
            f+=1
            #print('字典中没有这个索引值')
    b1=b/(len(data2)-f)
    c1=c/(len(data2)-f)
    d1=d/(len(data2)-f)


    print("18级物联网的分类情况!!!!!!!!!!!!!!!")
    print('\n')
    print('散点图上预测为0的概率:',b1)
    print('散点图上预测为1的概率:',c1)
    print('散点图上预测为2的概率:',d1)
    values=[b1,c1,d1]
    colors=['green','red','orange']
    print('\n')

    plt1.title('18物联网的分班情况!')

    plt1.pie(values,autopct='%3.1f %%',colors=colors)

    plt1.show()


one()
two()

四、运行结果(每次随机)

比如此次结果,0代表的就是优生,2代表的就是差生。因此所有学生的分类中优生占0.3,差生占0.2,中等生占0.489
在这里插入图片描述
在这里插入图片描述
分班过后的优生占0.1,差生占0.349,中等生占0.53
在这里插入图片描述

  • 3
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值