??我們以2022年全國服務外包大賽的A03題目作為示例。
??問題的主要任務時找出商品的銷量異常和價格異常,提供4個月的商品信息數據,共1700萬余條,4個月的店鋪信息數據,共60萬余條,強調時間復雜度空間復雜度、異常值識別率和準確率。我們用店鋪分析輔助商品的異常,以提高可信度和準確率。
??店鋪部分數據鏈接:https://pan.baidu.com/s/1iAp-s2JwG_YTB35BevMNyQ 提取碼:jhnb
??但是由于數據分布多樣,異常店鋪往往和奢侈品店鋪以及火爆店鋪同時出現,大大降低了我們的準確率。因此我們擬采取如下幾個辦法解決:
聚類
??思路:
??這樣就算部分異常值被歸入奢侈品行列,依靠第三步類目索引也會回到大部分的本類店鋪所在類別,然后在異常值識別時被識別出來。相當于在總流程中添加了這一步:
??代碼如下:
import numpy
as np
import pandas
as pd
from matplotlib
import pyplot
as pltpd
.set_option
('display.max_columns', None)
from sklearn
.preprocessing
import MinMaxScaler
, StandardScaler
from sklearn
.cluster
import KMeans
def clustering(data
):col_sale_amount
= ["SHOP_SALES_AMOUNT_x", "Rate_amount", "MAIN_BUSINESS"]sc
= StandardScaler
().fit
(data
[col_sale_amount
]) data
[col_sale_amount
] = sc
.transform
(data
[col_sale_amount
])file_name
= "shop_sale_amount_cluster"SSE
(data
, col_sale_amount
, file_name
)k_sale_volumn
= 4df_cluster_result
= Kmeans
(data
, col_sale_amount
, k_sale_volumn
, file_name
)df_cluster_result
[col_sale_amount
] = sc
.inverse_transform
(df_cluster_result
[col_sale_amount
])df_cluster_result
= df_cluster_result
.sort_values
("index")for i
in range(k_sale_volumn
):df_cluster_result
[df_cluster_result
["volumn_cluster"] == i
].to_csv
(file_name
+ "/ cluster " + str(i
) + ".csv", encoding
="utf-8-sig")return df_cluster_result
def SSE(data
, col_name
, file_name
):SSE
= []left
= 2right
= 16for k
in range(left
, right
):km
= KMeans
(n_clusters
=k
)km
.fit
(data
[col_name
])SSE
.append
(km
.inertia_
)xx
= range(left
, right
)plt
.xlabel
("k")plt
.ylabel
("SSE")plt
.plot
(xx
, SSE
, "o-")plt
.savefig
(file_name
+ "\SSE " + ".png")plt
.clf
() def Kmeans(data
, col
, k
, file_name
):km
= KMeans
(n_clusters
=k
, random_state
=1129).fit
(data
[col
])data
["volumn_cluster"] = km
.labels_data
= data
.sort_values
(by
="volumn_cluster")plt
.rcParams
["font.size"] = 14colors
= np
.array
(["lightcoral", "pink", "lightsteelblue", "lightseagreen", "grey", "green", "yellow"])ele_x
= col
[0]ele_y
= col
[1]xx
= np
.array
(data
[ele_x
])yy
= np
.array
(data
[ele_y
])cc
= np
.array
(data
["volumn_cluster"])plt
.scatter
(xx
, yy
, c
=colors
[cc
], s
=2) plt
.xlabel
(ele_x
)plt
.ylabel
(ele_y
)plt
.savefig
(file_name
+"\K_Means " + ".png")plt
.show
()return data
def main():df_filled_featured
["MAIN_BUSINESS"] = df_filled_featured
["MAIN_BUSINESS"].apply(lambda x
: dict_MainBussiness
[x
])df_filled_featured_clustered
= clustering
(df_filled_featured
)print("初步聚類完畢!!!")wrong_in_price
(df_filled_featured_clustered_boxed
, mode
="slow")wrong_in_volumn
(df_filled_featured_clustered_boxed
, mode
="slow")if __name__
== '__main__':main
()
??關于為什么采取K-Means聚類而不是其他的聚類方法:
K-MEANS聚類的目的只是根據幾個特定的指標將商品分為多個種類,利于后面的模型實施與調參;其本意并非尋找離群點。異常值數量較少,對聚類中心影響有限。就算收到影響,大部分正常數據類別還是對的,所以我們根據主要業務索引回來,將被歸錯類的異常值放回本來屬于它的聚類。DBscan和DeBaCL等基于密度聚類算法在初期建樹過程中所需空間太大,最多就只能承受3w不到的數據,這對于我們60w+和1700w+的數據大小是非常不友好的。
??聚類結果:
??其中,聚類三四已經篩選出部分異常值變量了:
衍生變量設計
??為了區別異常店鋪和奢侈品店鋪,一種辦法是設計衍生變量,比如店鋪商品均價與產業商品均價的均價的比值等等,從這個角度設計衍生變量可以很大程度上緩解奢侈品行業店鋪在價格異常店鋪以及廉價商品店鋪在銷量異常店鋪中霸屏的現象。
??計算方法其實就是pandas的熟練應用,在此不贅述,可以參考這篇博客:https://blog.csdn.net/Hjh1906008151/article/details/124330708
設置初篩
??有點像上一個解決方法,其實就是找一個切入點。因為我們的目標是尋找銷量異常和價格異常,這兩種異常在很大程度上會導致銷售額增多,因此我們可以考慮設置一個銷售額異常作為初篩。這部分的思路的要點就是尋找兩種異常的共性。
修改損失函數
??如果這部分有用到神經網絡等方法,個人認為可以采取這個辦法。因為異常值的加入會導致神經網絡在學習時學到不好的特征,要知道數據集數據有問題在神經網絡訓練中的后果是災難性的,為了緩解這個問題,可以采用 Minkowski error平滑異常值帶來的影響,效果如下:
??優化損失函數之后:
總結
以上是生活随笔為你收集整理的多种方法(聚类、衍生变量、多重筛选、损失函数)解决解决异常值识别效果不佳问题(含2022年全国服务外包大赛实例)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。