目录
一、数据集介绍
二、代码思维导图:
三、代码实现
1.导入库包,读取训练集和测试集数据
2.缺失值处理
缺失值展示:
3.类别型特征数值化
4.样本数据特征可视化
可视化展示:
5.构建svm模型
不同c值和gamma值结果展示:
6.评估模型
评估展示:
文章参考:
该数据从美国1994年人口普查数据库中抽取而来,因此也称作“人口普查收入”数据集,共包含48842条记录,年收入大于50k$的占比23.93%,年收入小于50k$的占比76.07%,数据集已经划分为训练数据32561条和测试数据16281条。
14个属性变量具体介绍如下:
属性名 |
类型 |
含义 |
age |
continuous |
年龄 |
workclass |
discrete |
工作类别 |
fnlwgt |
continuous |
序号 |
education |
discrete |
受教育程度 |
education-num |
continuous |
受教育时间 |
marital-status |
discrete |
婚姻状况 |
occupation |
discrete |
职业 |
relationship |
discrete |
社会角色 |
race |
discrete |
种族 |
sex |
discrete |
性别 |
capital-gain |
continuous |
资本收益 |
capital-loss |
continuous |
资本支出 |
hours-per-week |
continuous |
每周工作时间 |
native-country |
discrete |
国籍 |
下载地址:Index of /ml/machine-learning-databases/adult
平板字有些丑,将就一下⌯'▾'⌯
import pandas as pd
import numpy as np
from sklearn import svm
from sklearn import metrics
import warnings
import matplotlib.pyplot as plt
warnings.filterwarnings("ignore")#忽视警告
#导入Adult数据
train_filepath = "E:\\Pycharm\\Data_mining\\data\\Adult\\adult.data"#训练集
test_filepath = "E:\\Pycharm\\Data_mining\\data\\Adult\\adult.test"#测试集
adult_data = pd.read_csv(train_filepath,header=None)
adult_test = pd.read_csv(test_filepath,header=None)
warnings.filterwarnings("ignore"):python通过调用warnings模块中定义的warn()函数来发出警告。我们可以通过警告过滤器进行控制是否发出警告消息
#缺失值处理
def mis_value(data):
# 添加标题
# 年龄、工作类型、编号、受教育程度、受教育时长、婚姻状况、职位、家庭关系
# 种族、性别、资本收益、资本损失、每周工作时长、原籍、收入
data.rename(columns={0: 'age',
1: 'workclass',
2: 'fnlwgt',
3: 'education',
4: 'education_number',
5: 'marriage',
6: 'occupation',
7: 'relationship',
8: 'race',
9: 'sex',
10: 'capital_gain',
11: 'apital_loss',
12: 'hours_per_week',
13: 'native_country',
14: 'income'},
inplace=True)
#文件中缺失值用' ?'这一字符串填充,造成没有缺失值的假象
#使用lambda公式查看是否有' ?'这样的缺失值
#得到workclass(1列)、occupation(6列)、native-country(13列)含有缺失值
print("处理前的数据中含' ?'的数量")
print(data.apply(lambda x:np.sum(x==' ?')))
#缺失值处理,由于样本比较多,就选择删除缺失值
for i in range(len(data)):
if data['workclass'][i] == ' ?':
data.drop(index=i,axis=0,inplace=True)
elif data['occupation'][i] == ' ?':
data.drop(index=i,axis=0,inplace=True)
elif data['native_country'][i] == ' ?':
data.drop(index=i, axis=0, inplace=True)
print("处理后的数据中含' ?'的数量")
print(data.apply(lambda x: np.sum(x == ' ?')))
# 缺失值处理,也可以采用众数替换法(mode()方法取众数)
# data.replace(['workclass',' ?'],['workclass',data['workclass'].mode()[0]])#Workclass
# data.replace(['occupation',' ?'],['occupation',data['occupation'].mode()[0]])#Occupation
# data.replace(['native_country', ' ?'], ['native_country', data['native_country'].mode()[0]])#Native country
return data
drop(labels=None, axis=0, index=None, columns=None,
level=None, inplace=False, errors='raise'):labels:一个字符或者数值,加上axis ,表示带label标识的行或者列;如 (labels='A', axis=1) 表示A列
axis:axis=0表示行,axis=1表示列
columns:列名
index:表示dataframe的index, 如index=1, index=a
inplace:True表示删除某行后原dataframe变化,False不改变原始dataframe
#将类别型的属性转变为数值型
def digitalization(data):
adult_clean = mis_value(data)#获取处理缺失值后的数据
#包含工作类型、受教育程度、婚姻状况、职位、家庭关系、种族、性别、原籍、收入
tar_col = ['workclass','education','marriage','occupation','relationship','race','sex','native_country','income']
adult_digi = pd.DataFrame()#创建dataframe存放数据
no_map = []#创建用来存取未映射前的特征标签
for col in adult_clean.columns:
if col in tar_col:
unique_value = list(enumerate(np.unique(adult_clean[col])))#删除重复元素
no_map.append(list(unique_value))
dict_data = {key:value for value,key in unique_value}
adult_digi[col] = adult_clean[col].map(dict_data)#把类别型映射成数值型
else:
adult_digi[col] = adult_clean[col]
#通过索引列名构造样本特征和结果
character = adult_digi[['age', 'workclass', 'education', 'education_number','marriage', 'occupation',
'relationship', 'race', 'sex','capital_gain','apital_loss','hours_per_week', 'native_country']]#特征
result = adult_digi[['income']]#结果
return character,result,no_map
map是python内置函数,会根据提供的函数对指定的序列做映射
map(function,iterable,...):
第一个参数接受一个函数名,后面的参数接受一个或多个可迭代的序列,返回的是一个集合。把函数依次作用在list中的每一个元素上,得到一个新的list并返回。
catgory_col = ['workclass','education','marriage','occupation','relationship','race','sex','native_country']#类别型数据标签
#样本特征数据统计图表可视化
def chart_visual(name,j):
col = x_train[name]#获取特征集某列数据
lenth = np.max(col) - np.min(col) + 1 #统计特征映射到数值的个数
col_cla = np.linspace(np.max(col),np.min(col),lenth)#创建等间距数组,便于引用
count = [] #统计不同数值出现的次数
label = []#读取每个特征下的标签
lab = nomap1[j]
for i in range(lenth):
count.append(np.sum(col==col_cla[i]))
label.append(lab[i])
plt.pie(count,labels=label,autopct='%.1f%%')
#解决中文不能显示问题
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
plt.title(name+"下的不同类别占比")
plt.show()
for j in range(len(catgory_col)):
chart_visual(catgory_col[j],j)
#构建svm模型
#测试不同gamma值下的测试集准确率,得到当gamma=0.1时最大
# for g in range(1,7,1):
# #kenel='rbf'为高斯函数,gamma值越大,分类界面越连续;gamma值越小,分类效果越好
# #'ovo'两两之间进行划分
# gamma = g/10#gamma值在0-1之间
# classify = svm.SVC(kernel='rbf',gamma=gamma,decision_function_shape='ovo',C=0.8)
# classify.fit(x_train,y_train)#开始训练
# test_predict = classify.predict(x_test)#用训练好的模型预测测试集标签
# print("gamma=" + str(gamma) + ":测试集准确率:%.4f"%accuracy_score(y_test,test_predict))
#测试不同c值下测试集准确率,得到当c=0.9时最大
# for c in range(1,10,1):
# #kenel='rbf'为高斯函数,c值越大,训练样本准确率越高,泛化能力越低
# #'ovo'两两之间进行划分
# C = c/10#C值在0-1之间
# classify = svm.SVC(kernel='rbf',gamma=0.1,decision_function_shape='ovo',C=C)
# classify.fit(x_train,y_train)#开始训练
# test_predict = classify.predict(x_test)#用训练好的模型预测测试集标签
# print("C=" + str(C) + ":测试集准确率:%.4f"%accuracy_score(y_test,test_predict)
sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape=None,random_state=None)
主要调节的参数有:
C、kernel、degree、gamma、coef0
C越大,相当于惩罚松弛变量,希望松弛变量接近0,即对误分类的惩罚增大,趋向于对训练集全分对的情况,这样对训练集测试时准确率很高,但泛化能力弱。C值小,对误分类的惩罚减小,允许容错,将他们当成噪声点,泛化能力较强。
kernel :核函数,默认是rbf,可以是‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’
degree
:多项式poly函数的维度,默认是3,选择其他核函数时会被忽略。
gamma
: ‘rbf’,‘poly’ 和‘sigmoid’的核函数参数。默认是’auto’,则会选择1/n_features
decision_function_shape
:‘ovo’, ‘ovr’ or None, default=None3
coef0
:核函数的常数项。对于‘poly’和 ‘sigmoid’有用
classify = svm.SVC(kernel='rbf',gamma=0.1,decision_function_shape='ovo',C=0.9)
classify.fit(x_train,y_train)#开始训练
test_predict = classify.predict(x_test)#预测测试集
print("gamma=0.1,C=0.9:测试集准确率:%.4f"%metrics.accuracy_score(y_test,test_predict))#正确分类的样本数与总样本数之比
print("gamma=0.1,C=0.9:测试集精准率:%.4f"%metrics.precision_score(y_test,test_predict))#正确被预测的正样本(TP)占所有被预测为正样本(TP+FP)的比例
print("gamma=0.1,C=0.9:测试集召回率:%.4f"%metrics.recall_score(y_test,test_predict))#正确被预测的正样本(TP)占所有真正 正样本(TP+FN)的比例
1.【机器学习】svm.SVC参数详解_小苏打的学习博客-CSDN博客_svm.svc
2.使用随机森林与支持向量机实现Adult数据集上的分类_dianqijiaojianshuo的博客-CSDN博客