李宏毅机器学习HW2-winner or loser-利用逻辑回归进行收入分类

0.数据预处理

数据清洗

数据清洗是指发现并纠正数据文件中可识别的错误的最后一道程序,包括检查数据一致性,处理无效值和缺失值等。

将训练集(单独清洗),测试集、correct_ans(合并后清洗)

washdata函数要做的几件事:
			  0.将测试数据与correct_ans合并(行拼接,以下简称合并集),并将合并后的列名‘label’改为‘income’,将训练集的‘income’列赋予布尔值
              1.删除训练集与合并集中的‘?’行,并将它们的性别列赋予布尔值
              2.单独取出income列(将原有数据income列删除)
			  3.特征缩放

0.0将测试数据与correct_ans合并(行拼接,以下简称合并集),并将合并后的列名‘label’改为‘income’,将训练集的‘income’列赋予布尔值

import csv

import numpy as np
import pandas as pd


def washData(datapath1, datapath2='nothing'):
    

    df_x = pd.read_csv(datapath1)  # 读取训练集/测试集
    if datapath2 != 'nothing':
        # 输入的文件包括测试集和correct_ans时,进行合并之后再清洗:washData('test.csv', 'correct_answer.csv')
        df_correct_ans = pd.read_csv(datapath2)  # 读取correct_ans.csv

        df_x = pd.concat([df_x, df_correct_ans['label']],
                         axis=1)  # 将训练集与correct_ans进行行连接,注意correct_ans的index不能用数字(df_x为字典形式)
        # 测试集中为14列(没有income列)

        df_x.rename(columns={'label': 'income'},
                    inplace=True)  # 由于训练集中标签名为‘income’,correct_ans中标签为'label',因此需要转换:label→income
    # df_x: age,workclass,fnlwgt  ... hours_per_week,native_country,income    [16281 rows x 15 columns](14+1)

    else:
        # 输入的文件只有训练集时,进行单独清洗:washData(‘train.csv')
        df_x['income'] = (df_x['income'] == ' >50K')  # 将训练集中income列赋予布尔值(>50K赋予1,否则为0)注意‘ >50k’中有空格
    # 将训练集/测试集与corret——ans合并后的数据进行清洗

注意:‘ >50k’,’ male’中有空格,否则结果有误

0.1.删除训练集与合并集中的‘?’行,并将它们的性别列赋予布尔值

	df_x = df_x.replace('?', np.nan)  # 将‘?’换成nan

    df_x = df_x.dropna()  # 删除带有空值的行,只要有一个空值,就删除整行
    # 这里要将测试集与correct_ans合并后的数据进行数据清洗,否则它们的数据将不再对应

    df_x['sex'] = (df_x['sex'] == 'Male')  # 将df_x中的性别赋予布尔值

    #     da_x是一个dataframe,有行标签列标签,而series只有行标签

0.2.单独取出income项并将原数据中的income删除

    data_y = df_x[['income']].astype(
        np.int64)  # 这里df_[[]]双重括号保证data_y仍是dataframe类型,单括号则转为series类型,int64是numpy特有的数据类型,不同于python的int
    del df_x['income']

    #     将数据分为数字和非数字
    object_columns = [col for col in df_x.columns if
                      df_x[col].dtypes == 'object']  # 列表解析式。提取出非数字的列名称:判断每一列的数据中是否全为object类型,是则提取列名
    no_object_columns = [col for col in df_x.columns if df_x[col].dtypes == 'int64']  # 提取数字类型列名(有一个不为数字则不提取)
    object_data = df_x[object_columns]  # object_data包含df_x的所有object_columns列
    no_object_data = df_x[no_object_columns]

    object_data = pd.get_dummies(object_data)  # 将非文字转换为虚拟变量

    #     合并数据集
    data_x = pd.concat([no_object_data, object_data], axis=1)

    data_x = data_x.astype(np.int64)

补充:one-hot encoding(独热编码)与pd.get_dummies(data,prefix)

独热码,在英文文献中称做 one-hot code, 直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制。
pd.get_dummies(data,prefix)是pandas实现独热编码的函数。
其中data是要转换的文件
prefix是表头前缀
具体参考官网说明

官网说明

如一个dataframe:

A B C
a b 1
b a 2
a c 3

特征A有2种不同的值:[‘a’,‘b’]
特征B有3种不同的值[‘b’,‘a’,‘c’]
特征C有3种不同的值[1,2,3]#此处为数字
独热编码后
A中的
‘a’:[1 0]
‘b’:[0 1]
B中的
‘b’:[1 0 0]
‘a’:[0 1 0]
‘c’:[0 0 1]
由于C已经为数字,所以不再转化,直接输出
即利用线性无关的单位向量来表示不同的值(类似线性方程组中的基础解系

由此原dataframe可转化为

10 100 1
01 010 2
10 001 3

代码实现

df=pd.DataFrame({'a':['5',5,2],'b':[7,4,1],'c':['a','v','s']})
print(df)
   a  b  c
0  5  7  a
1  5  4  v
2  2  1  s
df_1=pd.get_dummies(df)
print(df_1)
   b  a_2  a_5  a_5  c_a  c_s  c_v
0  7    0    0    1    1    0    0
1  4    0    1    0    0    0    1
2  1    1    0    0    0    1    0

注意:除非某种特征值全为数字(如b列),不会进行转化,只要有一个值不是数字就要进行转化(a列中的 ‘5’)

查看训练集:

print(data_x)
        age  fnlwgt       ...            native_country_ Vietnam   native_country_ Yugoslavia
0       39   77516        ...                        0                           0
1       50   83311        ...                        0                           0
2       38  215646        ...                        0                           0
...     ...   ...         ...                      ...                         ...
32560   52   287927       ...                        0                           0
[32561 rows x 106 columns]

查看train.csv

text = open('b.csv', 'w+')
    my_writer = csv.writer(text, delimiter=',', lineterminator='\n')
    for i in data_x.T:  # i为data_x的每一个列名,键的类型为string
        my_writer.writerow(data_x.T[i])#这里为转置
    text.close()

查看合并集

           age  fnlwgt  ...  native_country_ Vietnam  native_country_ Yugoslavia
# # 0       25  226802  ...                        0                           0
# # 1       38   89814  ...                        0                           0
# # ...    ...     ...  ...                      ...                         ...
# # [16281 rows x 105 columns]

train.csv

0.3特征缩放

可以看到不同特征数据的取值范围差异很大,这样会导致梯度下降很慢(如对二维特征向量来说loss(w1,w2)的图像扁长,最优情况下图像应为近似圆形),因此要将特征进行归一化处理——特征缩放(feature scaling)。常用方法有:

1.均值归一化
2.方差归一化
3.标准归一化

其中标准归一化即正态分布标准化

x=(x-μ)/σ 

是较为常用的特征缩放方法

# feature scaling
data_x=(data_x-data_x.mean())/data_x.std()

小问题

训练集:[32561 rows x 106 columns]
合并集:[16281 rows x 105 columns]

打印后发现训练集与合并集列数并不相同,如下图:
native_country_holand-netherland多出来了,对其进行删除
列表对比

发布了24 篇原创文章 · 获赞 8 · 访问量 2177

猜你喜欢

转载自blog.csdn.net/weixin_44839513/article/details/102674282
今日推荐