估计收入

我们将建立一个分类器, 根据14个属性来估计一个人的收入. 可能的输出类别高于50K或低于或等于50K. 在这个数据集中存在轻微的扭曲, 每个数据点是数字和字符串的混合. 数值数据是有价值的, 我们不能在这些情况下使用标签编码器. 我们需要设计一个可以同时处理数值和非数值数据的系统. 我们将使用https://archive.ics.uci.edu/ml/datasets/Census+Income上的普查收入数据集.

怎么做...?

  • 我们将使用已经提供给您的income.py文件作为参考. 我们将使用朴素贝叶斯分类器来实现这一点. 让我们导入几个包:
import numpy as np
from sklearn import preprocessing
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import (
    train_test_split,
    cross_val_score
)
  • 载入数据
input_file = 'adult.data.txt'

# Reading the data
X = []
y = []
count_lessthan50k = 0
count_morethan50k = 0
num_images_threshold = 30000
with open(input_file, 'r') as f:
    for line in f.readlines():
        if '?' in line:
            continue

        data = line[:-1].split(', ')

        if data[-1] == '<=50K' and count_lessthan50k < num_images_threshold:
            X.append(data)
            count_lessthan50k = count_lessthan50k + 1

        elif data[-1] == '>50K' and count_morethan50k < num_images_threshold:
            X.append(data)
            count_morethan50k = count_morethan50k + 1

        if (
                count_lessthan50k >= num_images_threshold) and (
                count_morethan50k >= num_images_threshold):
            break

X = np.array(X)
  • 我们将使用来自数据集的20,000个数据点 - 每个类10,000个数据点, 以避免类不平衡. 在训练期间, 如果您使用属于单个类的许多数据点, 分类器往往偏向于此类. 因此, 最好对每个类使用相同数量的数据点.

  • 我们需要将字符串属性转换为数值数据, 同时省去原始的数值数据:

# Convert string data to numerical data
label_encoder = []
X_encoded = np.empty(X.shape)
for i, item in enumerate(X[0]):
    if item.isdigit():
        X_encoded[:, i] = X[:, i]
    else:
        label_encoder.append(preprocessing.LabelEncoder())
        X_encoded[:, i] = label_encoder[-1].fit_transform(X[:, i])

X = X_encoded[:, :-1].astype(int)
y = X_encoded[:, -1].astype(int)

isdigit()函数帮助我们识别数值数据. 我们将字符串数据转换为数字数据, 并将所有标签编码器存储在列表中, 以便我们在对未知数据进行分类时使用它.

  • 训练分类器:
classifier_gaussiannb = GaussianNB()
classifier_gaussiannb.fit(X, y)
  • 让我们将数据分成训练和测试以提取性能指标:
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.25, random_state=5)
classifier_gaussiannb = GaussianNB()
classifier_gaussiannb.fit(X_train, y_train)
y_test_pred = classifier_gaussiannb.predict(X_test)
  • 提取性能指标:
f1 = cross_val_score(
    classifier_gaussiannb,
    X, y,
    scoring='f1_weighted', cv=5
)
print ("F1 score: " + str(round(100 * f1.mean(), 2)) + "%")
  • 让我们看看如何分类单个数据点. 我们需要将数据点转换为我们的分类器可以理解的东西:
input_data = [
    '39', 'State-gov',
    '77516', 'Bachelors',
    '13', 'Never-married',
    'Adm-clerical', 'Not-in-family',
    'White', 'Male',
    '2174', '0',
    '40', 'United-States']
count = 0
input_data_encoded = [-1] * len(input_data)
for i, item in enumerate(input_data):
    if item.isdigit():
        input_data_encoded[i] = int(input_data[i])
    else:
        input_data_encoded[i] = int(
            label_encoder[count].transform(
                np.array([input_data[i]]).ravel()))
        count = count + 1

input_data_encoded = np.array(input_data_encoded).reshape(-1, 1)
  • 现在估计数据点
output_class = classifier_gaussiannb.predict(input_data_encoded)
print (label_encoder[-1].inverse_transform(output_class)[0])

就像以前一样, 我们使用predict方法来获取输出类和inverse_transform方法来将此标签转换回其原始形式, 以在终端上打印出来.

results matching ""

    No results matching ""