问题
修改前的代码
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
music_data=pd.read_csv("music.csv")
X= music_data.drop(columns=['genre'])
y=music_data['genre']
model=DecisionTreeClassifier()
model.fit(X,y)
predictions=model.predict([ [21,1],[22,0] ])
predictions
修改后的代码
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
music_data=pd.read_csv("music.csv")
X= music_data.drop(columns=['genre'])
y=music_data['genre']
model=DecisionTreeClassifier()
model.fit(X,y)
pred_data=pd.DataFrame([ [21,1],[22,0]],columns=X.columns )
#predictions=model.predict([ [21,1],[22,0] ])
predictions=model.predict(pred_data)
predictions
在提供的代码中,出现了上面提到的警告,原因是 model.predict()
方法传入了一个没有特征名称的 列表 [ [21, 1], [22, 0] ]
,但模型在训练时是使用 Pandas DataFrame(包含特征名称的表格数据)进行的。
详细原因:
- 在模型训练时 (
model.fit(X, y)
),你使用的是Pandas DataFrame
对象X
,它包含了列名称(即特征名称)。 - 但是,在预测时,你传入了一个二维的 列表
[[21, 1], [22, 0]]
,它没有任何特征名称(只是数据值)。这导致scikit-learn
发出了警告,因为它期望预测数据也包含与训练数据相同的特征名称。
解决方案:
要解决这个问题,你需要在预测时使用与训练时相同的数据结构,特别是 Pandas DataFrame,并确保它有与训练数据一致的特征名称。下面是修改后的代码:
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
# 加载数据
music_data = pd.read_csv("music.csv")
X = music_data.drop(columns=['genre'])
y = music_data['genre']
# 训练模型
model = DecisionTreeClassifier()
model.fit(X, y)
# 创建预测数据,并确保它是一个包含特征名称的 DataFrame
pred_data = pd.DataFrame([[21, 1], [22, 0]], columns=X.columns)
# 进行预测
predictions = model.predict(pred_data)
print(predictions)
解释:
-
pred_data = pd.DataFrame([[21, 1], [22, 0]], columns=X.columns)
:- 这里将预测数据封装成一个
Pandas DataFrame
,并确保它的列名称与训练数据X
中的列名称一致(通过X.columns
获得)。
- 这里将预测数据封装成一个
-
这样,
model.predict(pred_data)
就不会再出现警告,因为预测数据包含了与训练数据相同的特征名称。
总结:
在训练模型时,如果使用的是带有特征名称的 Pandas DataFrame
,在预测时同样需要传入一个带有相同特征名称的数据框。否则,模型会发出警告,提醒传入的数据格式与训练时不一致。