SVM支持向量机算法利用python实现:以预测CPU种类(i5,i7,i9)和通过学生成绩判断学生性别为例

1.线性可分的数据分类(二维数据为例)

2.近似线性可分

3.非线性可分SVM

4.用台式电脑的CPU参数判断CPU的种类(i7,i8,i9)

5.用学生各个成绩判断学生性别

5.1用默认参数尝试性拟合

5.2使用网格搜索法,寻找回归中的最佳惩罚项C值,epsilon和gamma

from  sklearn import svm
import pandas as pd
import numpy as np
from sklearn import model_selection
from sklearn import metrics
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['simhei']#用于正常显示中文标签
plt.rcParams['axes.unicode_minus']=False#用于正常显示负号
import re
import seaborn as sns
from scipy.stats import norm

#1.线性可分的数据分类(二维数据为例)

#生成二元正太分布的随机数据集
data_1=pd.DataFrame(np.random.multivariate_normal([0.5,0.5],[[4,0],[0,4]],size=1000),columns=['x1','x2'])
data_1['y']=1
data_2=pd.DataFrame(np.random.multivariate_normal([15,6],[[3,0],[0,3]],size=1000),columns=['x1','x2'])
data_2['y']=-1
data=pd.concat([data_1,data_2])
data_x=data[['x1','x2']]
data_y=data['y']

#绘制散点图
plt.figure(figsize=(12,12))
plt.scatter(data_1['x1'],data_1['x2'],color='red')
plt.scatter(data_2['x1'],data_2['x2'],color='green')

x_train,x_test,y_train,y_test=model_selection.train_test_split(data_x,data_y,test_size=0.2,random_state=12)#将数据划分为训练集和测试集
model=svm.LinearSVC(dual=False)#设置模型
model.fit(x_train,y_train)#拟合训练集模型
y_pred=model.predict(x_test)#用模型计算预测值
metrics.mean_squared_error(y_test,y_pred)#计算拟合误差

#绘制超平面支持向量分割线
def x1_(x2):#超平面函数
    x1=(model.intercept_[0]+model.coef_[0,1]*x2)/(-model.coef_[0,0])
    return x1

y_h=np.arange(data_x['x2'].min(),data_x['x2'].max())
x_h=x1_(y_h)
plt.plot(x_h,y_h,color='y')

最终效果如下:通过支持向量将两组样本数据分开来
在这里插入图片描述
#2.近似线性可分

#生成二元正太分布的随机数据集
data_1=pd.DataFrame(np.random.multivariate_normal([0.5,0.5],[[7,0],[0,6]],size=1000),columns=['x1','x2'])
data_1['y']=1
data_2=pd.DataFrame(np.random.multivariate_normal([15,6],[[7,0],[0,8]],size=1000),columns=['x1','x2'])
data_2['y']=-1
data=pd.concat([data_1,data_2])
data_x=data[['x1','x2']]
data_y=data['y']

#绘制散点图
plt.figure(figsize=(12,12))
plt.scatter(data_1['x1'],data_1['x2'],color='red')
plt.scatter(data_2['x1'],data_2['x2'],color='green')

x_train,x_test,y_train,y_test=model_selection.train_test_split(data_x,data_y,test_size=0.2,random_state=12)#将数据划分为训练集和测试集
model=svm.LinearSVC(dual=False)#设置模型
model.fit(x_train,y_train)#拟合训练集模型
y_pred=model.predict(x_test)#用模型计算预测值
metrics.mean_squared_error(y_test,y_pred)#计算拟合误差

#绘制超平面支持向量分割线
def x1_(x2):#超平面函数
    x1=(model.intercept_[0]+model.coef_[0,1]*x2)/(-model.coef_[0,0])
    return x1
y_h=np.arange(data_x['x2'].min(),data_x['x2'].max())
x_h=x1_(y_h)
plt.plot(x_h,y_h,color='y')
plt.text(x=x_h[0],y=y_h[0],s='支持向量超平面')

在这里插入图片描述
#3.非线性可分SVM

data_1=pd.DataFrame(np.random.multivariate_normal([0,0],[[11,0],[0,14]],size=1000),columns=['x1','x2'])
data_1['y']=1

drop_i=[]
for i in data_1.index:
    if np.sqrt(data_1.ix[i,'x1']**2+data_1.ix[i,'x2']**2)<3:
        drop_i.append(i)

data_2=data_1.ix[drop_i,:]
data_2['y']=-1
data_1.drop(drop_i,axis=0,inplace=True)

data=pd.concat([data_1,data_2])
data_x=data[['x1','x2']]
data_y=data['y']

#绘制散点图
plt.figure(figsize=(12,12))
plt.scatter(data_1['x1'],data_1['x2'],color='red')
plt.scatter(data_2['x1'],data_2['x2'],color='green')

#拟合模型
x_train,x_test,y_train,y_test=model_selection.train_test_split(data_x,data_y,test_size=0.2,random_state=12)#将数据划分为训练集和测试集
model=svm.SVC()#设置模型
model.fit(x_train,y_train)#拟合训练集模型
y_pred=model.predict(x_test)#用模型计算预测值
metrics.mean_squared_error(y_test,y_pred)#计算拟合误差

#查看测试集中预测正确概率
x_test['y']=y_test
x_test['y_pred']=y_pred
x_test['statue']=''
for i in x_test.index:
    if x_test.ix[i,'y']==x_test.ix[i,'y_pred']:
        x_test.ix[i,'statue']=1
    else:x_test.ix[i,'statue']=0

在这里插入图片描述
#4.用台式电脑的CPU参数判断CPU的种类(i7,i8,i9)

#(1)读取数据
data=pd.read_excel('E:\课件\研二上\文件\CPU.xlsx').ix[:,'核心架构':]
data.fillna(0,inplace=True)

#将数据做简单处理
for i in data.index:
    if data.ix[i,'加速频率'] =='无':
        data.ix[i, '加速频率'] =0

#(2)将部分数据做数值化处理
for col in ['核心架构','核显','插槽','种类', '后缀', '型号']:
    data[col]=pd.factorize(data[col])[0]

#(3)绘制因变量分布直方图,判断数据是否需要对数处理
plt.figure(figsize=(10,8))
sns.distplot(data['种类'],bins=20,kde=True,fit=norm,hist_kws={
    
    'color':'blue'},kde_kws={
    
    'color':'red','label':'Density'},fit_kws={
    
    'color':'black','label':'Normal'})
plt.legend()
plt.show()

#(4)将自变量做标准化处理
from sklearn import preprocessing
cols=list(data.columns)
cols.remove('种类')
data_x=preprocessing.scale(data[cols])
data_y=data['种类']

#(5)进行模型拟合
x_train,x_test,y_train,y_test=model_selection.train_test_split(data_x,data_y,test_size=0.2,random_state=12)#将数据划分为训练集和测试集

#用默认参数尝试性拟合
model=svm.SVR()#建立模型
model.fit(data_x,data_y)#模型拟合
y_pred=model.predict(x_test)#模型预测值
metrics.mean_squared_error(y_test,y_pred)#均方误差
pd.DataFrame({
    
    '实际值':y_test,'预测值':y_pred})#查看实际值和预测值对比

#使用网格搜索法,寻找回归中的最佳惩罚项C值,epsilon和gamma
epsilon=np.arange(0.1,0.5,0.2)
C=np.arange(100,1000,200)
gamma=np.arange(0.001,0.01,0.002)
parameters={
    
    'epsilon':epsilon,'C':C,'gamma':gamma}
model=model_selection.GridSearchCV(estimator=svm.SVR(),param_grid=parameters,scoring='neg_mean_squared_error',cv=5,verbose=1,n_jobs=2)#用网格搜索法建立模型
model.fit(x_train,y_train)#拟合模型
print(model.best_params_,model.best_score_)#查看模型最佳参数
y_pred=model.predict(x_test)#计算预测值
metrics.mean_squared_error(y_test,y_pred)#计算均方误差

pd.DataFrame({
    
    '实际值':y_test,'预测值':y_pred})#查看实际值和预测值的对比情况

从实际预测结果来看,预测值与实际值非常接近,模型预测效果非常好
在这里插入图片描述

#5.用学生各个成绩判断学生性别

data=pd.read_excel('学生考试成绩表.xlsx')

#简单处理,留下必要变量
data=data[['性别', '语文', '代数','英语', '物理','化学','生物','政治','历史','地理','总分']]

#将部分数据做数值化处理
data['性别']=pd.factorize(data['性别'])[0]

#绘制因变量分布直方图,判断数据是否需要对数处理
plt.figure(figsize=(10,8))
sns.distplot(data['性别'],bins=20,kde=True,fit=norm,hist_kws={
    
    'color':'blue'},kde_kws={
    
    'color':'red','label':'Density'},fit_kws={
    
    'color':'black','label':'Normal'})
plt.legend()
plt.show()

#将自变量做标准化处理
from sklearn import preprocessing
cols=['语文', '代数','英语', '物理','化学','生物','政治','历史','地理','总分']
data_x=preprocessing.scale(data[cols])
data_y=data['性别']

#进行模型拟合
x_train,x_test,y_train,y_test=model_selection.train_test_split(data_x,data_y,test_size=0.2,random_state=12)#将数据划分为训练集和测试集

##5.1用默认参数尝试性拟合

model=svm.SVR()#建立模型
model.fit(data_x,data_y)#模型拟合
y_pred=model.predict(x_test).round(0)#模型预测值
metrics.mean_squared_error(y_test,y_pred)#均方误差

data_summary=pd.DataFrame({
    
    '实际值':y_test,'预测值':y_pred})#查看实际值和预测值对比
data_summary['预测值']=data_summary['预测值']#预测值取四舍五入

#模型评价
#(1)测试集样本数据拟合优度,model.score(X,y)
model.score(x_test,y_test)

#(2)构建混淆矩阵,判断预测精准程度
"""
混淆矩阵中行代表真实值,列代表预测值
TN:实际为0预测为0的个数       FP:实际为0预测为1的个数
FN:实际为1预测为0的个数       TP:实际为1预测为1的个数

精准率precision=TP/(TP+FP)——被预测为1的样本的的预测正确率
召回率recall=TP/(TP+FN)——实际为1的样本的正确预测率
"""
from sklearn.metrics import confusion_matrix
cfm=confusion_matrix(y_test, y_pred)

plt.matshow(cfm,cmap=plt.cm.gray)#cmap参数为绘制矩阵的颜色集合,这里使用灰度
plt.show()

#(3)精准率和召回率
from sklearn.metrics import precision_score,recall_score
precision_score(y_test, y_pred)# 精准率
recall_score(y_test, y_pred)#召回率

#(4)错误率矩阵
row_sums = np.sum(cfm,axis=1)
err_matrix = cfm/row_sums
np.fill_diagonal(err_matrix,0)#对err_matrix矩阵的对角线置0,因为这是预测正确的部分,不关心

plt.matshow(err_matrix,cmap=plt.cm.gray)#亮度越高的地方代表错误率越高
plt.show()

##5.2使用网格搜索法,寻找回归中的最佳惩罚项C值,epsilon和gamma

epsilon=np.arange(0.1,0.5,0.2)
C=np.arange(100,1000,200)
gamma=np.arange(0.001,0.01,0.002)
parameters={
    
    'epsilon':epsilon,'C':C,'gamma':gamma}
model=model_selection.GridSearchCV(estimator=svm.SVR(),param_grid=parameters,scoring='neg_mean_squared_error',cv=5,verbose=1,n_jobs=2)#用网格搜索法建立模型
model.fit(x_train,y_train)#拟合模型
print(model.best_params_,model.best_score_)#查看模型最佳参数
y_pred=model.predict(x_test).round(0)#计算预测值
metrics.mean_squared_error(y_test,y_pred)#计算均方误差
pd.DataFrame({
    
    '实际值':y_test,'预测值':y_pred})#查看实际值和预测值的对比情况

#模型评价
#(1)测试集样本数据拟合优度,model.score(X,y)
model.score(x_test,y_test)

#(2)构建混淆矩阵,判断预测精准程度
"""
混淆矩阵中行代表真实值,列代表预测值
TN:实际为0预测为0的个数       FP:实际为0预测为1的个数
FN:实际为1预测为0的个数       TP:实际为1预测为1的个数

精准率precision=TP/(TP+FP)——被预测为1的样本的的预测正确率
召回率recall=TP/(TP+FN)——实际为1的样本的正确预测率
"""
from sklearn.metrics import confusion_matrix
cfm=confusion_matrix(y_test, y_pred)

plt.matshow(cfm,cmap=plt.cm.gray)#cmap参数为绘制矩阵的颜色集合,这里使用灰度
plt.show()

#(3)精准率和召回率
from sklearn.metrics import precision_score,recall_score
precision_score(y_test, y_pred)# 精准率
recall_score(y_test, y_pred)#召回率

#(4)错误率矩阵
row_sums = np.sum(cfm,axis=1)
err_matrix = cfm/row_sums
np.fill_diagonal(err_matrix,0)#对err_matrix矩阵的对角线置0,因为这是预测正确的部分,不关心

plt.matshow(err_matrix,cmap=plt.cm.gray)#亮度越高的地方代表错误率越高
plt.show()

数据下载:
学生成绩表:https://download.csdn.net/download/weixin_45590329/12427889
CPU数据:https://download.csdn.net/download/weixin_45590329/13056757

猜你喜欢

转载自blog.csdn.net/weixin_45590329/article/details/109299074