对于CSV文件中包含文本和整数值的汽车数据,培训价格预测机器学习模型的最佳方法是什么?

2024-04-28 22:01:03 发布

您现在位置:Python中文网/ 问答频道 /正文

谢谢你来到这篇文章,虽然有点长,但我希望它值得一读。我一直在尝试训练一个机器学习模型,根据CSV文件中的条目预测汽车的价格,但可能没有成功。我在一个CSV文件中有大约200000行数据,每行都有不同的条目。我想做的是一次给tensorflow/keras一批数据,比如说50到500行(如果它能产生更好的结果,可能更多或更少),并要求它预测每行的相应价格(其中每行代表一辆独特的汽车)。然后,我想使模型能够看到批处理中每一行的正确价格,然后尝试预测另外50到500行(可能更多或更少)数据的价格。我希望猜测价格,然后被告知正确价格的过程在整个培训数据中继续进行。我认为这个培训过程会非常缓慢,对于最初的几千行(甚至一万行以上)数据,模型在预测正确的价格时会非常不准确。我希望在模型看到所有的训练数据之后,我能够用测试数据验证其准确性,并且我希望模型能够足够准确地满足我的需要。我希望我已经清楚地解释了我想要实现的目标

为了给这篇文章提供更多信息,我的CSV文件如下:

(下面显示的车辆只是CSV中的一些条目)

注意阿尔法·罗密欧·朱利亚的“注意力捕捉器”一栏中没有任何信息,如“168英里”后的双逗号所示。这对于某些条目中没有任何数据是很常见的,并且不限于此列

CAR NAME, YEAR, MILEAGE, ATTENTION GRABBER, KEY SPECS, DESCRIPTION, URL, PRICE
Abarth 1.4 595 3d 144 BHP, 2018, 8000 miles, ASCARI 180 LIMITED EDITION, |2018 (18 reg)|Hatchback|8000 miles|1.4L|143bhp|Manual|Petrol|1 owner|Full service history|, VELOCES ARE VERY PLEASED TO PRESENT FOR SALE THIS AWESOME 595 ASCARI ABARTH …, https://www.autotrader.co.uk/classified/advert/201910173426267?model=595&sort=distance&make=Abarth&radius=1501&onesearchad=Used&onesearchad=Nearly%20New&onesearchad=New&advertising-location=at_cars&postcode=KY103AA&page=20, 11990
Alfa Romeo 159 Sportwagon 1.9 JTDM 16v TI Estate 5dr Diesel …, 2009, 100000 miles, RARE AUTO • TAN LEATHER • MINT, |2009 (09 reg)|Estate|100000 miles|1.9L|150bhp|Automatic|Diesel|, JUST ARRIVED IN STOCK A VERY RARE & SOUGHT AFTER ALFA ROMEO 159 TI 1.9 DIESEL …, https://www.autotrader.co.uk/classified/advert/201912095183372?model=159%20Sportwagon&sort=distance&make=Alfa%20Romeo&radius=1501&onesearchad=Used&onesearchad=Nearly%20New&onesearchad=New&advertising-location=at_cars&postcode=KY103AA&page=2, 5975
Alfa Romeo Giulia 2.0 TB 280 Veloce 4dr Auto, 2019, 168 miles,, |2019 (69 reg)|Saloon|168 miles|2.0L|276bhp|Automatic|Petrol|1 owner|, Alfa Romeo Giulia 2.0 TB 280 Veloce 4dr Auto White 1 owner £31000 Apple car …, https://www.autotrader.co.uk/classified/advert/202002087091280?model=Giulia&sort=distance&make=Alfa%20Romeo&radius=1501&onesearchad=Used&onesearchad=Nearly%20New&onesearchad=New&advertising-location=at_cars&postcode=KY103AA&page=12, 31000
Alfa Romeo Giulietta 1.4 MULTIAIR LUSSO TB 5d 170 BHP DNA …, 2012, 53610 miles, GREAT HISTORY, |2012 (62 reg)|Hatchback|53610 miles|1.4L|170bhp|Manual|Petrol|, BUY NOW PAY APRIL! FINANCE AVAILABLE  This vehicle is presented in excellent …, https://www.autotrader.co.uk/classified/advert/202001276642755?model=Giulietta&sort=distance&make=Alfa%20Romeo&radius=1501&onesearchad=Used&onesearchad=Nearly%20New&onesearchad=New&advertising-location=at_cars&postcode=KY103AA&page=25, 5250

还要注意,列键规格中也包含列年和里程的信息,这可能使这些列完全不相关,因为数据已经存在,没有这些列。但是,我决定将它们包括在内,因为我不确定机器学习到底是如何工作的,也不确定模型在列键规范中能够看到这些信息点的效果如何,所以我认为将它们提取出来并为它们创建新的列可能是有用的。如果ML模型完全能够从“关键规格”列中看到这些信息,那么我可以简单地删除“年份”和“里程”列。进一步需要注意的是,每辆车都有不同数量的关键规格,我的意思是,如果我们举第一个例子,我们有:

Abarth 1.4 595 3d 144 BHP, 2018, 8000 miles, ASCARI 180 LIMITED EDITION, |2018 (18 reg)|Hatchback|8000 miles|1.4L|143bhp|Manual|Petrol|1 owner|Full service history|, VELOCES ARE VERY PLEASED TO PRESENT FOR SALE THIS AWESOME 595 ASCARI ABARTH …, https://www.autotrader.co.uk/classified/advert/201910173426267?model=595&sort=distance&make=Abarth&radius=1501&onesearchad=Used&onesearchad=Nearly%20New&onesearchad=New&advertising-location=at_cars&postcode=KY103AA&page=20, 11990

我们可以看到,关键规格是:

|2018 (18 reg)|Hatchback|8000 miles|1.4L|143bhp|Manual|Petrol|1 owner|Full service history|

但在另一辆车上,关键规格可能是:

|2013 (13 reg)|120000 miles|8 owners|

我认为这不太理想,因为关键规范变量的数量不一致,在第一个示例中有9个变量,在第二个示例中,只有3个变量,并且这些变量在示例之间也不匹配。第一个例子的第二个变量是“掀背车”,第二个例子的第二个变量是“120000英里”,我假设这是一个问题,因为120000英里与掀背车不可比(同样,我不知道ML模型是如何工作的,所以我不确定这是否真的是一个问题)

现在我觉得我已经尽可能地解释了我的问题,我将告诉你一些我已经尝试过的事情。首先,我认为我可以对我的每一列分别使用一个热编码。我首先将第一列“CAR NAME”转换为一个庞大的列表,其中整个列表中的每个列表都包含一个表示该车名称的字符串。例如,如果我对我的示例中的汽车执行此操作,我将生成一个如下所示的列表:

[['Abarth 1.4 595 3d 144 BHP'], ['Alfa Romeo 159 Sportwagon 1.9 JTDM 16v TI Estate 5dr Diesel …'], ['Alfa Romeo Giulia 2.0 TB 280 Veloce 4dr Auto'], ['Alfa Romeo Giulietta 1.4 MULTIAIR LUSSO TB 5d 170 BHP DNA …']]

我采取的下一步是生成一个新的列表,它不是包含许多列表,而是包含每个单词。所以我会生成一个list看起来是这样的:

['Abarth', '1.4', '595', '3d', '144', 'BHP', 'Alfa', 'Romeo', '159', 'Sportwagon', '1.9', 'JTDM', '16v', 'TI', 'Estate', '5dr', 'Diesel', '…', 'Alfa', 'Romeo', 'Giulia', '2.0', 'TB', '280', 'Veloce', '4dr', 'Auto', 'Alfa', 'Romeo', 'Giulietta' '1.4', 'MULTIAIR', 'LUSSO', 'TB', '5d', '170', 'BHP', 'DNA', '…']

然后,我只从该列表中提取唯一的单词来创建另一个新列表,然后我使用word2int为最终列表中不包含任何重复单词的每个单词分配一个整数值。然后我试着用一个热向量来训练模型,但是我的电脑因为工作量太大而死机了。因此,我甚至无法训练我假设的第一列“护理人员姓名”,因为词汇表太大,而且热向量的效率太低。我使用的代码如下:

请随意跳过这段代码,因为它可能并不那么相关

# function to convert numbers to one hot vectors
def to_one_hot(data_point_index, vocab_size):
    temp = np.zeros(vocab_size)
    temp[data_point_index] = 1
    return temp
x_train = [] # input word
y_train = [] # output word
for data_word in data:
    x_train.append(to_one_hot(word2int[ data_word[0] ], vocab_size))
    y_train.append(to_one_hot(word2int[ data_word[1] ], vocab_size))
# convert them to numpy arrays, Now we have our x_train and our y_train! yay!
x_train = np.asarray(x_train)
y_train = np.asarray(y_train)

print(x_train.shape, y_train.shape)   # (x_train.shape, y_train.shape) = (392978, 1698) (392978, 1698)
                                      # This means 39,2978 training points, where each point has 1,698 dimensions


x = tf.placeholder(tf.float32, shape=(None, vocab_size))
y_label = tf.placeholder(tf.float32, shape=(None, vocab_size))
EMBEDDING_DIM = 5 # you can choose your own number
W1 = tf.Variable(tf.random_normal([vocab_size, EMBEDDING_DIM]))
b1 = tf.Variable(tf.random_normal([EMBEDDING_DIM])) #bias
hidden_representation = tf.add(tf.matmul(x,W1), b1)
#Next, we take what we have in the embedded dimension and make a prediction about the neighbour. To make the prediction we use softmax.
W2 = tf.Variable(tf.random_normal([EMBEDDING_DIM, vocab_size]))
b2 = tf.Variable(tf.random_normal([vocab_size]))
prediction = tf.nn.softmax(tf.add( tf.matmul(hidden_representation, W2), b2))
# Now all that's left to do is train it
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init) #make sure you do this!
# define the loss function:
cross_entropy_loss = tf.reduce_mean(-tf.reduce_sum(y_label * tf.log(prediction), reduction_indices=[1]))
# define the training step:
train_step = tf.train.GradientDescentOptimizer(0.1).minimize(cross_entropy_loss)
n_iters = 10000    #Suggested 10,000 iterations, takes forever!!!
# train for n_iter iterations
for _ in range(n_iters):
    sess.run(train_step, feed_dict={x: x_train, y_label: y_train})
    print('loss is : ', sess.run(cross_entropy_loss, feed_dict={x: x_train, y_label: y_train}))
print('----------')
print(sess.run(W1))
print('----------')
print(sess.run(b1))
print('----------')
vectors = sess.run(W1 + b1)
print(vectors[ word2int['sportback'] ])

所以在尝试了这一点之后,我尝试使用密集的单词嵌入,而不是一个热向量。我也不确定这是不是正确的决定。我希望有人能让我明白我正在努力实现的目标,并引导我朝着正确的方向前进。很抱歉发了这么长的帖子,但我认为有必要对自己进行充分的解释

最后,我要重申的是,通过使用我拥有的200000(或更多)行数据,帮助训练一个模型来预测汽车的价格,记住我拥有的数据与一些有文本的列、一些有数字的列以及一些同时有文本和数字的列混杂在一起

非常感谢你,如果你能登上这篇文章的底部,你能给我的任何帮助都会大有帮助。我希望Stack Exchange的其他用户也能从这个问题中受益


Tags: 数据模型列表sizemaketftrain价格