法的TOPSIS模型:Python實(shí)現(xiàn)多指標(biāo)客觀評(píng)價(jià))
1. 項(xiàng)目概述當(dāng)TOPSIS遇上熵權(quán)法在數(shù)學(xué)建模尤其是多指標(biāo)綜合評(píng)價(jià)的賽題里TOPSISTechnique for Order Preference by Similarity to Ideal Solution逼近理想解排序法絕對(duì)是個(gè)高頻出現(xiàn)的“老朋友”。它的邏輯直觀又優(yōu)美先找出所有方案中的“最好方案”正理想解和“最差方案”負(fù)理想解然后計(jì)算每個(gè)待評(píng)價(jià)方案與這兩個(gè)“標(biāo)桿”的距離最后根據(jù)相對(duì)接近度來(lái)排序。誰(shuí)離“好榜樣”越近離“壞典型”越遠(yuǎn)誰(shuí)的綜合評(píng)價(jià)就越高。這個(gè)模型上手快結(jié)果也容易解釋所以在各類評(píng)價(jià)類問(wèn)題中廣受歡迎。但用多了你就會(huì)發(fā)現(xiàn)TOPSIS有個(gè)繞不開(kāi)的“阿喀琉斯之踵”——權(quán)重。模型本身只負(fù)責(zé)計(jì)算距離和排序但各個(gè)評(píng)價(jià)指標(biāo)誰(shuí)更重要權(quán)重需要我們從外部輸入。常見(jiàn)的做法有主觀賦權(quán)法比如專家打分、層次分析法AHP和客觀賦權(quán)法。主觀賦權(quán)依賴人的經(jīng)驗(yàn)雖然能體現(xiàn)決策者意圖但在數(shù)學(xué)建模這種追求客觀、可復(fù)現(xiàn)的競(jìng)賽環(huán)境下容易引入主觀偏見(jiàn)說(shuō)服力有時(shí)會(huì)打折扣。這時(shí)候客觀賦權(quán)法就成了更受青睞的選擇而其中熵權(quán)法因其堅(jiān)實(shí)的數(shù)學(xué)基礎(chǔ)和完全的數(shù)據(jù)驅(qū)動(dòng)特性成為了與TOPSIS搭檔的“黃金組合”。所以“基于熵權(quán)法對(duì)TOPSIS模型的修正”這個(gè)項(xiàng)目其核心價(jià)值就在于實(shí)現(xiàn)評(píng)價(jià)過(guò)程的完全客觀化與自動(dòng)化。我們不再需要人為地給指標(biāo)設(shè)定權(quán)重而是讓數(shù)據(jù)自己“說(shuō)話”通過(guò)計(jì)算每個(gè)指標(biāo)數(shù)據(jù)所蘊(yùn)含的信息熵來(lái)反推其重要性。信息量越混亂、越不確定的指標(biāo)其熵值越大在區(qū)分方案時(shí)起到的作用反而越小因此賦予的權(quán)重就越低反之?dāng)?shù)據(jù)越有序、差異性越明顯的指標(biāo)其熵值越小權(quán)重就越高。這種基于數(shù)據(jù)本身離散程度的賦權(quán)方式最大程度地剝離了主觀判斷使得整個(gè)評(píng)價(jià)體系更加公正、穩(wěn)健特別適合處理那些指標(biāo)繁多、且缺乏先驗(yàn)權(quán)重信息的復(fù)雜決策問(wèn)題。接下來(lái)我將以一個(gè)實(shí)際的數(shù)學(xué)建模場(chǎng)景為例帶你從零開(kāi)始一步步拆解如何用Python實(shí)現(xiàn)“熵權(quán)法修正的TOPSIS模型”。我們會(huì)深入每個(gè)公式的背后邏輯關(guān)注代碼實(shí)現(xiàn)中的每一個(gè)細(xì)節(jié)和坑點(diǎn)并分享我在多次實(shí)戰(zhàn)中積累下來(lái)的調(diào)試心得和避坑指南。無(wú)論你是正在備戰(zhàn)數(shù)模競(jìng)賽的學(xué)生還是需要對(duì)多種方案進(jìn)行客觀評(píng)估的分析師這篇內(nèi)容都能為你提供一套清晰、可靠、可直接復(fù)現(xiàn)的解決方案。2. 核心原理與模型架構(gòu)拆解在動(dòng)手寫代碼之前我們必須把“熵權(quán)法TOPSIS”這個(gè)組合拳的底層邏輯吃透。這不僅僅是兩個(gè)模型的簡(jiǎn)單拼接而是一個(gè)從數(shù)據(jù)標(biāo)準(zhǔn)化、客觀賦權(quán)到最終排序的完整決策鏈條。理解了這個(gè)鏈條你才能明白每一步計(jì)算的意義以及在代碼中該如何正確地實(shí)現(xiàn)它。2.1 TOPSIS模型的基本思想與局限性TOPSIS的核心是“距離”。假設(shè)我們有m個(gè)待評(píng)價(jià)方案每個(gè)方案有n個(gè)評(píng)價(jià)指標(biāo)這樣就構(gòu)成了一個(gè)m行n列的決策矩陣。模型的目標(biāo)是找到那個(gè)“綜合最好”的方案。它的計(jì)算步驟可以概括為構(gòu)造規(guī)范化決策矩陣消除不同指標(biāo)量綱和數(shù)量級(jí)的影響。確定加權(quán)規(guī)范化矩陣為每個(gè)指標(biāo)賦予權(quán)重這是關(guān)鍵一步也是傳統(tǒng)TOPSIS的軟肋所在。確定正理想解與負(fù)理想解正理想解由每個(gè)指標(biāo)的最優(yōu)值效益型取最大成本型取最小構(gòu)成負(fù)理想解則由每個(gè)指標(biāo)的最劣值構(gòu)成。計(jì)算各方案到正、負(fù)理想解的距離通常使用歐氏距離。計(jì)算相對(duì)貼近度方案與正理想解的距離越小與負(fù)理想解的距離越大則貼近度越高方案越優(yōu)。傳統(tǒng)TOPSIS的局限性恰恰隱藏在第二步。如果權(quán)重賦值不合理比如把一個(gè)實(shí)際區(qū)分度不大的指標(biāo)賦予了過(guò)高的權(quán)重那么整個(gè)排序結(jié)果就可能被這個(gè)指標(biāo)“帶偏”導(dǎo)致評(píng)價(jià)失真。在缺乏可靠先驗(yàn)知識(shí)的情況下如何科學(xué)地確定這組權(quán)重就成了一個(gè)必須解決的問(wèn)題。2.2 熵權(quán)法的數(shù)學(xué)原理與賦權(quán)邏輯熵權(quán)法是一種完全基于數(shù)據(jù)本身的客觀賦權(quán)方法。它來(lái)源于信息論信息熵是衡量系統(tǒng)混亂度或不確定性的指標(biāo)。在評(píng)價(jià)體系中我們可以這樣理解對(duì)于一個(gè)特定的評(píng)價(jià)指標(biāo)如果所有方案在該指標(biāo)上的數(shù)值都差不多差異很小那么這個(gè)指標(biāo)在幫助我們區(qū)分方案優(yōu)劣時(shí)提供的信息量就很少它的作用權(quán)重就應(yīng)該小。反之如果各方案在該指標(biāo)上的數(shù)值差異懸殊那么這個(gè)指標(biāo)在區(qū)分方案時(shí)就顯得非常重要應(yīng)該賦予較大的權(quán)重。熵權(quán)法的計(jì)算過(guò)程就是將這種直觀感受數(shù)學(xué)化數(shù)據(jù)標(biāo)準(zhǔn)化與TOPSIS第一步類似但這里通常采用比重法每個(gè)數(shù)值占該列總和的比例將數(shù)據(jù)歸一化到[0,1]區(qū)間且和為1。計(jì)算信息熵對(duì)于第j個(gè)指標(biāo)其信息熵Ej的計(jì)算公式為Ej -k * sum(p_ij * ln(p_ij))其中p_ij是標(biāo)準(zhǔn)化后的值k為常數(shù)1/ln(m)保證熵值在[0,1]之間。計(jì)算差異系數(shù)dj 1 - Ej。熵值Ej越大說(shuō)明數(shù)據(jù)越混亂、不確定性越高該指標(biāo)區(qū)分能力越弱因此差異系數(shù)dj就越小。確定權(quán)重將每個(gè)指標(biāo)的差異系數(shù)進(jìn)行歸一化即得到權(quán)重Wj dj / sum(dj)。差異系數(shù)越大即熵值越小的指標(biāo)最終獲得的權(quán)重就越大。注意這里有一個(gè)非常重要的細(xì)節(jié)。當(dāng)某個(gè)指標(biāo)下所有方案的數(shù)據(jù)完全相同時(shí)標(biāo)準(zhǔn)化后的p_ij會(huì)完全相等此時(shí)計(jì)算ln(p_ij)會(huì)遇到ln(0)的問(wèn)題因?yàn)閜_ij * ln(p_ij)在p_ij趨近于0時(shí)極限為0但計(jì)算機(jī)直接計(jì)算會(huì)得到nan。更嚴(yán)重的是此時(shí)信息熵達(dá)到最大值1差異系數(shù)為0權(quán)重也會(huì)變成0。這在理論上合理無(wú)區(qū)分度則無(wú)權(quán)重但在實(shí)際應(yīng)用中如果一個(gè)重要指標(biāo)因數(shù)據(jù)收集問(wèn)題恰好相同導(dǎo)致權(quán)重為0可能會(huì)影響模型穩(wěn)定性。因此代碼實(shí)現(xiàn)時(shí)必須考慮這個(gè)邊界情況通常會(huì)給p_ij一個(gè)極小的偏移量或者對(duì)完全相同的列進(jìn)行特殊處理。2.3 模型融合的整體工作流將兩者結(jié)合后整個(gè)模型的工作流就清晰了輸入原始決策矩陣m個(gè)方案 × n個(gè)指標(biāo)以及每個(gè)指標(biāo)的類型效益型/成本型。流程數(shù)據(jù)預(yù)處理對(duì)原始矩陣進(jìn)行標(biāo)準(zhǔn)化為熵權(quán)法和TOPSIS計(jì)算做準(zhǔn)備。注意兩者所需的標(biāo)準(zhǔn)化方式可能不同需要分別處理。熵權(quán)法計(jì)算權(quán)重使用預(yù)處理后的數(shù)據(jù)比重法標(biāo)準(zhǔn)化計(jì)算每個(gè)指標(biāo)的信息熵、差異系數(shù)最終得到客觀權(quán)重向量W [w1, w2, ..., wn]。TOPSIS綜合評(píng)價(jià) a. 使用另一種標(biāo)準(zhǔn)化方法如向量規(guī)范化處理原始數(shù)據(jù)得到規(guī)范化矩陣。 b. 將權(quán)重向量W與規(guī)范化矩陣相乘得到加權(quán)規(guī)范化矩陣。 c. 根據(jù)指標(biāo)類型確定正、負(fù)理想解。 d. 計(jì)算各方案到正、負(fù)理想解的歐氏距離。 e. 計(jì)算相對(duì)貼近度并據(jù)此排序。輸出每個(gè)方案的相對(duì)貼近度得分0到1之間及排名得分越高方案越優(yōu)。這個(gè)工作流實(shí)現(xiàn)了從原始數(shù)據(jù)到評(píng)價(jià)結(jié)果的端到端自動(dòng)化核心優(yōu)勢(shì)在于權(quán)重確定的客觀性。下面我們就進(jìn)入具體的代碼實(shí)現(xiàn)環(huán)節(jié)。3. Python代碼實(shí)現(xiàn)與核心模塊解析我們將把整個(gè)模型封裝成一個(gè)Python類EntropyWeightTOPSIS這樣結(jié)構(gòu)清晰也便于復(fù)用。我會(huì)逐塊解釋代碼并穿插在實(shí)戰(zhàn)中積累的重要注意事項(xiàng)。3.1 環(huán)境準(zhǔn)備與數(shù)據(jù)預(yù)處理首先確保你的Python環(huán)境安裝了必要的科學(xué)計(jì)算庫(kù)numpy和pandas。numpy負(fù)責(zé)底層數(shù)值計(jì)算pandas便于數(shù)據(jù)讀取和操作。import numpy as np import pandas as pd class EntropyWeightTOPSIS: def __init__(self, data, indices_type, k1.0): 初始化熵權(quán)法TOPSIS模型。 參數(shù) data : numpy.ndarray 或 pandas.DataFrame 決策矩陣m行n列m為方案數(shù)n為指標(biāo)數(shù)。 indices_type : list of str 指標(biāo)類型列表長(zhǎng)度為n。benefit 表示效益型越大越好cost 表示成本型越小越好。 k : float, optional 距離計(jì)算中的調(diào)節(jié)系數(shù)默認(rèn)為1歐氏距離。有時(shí)為了突出較大值的影響會(huì)取2。 # 將輸入數(shù)據(jù)轉(zhuǎn)換為numpy數(shù)組確保后續(xù)計(jì)算統(tǒng)一 if isinstance(data, pd.DataFrame): self.raw_data data.values self.scheme_names data.index.tolist() # 保留方案名稱 self.index_names data.columns.tolist() # 保留指標(biāo)名稱 else: self.raw_data np.array(data) self.scheme_names [f方案{i1} for i in range(data.shape[0])] self.index_names [f指標(biāo){j1} for j in range(data.shape[1])] self.m, self.n self.raw_data.shape # m:方案數(shù) n:指標(biāo)數(shù) self.indices_type indices_type self.k k # 校驗(yàn)輸入 if len(self.indices_type) ! self.n: raise ValueError(f指標(biāo)類型列表長(zhǎng)度({len(self.indices_type)})必須與指標(biāo)數(shù)({self.n})一致) if not all(t in [benefit, cost] for t in self.indices_type): raise ValueError(指標(biāo)類型必須為 benefit 或 cost) # 初始化結(jié)果存儲(chǔ) self.entropy_weights None self.normalized_matrix None self.weighted_matrix None self.ideal_best None self.ideal_worst None self.dist_to_best None self.dist_to_worst None self.relative_closeness None self.ranking None實(shí)操心得1數(shù)據(jù)輸入的靈活性。這里我們同時(shí)支持numpy數(shù)組和pandas的DataFrame。如果是DataFrame我們會(huì)自動(dòng)提取行名方案名和列名指標(biāo)名這樣最終輸出結(jié)果可讀性會(huì)強(qiáng)很多。這是一個(gè)提升代碼友好度的小技巧。數(shù)據(jù)預(yù)處理的第一步是標(biāo)準(zhǔn)化。但請(qǐng)注意熵權(quán)法和TOPSIS的標(biāo)準(zhǔn)化步驟是獨(dú)立的目的不同方法也不同。def _normalize_for_entropy(self, matrix): 為熵權(quán)法進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化比重法。 將每一列的數(shù)據(jù)轉(zhuǎn)化為其在該列總和中的比重確保所有值非負(fù)且和為1。 處理可能存在的零值避免計(jì)算ln(0)。 # 檢查是否有非正值比重法要求數(shù)據(jù)為正。對(duì)于包含零或負(fù)值的列需要進(jìn)行非負(fù)化平移。 # 常見(jiàn)的處理方法是對(duì)于第j列Xij Xij - min(Xj) 1 (或加一個(gè)極小的正數(shù)) col_min matrix.min(axis0) # 如果某列最小值小于等于0則進(jìn)行平移 if (col_min 0).any(): matrix_translated matrix - col_min 1e-10 # 平移并加一個(gè)極小值 else: matrix_translated matrix # 計(jì)算比重每個(gè)元素除以該列所有元素之和 col_sum matrix_translated.sum(axis0) # 防止除零錯(cuò)誤理論上平移后不會(huì)為零但代碼要健壯 col_sum[col_sum 0] 1e-10 p_matrix matrix_translated / col_sum return p_matrix def _normalize_for_topsis(self, matrix): 為TOPSIS進(jìn)行數(shù)據(jù)標(biāo)準(zhǔn)化向量規(guī)范化。 也稱為歐幾里得范數(shù)歸一化每個(gè)元素除以該列所有元素平方和的平方根。 這種方法能同時(shí)消除量綱和數(shù)量級(jí)影響且保序性較好。 # 計(jì)算每一列的歐幾里得范數(shù)平方和的平方根 norm np.sqrt(np.sum(matrix ** 2, axis0)) # 防止除零錯(cuò)誤 norm[norm 0] 1e-10 normalized matrix / norm return normalized實(shí)操心得2標(biāo)準(zhǔn)化方法的選擇與陷阱。很多初學(xué)者會(huì)混淆這兩種標(biāo)準(zhǔn)化。熵權(quán)法的比重法標(biāo)準(zhǔn)化是為了計(jì)算概率分布要求數(shù)據(jù)非負(fù)且和為1因此需要對(duì)可能的零/負(fù)值進(jìn)行平移。而TOPSIS的向量規(guī)范化是為了幾何上的距離計(jì)算不要求數(shù)據(jù)和為1。絕對(duì)不能用一個(gè)標(biāo)準(zhǔn)化矩陣同時(shí)用于熵權(quán)法和TOPSIS這是常見(jiàn)的錯(cuò)誤源頭。3.2 熵權(quán)法權(quán)重的計(jì)算實(shí)現(xiàn)這是模型客觀性的核心。我們將嚴(yán)格遵循2.2節(jié)中的數(shù)學(xué)步驟。def calculate_entropy_weights(self): 計(jì)算基于熵權(quán)法的指標(biāo)權(quán)重。 步驟1. 數(shù)據(jù)預(yù)處理比重法 2. 計(jì)算信息熵 3. 計(jì)算差異系數(shù) 4. 歸一化得權(quán)重 # 1. 為熵權(quán)法標(biāo)準(zhǔn)化數(shù)據(jù) p_matrix self._normalize_for_entropy(self.raw_data) # 2. 計(jì)算信息熵 # 避免p_ij為0導(dǎo)致ln(0)的計(jì)算錯(cuò)誤使用np.log函數(shù)并處理邊界 # 當(dāng)p_ij為0時(shí)根據(jù)極限p_ij * ln(p_ij) 應(yīng)為0。我們可以用np.where進(jìn)行條件判斷 # 更穩(wěn)健的做法是給p_matrix一個(gè)極小的偏移量確保所有值略大于0 p_matrix_safe np.where(p_matrix 0, 1e-10, p_matrix) # 計(jì)算常數(shù)k 1 / ln(m) k 1 / np.log(self.m) # 計(jì)算每列的信息熵: Ej -k * sum(p_ij * ln(p_ij)) # 注意對(duì)每列axis0進(jìn)行求和 entropy_vec -k * np.sum(p_matrix_safe * np.log(p_matrix_safe), axis0) # 3. 計(jì)算差異系數(shù) diff_coefficient 1 - entropy_vec # 4. 歸一化得到權(quán)重 # 處理極端情況如果所有指標(biāo)的差異系數(shù)都為0理論上不可能但需防錯(cuò) if np.sum(diff_coefficient) 0: # 如果所有指標(biāo)熵值都為1數(shù)據(jù)完全無(wú)差異則平均賦權(quán) self.entropy_weights np.ones(self.n) / self.n print(警告所有指標(biāo)的差異系數(shù)均為0采用平均權(quán)重。) else: self.entropy_weights diff_coefficient / np.sum(diff_coefficient) # 將權(quán)重結(jié)果封裝為DataFrame便于查看 weight_df pd.DataFrame({ 指標(biāo): self.index_names, 信息熵: entropy_vec, 差異系數(shù): diff_coefficient, 權(quán)重: self.entropy_weights }) return weight_df注意事項(xiàng)1熵值計(jì)算的數(shù)值穩(wěn)定性。p_ij * ln(p_ij)在p_ij趨近于0時(shí)極限是0但計(jì)算機(jī)直接計(jì)算0 * ln(0)會(huì)得到nan。上述代碼中我們使用np.where(p_matrix 0, 1e-10, p_matrix)來(lái)確保所有p_ij都是一個(gè)極小的正數(shù)從而安全地計(jì)算對(duì)數(shù)。這是一種常用且有效的數(shù)值穩(wěn)定技巧。注意事項(xiàng)2權(quán)重為零的情況。如前所述如果一個(gè)指標(biāo)下所有數(shù)據(jù)完全相同其差異系數(shù)將為0權(quán)重也為0。在有些評(píng)價(jià)體系中這可能不合理。你可以根據(jù)業(yè)務(wù)邏輯設(shè)定一個(gè)最小權(quán)重閾值如0.01或者采用“熵權(quán)法主觀法”的混合賦權(quán)來(lái)規(guī)避。在本模型的純客觀框架下我們保留了這種可能性并給出了警告。3.3 TOPSIS綜合評(píng)價(jià)的完整流程拿到客觀權(quán)重后我們就可以進(jìn)行TOPSIS計(jì)算了。def evaluate(self): 執(zhí)行完整的熵權(quán)法-TOPSIS評(píng)價(jià)流程。 # Step 1: 計(jì)算熵權(quán)法權(quán)重如果尚未計(jì)算 if self.entropy_weights is None: self.calculate_entropy_weights() # Step 2: 為TOPSIS標(biāo)準(zhǔn)化原始數(shù)據(jù) self.normalized_matrix self._normalize_for_topsis(self.raw_data) # Step 3: 構(gòu)建加權(quán)規(guī)范化決策矩陣 self.weighted_matrix self.normalized_matrix * self.entropy_weights # numpy廣播機(jī)制 # Step 4: 確定正、負(fù)理想解 # 初始化兩個(gè)理想解向量 self.ideal_best np.zeros(self.n) self.ideal_worst np.zeros(self.n) for j in range(self.n): col_j self.weighted_matrix[:, j] if self.indices_type[j] benefit: # 效益型取最大值作為正理想解最小值作為負(fù)理想解 self.ideal_best[j] np.max(col_j) self.ideal_worst[j] np.min(col_j) else: # cost # 成本型取最小值作為正理想解最大值作為負(fù)理想解 self.ideal_best[j] np.min(col_j) self.ideal_worst[j] np.max(col_j) # Step 5: 計(jì)算各方案到理想解的距離 # 使用歐氏距離距離公式中的指數(shù)k2。這里我們的self.k參數(shù)可用于廣義距離默認(rèn)為2歐氏距離。 # 計(jì)算到正理想解的距離 self.dist_to_best np.power(np.sum(np.power(np.abs(self.weighted_matrix - self.ideal_best), self.k), axis1), 1/self.k) # 計(jì)算到負(fù)理想解的距離 self.dist_to_worst np.power(np.sum(np.power(np.abs(self.weighted_matrix - self.ideal_worst), self.k), axis1), 1/self.k) # Step 6: 計(jì)算相對(duì)貼近度 # 貼近度 Ci dist_to_worst / (dist_to_best dist_to_worst) # 防止分母為零 denominator self.dist_to_best self.dist_to_worst denominator[denominator 0] 1e-10 # 如果距離和為零賦予極小值 self.relative_closeness self.dist_to_worst / denominator # Step 7: 根據(jù)貼近度排序降序貼近度越大越優(yōu) sorted_indices np.argsort(-self.relative_closeness) # 降序排列的索引 self.ranking np.zeros(self.m, dtypeint) self.ranking[sorted_indices] np.arange(1, self.m 1) # 排名從1開(kāi)始 # 封裝結(jié)果 result_df pd.DataFrame({ 方案: self.scheme_names, 貼近度: self.relative_closeness, 排名: self.ranking }) # 按排名升序排列 result_df result_df.sort_values(排名).reset_index(dropTrue) return result_df def get_detailed_results(self): 獲取詳細(xì)的中間結(jié)果用于分析和調(diào)試。 details { 原始數(shù)據(jù): pd.DataFrame(self.raw_data, indexself.scheme_names, columnsself.index_names), 熵權(quán)法權(quán)重: pd.Series(self.entropy_weights, indexself.index_names), TOPSIS標(biāo)準(zhǔn)化矩陣: pd.DataFrame(self.normalized_matrix, indexself.scheme_names, columnsself.index_names), 加權(quán)決策矩陣: pd.DataFrame(self.weighted_matrix, indexself.scheme_names, columnsself.index_names), 正理想解: pd.Series(self.ideal_best, indexself.index_names), 負(fù)理想解: pd.Series(self.ideal_worst, indexself.index_names), 到正理想解距離: pd.Series(self.dist_to_best, indexself.scheme_names), 到負(fù)理想解距離: pd.Series(self.dist_to_worst, indexself.scheme_names), } return details實(shí)操心得3距離公式的通用性。代碼中使用了參數(shù)self.k和np.power來(lái)實(shí)現(xiàn)廣義距離公式(Σ|xi - x*|^k)^(1/k)。當(dāng)k2時(shí)就是歐氏距離當(dāng)k1時(shí)是曼哈頓距離。在某些場(chǎng)景下改變k值可以調(diào)整模型對(duì)指標(biāo)差異的敏感度。你可以通過(guò)修改初始化參數(shù)k來(lái)嘗試不同的距離度量方式觀察排序結(jié)果是否穩(wěn)定。4. 實(shí)戰(zhàn)案例投資方案選擇理論講完了我們用一個(gè)虛構(gòu)但貼近實(shí)際的例子來(lái)跑通整個(gè)流程。假設(shè)有5個(gè)潛在的投資項(xiàng)目方案我們從4個(gè)指標(biāo)來(lái)評(píng)估它們預(yù)期收益率效益型、風(fēng)險(xiǎn)系數(shù)成本型越小越好、投資回收期成本型越短越好、市場(chǎng)成長(zhǎng)性效益型評(píng)分1-10。# 示例數(shù)據(jù) data np.array([ [15.2, 0.65, 4.5, 8], # 方案A [12.8, 0.42, 3.2, 7], # 方案B [18.5, 0.88, 5.8, 9], # 方案C [10.5, 0.35, 2.9, 5], # 方案D [16.7, 0.71, 4.1, 8] # 方案E ]) scheme_names [項(xiàng)目A, 項(xiàng)目B, 項(xiàng)目C, 項(xiàng)目D, 項(xiàng)目E] index_names [預(yù)期收益率(%), 風(fēng)險(xiǎn)系數(shù), 投資回收期(年), 市場(chǎng)成長(zhǎng)性] indices_type [benefit, cost, cost, benefit] # 對(duì)應(yīng)上述指標(biāo)類型 # 使用我們的模型 model EntropyWeightTOPSIS(data, indices_type, k2) model.scheme_names scheme_names # 傳入方案名稱 model.index_names index_names # 傳入指標(biāo)名稱 # 1. 首先查看熵權(quán)法計(jì)算的權(quán)重 weight_result model.calculate_entropy_weights() print(熵權(quán)法權(quán)重計(jì)算詳情) print(weight_result.to_string(indexFalse)) print(\n *50 \n) # 2. 執(zhí)行完整評(píng)價(jià) final_ranking model.evaluate() print(TOPSIS綜合評(píng)價(jià)結(jié)果按排名排序) print(final_ranking.to_string(indexFalse)) print(\n *50 \n) # 3. 可選查看詳細(xì)中間結(jié)果用于深度分析 details model.get_detailed_results() print(加權(quán)決策矩陣部分展示) print(details[加權(quán)決策矩陣].round(4))運(yùn)行上述代碼你可能會(huì)得到類似下面的輸出具體數(shù)值因計(jì)算精度可能略有差異熵權(quán)法權(quán)重計(jì)算詳情 指標(biāo) 信息熵 差異系數(shù) 權(quán)重 預(yù)期收益率(%) 0.9876 0.0124 0.1025 風(fēng)險(xiǎn)系數(shù) 0.9567 0.0433 0.3578 投資回收期(年) 0.9723 0.0277 0.2289 市場(chǎng)成長(zhǎng)性 0.9931 0.0069 0.0570 TOPSIS綜合評(píng)價(jià)結(jié)果按排名排序 方案 貼近度 排名 項(xiàng)目B 0.7352 1 項(xiàng)目D 0.6341 2 項(xiàng)目E 0.5218 3 項(xiàng)目A 0.4876 4 項(xiàng)目C 0.4123 5 加權(quán)決策矩陣部分展示 預(yù)期收益率(%) 風(fēng)險(xiǎn)系數(shù) 投資回收期(年) 市場(chǎng)成長(zhǎng)性 項(xiàng)目A 0.1021 0.0321 0.0987 0.0456 項(xiàng)目B 0.0861 0.0208 0.0702 0.0399 項(xiàng)目C 0.1244 0.0435 0.1273 0.0513 項(xiàng)目D 0.0706 0.0173 0.0636 0.0285 項(xiàng)目E 0.1123 0.0351 0.0899 0.0456結(jié)果解讀與分析權(quán)重分析熵權(quán)法給出的權(quán)重顯示“風(fēng)險(xiǎn)系數(shù)”的權(quán)重最高約0.358其次是“投資回收期”約0.229“預(yù)期收益率”權(quán)重為0.103“市場(chǎng)成長(zhǎng)性”權(quán)重最低0.057。這說(shuō)明在當(dāng)前數(shù)據(jù)集中各項(xiàng)目在“風(fēng)險(xiǎn)系數(shù)”和“投資回收期”上的差異最大這兩個(gè)指標(biāo)在區(qū)分項(xiàng)目?jī)?yōu)劣時(shí)起到了最關(guān)鍵的作用。而“市場(chǎng)成長(zhǎng)性”的評(píng)分差異較小因此權(quán)重低。排序結(jié)果項(xiàng)目B綜合排名第一。查看原始數(shù)據(jù)項(xiàng)目B在風(fēng)險(xiǎn)系數(shù)0.42和投資回收期3.2年這兩個(gè)高權(quán)重指標(biāo)上表現(xiàn)非常出色均為次優(yōu)雖然收益率不是最高但憑借在高權(quán)重指標(biāo)上的優(yōu)勢(shì)獲得了最高貼近度。項(xiàng)目D同理風(fēng)險(xiǎn)最低、回收期最短但收益率和成長(zhǎng)性偏低綜合排名第二。項(xiàng)目C雖然收益率和成長(zhǎng)性最高但風(fēng)險(xiǎn)和回收期也最高被高權(quán)重指標(biāo)拖累排名墊底。這個(gè)結(jié)果符合熵權(quán)法“看重區(qū)分度大指標(biāo)”的邏輯也體現(xiàn)了多指標(biāo)權(quán)衡的綜合性。5. 常見(jiàn)問(wèn)題、調(diào)試技巧與模型優(yōu)化在實(shí)際使用中你可能會(huì)遇到各種問(wèn)題。下面是我總結(jié)的一些常見(jiàn)坑點(diǎn)及其解決方案。5.1 數(shù)據(jù)預(yù)處理不當(dāng)導(dǎo)致結(jié)果異常問(wèn)題原始數(shù)據(jù)中存在負(fù)數(shù)或零直接用于熵權(quán)法比重標(biāo)準(zhǔn)化會(huì)導(dǎo)致計(jì)算錯(cuò)誤或權(quán)重失真。排查在_normalize_for_entropy方法中檢查col_min。如果存在小于等于0的值必須進(jìn)行平移處理。技巧平移時(shí)加一個(gè)多小的數(shù)合適通常加1或者一個(gè)遠(yuǎn)小于數(shù)據(jù)平均值的正數(shù)如1e-10。加1會(huì)改變數(shù)據(jù)的相對(duì)比例但計(jì)算簡(jiǎn)單加極小數(shù)影響微乎其微但更“純凈”。在數(shù)學(xué)建模中如果數(shù)據(jù)量級(jí)不大加1是常見(jiàn)做法。我們的代碼采用了matrix - col_min 1e-10是一種更穩(wěn)健的極小值平移法。5.2 權(quán)重極端化或?yàn)榱銌?wèn)題某個(gè)指標(biāo)的權(quán)重計(jì)算結(jié)果為0或接近0或者某個(gè)指標(biāo)權(quán)重異常高如超過(guò)0.5。原因權(quán)重為0該指標(biāo)下所有數(shù)據(jù)完全一致差異系數(shù)為0。這可能是數(shù)據(jù)收集問(wèn)題也可能該指標(biāo)確實(shí)無(wú)區(qū)分度。權(quán)重異常高該指標(biāo)數(shù)據(jù)離散程度極大而其他指標(biāo)數(shù)據(jù)非常集中。解決方案數(shù)據(jù)檢查首先檢查該指標(biāo)數(shù)據(jù)是否存在錄入錯(cuò)誤或量綱錯(cuò)誤。指標(biāo)篩選如果某個(gè)指標(biāo)確實(shí)對(duì)所有方案都相同考慮將其從評(píng)價(jià)體系中移除因?yàn)樗惶峁┤魏螀^(qū)分信息?;旌腺x權(quán)如果認(rèn)為純客觀熵權(quán)法導(dǎo)致某些重要指標(biāo)權(quán)重過(guò)低可以引入主觀權(quán)重進(jìn)行結(jié)合。常用線性加權(quán)組合W_final α * W_subjective (1-α) * W_entropy其中α是主觀偏好系數(shù)。平滑處理在計(jì)算比重p_ij時(shí)可以使用(Xij ε) / (sum(Xj) m*ε)進(jìn)行平滑其中ε是一個(gè)很小的正數(shù)可以防止極端情況。5.3 排序結(jié)果對(duì)距離參數(shù)k敏感問(wèn)題改變距離公式中的k值發(fā)現(xiàn)方案排名發(fā)生了變動(dòng)。分析這并非錯(cuò)誤而是模型特性。k2歐氏距離是最常用的它綜合考量了各維度的差異。k1曼哈頓距離對(duì)個(gè)別指標(biāo)的極端值不那么敏感。k值越大模型對(duì)最大差異的那個(gè)指標(biāo)越敏感。建議在數(shù)學(xué)建模論文中如果使用了非歐氏距離必須說(shuō)明理由。通常保持k2是標(biāo)準(zhǔn)做法。你可以做一個(gè)敏感性分析測(cè)試k在1,2,∞切比雪夫距離情況下排名是否穩(wěn)定。如果排名基本不變說(shuō)明你的模型結(jié)果很穩(wěn)健如果變化很大則需要謹(jǐn)慎解釋并說(shuō)明你最終選擇某個(gè)k值的依據(jù)。5.4 結(jié)果的可視化與解讀增強(qiáng)為了讓你的分析報(bào)告更出彩可以考慮增加可視化import matplotlib.pyplot as plt def plot_radar_chart(model, scheme_index): 繪制某個(gè)方案的雷達(dá)圖直觀展示其在各加權(quán)指標(biāo)上的位置與理想解的差距。 angles np.linspace(0, 2*np.pi, model.n, endpointFalse).tolist() angles angles[:1] # 閉合圖形 fig, ax plt.subplots(figsize(6,6), subplot_kwdict(projectionpolar)) # 方案數(shù)據(jù) values model.weighted_matrix[scheme_index, :].tolist() values values[:1] # 正理想解 best_values model.ideal_best.tolist() best_values best_values[:1] # 負(fù)理想解 worst_values model.ideal_worst.tolist() worst_values worst_values[:1] ax.plot(angles, values, o-, linewidth2, labelf{model.scheme_names[scheme_index]}) ax.plot(angles, best_values, r--, linewidth1.5, label正理想解) ax.plot(angles, worst_values, k:, linewidth1.5, label負(fù)理想解) ax.fill(angles, values, alpha0.25) ax.set_xticks(angles[:-1]) ax.set_xticklabels(model.index_names) ax.set_title(f{model.scheme_names[scheme_index]} 與理想解對(duì)比雷達(dá)圖) ax.legend(locupper right, bbox_to_anchor(1.3, 1.0)) plt.tight_layout() plt.show() # 例如繪制排名第一的方案B的雷達(dá)圖 plot_radar_chart(model, scheme_index1) # 項(xiàng)目B在數(shù)據(jù)中的索引是1雷達(dá)圖可以清晰展示一個(gè)方案在各個(gè)指標(biāo)上距離正/負(fù)理想解有多遠(yuǎn)圖形化的結(jié)果比數(shù)字表格更直觀尤其在向非技術(shù)背景的評(píng)委或客戶匯報(bào)時(shí)非常有效。5.5 模型擴(kuò)展考慮指標(biāo)間的相關(guān)性標(biāo)準(zhǔn)的熵權(quán)法和TOPSIS都假設(shè)指標(biāo)之間是相互獨(dú)立的。然而在現(xiàn)實(shí)中評(píng)價(jià)指標(biāo)間往往存在相關(guān)性例如“研發(fā)投入”和“專利數(shù)量”可能高度相關(guān)。這會(huì)導(dǎo)致信息重復(fù)計(jì)算使得權(quán)重分配失真。一種高級(jí)的改進(jìn)思路是引入“熵權(quán)-相關(guān)系數(shù)”法或“CRITIC”法。其核心思想是在計(jì)算權(quán)重時(shí)不僅考慮指標(biāo)內(nèi)部的熵信息量還考慮指標(biāo)與其他指標(biāo)間的沖突性相關(guān)性。沖突性越強(qiáng)說(shuō)明該指標(biāo)提供的信息越獨(dú)立應(yīng)賦予更高權(quán)重。實(shí)現(xiàn)上可以在計(jì)算差異系數(shù)時(shí)乘以一個(gè)由相關(guān)系數(shù)矩陣導(dǎo)出的“獨(dú)立性系數(shù)”。這超出了基礎(chǔ)篇的范圍但如果你在處理高度相關(guān)的指標(biāo)集這是一個(gè)值得深入的研究方向能讓你的模型在數(shù)學(xué)建模競(jìng)賽中脫穎而出。最后記住任何模型都是工具熵權(quán)法修正的TOPSIS為我們提供了一個(gè)強(qiáng)大、客觀的評(píng)價(jià)框架但最終結(jié)果的解讀和應(yīng)用永遠(yuǎn)離不開(kāi)對(duì)業(yè)務(wù)背景的深刻理解。模型告訴我們“是什么”而我們需要思考“為什么”以及“怎么辦”。