【问题标题】:Use get_dummies to turn categorical values to numeric?使用 get_dummies 将分类值转换为数字?
【发布时间】:2020-02-24 19:59:58
【问题描述】:

我正在制作一个简单的可重现示例来了解训练和测试的工作原理:

示例

我想根据Location 的来源预测Ages

import pandas as pd

# create a simple dataset of people
data = {'Name': ["John", "Anna", "Peter", "Linda","John","John","John"],
        'Location' : ["Paris","Paris","Paris","Paris", "New York", "Berlin", "London"],
        'Age' : [24, 23, 21, 24,36,34,36]
       }

df = pd.DataFrame(data)

在下面这部分,城市名称有问题,因此我决定使用虚拟变量,但get_dummies 的行不正确。我认为它需要将NameLocation 字符串都转换为虚拟变量,这就是我尝试过的,但正确的方法是什么?

from sklearn.model_selection import train_test_split
X = df.drop('Age', axis=1)
y = df['Age']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20)

from sklearn.svm import SVC
svclassifier = SVC(kernel='linear')
X_train = pd.get_dummies(df.columns)  #<---- here is the issue probably
svclassifier.fit(X_train, y_train)
y_pred = svclassifier.predict(X_test)

【问题讨论】:

    标签: python pandas machine-learning scikit-learn svm


    【解决方案1】:

    svclassifier.fit(X_train, y_train) 将数组作为输入,但您提供的是 pandas DataFrame。尝试使用sklearn.preprocessing.LabelEncoder 而不是pd.get_dummies

    编辑:LabelEncoderOneHotEncoder 的示例:

    # create a simple dataset of people
    data = {'Name': ["John", "Anna", "Peter", "Linda","John","John","John"],
            'Location' : ["Paris","Paris","Paris","Paris", "New York", "Berlin", "London"],
            'Age' : [24, 23, 21, 24,36,34,36]
           }
    
    from sklearn.model_selection import train_test_split
    from sklearn.preprocessing import LabelEncoder, OneHotEncoder
    from sklearn.svm import SVC
    import numpy as np
    
    X = data['Location']
    y = data['Age']
    
    # Label
    print("Label Encoded")
    le = LabelEncoder()
    le.fit(X)
    X_enc = le.transform(X)
    
    X_train, X_test, y_train, y_test = train_test_split(X_enc, y, test_size = 0.20, random_state=42)
    
    svclassifier = SVC(kernel='linear')
    svclassifier.fit(np.reshape(X_train,(X_train.shape[0],1)), y_train)
    y_pred = svclassifier.predict(np.reshape(X_test, (X_test.shape[0],1)))
    print(f"y_pred: {y_pred}, y_test: {y_test}")
    
    # OneHot
    print("OneHot Encoded")
    ohe = OneHotEncoder()
    ohe.fit(np.reshape(X,(len(X),1)))
    X_oh = ohe.transform(np.reshape(X,(len(X),1)))
    
    X_train, X_test, y_train, y_test = train_test_split(X_oh, y, test_size = 0.20, random_state=42)
    
    svclassifier = SVC(kernel='linear')
    svclassifier.fit(X_train, y_train)
    y_pred = svclassifier.predict(X_test)
    print(f"y_pred: {y_pred}, y_test: {y_test}")
    

    给予:

    Label Encoded
    y_pred: [24 24], y_test: [24, 23]
    OneHot Encoded
    y_pred: [24 24], y_test: [24, 23]
    

    还不错。

    【讨论】:

    • 由于这是一个可重复的示例,请输入您建议的方法以了解您的意思以及为什么会发生这种情况。谢谢
    • 标签编码是不是因为数字的顺序而有偏差,一种热编码更可取?
    • 可能是这样。我在最初的最小示例中添加了一个 onehot 示例,但结果是相同的。
    【解决方案2】:

    您没有定义您的功能(x)和目标(y)。您的X是您的模型学会预测目标y的位置。由于您的功能是 name 位置,这是分类的,那么您需要使用像get_dummies等自动编码器。

    from sklearn.model_selection import train_test_split
    #features
    X = pd.get_dummies(df[['Name','Location']])
    
    #Target
    y = df['Age']
    
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20)
    
    from sklearn.svm import SVC
    
    svclassifier = SVC(kernel='linear')
    svclassifier.fit(X_train, y_train)
    y_pred = svclassifier.predict(X_test)
    

    【讨论】:

    • 您可以显示评估结果的合适方法,因为当我键入y_pred时,我不知道我看到了什么 span>
    • 结果模型Y预测是print(y_pred) # [24 36] 987654322 @哪个年龄24和26,预测的x功能是print(X_test.index) #[ 1 4],这意味着来自巴黎的John是24岁,来自NY的John是36。 span>
    • 是的,我的意思是它说[36,24]但是每个行都对应?展示例如John Paris 24实际上的行是有帮助的,这是预测为“预测值”或类似的行。 span>
    • 请在答案中更清楚的结果,让我不知道结果对应什么。 span>
    • 如果生成的预测是[36,24],如果您的x_test.index是[1,4]那么模型预测错误,因为x_test.index为您提供了预测的功能顺序。 span>
    猜你喜欢
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多