作者|Yogeeshwari S 编译|VK 来源|Towards Data Science

我很高兴与大家分享我的机器学习和深度学习经验,同时我们将在一个Kaggle竞赛得到解决方案。学习过程的分析也是非常直观,具有娱乐性和挑战性。希望这个博客最终能给读者一些有用的学习帮助。


目录

  1. 业务问题

  2. 误差度量

  3. 机器学习和深度学习在我们的问题中的应用

  4. 数据来源

  5. 探索性数据分析-EDA

  6. 现有方法

  7. 资料准备

  8. 模型说明

  9. 结果

  10. 我对改善RMSLE的尝试

  11. 未来的工作

  12. GitHub存储库

  13. 参考引用


1.业务问题

Mercari是一家在日本和美国运营的电子商务公司,其主要产品是Mercari marketplace的应用程序。人们可以使用智能手机轻松地出售或购买物品。

应用程序的用户可以自由选择价格,同时列出商品。然而,这里的风险更高,因为如果价格表与市场价格相比过高或过低,消费者和客户都会处于亏损状态。上述问题的解决方案是自动推荐商品价格,因此,最大的社区购物应用程序希望向卖家提供价格建议。

目前的问题是预测任何给定产品的价格,这说明这是一个回归问题。训练数据中的特征包括物品的train_id, name, item_condition_id, category_name, brand_name, price, shipping, item_description

除了目标变量价格之外,我们在测试数据中拥有所有其他特征。这些特征不仅是离散的和连续的,而且包含卖家提供的商品的文字描述。例如,女性配饰产品的文字说明如下:

我们可以看到,这两种产品的售价不同,第一种售价16美元,第二种售价9美元。

因此,这里的挑战是,我们需要建立一个模型,根据上图所示的描述,以及产品名称、品牌名称、商品状况等,来预测产品的正确价格。


2.误差度量

这个问题的误差度量是均方根对数误差(RMSLE)。请参阅此博客以了解有关度量的更多信息

https://medium.com/analytics-vidhya/root-mean-square-log-error-rmse-vs-rmlse-935c6cc1802a

度量计算公式如下图所示:

RMSLE计算代码如下:

def rmsle_compute(y_true, y_pred):#https://www.kaggle.com/gspmoreira/cnn-glove-single-model-private-lb-0-41117-35thassert len(y_true) == len(y_pred)score = np.sqrt(np.mean(np.power(np.log1p(y_pred) - np.log1p(y_true), 2)))return score

3.机器学习和深度学习在我们的问题中的应用

在这个人工智能(AI)时代,当我们想到AI的时候,有两个流行词分别是机器学习和深度学习。我们发现人工智能无处不在,它们现在是人类生活的一部分。无论是通勤(例如出租车预订)、医疗诊断、个人助理(如Siri、Alexa)、欺诈检测、犯罪侦查、在线客户支持、产品推荐、自动驾驶汽车,等等。利用先进的机器学习和深度学习算法,任何类型的预测问题都可以解决。

我们的问题是独特的,因为它是一个基于自然语言处理(NLP)的回归任务。NLP的第一步是将文本表示为数字,即将文本转换为数字向量表示,以构造回归函数。

解决价格预测问题的一种方法是利用向量化技术,如TF-IDF、BoW,并构建固定大小的稀疏向量表示,这些表示将被经典的机器学习算法(例如简单线性回归器、基于树的回归器等)使用。

另一种方法是使用深层NLP体系结构(例如CNN、LSTM、GRU或它们的组合),这些体系结构可以独立学习特征,可以得到密集向量。在当前的分析中,我们正在研究这两种方法。


4.数据来源

这个分析的数据集来自Kaggle,一个流行的在线社区或者数据科学家的数据平台。

了解数据

训练集由140多万件产品组成,第二阶段测试集由340多万件产品组成。

列出训练/测试数据中的字段名:

  • train_id 或者test_id — 列表的唯一id
  • name — 卖方提供的产品名称。请注意,为避免数据泄漏,此字段中的价格被删除并表示为[rm]
  • item_condition_id — 这里卖家提供物品条件
  • category_name — 每个物品的类别列表
  • brand_name — 每个商品所属的相应品牌
  • price — 这是我们的目标变量,以美元表示(不在测试集中)
  • shipping — 1,如果运费由卖方支付,否则为0
  • item_description — 此处给出了每个物品的描述,价格被删除并表示为[rm]

以下数据的部分截图:


5.探索性数据分析-EDA

EDA是数据科学过程中的一个重要步骤,是一种统计方法,通常使用可视化方法从数据集中获得更多的见解。在深入研究EDA之前,让我们快速查看数据以了解更多信息。下面是检查空值的代码段:

print(train.isnull().sum())

从上面的输出中,我们发现三列,即类别名称(category name)、品牌名称(brand name)和物品描述(item description)携带空值。其中,品牌名称包含了很多缺失的值(632k)。列类别名称包含6.3k个空值,而物品描述只有4个空值。让我们稍后在创建模型时再处理它们,现在我们逐个深入研究EDA特性。

5.1 类别名称的单变量分析

训练数据集中共有1287个类别。下面是用于计数的代码段:

category_count = train['category_name'].value_counts()

类别计数图如下所示:

上面的条形图显示了出现频率最高的10个类别。人们会注意到,女装在所有群体中占据着制高点。

每个类别名称由3个子部分组成,用“/”分隔,并有主类别/子类别1/子类别2名称。重要的是要将它们分开,并将它们作为新的特征包含进来,这样我们的模型就能做出更好的预测。

划分类别

在我们的分析中,我们使用以下函数将每个类别的名称划分为主类别、子类别1、子类别2。

def split_categories(category):'''函数在数据集中划分类别列并创建3个新列:'main_category','sub_cat_1','sub_cat_2''''try:sub_cat_1,sub_cat_2,sub_cat_3 = category.split("/")return sub_cat_1,sub_cat_2,sub_cat_3except:return ("No label","No label","No label")def create_split_categories(data):'''使用split_categories函数创建3个新列的函数: 'main_category','sub_cat_1','sub_cat_2''''#https://medium.com/analytics-vidhya/mercari-price-suggestion-challenge-a-machine-learning-regression-case-study-9d776d5293a0data['main_category'],data['sub_cat_1'],data['sub_cat_2']=zip(*data['category_name'].\apply(lambda x: split_categories(x)))

此外,使用下面的代码行计算三列中每个列中的类别数:

main_category_count_te = test['main_category'].value_counts()
sub_1_count_te = test['sub_cat_1'].value_counts()
sub_2_count_te = test['sub_cat_2'].value_counts()

上述分析表明,训练数据中有11个主要类别,这些类别又分为114个子类别(子类别1),这些子类别又被进一步分配到865个特定类别(子类别2)。绘制类别的代码如下所示:

def plot_categories(category,title):'''这个函数接受一个类别和标题作为输入,并绘制条形图。'''#https://seaborn.pydata.org/generated/seaborn.barplot.htmlsns.set(style="darkgrid")sns.barplot(x=category[:10].values, y=category[:10].index)plt.title(title)plt.xlabel('Counts', fontsize=12)plt.show()
#https://www.datacamp.com/community/tutorials/categorical-dataplot_categories(category_count,"Frequency Distribution of top 10 categories")

拆分后该类别每列前10项的条形图如下:

5.2品牌名称的单变量分析

共有4807个品牌,其中最常出现的前10个品牌如下图所示:

绘图代码在这里:

#https://www.datacamp.com/community/tutorials/categorical-data
sns.barplot(x=brand_count[:10].values, y=brand_count[:10].index)
plt.title('Frequency Distribution of top 10 brand names')
plt.xlabel('Counts', fontsize=12)
plt.show()

值得注意的是PINK 和NIKE 品牌,紧随其后的是维多利亚的秘密。

5.3价格单变量分析

由于价格是数值的,所以我们使用describe()函数来查看摘要。下面是代码片段:

train.price.describe()

任何产品的最高价格为2009美元,最低价格为0。还应注意的是,75%的产品价格低于29美元,50%的产品价格低于17美元,而25%的产品价格低于10美元。平均价格区间为26.7美元。

价格变量分布

目标的分布

plt.title("Distribution of Price variable")
plt.xlabel("Price(USD)")
plt.ylabel("No. of products")
plt.hist(train['price'],bins=30)

价格特征遵循右偏分布,如上图所示。正如这里所讨论的,由于分布的另一侧的点,倾斜分布会导致较高的均方误差(MSE)值,如果数据是正态分布,则MSE就不会那么大。

因此,对price特征进行log转换是不可避免的,如果数据是正态分布的,那么模型的性能也会更好(参见这里)。这是通过以下代码片段完成的:

def log_price(price):return np.log1p(price)

下图为对数转换后的价格变量图。

5.4物品描述的单变量分析

我们正在绘制词云以了解描述中常见的单词。对应的代码段,图如下:

word_counter = Counter(train['item_description'])
most_common_words = word_counter.most_common(500)#https://www.geeksforgeeks.org/generating-word-cloud-python/
# 创建并生成一个词云图像:
stopwords = get_stop_words('en')
#https://github.com/Alir3z4/python-stop-words/issues/19
stopwords.extend(['rm'])
wordcloud = WordCloud(stopwords=stopwords,background_color="white").generate(str(most_common_words))# 显示生成的图像:
plt.figure(figsize=(10,15))
plt.imshow(wordcloud, interpolation='bilinear')
plt.title("Word cloud generated from the item_descriptions\n")
plt.axis("off")
plt.show()

从上面的单词cloud中,我们可以注意到在我们的item_description中经常出现的单词。

描述的字数

单独的文本描述可能是这个问题(参考)的一个重要特征,即对于机器学习模型,并且将有助于嵌入深度学习模型的过程。

train['description_wc'] = [len(str(i).split()) for i in train['item_description']]

为了进一步研究该特征,我们绘制了如下所示的箱线图和分布图,下面是代码:

箱线图
sns.boxplot(train['description_wc'],orient='v')
plt.title("Box plot of description word count")
plt.xlabel("item_description")
plt.ylabel("No. of words")
plt.show()

我们可以注意到,大多数描述包含大约少于40个单词。

分布图
plt.figure(figsize=(10,3))
sns.distplot(train['description_wc'], hist=False)
plt.title('Plot of the word count for each item description')
plt.xlabel('Number of words in each description')
plt.show()

描述字数的密度图是右偏的。

统计数据摘要

Summary stats表明item_description的最小长度为1,而最大长度为245。平均长度约为25个单词。少数描述比较长,而大多数描述包含不到40个单词,正如我们在箱线图中看到的那样。

5.5物品条件的单变量分析

离散特征item_condition_id 的范围是1到5。该特征具有顺序性,1的物品是“最好的”,条件5的物品是“最差的”。item_condition_id的条形图如下所示:

大多数待售商品状况良好,如上图所示。因此,条件1的物品较高,其次是条件3和2,而条件4和5的物品较低。

5.6双变量分析

了解目标变量与其他特征的关联类型将有助于特征工程。因此,将价格变量与其他两个变量进行比较。

价格与运费

和往常一样,图表有助于我们更好地理解事物。代码和绘图如下所示:

#https://seaborn.pydata.org/generated/seaborn.boxplot.htmlax = sns.boxplot(x=train['shipping'],y=train['log_price'],palette="Set3",hue=train['shipping'])
handles, _ = ax.get_legend_handles_labels()
ax.legend(handles, ["seller pays", "Buyer pays"])
plt.title('Price distribution', fontsize=15)
plt.show()

我们可以观察到,当商品价格较高时,卖方支付运费,反之亦然。

价格与描述长度

我们上面所做的两个变量的绘图。

plt.scatter(train['description_wc'],train['price'],alpha=0.4)
plt.title("Price Vs Description length")
plt.xlabel("Description length")
plt.ylabel("Price(USD)")
plt.show()

值得注意的是,描述长度较短的商品价格往往高于描述长度较长的商品。


6.现有方法

有一些博客和论文已经使用简单的机器学习或深度学习方法提出了解决方案。我们将简要介绍其中一些:

MLP

Pawel和Konstantin以他们惊人的解决方案赢得了这场比赛。他们使用了一种基于前馈神经网络的方法,即一种简单的MLP,它可以有效地处理稀疏特征。

他们所执行的一些预处理技巧包括对分类列进行一次one-hot编码、使用PorterStemmer进行词干分析、BoW-1,2-grams(带和不带TF-IDF)、将不同字段(如名称、品牌名称和物品描述)串联到单个字段中。他们的最终得分是0.37:https://www.kaggle.com/lopuhin/mercari-golf-0-3875-cv-in-75-loc-1900-s

CNN

在本研究中,作者使用了CNN架构,结合max-pooling,分别对名称和物品描述进行向量化。他使用预训练好的GloVE向量进行词嵌入,嵌入是在名称和物品描述中得到的。一些有用的技巧是在最后一个全连接层之前使用跳跃连接并且进行一些离散特征的连接,以及使用了词嵌入的平均池层。作者通过一个单一的深度学习模型取得了0.41的惊人成绩:https://www.kaggle.com/gspmoreira/cnn-glove-single-model-private-lb-0-41117-35th

LGBM + Ridge

在这里,作者应用了一个基于树的梯度提升框架LightGBM,以实现更快的训练和更高的效率。该研究还使用了一种简单、快速的岭回归模型进行训练。一些特色技术包括:使用CountVectorizer对name和category_name列进行向量化,TfidfVectorizer用于item_description,dummy 变量创建用于item_condition_id和shipping_id,以及LabelBinarizer用于品牌名。两个模型合二为一后,作者得到了0.44分:https://www.kaggle.com/tunguz/more-effective-ridge-lgbm-script-lb-0-44823

GRU+2 Ridge

在这项研究中,作者使用RNN、Ridge和RidgeCV构建了一个关联模型,其RMSLE约为0.427。这里应用的一些有用的技巧包括使用GRU层实现文本特征,为RNN训练采用早停策略,在两个epoch使用小批量大小,以及用于岭回归模型的超过300k个特征:https://www.kaggle.com/valkling/mercari-rnn-2ridge-models-with-notes-0-42755#RNN-Model


7.数据准备

清理数据

根据这一参考资料,Mercari网站上的最低价格为3美元。因此,在我们的训练数据中,我们保留价格高于3美元的物品。下面显示的是相同的代码段:

#https://www.kaggle.com/valkling/mercari-rnn-2ridge-models-with-notes-0-42755
train = train.drop(train[(train.price < 3.0)].index)

处理空值/缺失值

从EDA中,我们知道3列,即category_name, brand_name,item_description包含空值。因此,我们用适当的值来代替它们。我们使用以下函数执行此操作:

def fill_nan(dataset):'''函数填充各列中的NaN值'''dataset["item_description"].fillna("No description yet",inplace=True)dataset["brand_name"].fillna("missing",inplace=True)dataset["category_name"].fillna("missing",inplace=True)

训练测试集拆分

在我们的分析中,价格是目标变量y。基于误差函数来评估回归模型的拟合度是很重要的,我们需要对y进行观察和预测。训练数据分为训练集和测试集。

对于基本线性回归模型,测试集包含10%的数据,对于深度学习模型,测试集包含总数据的20%。

缩放目标变量

目标变量的标准化是使用sklearn的StandardScaler函数。预处理如下图所示:

global y_scalar
y_scalar = StandardScaler()
y_train = y_scalar.fit_transform(log_price(X_train['price']).values.reshape(-1, 1))
y_test = y_scalar.transform(log_price(X_test['price']).values.reshape(-1, 1))

由于我们的目标变量是使用上述函数进行标准化的,所以在计算误差度量之前,将预测进行逆变换是很重要的。这是通过使用以下函数来完成的:

def scale_back(x):'''函数对缩放值进行逆变换'''x= np.expm1(y_scalar.inverse_transform(x.reshape(-1,1))[:,0])return x

8.模型说明

让我们详细介绍机器学习和深度学习管道。

8.1机器学习管道

在这一分析中,自然语言处理的概念,如BoW,TFIDF等被用来向量化文本的机器学习回归模型。

构建特征

在执行EDA时,我们添加了四个新特征,即通过拆分列category生成三个新列,并从item_description中添加文本描述的字数。另外,我们根据名称文本的长度再创建一个列。所以,我们有五个新特征。

我们的数据集包括离散特征、数字特征和文本特征。必须对离散特征进行编码,并将文本特征向量化,以创建模型使用的特征矩阵。

离散特征编码

我们使用sci工具包中的CountVectorizer函数对离散特征(如category_name, main_category,sub_cat_1,sub_cat_2,brand_name)进行one-hot编码,并使用get_dummies()函数对shipping_iditem_condition_id 进行编码。其代码如下:

def one_hot_encode(train,test):'''函数对离散列进行one-hot编码'''vectorizer = CountVectorizer(token_pattern='.+')vectorizer = vectorizer.fit(train['category_name'].values) # 只在训练数据上拟合column_cat = vectorizer.transform(test['category_name'].values)#向量化main_category列vectorizer = vectorizer.fit(train['main_category'].values) # 只在训练数据上拟合column_mc = vectorizer.transform(test['main_category'].values)#向量化sub_cat_1列vectorizer = vectorizer.fit(train['sub_cat_1'].values) # 只在训练数据上拟合column_sb1 = vectorizer.transform(test['sub_cat_1'].values)#向量化sub_cat_2列vectorizer = vectorizer.fit(train['sub_cat_2'].values) # 只在训练数据上拟合column_sb2 = vectorizer.transform(test['sub_cat_2'].values)#向量化brand列vectorizer = vectorizer.fit(train['brand_name'].astype(str)) # 只在训练数据上拟合brand_encodes = vectorizer.transform(test['brand_name'].astype(str))print("created OHE columns for main_category,sub_cat_1,sub_cat_2\n")print(column_cat.shape)print(column_mc.shape)print(column_sb1.shape)print(column_sb2.shape)print(brand_encodes.shape)print("="*100)return column_cat,column_mc,column_sb1,column_sb2,brand_encodesdef get_dummies_item_id_shipping(df):df['item_condition_id'] = df["item_condition_id"].astype("category")df['shipping'] = df["shipping"].astype("category")item_id_shipping = csr_matrix(pd.get_dummies(df[['item_condition_id', 'shipping']],\sparse=True).values)return item_id_shipping
文本特征向量化

我们分别使用BoW(用uni-和bi-grams)和TFIDF(用uni-、bi-和tri-grams)对文本特征名称和条目描述进行编码。其函数如下:

def vectorizer(train,test,column,no_of_features,n_range,vector_type):'''函数使用TFIDF/BoW对文本进行向量化'''if str(vector_type) == 'bow':vectorizer = CountVectorizer(ngram_range=n_range,max_features=no_of_features).fit(train[column])  #拟合else:vectorizer = TfidfVectorizer(ngram_range=n_range, max_features=no_of_features).fit(train[column]) # 只在训练数据上拟合# 我们使用vectorizer将文本转换为矢量transformed_text = vectorizer.transform(tqdm(test[column]))###############################print("After vectorizations")print(transformed_text.shape)print("="*100)return transformed_text

使用上述函数的代码如下:

X_train_bow_name = vectorizer(X_train,X_train,'name',100000,(1,2),'bow')
X_test_bow_name = vectorizer(X_train,X_test,'name',100000,(1,2),'bow')
X_train_tfidf_desc = vectorizer(X_train,X_train,'item_description',100000,(1,3),'tfidf')
X_test_tfidf_desc = vectorizer(X_train,X_test,'item_description',100000,(1,3),'tfidf')
特征矩阵

最后的矩阵是通过将所有编码特征(包括离散特征和文本特征)以及两个数字特征(即文本描述的字数和名称)串联起来生成的。参考代码如下:

x_train_set = hstack((X_train_bow_name,X_train_tfidf_desc,tr_cat,X_train['wc_name'].values.reshape(-1,1),X_train['wc_desc'].values.reshape(-1,1))).tocsr()
x_test_set = hstack((X_test_bow_name,X_test_tfidf_desc,te_cat,X_test['wc_name'].values.reshape(-1,1),X_test['wc_desc'].values.reshape(-1,1))).tocsr()

最终生成的矩阵包含206k多个特征。事实上,这有很多特征。

首次选择模型

为这个问题选择一个合适的算法可能是一项艰巨的任务,尤其是对初学者来说。

我们学习根据数据维度、线性度、训练时间、问题类型等来选择算法,如这里所讨论的。

在我们的分析中,我们首先实验简单的线性模型,如线性回归,支持向量回归,对于这两个模型,我们选择了来自scikit-learn的SGDRegressor 。接下来,我们训练岭回归。

我们使用以下函数使用GridSearchCV超参数调整所有模型的参数:

def hyperparameter_tuning_random(x,y,model_estimator,param_dict,cv_no):start = time.time()hyper_tuned = GridSearchCV(estimator = model_estimator, param_grid = param_dict,\return_train_score=True, scoring = 'neg_mean_squared_error',\cv = cv_no, \verbose=2, n_jobs = -1)hyper_tuned.fit(x,y)print("\n######################################################################\n")print ('Time taken for hyperparameter tuning is {} sec\n'.format(time.time()-start))print('The best parameters_: {}'.format(hyper_tuned.best_params_))return hyper_tuned.best_params_
线性回归

线性回归的目的是减少预测与实际数据之间的误差。我们使用带有“squared_loss”和超参数调整的SGDregressor 训练简单线性回归模型。下面显示了代码:

#超参数调优
parameters = {'alpha':[10**x for x in range(-10, 7)],}
model_lr_reg = SGDRegressor(loss = "squared_loss",fit_intercept=False,l1_ratio=0.6)
best_parameters_lr = hyperparameter_tuning_random(x_train_set,y_train,model_lr_reg,parameters,3)model_lr_best_param = SGDRegressor(loss = "squared_loss",alpha = best_parameters_lr['alpha'],\fit_intercept=False)
model_lr_best_param.fit(x_train_set,y_train)
y_train_pred = model_lr_best_param.predict(x_train_set)
y_test_pred = model_lr_best_param.predict(x_test_set)

在我们的测试数据中,这个简单的模型得出了最佳α=0.001的RMSLE为0.513。

SVR:

支持向量回归(SVR)是指用不超过ε的值来预测偏离实际数据的函数。我们使用SGDRegressor训练一个SVR,“epsilon_unsensitive”作为损失,alphas作为超参数。根据我们的测试数据,该模型产生了α=0.0001的RMSLE为0.632。在我们的例子中,简单的线性回归比支持向量机的性能要好得多。SVR代码如下:

#超参数调优
parameters_svr = {'alpha':[10**x for x in range(-4, 4)]}
model_svr = SGDRegressor(loss = "epsilon_insensitive",fit_intercept=False)
best_parameters_svr = hyperparameter_tuning_random(x_train_set,y_train,model_svr,parameters_svr,3)model_svr_best_param = SGDRegressor(loss = "epsilon_insensitive",alpha = 0.0001,\fit_intercept=False)
model_svr_best_param.fit(x_train_set,y_train[:,0])
y_train_pred_svr = model_svr_best_param.predict(x_train_set)
y_test_pred_svr = model_svr_best_param.predict(x_test_set)
岭回归

岭回归是线性回归的近亲,通过L2范数给出一些正则化来防止过度拟合。我们在线性模型下使用scikit-learn的Ridge得到了很好的拟合,α=6.0的RMSLE为0.490。下面是具有超参数调整的Ridge模型代码:

#超参数调优
parameters_ridge = {'alpha':[0.0001,0.001,0.01,0.1,1.0,2.0,4.0,5.0,6.0]}
model_ridge = Ridge(solver='auto', fit_intercept=True,max_iter=100, normalize=False, tol=0.05, random_state = 1,
)
rs_ridge = hyperparameter_tuning_random(x_train_set,y_train,model_ridge,parameters_ridge,3)ridge_model = Ridge(solver='auto', fit_intercept=True,max_iter=100, normalize=False, tol=0.05, alpha=6.0,random_state = 1,
)
ridge_model.fit(x_train_set, y_train)
RidgeCV

它是一个交叉验证估计器,可以自动选择最佳超参数。换言之,具有内置交叉验证的岭回归。对于我们的问题,这比Ridge表现得更好,我们构建了RidgeCV模型,根据我们的测试数据,alpha6.0的RMSLE为0.442。代码如下:

from sklearn.linear_model import RidgeCV
print("Fitting Ridge model on training examples...")
ridge_modelCV = RidgeCV(fit_intercept=True, alphas=[6.0],normalize=False, cv = 2, scoring='neg_mean_squared_error',
)
ridge_modelCV.fit(x_train_set1, y_train)
preds_ridgeCV = ridge_modelCV.predict(x_test_set1)

我们可以观察到RidgeCV表现得最好。为了进一步提高分数,我们正在探索使用深度学习来解决这个问题

8.2深度学习

递归神经网络(RNN)擅长处理序列数据信息。我们使用门控递归单元(GRU),它是一种新型的RNN,训练速度更快。

从GRU中,我们在name, item_description列获取文本特征向量,对于其他类别字段,我们使用嵌入后再展平向量。所有这些共同构成了我们的深度学习模型的80维特征向量。

嵌入

除了训练测试的划分,深度学习(DL)管道的数据准备遵循与ML管道相同的例程。如前所述,DL管道需要密集向量,而神经网络嵌入是将离散变量表示为密集向量的有效方法

标识化和填充

嵌入层要求输入是整数编码的。因此,我们使用Tokenizer API对文本数据进行编码,下面是代码片段:

def tokenize_text(train,test,column):#参考AAIC课程global tt = Tokenizer()t.fit_on_texts(train[column].str.lower())vocab_size = len(t.word_index) + 1#对文档进行整数编码encoded_text_tr = t.texts_to_sequences(train[column].str.lower())encoded_text_te = t.texts_to_sequences(test[column].str.lower())return encoded_text_tr,encoded_text_te,vocab_size

标识化后的样本描述数据截图如下:

在标识化之后,我们填充序列。名称和描述文本的长度不同,Keras希望输入序列的长度相同。我们计算超出特定范围的数据点的百分比,以确定填充的长度。

下面显示了选择描述文本填充长度的代码:

print("% of sequence containing len > 160 is")
len(X_train[X_train.wc_desc > 160])/X_train.shape[0]*100

从上面的图像我们可以看到长度在160以上的点的百分比为0.7,即<1%。因此我们用160填充描述文本。类似地,我们计算name列,得到10。对应的代码片段如下所示:

print("% of name containing len > 10 is")
len(X_train[X_train.wc_name > 10])/X_train.shape[0]*100

此外,我们对离散变量进行编码,代码片段如下:

def rank_category(dataset,column_name):'''这个函数接受列名,并返回具有排名后类别'''counter = dataset[column_name].value_counts().index.valuestotal = list(dataset[column_name])ranked_cat = {}for i in range(1,len(counter)+1):ranked_cat.update({counter[i-1] : i})return ranked_cat,len(counter)def encode_ranked_category(train,test,column):'''这个函数调用rank_category函数并返回已编码的列    '''train[column] = train[column].astype('category')test[column] = test[column].astype('category')cat_list = list(train[column].unique())ranked_cat_tr,count = rank_category(train,column)encoded_col_tr = []encoded_col_te = []for category in train[column]:encoded_col_tr.append(ranked_cat_tr[category])for category in test[column]:if category in cat_list:encoded_col_te.append(ranked_cat_tr[category])else:encoded_col_te.append(0)encoded_col_tr = np.asarray(encoded_col_tr)encoded_col_te = np.asarray(encoded_col_te)return encoded_col_tr,encoded_col_te,count

注意:所有的嵌入都是和模型本身一起学习的。

整个数据准备管道以及编码、标识化和填充都由以下函数执行:

def data_gru(train,test):global max_length,desc_size,name_sizeencoded_brand_tr,encoded_brand_te,brand_len = encode_ranked_category(train,test,'brand_name')encoded_main_cat_tr,encoded_main_cat_te,main_cat_len = encode_ranked_category(train,test,'main_category')encoded_sub_cat_1_tr,encoded_sub_cat_1_te,sub_cat1_len = encode_ranked_category(train,test,'sub_cat_1')encoded_sub_cat_2_tr,encoded_sub_cat_2_te,sub_cat2_len = encode_ranked_category(train,test,'sub_cat_2')tokenized_desc_tr,tokenized_desc_te,desc_size = tokenize_text(train,test,'item_description')tokenized_name_tr,tokenized_name_te,name_size = tokenize_text(train,test,'name')max_length = 160desc_tr_padded = pad_sequences(tokenized_desc_tr, maxlen=max_length, padding='post')desc_te_padded = pad_sequences(tokenized_desc_te, maxlen=max_length, padding='post')del tokenized_desc_tr,tokenized_desc_tename_tr_padded = pad_sequences(tokenized_name_tr, maxlen=10, padding='post')name_te_padded = pad_sequences(tokenized_name_te, maxlen=10, padding='post')del tokenized_name_tr,tokenized_name_tegc.collect()train_inputs = [name_tr_padded,desc_tr_padded,encoded_brand_tr.reshape(-1,1),\encoded_main_cat_tr.reshape(-1,1),encoded_sub_cat_1_tr.reshape(-1,1),\encoded_sub_cat_2_tr.reshape(-1,1),train['shipping'],\train['item_condition_id'],train['wc_desc'],\train['wc_name']]test_inputs = [name_te_padded,desc_te_padded,encoded_brand_te.reshape(-1,1),\encoded_main_cat_te.reshape(-1,1),encoded_sub_cat_1_te.reshape(-1,1),\encoded_sub_cat_2_te.reshape(-1,1),test['shipping'],\test['item_condition_id'],test['wc_desc'],\test['wc_name']]item_condition_counter = train['item_condition_id'].value_counts().index.valueslist_var = [brand_len,main_cat_len,sub_cat1_len,sub_cat2_len,len(item_condition_counter)]return train_inputs,test_inputs,list_var

网络体系结构

对当前网络设计的分析正是受到了这个的启发(https://www.kaggle.com/valkling/mercari-rnn-2ridge-models-with-notes-0-42755#RNN-Model)。此外,我们在这个框架中对Dropout层和batch-normalization层进行了实验。以下是构建我们网络的代码片段:

def construct_GRU(train,var_list,drop_out_list):#name的GRU输入层input_name =  tf.keras.layers.Input(shape=(10,), name='name')embedding_name = tf.keras.layers.Embedding(name_size, 20)(input_name)gru_name = tf.keras.layers.GRU(8)(embedding_name)#description的GRU输入层input_desc =  tf.keras.layers.Input(shape=(max_length,), name='desc')embedding_desc = tf.keras.layers.Embedding(desc_size, 60)(input_desc)gru_desc = tf.keras.layers.GRU(16)(embedding_desc)#input layer for brand_name的输入层input_brand =  tf.keras.layers.Input(shape=(1,), name='brand')embedding_brand = tf.keras.layers.Embedding(var_list[0] + 1, 10)(input_brand)flatten1 = tf.keras.layers.Flatten()(embedding_brand)#main_category的输入层input_cat = tf.keras.layers.Input(shape=(1,), name='main_cat')Embed_cat = tf.keras.layers.Embedding(var_list[1] + 1, \10,input_length=1)(input_cat)flatten2 = tf.keras.layers.Flatten()(Embed_cat)#sub_cat_1的输入层input_subcat1 = tf.keras.layers.Input(shape=(1,), name='subcat1')Embed_subcat1 = tf.keras.layers.Embedding(var_list[2] + 1, \10,input_length=1)(input_subcat1)flatten3 = tf.keras.layers.Flatten()(Embed_subcat1)#sub_cat_2的输入层input_subcat2 = tf.keras.layers.Input(shape=(1,), name='subcat2')Embed_subcat2 = tf.keras.layers.Embedding(var_list[3] + 1, \10,input_length=1)(input_subcat2)flatten4 = tf.keras.layers.Flatten()(Embed_subcat2)#shipping的输入层input_shipping = tf.keras.layers.Input(shape=(1,), name='shipping')#item_condition_id的输入层input_item = tf.keras.layers.Input(shape=(1,), name='item_condition_id')Embed_item = tf.keras.layers.Embedding(var_list[4] + 1, \5,input_length=1)(input_item)flatten5 = tf.keras.layers.Flatten()(Embed_item)#数字特征的输入层desc_len_input = tf.keras.layers.Input(shape=(1,), name='description_length')desc_len_embd = tf.keras.layers.Embedding(DESC_LEN,5)(desc_len_input)flatten6 = tf.keras.layers.Flatten()(desc_len_embd)#name_len的输入层name_len_input = tf.keras.layers.Input(shape=(1,), name='name_length')name_len_embd = tf.keras.layers.Embedding(NAME_LEN,5)(name_len_input)flatten7 = tf.keras.layers.Flatten()(name_len_embd)# 级联concat_layer = tf.keras.layers.concatenate(inputs=[gru_name,gru_desc,flatten1,flatten2,flatten3,flatten4,input_shipping,flatten5,\flatten6,flatten7],name="concatenate")#全连接层Dense_layer1 = tf.keras.layers.Dense(units=512,activation='relu',kernel_initializer='he_normal',\name="Dense_l")(concat_layer)dropout_1 = tf.keras.layers.Dropout(drop_out_list[0],name='dropout_1')(Dense_layer1)batch_n1 = tf.keras.layers.BatchNormalization()(dropout_1)Dense_layer2 = tf.keras.layers.Dense(units=128,activation='relu',kernel_initializer='he_normal',\name="Dense_2")(batch_n1)dropout_2 = tf.keras.layers.Dropout(drop_out_list[1],name='dropout_2')(Dense_layer2)batch_n2 = tf.keras.layers.BatchNormalization()(dropout_2)Dense_layer3 = tf.keras.layers.Dense(units=128,activation='relu',kernel_initializer='he_normal',\name="Dense_3")(batch_n2)dropout_3 = tf.keras.layers.Dropout(drop_out_list[2],name='dropout_3')(Dense_layer3)Dense_layer4 = tf.keras.layers.Dense(units=64,activation='relu',kernel_initializer='he_normal',\name="Dense_4")(dropout_3)dropout_4 = tf.keras.layers.Dropout(drop_out_list[3],name='dropout_4')(Dense_layer4)#输出层final_output = tf.keras.layers.Dense(units=1,activation='linear',name='output_layer')(dropout_4)model = tf.keras.Model(inputs=[input_name,input_desc,input_brand,input_cat,input_subcat1,input_subcat2,\input_shipping,input_item,desc_len_input,name_len_input],outputs=[final_output])#我们指定了模型的输入和输出print(model.summary())img_path = "GRU_model_2_lr.png"plot_model(model, to_file=img_path, show_shapes=True, show_layer_names=True) return model

下面是我们的网络:

深度学习模型

共训练了四个不同Dropout和学习率的模型。每个网络由四个Dropout层组成,对于每一层,我们尝试对所有模型使用不同的Dropout率(有关详细信息,请参阅结果)。

训练

对于训练模型1和模型2,我们使用具有默认学习率的Adam优化器。此外,这些模型被训练为3个epoch,batch量大小加倍。模型1和模型2的试验数据的RMSLE分别为0.436和0.441。模型训练说明如下:

模型3和4使用Adam优化器和预定学习率进行训练,batch大小为1024个。对于epoch 1和2,学习率为0.005,对于最后一个epoch,我们将其降低到0.001。模型4的训练如下:

模型平均集成

模型平均是一种降低神经网络高方差的集成学习技术。在当前的分析中,我们对在不同条件下训练的模型进行集成,这些模型的正则化程度不同。每一款模型的训练时间约为30至35分钟。考虑到训练时间,我们只包含了两个模型。因此,在四个模型中,创建了两个模型组,即一个来自模型1和模型2,实现后RMSLE 0.433,另一个来自模型3和4,RMSLE为0.429

集成模型1和2的代码如下所示:

#https://machinelearningmastery.com/model-averaging-ensemble-for-deep-learning-neural-networks/
y_hats = np.array([preds_m1_te,te_preds_m2]) #making an array out of all the predictions
# 平均集成
mean_preds = np.mean(y_hats, axis=0)
print("RMSLE on test: {}".format(rmsle_compute(X_test['price'],scale_back(mean_preds))))

我们观察到模型3和4的集成表现最好。

最终模型

为了获得Kaggle的最终分数,我们现在在Kaggle中进行训练。我们建立了两个模型相同的模型模型3和4进行装配。下面展示的是在Kaggle训练过的模型的截图:

对这两个模型的平均模型在我们的最终测试数据(包含约340万个产品)中产生0.428的Kaggle分数。因此,我们的得分排名前10%。

9.结果

以下是模型输出的摘要截图:

机器学习管道的输出

深度学习管道的输出:

集成模型的输出

Kaggle提交分数:

10.改善RMSLE的尝试

提高我们得分的策略如下:

  • 不去除停用词:这个问题的一个关键是删除停用词会影响RMSLE分数。保留停用词可以提高分数。

  • 考虑到更多的文本特征用于模型构建:我们总共得到206k个特征,其中包括仅从文本数据中提取的200k个特征。在这个问题中,更加重视文本信息可以提高分数。

  • bigram和Tri-gram:在NLP中,如果我们打算在向量化过程中添加一些语义,通常会包含n-gram,如bigram、Tri-gram等。

  • 根据价格过滤数据:Mercari不允许发布低于3美元的商品。因此,那些产品价格低于3美元的是错误的。删除它们将有助于模型的性能更好。

  • 小批量和少epoch的模型训练:使用1024的batch和更好的学习率调度程序提高了分数

  • 整合两个神经网络模型:这一策略是目前研究所独有的,它将领先者的得分推得更高。我们通过训练两个神经网络模型并建立它们的集成来进行预测分析。


11.未来工作

可以通过探索以下选项来提高分数:

  1. 使用多层感知器是解决这一问题的常用方法

  2. 利用CNN与RNN结合处理文本数据

  3. 添加更多GRU层或进一步微调

这些是我们随后将要探讨的一些可能性。


12.GitHub存储库

请参考我的GitHub存储库查看完整代码:https://github.com/syogeeshwari/Mercari_price_prediction


13.参考引用

  • https://github.com/pjankiewicz/mercarisolution/blob/master/presentation/build/yandex.pdf

  • https://www.kaggle.com/valkling/mercari-rnn-2ridge-models-with-notes-0-42755

  • https://medium.com/analytics-vidhya/mercari-price-suggestion-challenge-66500ac1f88a

  • https://medium.com/analytics-vidhya/mercari-price-suggestion-challenge-a-machine-learning-regression-case-study-9d776d5293a0

  • https://machinelearningmastery.com/ensemble-methods-for-deep-learning-neural-networks/

  • https://machinelearningmastery.com/model-averaging-ensemble-for-deep-learning-neural-networks/

  • https://medium.com/unstructured/how-i-lost-a-silver-medal-in-kaggles-mercari-price-suggestion-challenge-using-cnns-and-tensorflow-4013660fcded

  • https://www.appliedaicourse.com/course/11/Applied-Machine-learning-course

原文链接:https://towardsdatascience.com/pricing-objects-in-mercari-machine-learning-deep-learning-perspectives-6aa80514b2c8

欢迎关注磐创AI博客站: http://panchuang.net/

sklearn机器学习中文官方文档: http://sklearn123.com/

欢迎关注磐创博客资源汇总站: http://docs.panchuang.net/

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. msf之木马程序

    目录捆绑木马生成木马文件附&#xff1a;msfvenom介绍msfvenom简介msfvenom生成exploit/multi/handler模块简介设置监听反弹发送木马查看对方的ip查看对方目录截图开启摄像头附&#xff1a;Meterpreter常用命令进一步获取权限伪装捆绑木马 这里使用的是Kali linux虚拟机 攻击机…...

    2024/4/24 23:13:18
  2. Datawhale零基础入门金融风控 task-1 初识数据

    这次已经是我第n次参加datawhale活动了&#xff0c;每次任务都比较贴合实际生产生活&#xff0c;选题都比较有代表性。硕士毕业后第一次&#xff08;纪念下&#xff09; 赛题以预测金融风险为任务&#xff0c;数据集报名后可见并可下载&#xff0c;该数据来自某信贷平台的贷款…...

    2024/4/22 12:23:37
  3. java高并发系列:google提供的一些好用的并发工具类

    环境&#xff1a;jdk1.8。 关于并发方面的&#xff0c;juc已帮我们提供了很多好用的工具&#xff0c;而谷歌在此基础上做了扩展&#xff0c;使并发编程更容易&#xff0c;这些工具放在guava.jar包中。 本文演示几个简单的案例&#xff0c;见一下guava的效果。 需要先了解的一…...

    2024/5/1 15:36:45
  4. Vuex笔记

    Vuex笔记 1.Vuex概述 Vuex是实现全局状态&#xff08;数据&#xff09;管理的一种机制&#xff0c;可以方便的实现组件之间数据的共享。 使用Vuex的好处&#xff1a; &#xff08;1&#xff09;能够在vuex中集中管理共享的数据&#xff0c;易于开发和后期维护&#xff0c; …...

    2024/4/27 19:57:29
  5. (八)软件测试人员的定位

    工作已将近三年了&#xff0c;虽然这三个年头里我都在积极的学习着软件开发与软件测试的相关的技术&#xff1b;但是能沉淀的东西很少。相信都有类似的感觉。 不要为了测试而测试 前几天做一个测试的PPT&#xff0c;就是讲项目中要用到的测试技术&#xff0c;总结了半天其实实…...

    2024/4/1 16:39:40
  6. 【项目评级】去中心化数字金融交易生态Group(GRP)

    1、项目&#xff08;权重30%&#xff0c;得分83分&#xff09; 项目简述&#xff1a; Group&#xff08;歌谱&#xff09;&#xff0c;全称ProofofGroup&#xff0c;是一流的去中心化数字金融交易生态&#xff0c;基于EOS发行了自己的GRP代币&#xff0c;并通过独创的POG工作证…...

    2024/4/25 5:25:23
  7. Leetcode75题-颜色分类 荷兰国旗问题

    给定一个包含红色、白色和蓝色&#xff0c;一共 n 个元素的数组&#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 此题中&#xff0c;我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 注意: 不能使用代码库…...

    2024/5/2 8:27:46
  8. 金融风控-贷款违约预测Task1 学习笔记

    金融风控-贷款违约预测Task1 学习笔记 目标&#xff1a;理解赛题目标&#xff0c;学习相应理论概念&#xff0c;熟悉应用预测指标&#xff0c;评分规则。 学习&#xff1a; 一.容易混淆 若一个实例为正类&#xff0c;被预测为负类&#xff0c;即为假负类。&#xff08;False N…...

    2024/4/20 5:32:49
  9. GC基础

    GC基础 1.什么是垃圾 自动内存回收,编程简单,系统不容易出错,手动释放内存,容易出现两种类型问题: 忘记回收多次回收 没有任何引用指向一个对象或者多个对象(循环引用) 2.如何定义垃圾 1.引用计算 2.根可达算法 3.常见的垃圾回收算法 Mark-Sweep(标记清除) 位置不连续…...

    2024/5/1 3:00:39
  10. c++11 std::thread多线程简单模型

    最近重新翻阅了一下c11新特性&#xff0c;发现标准库中新增了线程类std::thread。实际试用之后&#xff0c;的确比原项目中使用POSIX标准的线程API封装程度更高&#xff0c;用起来也更简单。另外在c11中还增加了atomic原子变量&#xff0c;简单类型的变量锁也被集成了。或许以后…...

    2024/4/23 21:04:10
  11. Jquery相关知识

    Jquery相关知识 一、 &#xff08;1&#xff09;认识jquery jquery是一个快速的、简洁的JavaScript框架&#xff0c;它封装JavaScript常用的功能代码&#xff0c;提供一种简便的JavaScript设计模式&#xff0c;优化HTML文档操作、事件处理、动画设计和Ajax交互。 &#xff08;…...

    2024/5/1 0:27:49
  12. 小福利,带你快速入门前端vue框架

    大家好&#xff0c;我是天空之城&#xff0c;今天给大家带来小福利&#xff0c;带你快速入门前端vue框架 安装vscode软件&#xff0c;编辑html文件&#xff0c;每次编辑完都要保存下&#xff0c;不然无法显示修改后的效果&#xff0c;这点比较坑 首先要引入vue.js文件&#xff…...

    2024/4/21 17:43:29
  13. 《计算机图形学基础(OpenGL版)》(第2版)勘误表

    页码行或位置原内容更正为备注98式(4.49)[cosθ−sinθ0sinθcosθ0001]\begin{bmatrix} cos\theta & \mathbf{-sin\theta} & 0 \\ \mathbf{sin\theta} & cos\theta & 0 \\ 0 & 0 & 1 \\ \end{bmatrix} ⎣⎡​cosθsinθ0​−sinθcosθ0​001​⎦⎤​…...

    2024/4/21 2:11:05
  14. docker logs无法查找字符串

    以下命令并不会在docker lgos的结果中查找字符串&#xff0c;而是会输出所有的日志 docker logs nginx | grep 127这是因为管道仅对stdout有效&#xff0c;如果容器将日志记录到stderr&#xff0c;这种情况就会发生&#xff0c;这时可以尝试这样写 docker logs nginx 2>&a…...

    2024/4/28 9:59:49
  15. (七)软件测试的流程

    如果想让测试在公司的项目中发挥出它最大的价值&#xff0c;并不是招两个测试技术高手&#xff0c;或引入几个测试技术&#xff0c;而是测试技术对项目流程的渗透&#xff0c;以及测试流程的改进与完善。虽然&#xff0c;当然测试行业前景乐观&#xff0c;许多中小企业也都在引…...

    2024/4/17 21:48:06
  16. string容器

    ...

    2024/4/1 16:40:00
  17. 自测-1 打印沙漏

    本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”&#xff0c;要求按下列格式打印 所谓“沙漏形状”&#xff0c;是指每行输出奇数个符号&#xff1b;各行符号中心对齐&#xff1b;相邻两行符号数差2&#xff1b;符号数先从大到小顺序递减到1&#xff0c;再…...

    2024/4/1 16:39:57
  18. javascript 发布订阅模式和观察者模式

    发布订阅模式 三要素&#xff1a;订阅者&#xff0c;发布者&#xff0c;信号中心 我们假定存在一个信号中心&#xff0c;某个任务完成就向信号中心发布一个信号&#xff0c;其他任务可以向这个信号订阅这个模式&#xff0c;从而知道自己什么时候可以开始执行&#xff0c;这样…...

    2024/4/1 16:39:57
  19. 【每日一题】37.解数独

    【&#x1f616;每日一题&#x1f62f;】37.解数独 本解法参考labuladong大神的题解 https://leetcode-cn.com/problems/sudoku-solver/ 编写一个程序&#xff0c;通过已填充的空格来解决数独问题。 数独规则&#xff1a; 数字1-9在每一行只能出现一次数字1-9在每一列只能出…...

    2024/4/16 7:43:28
  20. 在Java的反射中,Class.forName和ClassLoader的区别

    前言 最近在面试过程中有被问到&#xff0c;在Java反射中Class.forName()加载类和使用ClassLoader加载类的区别。当时没有想出来后来自己研究了一下就写下来记录一下。 解释 在java中Class.forName()和ClassLoader都可以对类进行加载。ClassLoader就是遵循双亲委派模型最终调…...

    2024/4/11 6:45:58

最新文章

  1. 2024.5.5 机器学习周报

    引言 Abstract 文献阅读 1、题目 SuperGlue: Learning Feature Matching with Graph Neural Networks 2、引言 本文介绍了SuperGlue&#xff0c;这是一种神经网络&#xff0c;它通过联合寻找对应关系并拒绝不匹配的点来匹配两组局部特征。通过求解一个可微的最优运输问题…...

    2024/5/2 8:54:26
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. Linux学习-网络UDP

    网络 数据传输,数据共享 网络协议模型 OSI协议模型 应用层 实际发送的数据 表示层 发送的数据是否加密 会话层 是否建立会话连接 传输层 数据传输的方式&#xff08;数据报、流式&#…...

    2024/4/30 10:44:30
  4. Go语言中如何实现继承

    完整课程请点击以下链接 Go 语言项目开发实战_Go_实战_项目开发_孔令飞_Commit 规范_最佳实践_企业应用代码-极客时间 Go语言中没有传统意义上的类和继承的概念&#xff0c;但可以通过嵌入类型&#xff08;embedded types&#xff09;来实现类似的功能。嵌入类型允许一个结构…...

    2024/4/30 4:14:53
  5. 最新在线工具箱网站系统源码

    内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 系统内置高达72种站长工具、开发工具、娱乐工具等功能。此系统支持本地调用API&#xff0c;同时还自带免费API接口&#xff0c; 是一个多功能性工具程序&#xff0c;支持后台管理、上…...

    2024/5/1 13:29:34
  6. 416. 分割等和子集问题(动态规划)

    题目 题解 class Solution:def canPartition(self, nums: List[int]) -> bool:# badcaseif not nums:return True# 不能被2整除if sum(nums) % 2 ! 0:return False# 状态定义&#xff1a;dp[i][j]表示当背包容量为j&#xff0c;用前i个物品是否正好可以将背包填满&#xff…...

    2024/5/1 10:25:26
  7. 【Java】ExcelWriter自适应宽度工具类(支持中文)

    工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

    2024/5/1 13:20:04
  8. Spring cloud负载均衡@LoadBalanced LoadBalancerClient

    LoadBalance vs Ribbon 由于Spring cloud2020之后移除了Ribbon&#xff0c;直接使用Spring Cloud LoadBalancer作为客户端负载均衡组件&#xff0c;我们讨论Spring负载均衡以Spring Cloud2020之后版本为主&#xff0c;学习Spring Cloud LoadBalance&#xff0c;暂不讨论Ribbon…...

    2024/5/1 21:18:12
  9. TSINGSEE青犀AI智能分析+视频监控工业园区周界安全防范方案

    一、背景需求分析 在工业产业园、化工园或生产制造园区中&#xff0c;周界防范意义重大&#xff0c;对园区的安全起到重要的作用。常规的安防方式是采用人员巡查&#xff0c;人力投入成本大而且效率低。周界一旦被破坏或入侵&#xff0c;会影响园区人员和资产安全&#xff0c;…...

    2024/5/1 4:07:45
  10. VB.net WebBrowser网页元素抓取分析方法

    在用WebBrowser编程实现网页操作自动化时&#xff0c;常要分析网页Html&#xff0c;例如网页在加载数据时&#xff0c;常会显示“系统处理中&#xff0c;请稍候..”&#xff0c;我们需要在数据加载完成后才能继续下一步操作&#xff0c;如何抓取这个信息的网页html元素变化&…...

    2024/4/30 23:32:22
  11. 【Objective-C】Objective-C汇总

    方法定义 参考&#xff1a;https://www.yiibai.com/objective_c/objective_c_functions.html Objective-C编程语言中方法定义的一般形式如下 - (return_type) method_name:( argumentType1 )argumentName1 joiningArgument2:( argumentType2 )argumentName2 ... joiningArgu…...

    2024/5/2 6:03:07
  12. 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】

    &#x1f468;‍&#x1f4bb;博客主页&#xff1a;花无缺 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 花无缺 原创 收录于专栏 【洛谷算法题】 文章目录 【洛谷算法题】P5713-洛谷团队系统【入门2分支结构】&#x1f30f;题目描述&#x1f30f;输入格…...

    2024/5/1 6:35:25
  13. 【ES6.0】- 扩展运算符(...)

    【ES6.0】- 扩展运算符... 文章目录 【ES6.0】- 扩展运算符...一、概述二、拷贝数组对象三、合并操作四、参数传递五、数组去重六、字符串转字符数组七、NodeList转数组八、解构变量九、打印日志十、总结 一、概述 **扩展运算符(...)**允许一个表达式在期望多个参数&#xff0…...

    2024/5/1 11:24:00
  14. 摩根看好的前智能硬件头部品牌双11交易数据极度异常!——是模式创新还是饮鸩止渴?

    文 | 螳螂观察 作者 | 李燃 双11狂欢已落下帷幕&#xff0c;各大品牌纷纷晒出优异的成绩单&#xff0c;摩根士丹利投资的智能硬件头部品牌凯迪仕也不例外。然而有爆料称&#xff0c;在自媒体平台发布霸榜各大榜单喜讯的凯迪仕智能锁&#xff0c;多个平台数据都表现出极度异常…...

    2024/5/2 5:31:39
  15. Go语言常用命令详解(二)

    文章目录 前言常用命令go bug示例参数说明 go doc示例参数说明 go env示例 go fix示例 go fmt示例 go generate示例 总结写在最后 前言 接着上一篇继续介绍Go语言的常用命令 常用命令 以下是一些常用的Go命令&#xff0c;这些命令可以帮助您在Go开发中进行编译、测试、运行和…...

    2024/5/1 20:22:59
  16. 用欧拉路径判断图同构推出reverse合法性:1116T4

    http://cplusoj.com/d/senior/p/SS231116D 假设我们要把 a a a 变成 b b b&#xff0c;我们在 a i a_i ai​ 和 a i 1 a_{i1} ai1​ 之间连边&#xff0c; b b b 同理&#xff0c;则 a a a 能变成 b b b 的充要条件是两图 A , B A,B A,B 同构。 必要性显然&#xff0…...

    2024/4/30 22:14:26
  17. 【NGINX--1】基础知识

    1、在 Debian/Ubuntu 上安装 NGINX 在 Debian 或 Ubuntu 机器上安装 NGINX 开源版。 更新已配置源的软件包信息&#xff0c;并安装一些有助于配置官方 NGINX 软件包仓库的软件包&#xff1a; apt-get update apt install -y curl gnupg2 ca-certificates lsb-release debian-…...

    2024/5/1 6:34:45
  18. Hive默认分割符、存储格式与数据压缩

    目录 1、Hive默认分割符2、Hive存储格式3、Hive数据压缩 1、Hive默认分割符 Hive创建表时指定的行受限&#xff08;ROW FORMAT&#xff09;配置标准HQL为&#xff1a; ... ROW FORMAT DELIMITED FIELDS TERMINATED BY \u0001 COLLECTION ITEMS TERMINATED BY , MAP KEYS TERMI…...

    2024/5/2 0:07:22
  19. 【论文阅读】MAG:一种用于航天器遥测数据中有效异常检测的新方法

    文章目录 摘要1 引言2 问题描述3 拟议框架4 所提出方法的细节A.数据预处理B.变量相关分析C.MAG模型D.异常分数 5 实验A.数据集和性能指标B.实验设置与平台C.结果和比较 6 结论 摘要 异常检测是保证航天器稳定性的关键。在航天器运行过程中&#xff0c;传感器和控制器产生大量周…...

    2024/5/2 8:37:00
  20. --max-old-space-size=8192报错

    vue项目运行时&#xff0c;如果经常运行慢&#xff0c;崩溃停止服务&#xff0c;报如下错误 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 因为在 Node 中&#xff0c;通过JavaScript使用内存时只能使用部分内存&#xff08;64位系统&…...

    2024/5/1 4:45:02
  21. 基于深度学习的恶意软件检测

    恶意软件是指恶意软件犯罪者用来感染个人计算机或整个组织的网络的软件。 它利用目标系统漏洞&#xff0c;例如可以被劫持的合法软件&#xff08;例如浏览器或 Web 应用程序插件&#xff09;中的错误。 恶意软件渗透可能会造成灾难性的后果&#xff0c;包括数据被盗、勒索或网…...

    2024/5/1 8:32:56
  22. JS原型对象prototype

    让我简单的为大家介绍一下原型对象prototype吧&#xff01; 使用原型实现方法共享 1.构造函数通过原型分配的函数是所有对象所 共享的。 2.JavaScript 规定&#xff0c;每一个构造函数都有一个 prototype 属性&#xff0c;指向另一个对象&#xff0c;所以我们也称为原型对象…...

    2024/5/1 14:33:22
  23. C++中只能有一个实例的单例类

    C中只能有一个实例的单例类 前面讨论的 President 类很不错&#xff0c;但存在一个缺陷&#xff1a;无法禁止通过实例化多个对象来创建多名总统&#xff1a; President One, Two, Three; 由于复制构造函数是私有的&#xff0c;其中每个对象都是不可复制的&#xff0c;但您的目…...

    2024/5/1 11:51:23
  24. python django 小程序图书借阅源码

    开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索图书&#xff0c;轮播图&#xff0…...

    2024/5/2 7:30:11
  25. 电子学会C/C++编程等级考试2022年03月(一级)真题解析

    C/C++等级考试(1~8级)全部真题・点这里 第1题:双精度浮点数的输入输出 输入一个双精度浮点数,保留8位小数,输出这个浮点数。 时间限制:1000 内存限制:65536输入 只有一行,一个双精度浮点数。输出 一行,保留8位小数的浮点数。样例输入 3.1415926535798932样例输出 3.1…...

    2024/5/1 20:56:20
  26. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  27. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  28. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  29. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  30. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  31. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  32. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  33. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  34. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  35. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  36. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  37. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  38. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  39. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  40. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  41. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  42. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  43. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  44. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  45. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57