机器学习1:scikit-learn简介(5)—— 文本数据处理

scikit-learn的介绍

一、机器学习的一般步骤

链接:机器学习的一般步骤

二、预处理数据

链接:预处理数据

三、交叉验证

链接:交叉验证

四、超参数优化

链接:超参数优化

五、文本数据处理

异构数据:当使用文本数据时

到目前为止,我们使用 scikit-learn 来训练使用数值数据的模型。
X是仅包含浮点值的NumPy数组。但是,数据集可能包含文本类型等。

import os
import pandas as pd
data = pd.read_csv(os.path.join('data', 'titanic_openml.csv'), na_values='?')
data.head()

输出:
在这里插入图片描述

泰坦尼克号数据集包含分类,文本和数字特征。 我们将使用此数据集来预测乘客是否在泰坦尼克号中幸存下来。
让我们将数据拆分为训练和测试集,并将幸存列用作目标。

y = data['survived']
X = data.drop(columns='survived')
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
  • 首先,可以尝试使用LogisticRegression分类器,看看它的表现有多好。
from sklearn.linear_model import LogisticRegression
clf = LogisticRegression()
clf.fit(X_train, y_train)   #这里肯定会报错。
  • 因为,大多数分类器都设计用于处理数值数据。 因此,我们需要将文本数据转换为数字数据。
  • 最简单的方法是使用独热编码OneHotEncoder对每个文本特征进行编码。 让我们以 sex 与 embarked 列为例。
  • 请注意,我们还会遇到一些缺失的数据。 我们将使用SimpleImputer用常量值替换缺失值。
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder
from sklearn.pipeline import make_pipeline
ohe = make_pipeline(SimpleImputer(strategy='constant'), OneHotEncoder())
X_encoded = ohe.fit_transform(X_train[['sex', 'embarked']])
X_encoded.toarray()

输出:

array([[0., 1., 0., 0., 1., 0.],
       [0., 1., 1., 0., 0., 0.],
       [0., 1., 0., 0., 1., 0.],
       ...,
       [0., 1., 0., 0., 1., 0.],
       [1., 0., 0., 0., 1., 0.],
       [1., 0., 0., 0., 1., 0.]])

这样,可以对文本特征进行编码。 但是,我们也希望标准化数字特征。
因此,我们需要将原始数据分成2个子组并应用不同的预处理:(i)分类数据的独热编;(ii)数值数据的标准缩放(归一化)。
我们还需要处理两种情况下的缺失值: 对于分类列,我们将字符串'missing_values'替换为缺失值,该字符串将自行解释为类别。
对于数值数据,我们将用感兴趣的特征的平均值替换缺失的数据。

col_cat = ['sex', 'embarked']   # 文本型数据
col_num = ['age', 'sibsp', 'parch', 'fare']  #数值型数据

X_train_cat = X_train[col_cat]
X_train_num = X_train[col_num]
X_test_cat = X_test[col_cat]
X_test_num = X_test[col_num]
from sklearn.preprocessing import StandardScaler

scaler_cat = make_pipeline(SimpleImputer(strategy='constant'), OneHotEncoder())
X_train_cat_enc = scaler_cat.fit_transform(X_train_cat)
X_test_cat_enc = scaler_cat.transform(X_test_cat)

scaler_num = make_pipeline(SimpleImputer(strategy='mean'), StandardScaler())
X_train_num_scaled = scaler_num.fit_transform(X_train_num)
X_test_num_scaled = scaler_num.transform(X_test_num)
  • 在训练集上将文本数据和数字数据进行合并, 在测试集上也将文本数据和数字数据进行合并。
import numpy as np
from scipy import sparse

X_train_scaled = sparse.hstack((X_train_cat_enc,
                                sparse.csr_matrix(X_train_num_scaled))) # 文本数据和数字数据进行合并
X_test_scaled = sparse.hstack((X_test_cat_enc,
                               sparse.csr_matrix(X_test_num_scaled)))   # 文本数据和数字数据进行合并
  • 合并完成后,我们现在可以组合所有数值的信息。最后,我们使用LogisticRegression分类器作为模型。
clf = LogisticRegression(solver='lbfgs')
clf.fit(X_train_scaled, y_train)
accuracy = clf.score(X_test_scaled, y_test)
print('Accuracy score of the {} is {:.2f}'.format(clf.__class__.__name__, accuracy))

输出:

Accuracy score of the LogisticRegression is 0.79
  • 上面案例是首先转换数据,然后拟合/评分分类器。但是,我们还希望对矩阵的不同列进行不同的处理。应使用make_column_transformer函数。它用于在不同的列上自动应用不同的管道。
from sklearn.impute import SimpleImputer
from sklearn.compose import make_column_transformer
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_validate
pipe_cat = make_pipeline(SimpleImputer(strategy='constant'), OneHotEncoder(handle_unknown='ignore'))
pipe_num = make_pipeline(StandardScaler(), SimpleImputer())
preprocessor = make_column_transformer((col_cat, pipe_cat), (col_num, pipe_num))

pipe = make_pipeline(preprocessor, LogisticRegression(solver='lbfgs'))

param_grid = {'columntransformer__pipeline-2__simpleimputer__strategy': ['mean', 'median'],
              'logisticregression__C': [0.1, 1.0, 10]}
grid = GridSearchCV(pipe, param_grid=param_grid, cv=3, n_jobs=-1)
scores = pd.DataFrame(cross_validate(grid, X, y, scoring='balanced_accuracy', cv=5, n_jobs=-1, return_train_score=True))
scores[['train_score', 'test_score']].boxplot()

输出:

<matplotlib.axes._subplots.AxesSubplot at 0x27e17d62470>

在这里插入图片描述

练习

加载位于./data/adult_openml.csv中的成人数据集。
制作自己的ColumnTransformer预处理器,并用分类器管道化它。对其进行微调并在交叉验证中检查预测准确性。

  • Read the adult dataset located in ./data/adult_openml.csv using pd.read_csv.
  • 使用pd.read_csv读取位于./data/adult_openml.csv中的成人数据集。
import os
import pandas as pd

data = pd.read_csv(os.path.join('data', 'adult_openml.csv'))
data.shape

输出:

(48842, 15)
data.head()

在这里插入图片描述

  • 将数据集拆分为数据和目标。 目标对应于类列。
  • 对于数据,删除列fnlwgtcapitalgaincapitalloss
y = data['class']
X = data.drop(columns=['class', 'fnlwgt', 'capitalgain', 'capitalloss'])
X.head()

在这里插入图片描述

y.head()

在这里插入图片描述

  • 目标未编码。
  • 使用 sklearn.preprocessing.LabelEncoder 对类进行编码。
from sklearn.preprocessing import LabelEncoder

encoder = LabelEncoder()
y = encoder.fit_transform(y)
y

输出:

array([0, 0, 0, ..., 0, 0, 1])
  • 创建一个包含分类列名称的列表。 同样,对数值数据也一样。
col_cat = ['workclass', 'education', 'marital-status', 'occupation', 'relationship', 'race', 'native-country', 'sex']
col_num = ['age', 'hoursperweek']
  • 创建一个管道以对分类数据进行独热编码。 使用 KBinsDiscretizer 对数值数据进行处理。 从sklearn.preprocessing 导入它。
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import KBinsDiscretizer

pipe_cat = OneHotEncoder(handle_unknown='ignore')
pipe_num = KBinsDiscretizer()
  • 使用 make_column_transformer 创建预处理器,将创建好的管道应用于文本列和数字列。
from sklearn.compose import make_column_transformer
preprocessor = make_column_transformer((col_cat, pipe_cat, ), (col_num, pipe_num))
  • 使用LogisticRegression 分类器对预处理器进行管道传输。 随后定义网格搜索以找到最佳参数C.使用cross_validate 在交叉验证方案中训练和测试此工作流程。
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import cross_validate

pipe = make_pipeline(preprocessor, LogisticRegression(solver='lbfgs', max_iter=1000))
param_grid = {'logisticregression__C': [0.1, 1.0, 10]}
grid = GridSearchCV(pipe, param_grid=param_grid, cv=5, n_jobs=-1)
scores = pd.DataFrame(cross_validate(grid, X, y, scoring='balanced_accuracy', cv=3, n_jobs=-1, return_train_score=True))
scores[['train_score', 'test_score']].boxplot(whis=10)

输出:

<matplotlib.axes._subplots.AxesSubplot at 0x1efba9f7d30>

在这里插入图片描述
(完。)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shi_jiaye

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值