我有一个包含超过10列的CSV文件,其中一些列包含分类数据,有些分类列只有yes
和no
值,有些列包含颜色(如green
、blue
、red
等),还有一些列包含其他字符串值。
有没有办法使用所有列来构建回归模型呢?
我知道yes
和no
值可以表示为1和0,但我听说用数字来表示颜色名称或城市名称是不好的做法。有没有更好的、正确的做法?
以下是使用虚拟数据的简单代码示例:
import pandas as pdfrom sklearn.linear_model import LinearRegressiondf = pd.DataFrame({'par1':[1,3,5,7,9, 11,13], 'par2':[0.2, 0.4, 0.5, 0.7, 1, 1.2, 1.45], 'par3':['yes', 'no', 'no', 'yes', 'no', 'yes', 'no'], 'par4':['blue', 'red', 'red', 'blue', 'green', 'green', 'blue'], 'output':[103, 310, 522, 711, 921, 1241, 1451]})print(df)features = df.iloc[:,:-1]result = df.iloc[:,-1]reg = LinearRegression()model = reg.fit(features, result)prediction = model.predict([[2, 0.33, 'no', 'red']])reg_score = reg.score(features, result)print(prediction, reg_score)
在我使用的实际数据集中,这些字符串值对数据集非常重要,所以我不能简单地删除这些列
回答:
通常,你会对分类变量进行”独热编码“。这也被称为”添加虚拟变量“。
你还需要对数值变量进行”标准化“处理。
Scikit-learn让这些操作变得非常简单:
from sklearn.compose import ColumnTransformerfrom sklearn.preprocessing import OneHotEncodert = ColumnTransformer(transformers=[ ('onehot', OneHotEncoder(), ['par3', 'par4']), ('scale', StandardScaler(), ['par1', 'par2'])], remainder='passthrough') # 默认是删除未转换的列t.fit_transform(df)
最后,你需要以相同的方式转换你的输入数据,然后再通过模型进行处理。
综合起来,你可以得到以下代码:
import pandas as pdfrom sklearn.linear_model import LinearRegressionfrom sklearn.compose import ColumnTransformerfrom sklearn.preprocessing import OneHotEncoder, StandardScalerdf = pd.DataFrame({'par1':[1,3,5,7,9, 11,13], 'par2':[0.2, 0.4, 0.5, 0.7, 1, 1.2, 1.45], 'par3':['yes', 'no', 'no', 'yes', 'no', 'yes', 'no'], 'par4':['blue', 'red', 'red', 'blue', 'green', 'green', 'blue'], 'output':[103, 310, 522, 711, 921, 1241, 1451]})t = ColumnTransformer(transformers=[ ('onehot', OneHotEncoder(), ['par3', 'par4']), ('scale', StandardScaler(), ['par1', 'par2'])], remainder='passthrough')# 转换特征features = t.fit_transform(df.iloc[:,:-1])result = df.iloc[:,-1]# 训练线性回归模型reg = LinearRegression()model = reg.fit(features, result)# 生成预测example = t.transform(pd.DataFrame([{ 'par1': 2, 'par2': 0.33, 'par3': 'no', 'par4': 'red'}]))prediction = model.predict(example)reg_score = reg.score(features, result)print(prediction, reg_score)