Python 的 "StandardScaler" 和 "LabelEncoder",以及 "fit" 和 "fit_transform" 不适用于包含浮点数和字符串的 CSV
Python's "StandardScaler" and "LabelEncoder", and "fit" and "fit_transform" do not work with a CSV which contains both float and string
我在 Google Colaboratory 学习 MPL 回归器和 运行 源代码:
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
data = np.array(table)
scaler.fit(data)
y_index = data.shape[1]-1
sd_x = (scaler.var_[:y_index])**0.5
sd_y = (scaler.var_[y_index])**0.5
mean_x = scaler.mean_[:y_index]
mean_y = scaler.mean_[y_index]
x = (data[:, :y_index]).astype(np.float32)
y = (data[:, y_index]).astype(np.float32)
train_x, test_x, train_y, test_y = train_test_split(x, y, test_size=0.25)
print('Separate training and testing sets!')
它给出了错误ValueError: could not convert string to float: 'Photo Editor & Candy Camera & Grid & ScrapBook'
。
所以我检查了问题. I also tried 。
我从fit(data)
改成fit_transform(data)
,还是一样的错误。然后我从StandardScaler
变成了LabelEncoder
,从scaler = StandardScaler()
变成了scaler = LabelEncoder()
。但是出现了不同的错误: ValueError: bad input shape (10841, 13)
on the line scaler.fit_transform(data)
.
您可以在此处查看 Kaggle's CSV 中的 CSV。 CSV 包含不带引号的字符串和数字(包含双引号的价格除外)。
StandardScaler 是来自 sklearn 的预处理 class,它采用数字条目并将它们转换为具有 0 均值和单位方差的可能高斯分布。它不处理文本数据。这解释了第一个错误。
LabelEncoder 是 sklearn 的另一个预处理 class,它获取数据并将它们映射到数字编码表示。
例如:["apple","banana","apple","banana"] 到 [0,1,0,1]
你的数据集有缺失值,你应该先处理它们。通过 imputing、droping 或一些类似的方法。
那么您应该转换每列的类型(除评级外的所有类型都被视为对象或字符串)以正确处理每种数据类型。
table = pd.read_csv('googleplaystore.csv')
# check dataset info
table.info()
# check missing values
table.isna().sum()
来自 sklearn 的 LabelEncoder
文档:此转换器应该用于编码目标值,即 y,而不是输入 X。
特别是,它不打算在完整数据集上拟合 LabelEncoder
。
如果您只想用唯一和数字 ID 替换分类(即字符串值)列的值,一种方法是在您要创建的每一列上应用标签编码器(在拆分数据之前)想单独编码。当您的示例代码导入 pandas
时,我假设您的数据已加载到 pandas.DataFrame
中,例如
df = pd.read_csv('/path/to/googleplaystore.csv')
从那里,您可以在每一列上应用编码器:
df['App'] = LabelEncoder().fit_transform(df['App'].values)
您可能还想看看如何在 pandas 内处理 categorical data。
然而,即使对数据集中的每个非数字列都执行了此操作,在对编码数据拟合模型之前还有很长的路要走(您可能希望之后将 one-hot encoding 应用于这些列,但这在很大程度上取决于您要使用的模型)。
老实说,我认为这更多是概念问题而不是技术问题。正如其他用户告诉您的那样,StandarScaler
必须用于数字列,但您的大多数数据框列都是 object
类型。可能你应该在上面使用 OneHotEncoder
,sklearn 上的所有转换器都有类似的行为。
from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder(handle_unknown='ignore')
ohe.fit_transform(X) # your data without target column
# ...blabla...
最后,我推荐你阅读 sklearn 中关于 Pipelines 的内容,我认为它们比一堆乱七八糟的代码更优雅。您可以将预处理和模型步骤放在同一管道上,例如 here.
我在 Google Colaboratory 学习 MPL 回归器和 运行 源代码:
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
data = np.array(table)
scaler.fit(data)
y_index = data.shape[1]-1
sd_x = (scaler.var_[:y_index])**0.5
sd_y = (scaler.var_[y_index])**0.5
mean_x = scaler.mean_[:y_index]
mean_y = scaler.mean_[y_index]
x = (data[:, :y_index]).astype(np.float32)
y = (data[:, y_index]).astype(np.float32)
train_x, test_x, train_y, test_y = train_test_split(x, y, test_size=0.25)
print('Separate training and testing sets!')
它给出了错误ValueError: could not convert string to float: 'Photo Editor & Candy Camera & Grid & ScrapBook'
。
所以我检查了问题
我从fit(data)
改成fit_transform(data)
,还是一样的错误。然后我从StandardScaler
变成了LabelEncoder
,从scaler = StandardScaler()
变成了scaler = LabelEncoder()
。但是出现了不同的错误: ValueError: bad input shape (10841, 13)
on the line scaler.fit_transform(data)
.
您可以在此处查看 Kaggle's CSV 中的 CSV。 CSV 包含不带引号的字符串和数字(包含双引号的价格除外)。
StandardScaler 是来自 sklearn 的预处理 class,它采用数字条目并将它们转换为具有 0 均值和单位方差的可能高斯分布。它不处理文本数据。这解释了第一个错误。
LabelEncoder 是 sklearn 的另一个预处理 class,它获取数据并将它们映射到数字编码表示。 例如:["apple","banana","apple","banana"] 到 [0,1,0,1]
你的数据集有缺失值,你应该先处理它们。通过 imputing、droping 或一些类似的方法。
那么您应该转换每列的类型(除评级外的所有类型都被视为对象或字符串)以正确处理每种数据类型。
table = pd.read_csv('googleplaystore.csv')
# check dataset info
table.info()
# check missing values
table.isna().sum()
来自 sklearn 的 LabelEncoder
文档:此转换器应该用于编码目标值,即 y,而不是输入 X。
特别是,它不打算在完整数据集上拟合 LabelEncoder
。
如果您只想用唯一和数字 ID 替换分类(即字符串值)列的值,一种方法是在您要创建的每一列上应用标签编码器(在拆分数据之前)想单独编码。当您的示例代码导入 pandas
时,我假设您的数据已加载到 pandas.DataFrame
中,例如
df = pd.read_csv('/path/to/googleplaystore.csv')
从那里,您可以在每一列上应用编码器:
df['App'] = LabelEncoder().fit_transform(df['App'].values)
您可能还想看看如何在 pandas 内处理 categorical data。
然而,即使对数据集中的每个非数字列都执行了此操作,在对编码数据拟合模型之前还有很长的路要走(您可能希望之后将 one-hot encoding 应用于这些列,但这在很大程度上取决于您要使用的模型)。
老实说,我认为这更多是概念问题而不是技术问题。正如其他用户告诉您的那样,StandarScaler
必须用于数字列,但您的大多数数据框列都是 object
类型。可能你应该在上面使用 OneHotEncoder
,sklearn 上的所有转换器都有类似的行为。
from sklearn.preprocessing import OneHotEncoder
ohe = OneHotEncoder(handle_unknown='ignore')
ohe.fit_transform(X) # your data without target column
# ...blabla...
最后,我推荐你阅读 sklearn 中关于 Pipelines 的内容,我认为它们比一堆乱七八糟的代码更优雅。您可以将预处理和模型步骤放在同一管道上,例如 here.