'''
KNN是一个典型的分类模型,就时预测类别,例如苹果,香蕉等。预测的结果是
训练集上已经包含的类别,并不会预测出新的类别
二手车价格预测是预测车的价格,是数值。理应按照回归算法来算
怎么用knn来实现回归问题呢? 找到最近的K样本之后,我们直接取了平均作为预测值,很直观
这里给出了对于数据的简单描述。
Ask Price 字段是我们要预测的值,即二手车的估价。
Brand 为车辆的牌子。
Type 指的是它的发动机类型。
Color 字段为车辆外观颜色。
Construction Year 字段为车子生产年份。
Odometer 为仪表盘已经行驶的里程数。
DaysUntilMOT 指的是自从上一次的保养过了多久
HP 字段代表的是马力。 "
'''
import sys ,os
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib
import matplotlib.pyplot as plt
# 读取数据
path=os.getcwd()+"\source\double_car.csv"
df=pd.read_csv(path,engine='python',encoding='gbk') # 务必加上 engine='python' 不然会报错
'''
Brand Type Color Construction Year Odometer Ask Price Days Until MOT HP
0 Peugeot 106 1.0 blue 2002 166879 999 138 60
1 Peugeot 106 1.0 blue 1998 234484 999 346 60
'''
#特征处理
#颜色独热编码
df_color=df['Color'].str.get_dummies().add_prefix('color:')
'''
color:black color:blue color:green color:grey color:red color:white
0 0 1 0 0 0 0
1 0 1 0 0 0 0
'''
#类型独热编码
df_type=df['Type'].apply(str).str.get_dummies().add_prefix('Type:')
#添加度热编码列
df=pd.concat([df,df_color,df_type],axis=1)
#去掉原列
df=df.drop(['Brand','Color','Type'],axis=1)
'''
Construction Year Odometer Ask Price Days Until MOT HP color:black color:blue color:green color:grey color:red color:white Type:1.0 Type:1.1 Type:1.4
'''
# s数据转换
'''
看一下数据之间的相关性 使用corr() 函数 来计算特征之间的相关性 之后通过sns进行可视化相关性
'''
matrix=df.corr()
#f,ax=plt.subplots(figsize=(8,6))
#sns.heatmap(matrix,square=True)
#plt.title('变量')
#plt.show()
## KNeighborsClassifier KNN分类
## KNeighborsRegressor KNn回归
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.preprocessing import StandardScaler
import numpy as np
# Brand Type Color Construction Year Odometer Ask Price Days Until MOT HP
X=df[['Construction Year','Days Until MOT','Odometer']]
y=df['Ask Price'].values.reshape(-1,1)
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3,random_state=41)
X_normanlizer=StandardScaler()
X_train=X_normanlizer.fit_transform(X_train)
X_test=X_normanlizer.transform(X_test)
y_normanlizer=StandardScaler()
y_train =y_normanlizer.fit_transform(y_train) #特征的归一化标准是来自训练数据,然后应用在测试数据,
y_test=y_normanlizer.transform(y_test) #因为在实际的情况下,测试数据是看不到的,是算不出来均值和方差的
knn=KNeighborsRegressor(n_neighbors=2)
knn.fit(X_train,y_train.ravel()) #.ravel() 多维的数组降为1维
y_pred=knn.predict(X_test)
# y_pred=y_pred.astype('float')
y_pred_inv=y_normanlizer.inverse_transform(y_pred)
y_test_inv=y_normanlizer.inverse_transform(y_test)
#from sklearn.metrics import accuracy_score
# acc=accuracy_score(y_test_inv,y_pred_inv) print('准确率:',acc) # 0.0 回归的问题算准确率意义不大
plt.scatter(y_pred_inv,y_test_inv) # 点
plt.xlabel('pred')
plt.ylabel('test')
diag=np.linspace(500,1500,100) # 准备画 对角线
plt.plot(diag,diag,'-r')
plt.show()
print(y_pred_inv) # 预测值
print(knn) #knn的相关属性