数据可视化期末考试(编程)

发布于:2024-07-03 ⋅ 阅读:(39) ⋅ 点赞:(0)

1.KNN

1.新增数据的分类

import pandas as pd  
  
# 您的原始数据字典  
data = {    
    '电影名称': ['电影1', '电影2', '电影3', '电影4', '电影5'],    
    '打斗镜头': [10, 5, 108, 115, 20],    
    '接吻镜头': [110, 89, 5, 8, 200],    
    '电影类型': ['爱情片', '爱情片', '动作片', '动作片', '爱情片']    
}  
  
# 将数据字典转换为DataFrame  
df = pd.DataFrame(data)  
  
# 定义一个简单的分类逻辑(这里只是一个示例,您可以根据数据调整阈值)  
def predict_movie_type(fights, kisses):  
    if fights > kisses:  
        return '动作片'  
    else:  
        return '爱情片'  
  
# 输入您想要预测的电影数据  
input_fights = float(input("请输入打斗镜头的数量: "))  
input_kisses = float(input("请输入接吻镜头的数量: "))  
  
# 预测电影类型  
predicted_type = predict_movie_type(input_fights, input_kisses)  
print(f"基于您输入的数据,电影类型被预测为: {predicted_type}")

2.把新增数据放在散点图上并标记坐标

import numpy as np  
import pandas as pd  
import matplotlib.pyplot as plt  
  
# 您的修正后的数据字典  
data = {    
    '电影名称': ['电影1', '电影2', '电影3', '电影4', '电影5'],    
    '打斗镜头': [10, 5, 108, 115, 120],    
    '接吻镜头': [110, 89, 5, 8, 20],    
    '电影类型': ['爱情片', '爱情片', '动作片', '动作片', '动作片']    
}  
  
pd_data = pd.DataFrame(data)  
  
colors = ['red' if t == '爱情片' else 'green' for t in pd_data['电影类型']]  
  
# 设置中文字体,以便正确显示中文标签和标题  
plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体字体显示中文  
plt.rcParams['axes.unicode_minus'] = False  # 正确显示负号  
  
# 创建图形和散点图  
plt.figure()  
  
# 绘制散点图并添加坐标  
for index, row in pd_data.iterrows():  
    plt.scatter(row['打斗镜头'], row['接吻镜头'], c=colors[index])  
    plt.annotate(f'({row["打斗镜头"]}, {row["接吻镜头"]})',   
                 (row['打斗镜头'], row['接吻镜头']),   
                 textcoords="offset points", xytext=(0,10), ha='center')  
  
plt.grid(linestyle='-.')  
plt.xlim(0, 140)  
plt.ylim(0, 220)  # 调整y轴范围以适应新的数据  
  
plt.xlabel("打斗镜头")  
plt.ylabel("接吻镜头")  
plt.title("电影分析")  
  
# 添加图例  
legend_elements = [plt.Line2D([0], [0], color='red', label='爱情片'),  
                    plt.Line2D([0], [0], color='green', label='动作片')]  
plt.legend(handles=legend_elements, loc='best')  
  
# 显示图形  
plt.show()

2.logistic回归,用线性来划分两个类型

import matplotlib.pyplot as plt
import numpy as np


#用回归思想作二分类(线性回归 wx+b),用激活函数(sigmoid函数)来转为0 1的结果进行分类【z=wx+b】。
#x:为样本的输入特征向量,w和b:w为模型权重参数参数,b为偏置。当确定w和b时,可确定模型
#所以,需要损失函数来确定最优的w和b(随机事件越不确定,所包含的信息量就越多,熵越大)
#则,样本所属类别的概率,而这个概率越大越好,所以也就是求解这个损失函数的最大值。
#怎么求解使J(θ)最大的θ值呢?因为是求最大值,所以我们需要使用梯度上升算法。
#(个人理解θ就是w0,w1,w2)

"""
def loadDataSet():
	dataMat = []														#创建数据列表
	labelMat = []														#创建标签列表
	fr = open('testSet.txt')											#打开文件	
	for line in fr.readlines():											#逐行读取
		lineArr = line.strip().split()									#去回车,放入列表,以空格分割split,并去掉空格strip
		dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])		#添加数据,
#lineArr[0]放w,lineArr[1]放x
#z=w0x0 + w1x1 + w2x2,即可将数据分割开。其中,x0为全是1的向量,x1为数据集的第一列数据,x2为数据集的第二列数据。
#另z=0,则0=w0 + w1x1 + w2x2。横坐标为x1,纵坐标为x2。这个方程未知的参数为w0,w1,w2,也就是我们需要求的回归系数(最优参数)。
		labelMat.append(int(lineArr[2]))								#添加标签,第三列标签
#labelMat即为分类标签。根据标签的不同,对这些点进行分类。
	fr.close()															#关闭文件
	return dataMat, labelMat											#返回
if __name__=='__main__':
	dataMat,labelMat=loadDataSet()
	print(dataMat)
	print(labelMat)    

def plotDataSet():
	dataMat, labelMat = loadDataSet()									#加载数据集
	dataArr = np.array(dataMat)											#转换成numpy的array数组
	n = np.shape(dataMat)[0]											#数据个数(读取一维dataMat矩阵的长度)
	xcord1 = []; ycord1 = []											#正样本
	xcord2 = []; ycord2 = []											#负样本
	for i in range(n):													#根据数据集标签进行分类
		if int(labelMat[i]) == 1:
			xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])	#1为正样本
#dataArr[i,1]:表示dataArr[]数组中下标为1的第i个元素
		else:
			xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])	#0为负样本
	fig = plt.figure()#创建一个绘图对象
	ax = fig.add_subplot(111)											#添加subplot
#add_subplot(111),a=1,b=1,c=1,表示把他的行和列都分为1份,
#其实就是保持不变,所以子图只有1*1=1个,那么当我们最后选择展示第1个子图时,其实就是展示他本身。
	ax.scatter(xcord1, ycord1, s = 30, c = "red", marker = 'x',alpha=0.9)#绘制正样本(用于生成一个scatter散点图)
#s:表示的是大小,是一个标量或者是一个shape大小为(n,)的数组,可选,默认20。
#marker:MarkerStyle,表示的是标记的样式,可选,默认’o’
#alpha:标量(表样本点的亮度),0-1之间,可选,默认None。
	ax.scatter(xcord2, ycord2, s =30, c = 'blue',alpha=0.9)			#绘制负样本
	plt.title('DataSet')												#绘制title
	plt.xlabel('X1'); plt.ylabel('X2')									#绘制label
	plt.show()															#显示
plotDataSet()

def sigmoid(inX):
	sig= 1.0 / (1 + np.exp(-inX))
	return sig
def Gradient_Ascent_test():
	def f_prime(x_old):									#f(x)的导数
		return -2 * x_old + 4
	x_old = -1											#初始值,给一个小于x_new的值
	x_new = 0											#梯度上升算法初始值,即从(0,0)开始
	alpha = 0.001										#步长,也就是学习速率,控制更新的幅度
	presision = 0.00000001								#精度,也就是更新阈值
	while abs(x_new - x_old) > presision:
		x_old = x_new
		x_new = x_old + alpha * f_prime(x_old)			#上面提到的公式
	print(x_new)										#打印最终求解的极值近似值
Gradient_Ascent_test()

def gradAscent(dataMatIn, classLabels):
	dataMatrix = np.mat(dataMatIn)										#转换成numpy的mat(生成矩阵)
	labelMat = np.mat(classLabels).transpose()							#转换成numpy的mat,并进行转置(行变列)
#区别mat和array,mat可以从字符串或者列表中生成,但是array只能从列表中生成
	m, n = np.shape(dataMatrix)#返回dataMatrix的大小。m为行数,n为列数。
	alpha = 0.001														#移动步长,也就是学习速率,控制更新的幅度。
	maxCycles = 500														#最大迭代次数
	weights = np.ones((n,1))
    #返回n个数组,每个数组1个元素(上述定义n为列数)
	weights_history = []     
	for k in range(maxCycles):
		h= sigmoid(dataMatrix * weights)
		error = labelMat - h#是公式里的【y-h0(x)】(labelMat是有0或1的矩阵)
        
		weights = weights + alpha * dataMatrix.transpose() * error    #  梯度上升迭代公式

	return weights.getA()												#将矩阵转换为数组,返回权重数组
if __name__=='__main__':
	weights= gradAscent(dataMat,labelMat)
#	weights, weights_history = gradAscent(dataMat, labelMat)
	print(weights)

def plotBestFit(dataMat, labelMat, weights):
	dataMat, labelMat = loadDataSet()									#加载数据集,
#将loadDataSet()函数得到的dataMat, labelMat值传到dataMat, labelMat
	dataArr = np.array(dataMat)											#转换成numpy的array数组
	n = np.shape(dataMat)[0]											#数据个数,
	xcord1 = []; ycord1 = []											#正样本
	xcord2 = []; ycord2 = []											#负样本
	for i in range(n):													#根据数据集标签进行分类
		if int(labelMat[i]) == 1:
			xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])	#1为正样本
		else:
			xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])	#0为负样本
	fig = plt.figure()
	ax = fig.add_subplot(111)											#添加subplot
	ax.scatter(xcord1, ycord1, s = 30, c = 'red', marker = 'x',alpha=.9)#绘制正样本
#s:表示的是大小,是一个标量或者是一个shape大小为(n,)的数组,可选,默认20。
#marker:MarkerStyle,表示的是标记的样式,可选,默认’o’
#alpha:标量(表样本点的亮度),0-1之间,可选,默认None。
	ax.scatter(xcord2, ycord2, s = 30, c = 'blue',alpha=.9)			#绘制负样本
	x = np.arange(-3.0, 3.0, 0.1)
	y = (-weights[0] - weights[1] * x) / weights[2]
	ax.plot(x, y)
	plt.title('BestFit')												#绘制title
	plt.xlabel('X1'); plt.ylabel('X2')									#绘制label
	plt.show()		
plotBestFit(dataMat, labelMat, weights)

3.logistic,回归系数与迭代次数的关系

# -*- coding:UTF-8 -*-
from matplotlib.font_manager import FontProperties
import matplotlib.pyplot as plt
import numpy as np
import random
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def loadDataSet():  
    dataMat = []  
    labelMat = []  
    fr = open('testSet.txt')  # 替换为你的数据文件路径  
    for line in fr.readlines():  
        lineArr = line.strip().split()  
        if len(lineArr) >= 3:  # 检查列表长度是否足够  
            dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])  
            labelMat.append(int(lineArr[2]))  
        else:  
            print(f"Skipping line with insufficient data: {line.strip()}")  
    fr.close()  
    return dataMat, labelMat

"""
函数说明:梯度上升算法

Parameters:
	dataMatIn - 数据集
	classLabels - 数据标签
Returns:
	weights.getA() - 求得的权重数组(最优参数)
	weights_array - 每次更新的回归系数
"""
def gradAscent(dataMatIn, classLabels):
	dataMatrix = np.mat(dataMatIn)										#转换成numpy的mat
	labelMat = np.mat(classLabels).transpose()							#转换成numpy的mat,并进行转置
	m, n = np.shape(dataMatrix)											#返回dataMatrix的大小。m为行数,n为列数。
	alpha = 0.01														#移动步长,也就是学习速率,控制更新的幅度。
	maxCycles = 500														#最大迭代次数
	weights = np.ones((n,1))
	weights_array = np.array([])
	for k in range(maxCycles):
		h = sigmoid(dataMatrix * weights)								#梯度上升矢量化公式
		error = labelMat - h
		weights = weights + alpha * dataMatrix.transpose() * error
		weights_array = np.append(weights_array,weights)
	weights_array = weights_array.reshape(maxCycles,n)
	return weights.getA(),weights_array									#将矩阵转换为数组,并返回

"""
函数说明:改进的随机梯度上升算法
Parameters:
	dataMatrix - 数据数组
	classLabels - 数据标签
	numIter - 迭代次数
Returns:
	weights - 求得的回归系数数组(最优参数)
	weights_array - 每次更新的回归系数
"""
def stocGradAscent1(dataMatrix, classLabels, numIter=150):
	m,n = np.shape(dataMatrix)												#返回dataMatrix的大小。m为行数,n为列数。
	weights = np.ones(n)   													#参数初始化
	weights_array = np.array([])											#存储每次更新的回归系数
	for j in range(numIter):											
		dataIndex = list(range(m))
		for i in range(m):			
			alpha = 4/(1.0+j+i)+0.01   	 									#降低alpha的大小,每次减小1/(j+i)。
			randIndex = int(random.uniform(0,len(dataIndex)))				#随机选取样本
			h = sigmoid(sum(dataMatrix[dataIndex[randIndex]]*weights))		#选择随机选取的一个样本,计算h
			error = classLabels[dataIndex[randIndex]] - h 								#计算误差
			weights = weights + alpha * error * dataMatrix[dataIndex[randIndex]]   	#更新回归系数
			weights_array = np.append(weights_array,weights,axis=0) 		#添加回归系数到数组中
			del(dataIndex[randIndex]) 										#删除已经使用的样本
	weights_array = weights_array.reshape(numIter*m,n) 						#改变维度
	return weights,weights_array 											#返回


"""
函数说明:绘制回归系数与迭代次数的关系

Parameters:
	weights_array1 - 回归系数数组1
	weights_array2 - 回归系数数组2

"""
def plotWeights(weights_array1,weights_array2):
    fig, axs = plt.subplots(nrows=3, ncols=2,sharex=False, sharey=False, figsize=(20,10))
    x1 = np.arange(0, len(weights_array1), 1)
    # 绘制w0与迭代次数的关系
    axs[0][0].plot(x1,weights_array1[:,0])
    axs0_title_text = axs[0][0].set_title(u'Improved Random Gradient Ascension Algorithm')
    axs0_ylabel_text = axs[0][0].set_ylabel(u'W0')
    plt.setp(axs0_title_text, size=20, weight='bold', color='black')  
    plt.setp(axs0_ylabel_text, size=20, weight='bold', color='black') 
    # 绘制w1与迭代次数的关系
    axs[1][0].plot(x1,weights_array1[:,1])
    axs1_ylabel_text = axs[1][0].set_ylabel(u'W1')
    plt.setp(axs1_ylabel_text, size=20, weight='bold', color='black') 
    # 绘制w2与迭代次数的关系
    axs[2][0].plot(x1,weights_array1[:,2])
    axs2_xlabel_text = axs[2][0].set_xlabel(u'Iterations')
    axs2_ylabel_text = axs[2][0].set_ylabel(u'W2')
    plt.setp(axs2_xlabel_text, size=20, weight='bold', color='black')  
    plt.setp(axs2_ylabel_text, size=20, weight='bold', color='black') 

    x2 = np.arange(0, len(weights_array2), 1)
    # 绘制w0与迭代次数的关系
    axs[0][1].plot(x2,weights_array2[:,0])
    axs0_title_text = axs[0][1].set_title(u'Gradient Ascending Algorithm')
    axs0_ylabel_text = axs[0][1].set_ylabel(u'W0')
    plt.setp(axs0_title_text, size=20, weight='bold', color='black')  
    plt.setp(axs0_ylabel_text, size=20, weight='bold', color='black') 
    # 绘制w1与迭代次数的关系
    axs[1][1].plot(x2,weights_array2[:,1])
    axs1_ylabel_text = axs[1][1].set_ylabel(u'W1')
    plt.setp(axs1_ylabel_text, size=20, weight='bold', color='black') 
    # 绘制w2与迭代次数的关系
    axs[2][1].plot(x2,weights_array2[:,2])
    axs2_xlabel_text = axs[2][1].set_xlabel(u'Iterations')
    axs2_ylabel_text = axs[2][1].set_ylabel(u'W2')
    plt.setp(axs2_xlabel_text, size=20, weight='bold', color='black')  
    plt.setp(axs2_ylabel_text, size=20, weight='bold', color='black') 

    plt.show()

if __name__ == '__main__':
	dataMat, labelMat = loadDataSet()			
	weights1,weights_array1 = stocGradAscent1(np.array(dataMat), labelMat)

	weights2,weights_array2 = gradAscent(dataMat, labelMat)
	plotWeights(weights_array1, weights_array2)


网站公告

今日签到

点亮在社区的每一天
去签到