输家问题"/>
机器学习作业 李宏毅老师——HW2 赢家还是输家问题
简介
这个作业是根据一个人口普查的数据判断年收入是否>50K。
输入有:一个人的年龄、受教育程度、职业、国籍等14项参数共2w笔
输出:这个人年收入是否>50K
思路分析
这个作业是一个二分类问题。使用逻辑回归比较好使。实际就是在线性回归的基础上加sigmoid函数,将其转化为概率。
与线性回归的主要区别在于loss函数的计算上。逻辑回归采用交叉滴的方法;线性回归采用欧氏距离的方法。
数据预处理
源数据都是干净的数据,而且格式很好,省去的很多麻烦。
直接进行数值化、归一化即可。
- 数值化:它很多的项中是利用字符串表示的。比如国籍这一项,内容就像这样:
native-country: United-States, Cambodia, England, Puerto-Rico, Canada, Germany, Outlying-US(Guam-USVI-etc).
等。为了能够让计算机处理,就需要将其数值化。
数值化时我想到了两种解决方案,
1.用数值表示。比如:中国=1.0,美国=2.0,英国=3.0等等。
2.将国籍中的每个国家作为一个项,如果国籍是这个国家,则该项为1,否则是0。
如果用方案1的话,不同的国家之间,看起来就像有联系似的,但是实际并没有。所以在作业中使用了方案2.
ps:这里还可以用one-hot编码方式。这是我已经数据处理完之后才想到的,所以没有过多涉猎。 - 归一化:把数据范围尽量scale到同一个数量级上。(这里我不能肯定的给出为什么这么做。如果有小伙伴清楚,麻烦留个言Thanks♪(・ω・)ノ)。查看数据,发现实际只有6项需要归一化。
模型介绍
详见.html。这篇文章介绍的已经很详细了。
代码
对文件进行预处理 源文件是老师提供的官方文件,已在参考资料中提供下载
输出是两个文件。分别是answer.csv(结果)和data.csv(人口的各个数据)。
import pandas as pd
from pandas import DataFrame,Series
import numpy as np
import csvrdf = pd.read_excel("C:/Users/帅哥/Desktop/普查数据 .xlsx")
#重写文件的列
name_list = []
name_list.append('age')
name_list.append('fnlwgt')
name_list.append('education-num')
name_list.append('capital-gain')
name_list.append('capital-loss')
name_list.append('hours-per-week')all_array =np.array(rdf)
x,y = all_array.shape
data_array = all_array[:,:14]
#结果集
answer_list=[1 if i==[' >50K']else 0 for i in all_array[:,14:15]]
trans_array =np.transpose(data_array)#将数组翻转,用于找到项
for i in trans_array:for j in i:if type(j) is str and j not in name_list:name_list.append(j)
name_list.remove(' ?')#生成实际用的数据集
train_array = np.zeros((int(x),len(name_list)))
for i in range(x):train_array[i][0] = data_array[i][0]train_array[i][1] = data_array[i][2]train_array[i][2] = data_array[i][4]train_array[i][3] = data_array[i][10]train_array[i][4] = data_array[i][11]train_array[i][5] = data_array[i][12]for j in range(14):if data_array[i][j] in name_list:train_array[i][name_list.index(data_array[i][j])] = 1
for j in range(6):train_array[:,j]/=np.mean(train_array[:,j])
#将数据集写入文件
with open("C:/Users/帅哥/Desktop/data.csv","w",newline='') as csvfile:writer = csv.writer(csvfile)writer.writerow(name_list)writer.writerows(train_array.tolist())csvfile.close()
#将结果集写入文件
answer = {'answer':answer_list}
df1 = pd.DataFrame(answer)
df1.to_csv("C:/Users/帅哥/Desktop/answer.csv",index=None)
print("over")
模型训练和验证集验证
print("开始执行")
import pandas as pd
import numpy as np
import mathdata=pd.read_csv("C:/Users/帅哥/Desktop/data.csv")
answer = pd.read_csv("C:/Users/帅哥/Desktop/answer.csv")
#数据切割为训练集和测试集
array = np.array(data)
array1 = np.array(answer)
x,y = array.shapetrain_num = int(0.67*x)
test_num = x-int(train_num)
train_data = array[:train_num,:]
test_data = array[train_num:,:]
train_answer = array1[:train_num]
test_answer = array1[train_num:] #更新参数、训练模型
bias = 0#偏置初始化
weights = np.ones(y)#权重初始化
learning_rate = 1
reg_rate = 0.0001
bg2_sum = 0#偏置值的梯度平方和
wg2_sum = np.zeros(y)#偏置的梯度平方和
#Pn = np.zeros(y)
print("开始循环处理")
epoches = 700for times in range(epoches):b_g = 0w_g = np.zeros(y)for i in range(train_num):#计算b偏导和w偏导# Pn = weights.dot(train_data[i,:])+bias#Pn/=8Pn = weights.dot(train_data[i, :]) + bias sigmoid = 1/(1+np.exp(-Pn))#Pntemp = -(train_answer[i] - sigmoid)b_g += tempw_g +=train_data[i,:]*temp#+2*reg_rate*weights# 这里可以加入正则项,防止过拟合b_g/=train_numw_g/=train_num#adagradbg2_sum+=b_g**2wg2_sum+=w_g**2#更新权重和偏置bias -= learning_rate * b_g / bg2_sum ** 0.5 weights -= learning_rate * w_g / wg2_sum ** 0.5if times%10== 0:#print("测试点2")loss = 0acc = 0result = np.zeros(train_num)for j in range(train_num):#print("测试点3")y_pre = weights.dot(train_data[j,:])+bias#print("测试点4")sig = 1/(1+np.exp(-y_pre))if sig >= 0.5:result[j] = 1else:result[j] = 0if result[j] == train_answer[j]:acc+=1.0print("after {} epoches,the acc on train data:".format(times),acc/train_num)# 验证模型效果
acc = 0
result = np.zeros(test_num)
for j in range(test_num):y_pre = weights.dot(test_data[j, :]) + biassig = 1 / (1 + np.exp(-y_pre))if sig >= 0.5:result[j] = 1else:result[j] = 0if result[j] == test_answer[j]: acc += 1.0
print("after train,the acc on test data:",acc/test_num)
结果
- 利用自己做的数据得出的结果
- 基于秋沐霖博主的数据集,利用自己的代码进行训练得出的结果
- 同样都是数据预处理,咋就差距这么大。。。85%和92.5%的区别
参考资料
- 数据源
- 参考秋沐霖博主的文章
更多推荐
机器学习作业 李宏毅老师——HW2 赢家还是输家问题
发布评论