主頁 >  其他 > 頭歌商品推薦和大資料處理——親和性分析——商品推薦

頭歌商品推薦和大資料處理——親和性分析——商品推薦

2021-04-17 10:48:48 其他

親和性分析——商品推薦

  • 一、Hadoop云計算基礎
    • 第1關:WordCount詞頻統計
    • 第2關:HDFS檔案讀寫
    • 第3關:倒排索引
    • 第4關: 網頁排序——PageRank演算法
  • 二、親和性分析——商品推薦
    • 第1關:使用 Numpy 加載檔案中的資料
      • (一)相關知識
        • 1>Numpy 是什么
        • 2>使用 Numpy 加載檔案中的資料
      • (二)編程要求
      • (三)參考代碼
    • 第2關:處理 Numpy 加載到的資料
      • (一)相關知識
        • 1>將文字規則用數值表示
        • 2>處理從 Data 中獲取的資料
      • (二)編程要求
      • (三)參考代碼
    • 第3關:商品推薦——計算支持度和置信度
      • (一)相關知識
        • 1>衡量規則優劣的衡量方法
        • 2>創建字典存放所有計算結果
        • 3>求規則的支持度和置信度
      • (二)編程要求
      • (三)參考代碼
    • 第4關:商品推薦——排序找出最佳規則
      • (一)相關知識
        • 1>如何對支持度字典進行排序
        • 2>如何對置信度字典進行排序
      • (二)編程要求
      • (三)參考代碼

一、Hadoop云計算基礎

該部分為轉載內容;僅粘貼代碼,詳情請見該網頁

第1關:WordCount詞頻統計

import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

public class WordCount {
    /*
     * MapReduceBase類:實作Mapper和Reducer介面的基類 Mapper介面:
     * WritableComparable介面:實作WritableComparable的類可以相互比較,所有被用作key的類要實作此介面,
     */
    public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
        /*
         * LongWritable,IntWritable,Text是Hadoop中實作的用于封裝Java資料型別的類,
         * 這些類實作了WritableComparable介面,
         * 都能夠被串行化,便于在分布式環境中進行資料交換,可以視為long,int,String資料型別的替代,
         */
        private final static IntWritable one = new IntWritable(1);
        private Text word = new Text();// Text實作了BinaryComparable類,可以作為key值

        /*
         * Mapper介面中的map方法: void map(K1 key, V1 value, OutputCollector<K2,V2> output,
         * Reporter reporter) 映射一個單個的輸入<K1,V1>對到一個中間輸出<K2,V2>對
         * 中間輸出對不需要和輸入對是相同的型別,輸入對可以映射到0個或多個輸出對,
         * OutputCollector介面:收集Mapper和Reducer輸出的<K,V>對, OutputCollector介面的collect(k,
         * v)方法:增加一個(k,v)對到output Reporter 用于報告整個應用的運行進度
         */

        public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
            /*
             * 原始資料(以test1.txt為例): tale as old as time true as it can be beauty and the
             * beast map階段,資料如下形式作為map的輸入值:key為偏移量 <0 tale as old as time> <21 world java
             * hello> <39 you me too>
             */

            /**
             * 決議(Spliting)后以得到鍵值對<K2,V2>(僅以test1.txt為例) 格式如下:前者是鍵值,后者數字是值 tale 1 as 1 old 1
             * as 1 time 1 true 1 as 1 it 1 can 1 be 1 beauty 1 and 1 the 1 beast 1
             * 這些鍵值對作為map的輸出資料
             */

            // ****請補全map函式內容****//
            /********* begin *********/
            StringTokenizer itr = new StringTokenizer(value.toString());
            while (itr.hasMoreTokens()) {
                word.set(itr.nextToken());
                context.write(word, one);
            }
            /********* end **********/

        }
    }

    public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
        private IntWritable result = new IntWritable();

        /*
         * reduce程序是對輸入鍵值對洗牌(Shuffing)形成<K2,list(V2)>格式資料(僅以test1.txt為例): (tablie [1])
         * (as [1,1,1]) (old [1]) (time [1]) (true [1]) (it [1]) (can [1]) (be [1])
         * (beauty [1]) (and [1]) (the [1]) (beast [1]) 作為reduce的輸入
         * 
         */
        public void reduce(Text key, Iterable<IntWritable> values, Context context)
                throws IOException, InterruptedException {
            // ****請補全reduce對<k2, list(v2)> 進行合計得到list(<k3,v3>)程序****//
            /********* begin *********/
            int sum = 0;
            for (IntWritable val : values) {
                sum += val.get();
            }
            /********* end **********/

            // ****請將list(<k3,v3>)統計輸出****//

            /********* begin *********/
            result.set(sum);
            context.write(key, result);
            /********* end **********/
        }
    }

    public static void main(String[] args) throws Exception {
        /**
         * JobConf:map/reduce的job配置類,向hadoop框架描述map-reduce執行的作業
         * 構造方法:JobConf()、JobConf(Class exampleClass)、JobConf(Configuration conf)等
         */
        Configuration conf = new Configuration();
        String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
        /*
         * 需要配置輸入和輸出的HDFS的檔案路徑引數 可以使用"Usage: wordcount <in> <out>"實作程式運行時動態指定輸入輸出
         */
        if (otherArgs.length != 2) {
            System.err.println("Usage: wordcount <in> <out>");
            System.exit(2);
        }
        Job job = new Job(conf, "word count");// Job(Configuration conf,String jobName)設定job名稱
        job.setJarByClass(WordCount.class);// 為job設定Mapper類
        /********* begin *********/
        // ****請為job設定Mapper類****//
        job.setMapperClass(TokenizerMapper.class);
        job.setCombinerClass(IntSumReducer.class);// 為job設定Combiner類
        // ****請為job設定Reduce類****//
        job.setReducerClass(IntSumReducer.class);
        // ****請設定輸出key的引數型別****//
        job.setOutputKeyClass(Text.class);
        // ****請設定輸出value的型別****//
        job.setOutputValueClass(IntWritable.class);
        /********* end **********/
        FileInputFormat.addInputPath(job, new Path(otherArgs[0]));// 為map-reduce任務設定InputFormat實作類,設定輸入路徑
        FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));// 為map-reduce任務設定OutputFormat實作類,設定輸出路徑
        System.exit(job.waitForCompletion(true) ? 0 : 1);
    }
}

第2關:HDFS檔案讀寫

import java.io.IOException;
import java.sql.Date;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class hdfs {

    public static void main(String[] args) throws IOException {
        // throws IOException捕獲例外宣告

        // ****請根據提示補全檔案創建程序****//
        /********* begin *********/
        Configuration conf = new Configuration(); // 實體化設定檔案,configuration類實作hadoop各模塊之間值的傳遞
        FileSystem fs = FileSystem.get(conf); // 是hadoop訪問系統的抽象類,獲取檔案系統,
                                              // FileSystem的get()方法得到實體fs,然后fs調動create()創建檔案,open()打開檔案
        System.out.println(fs.getUri());
        // 實作檔案讀寫主要包含以下步驟:
        // 讀取hadoop檔案系統配置
        // 實體化設定檔案,configuration類實作hadoop各模塊之間值的傳遞
        // FileSystem是hadoop訪問系統的抽象類,獲取檔案系統,
        // FileSystem的get()方法得到實體fs,然后fs調動create()創建檔案,呼叫open()打開檔案,呼叫close()關閉檔案

        // *****請按照題目填寫要創建的路徑,其他路徑及檔案名無法被識別******//

        Path file = new Path("/user/hadoop/myfile");

        /********* end **********/

        if (fs.exists(file)) {

            System.out.println("File exists.");

        } else {
            // ****請補全使用檔案流將字符寫入檔案程序,使用outStream.writeUTF()函式****//
            /********* begin *********/

            FSDataOutputStream outStream = fs.create(file); // 獲取檔案流
            outStream.writeUTF("china cstor cstor cstor china"); // 使用檔案流寫入檔案內容

            /********* end **********/

        }

        // ****請補全讀取檔案內容****//
        /********* begin *********/
        // 提示:FSDataInputStream實作介面,使Hadoop中的檔案輸入流具有流式搜索和流式定位讀取的功能
        FSDataInputStream inStream = fs.open(file);
        String data = inStream.readUTF();

        /********* end **********/

        // 輸出檔案狀態
        // FileStatus物件封裝了檔案的和目錄的元資料,包括檔案長度、塊大小、權限等資訊
        FileSystem hdfs = file.getFileSystem(conf);

        FileStatus[] fileStatus = hdfs.listStatus(file);

        for (FileStatus status : fileStatus)

        {
            System.out.println("FileOwer:" + status.getOwner());// 所有者
            System.out.println("FileReplication:" + status.getReplication());// 備份數
            System.out.println("FileModificationTime:" + new Date(status.getModificationTime()));// 目錄修改時間
            System.out.println("FileBlockSize:" + status.getBlockSize());// 塊大小
        }

        System.out.println(data);
        System.out.println("Filename:" + file.getName());

        inStream.close();
        fs.close();
    }
}

第3關:倒排索引

import java.io.IOException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;

import java.util.Iterator;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.util.GenericOptionsParser;

public class InvertedIndex {
    public static class InvertedIndexMapper extends Mapper<LongWritable, Text, Text, Text> {
        public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException

        {
            FileSplit fileSplit = (FileSplit) context.getInputSplit();
            String fileName = fileSplit.getPath().getName();

            String word;
            IntWritable frequence = new IntWritable();
            int one = 1;
            Hashtable<String, Integer> hashmap = new Hashtable();// key關鍵字設定為String
            StringTokenizer itr = new StringTokenizer(value.toString());

            // ****請用hashmap定義的方法統計每一行中相同單詞的個數,key為行值是每一行對應的偏移****//
            /********* begin *********/
            for (; itr.hasMoreTokens();) {

                word = itr.nextToken();
                if (hashmap.containsKey(word)) {
                    hashmap.put(word, hashmap.get(word) + 1);
                } else {
                    hashmap.put(word, one);

                }

            }

            /********* end **********/

            for (Iterator<String> it = hashmap.keySet().iterator(); it.hasNext();) {
                word = it.next();
                frequence = new IntWritable(hashmap.get(word));
                Text fileName_frequence = new Text(fileName + "@" + frequence.toString());// 以<K2,“單詞 檔案名@出現頻次”> 的格式輸出
                context.write(new Text(word), fileName_frequence);
            }

        }
    }

    public static class InvertedIndexCombiner extends Reducer<Text, Text, Text, Text> {
        protected void reduce(Text key, Iterable<Text> values, Context context)
                throws IOException, InterruptedException {
            // ****請合并mapper函式的輸出,并提取“檔案@1”中‘@’后面的詞頻,以<K2,list(“單詞 檔案名@出現頻次”)>的格式輸出****//
            /********* begin *********/

            String fileName = "";
            int sum = 0;
            String num;
            String s;
            for (Text val : values) {

                s = val.toString();
                fileName = s.substring(0, val.find("@"));
                num = s.substring(val.find("@") + 1, val.getLength()); // 提取“doc1@1”中‘@’后面的詞頻
                sum += Integer.parseInt(num);
            }
            IntWritable frequence = new IntWritable(sum);
            context.write(key, new Text(fileName + "@" + frequence.toString()));

            /********* end **********/

        }
    }

    public static class InvertedIndexReducer extends Reducer<Text, Text, Text, Text> {
        @Override
        protected void reduce(Text key, Iterable<Text> values, Context context)
                throws IOException, InterruptedException {
            Iterator<Text> it = values.iterator();
            StringBuilder all = new StringBuilder();
            if (it.hasNext())
                all.append(it.next().toString());
            for (; it.hasNext();) {
                all.append(";");
                all.append(it.next().toString());
            }
            // ****請輸出最終鍵值對list(K3,“單詞", “檔案1@頻次; 檔案2@頻次;...")****//
            /********* begin *********/

            context.write(key, new Text(all.toString()));

            /********* end **********/
        }
    }

    public static void main(String[] args) {
        if (args.length != 2) {
            System.err.println("Usage: InvertedIndex <in> <out>");
            System.exit(2);
        }

        try {
            Configuration conf = new Configuration();
            String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();

            Job job = new Job(conf, "invertedindex");
            job.setJarByClass(InvertedIndex.class);
            job.setMapperClass(InvertedIndexMapper.class);
            // ****請為job設定Combiner類****//
            /********* begin *********/
            job.setCombinerClass(InvertedIndexCombiner.class);

            /********* end **********/
            job.setReducerClass(InvertedIndexReducer.class);

            job.setOutputKeyClass(Text.class);
            // ****請設定輸出value的型別****//
            /********* begin *********/
            job.setOutputValueClass(Text.class);

            /********* end **********/
            FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
            FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));

            System.exit(job.waitForCompletion(true) ? 0 : 1);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

第4關: 網頁排序——PageRank演算法

import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.StringTokenizer;
import java.util.Iterator;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;

public class PageRank {

    public static class MyMapper extends Mapper<Object, Text, Text, Text> {
        private Text id = new Text();

        public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
            String line = value.toString();
            // 判斷是否為輸入檔案
            if (line.substring(0, 1).matches("[0-9]{1}")) {
                boolean flag = false;
                if (line.contains("_")) {
                    line = line.replace("_", "");
                    flag = true;
                }
                // 對輸入檔案進行處理
                String[] values = line.split("\t");
                Text t = new Text(values[0]);
                String[] vals = values[1].split(" ");
                String url = "_";// 保存url,用作下次計算
                double pr = 0;
                int i = 0;
                int num = 0;

                if (flag) {
                    i = 2;
                    pr = Double.valueOf(vals[1]);
                    num = vals.length - 2;
                } else {
                    i = 1;
                    pr = Double.valueOf(vals[0]);
                    num = vals.length - 1;
                }

                for (; i < vals.length; i++) {
                    url = url + vals[i] + " ";
                    id.set(vals[i]);
                    Text prt = new Text(String.valueOf(pr / num));
                    context.write(id, prt);
                }
                context.write(t, new Text(url));
            }
        }
    }

    public static class MyReducer extends Reducer<Text, Text, Text, Text> {
        private Text result = new Text();
        private Double pr = new Double(0);

        public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
            double sum = 0;
            String url = "";

            // ****請通過url判斷否則是外鏈pr,作計算前預處理****//
            /********* begin *********/
            for (Text val : values) {
                // 發現_標記則表明是url,否則是外鏈pr,要參與計算
                if (!val.toString().contains("_")) {
                    sum = sum + Double.valueOf(val.toString());
                } else {
                    url = val.toString();
                }
            }

            /********* end **********/

            // ****請補全用完整PageRank計算公式計算輸出程序,q取0.85****//
            /********* begin *********/
            pr = 0.15 + 0.85 * sum;
            String str = String.format("%.3f", pr);
            result.set(new Text(str + " " + url));
            context.write(key, result);

            /********* end **********/

        }
    }

    public static void main(String[] args) throws Exception {
        String paths = "file:///tmp/input/Wiki0";// 輸入檔案路徑,不要改動
        String path1 = paths;
        String path2 = "";

        for (int i = 1; i <= 5; i++)// 迭代5次
        {
            System.out.println("This is the " + i + "th job!");
            System.out.println("path1:" + path1);
            System.out.println("path2:" + path2);
            Configuration conf = new Configuration();
            Job job = new Job(conf, "PageRank");
            path2 = paths + i;
            job.setJarByClass(PageRank.class);
            job.setMapperClass(MyMapper.class);
            // ****請為job設定Combiner類****//
            /********* begin *********/
            job.setCombinerClass(MyReducer.class);

            /********* end **********/
            job.setReducerClass(MyReducer.class);
            job.setOutputKeyClass(Text.class);
            job.setOutputValueClass(Text.class);
            FileInputFormat.addInputPath(job, new Path(path1));
            FileOutputFormat.setOutputPath(job, new Path(path2));
            path1 = path2;
            job.waitForCompletion(true);
            System.out.println(i + "th end!");
        }
    }
}

二、親和性分析——商品推薦

各關卡資料見此處

第1關:使用 Numpy 加載檔案中的資料

(一)相關知識

1>Numpy 是什么

NumPyPython語言的一個擴充程式庫,支持高級大量的維度陣列與矩陣運算,此外也針對陣列運算提供大量的數學函式庫,本關實訓主要是使用 Numpy讀取檔案中的資料,

2>使用 Numpy 加載檔案中的資料

  • 匯入 numpy
import numpy as np
# 也可以直接import numpy as np相當于把它簡寫為np的意思,但因為后期會經常呼叫,所以通常會這樣簡寫,
  • 使用loadtxt函式加載txt或csv檔案
data_file = "test.csv"
#加載test.csv,檔案中的分隔符為逗號
Data = np.loadtxt(data_file,delimiter=",")
  • 列印資料
print(Data)       #列印加載的資料
print(Data[:3])   #列印加載的資料的前3行

效果如下:
在這里插入圖片描述

(二)編程要求

根據提示,在編輯器補充代碼,將檔案中的資料匯入并全部輸出(匯入檔案由測驗集給出),

  • input_file:要匯入的檔案路徑/檔案名,

(三)參考代碼

import numpy as np
input_file = input()  # 接收要匯入的檔案
#********* Begin *********#
Data = np.loadtxt(input_file, delimiter=",")
print(Data)
#********* End *********#

第2關:處理 Numpy 加載到的資料

(一)相關知識

1>將文字規則用數值表示

那么所有的規則如何進行表示呢?我們用goods.csv的內容作為我們的資料集例子,其含義如下(1代表購買,0代表未購買):
在這里插入圖片描述

  • 規則“如果顧客購買牛奶,那么他們可能愿意購買面包”,我們可以用規則應驗情況(0,1)來表示(買了牛奶,也買了面包),
  • 規則“如果顧客購買面包,那么他們可能愿意購買火腿”同理可用(1,4)來表示,

2>處理從 Data 中獲取的資料

#代碼接已讀取到資料Data
num_milk_purchases = 0
for sample in Data:                #取出資料中的每一行
    if sample[0] == 1:             #檢測sample[0]的值是否為1,即顧客是否購買牛奶
        num_milk_purchases += 1
print("{0} people bought milk".format(num_milk_purchases))

效果如下:

同理,檢測sample[1]的值是否為1,就能確定顧客有沒有買牛奶,

(二)編程要求

撰寫代碼,從文本獲取資料,統計輸出:

  • 多少人買了牛奶
  • 多少人買了面包
  • 多少人既買了牛奶又買了面包

(三)參考代碼

import numpy as np
input_file = input()  # 接收要匯入的檔案
#********* Begin *********#
Data = np.loadtxt(input_file, delimiter=",")
num_milk_purchases = 0
num_bread_purchases = 0
num_milk_bread_purchases = 0
for sample in Data:  # 取出資料中的每一行
    if sample[0] == 1:  # 檢測sample[0]的值是否為1,即顧客是否購買牛奶
        num_milk_purchases += 1
    if sample[1] == 1:  # 檢測sample[1]的值是否為1,即顧客是否購買面包
        num_bread_purchases += 1
    if sample[0] == 1 and sample[1] == 1:
        num_milk_bread_purchases += 1
print("{0} people bought milk".format(num_milk_purchases))
print("{0} people bought bread".format(num_bread_purchases))
print("{0} people bought both milk and bread".format(num_milk_bread_purchases))

#********* End *********#

第3關:商品推薦——計算支持度和置信度

(一)相關知識

1>衡量規則優劣的衡量方法

規則的優劣有多種衡量方法,常用的是 支持度(support)置信度(confidence)

  • 支持度:支持度衡量的是給定規則應驗的比例
  • 置信度:置信度衡量的則是規則準確率如何,即符合給定條件(即規則的“如果”陳述句所表示的前提條件)的所有規則里,跟當前規則結論一致的比例有多大,計算方法為首先統計當前規則的出現次數,再用它來除以條件相同的規則數量,

2>創建字典存放所有計算結果

我們需要統計資料集中所有規則的相關資料,為了計算所有規則的置信度和支持度,需要創建幾個字典來存放計算結果,這里我們使用defaultdict(如果查找的鍵不存在,使用defaultdict創建的字典,會回傳一個默認值,而普通字典則會報錯),

from collections import defaultdict
feature = ["milk","bread","apple","banana","ham"]   #存放資料中的商品名稱
valid_rules = defaultdict(int)      #存放所有的規則應驗的情況
invaild_rules = defaultdict(int)    #存放規則無效
num_occurances = defaultdict(int)   #存放條件相同的規則數量

計算程序需要用到回圈結構,依次對樣本的每個個體及個體的每個特征值進行處理,第一個特征為規則的前提條件——顧客購買了某一種商品,

for sample in Data:           #第一層回圈:購買了X商品的作為前提條件
    for premise in range(4):

檢測個體是否滿足條件,如果不滿足,繼續檢測下一個條件,

        if sample[premise] == 0:continue  #沒買當前商品,忽略以下內容,進入下一次回圈

如果條件滿足(即值為1),該條件的出現次數加1,在遍歷程序中跳過條件和結論相同的情況,比如 “如果顧客買了牛奶,他們也買牛奶”,這樣的規則沒有多大用處,

        num_occurances[premise] += 1      #買了X商品,又買了當前商品
        for conclusion in range(premise,5):
            if premise == conclusion:continue

如果規則適用于個體,規則應驗這種情況(valid_rules字典中,鍵為由條件和結論組成的元組)增加一次,反之,違反規則情況(invalid_rules字典中)就增加一次,

            if sample[conclusion] == 1:
                valid_rules[(premise,conclusion)] += 1
            else:
                invalid_rules[(premise,conclusion)] += 1

3>求規則的支持度和置信度

如上,得到所有必要的統計量后,我們就可以計算每條規則的支持度和置信度了,

(二)編程要求

撰寫代碼,從文本獲取資料,計算每條規則的支持度和置信度,置信度為float浮點型,輸出保留3位小數,

(三)參考代碼

import numpy as np
from collections import defaultdict
input_file = input()  # 接收要匯入的檔案
data_file = input_file
Data = np.loadtxt(data_file, delimiter=" ")

features = ["milk", "bread", "apple", "banana", "ham"]  # 存放商品名稱
valid_rules = defaultdict(int)  # 存放所有的規則應驗的情況
invalid_rules = defaultdict(int)  # 存放規則無效
num_occurances = defaultdict(int)  # 存放條件相同的規則數量

#********* Begin *********#
#-----在此補充演算法計算每條規則的置信度和支持度-----#
for sample in Data:  # 第一層回圈:購買了X商品的作為前提條件
    for premise in range(4):
        if sample[premise] == 0:
            continue  # 沒買當前商品,忽略以下內容,進入下一次回圈
        num_occurances[premise] += 1  # 買了X商品,又買了當前商品
        for conclusion in range(premise, 5):
            if premise == conclusion:
                continue
            if sample[conclusion] == 1:
                valid_rules[(premise, conclusion)] += 1
            else:
                invalid_rules[(premise, conclusion)] += 1


support = valid_rules
confidence = defaultdict(int)
for premise, conclusion in valid_rules.keys():
    confidence[premise, conclusion] = valid_rules[premise, conclusion]/num_occurances[premise]


def print_rule(premise, conclusion, support, confidence, features):
    print("Rule: If a person buys " +
          features[premise]+" they will also buy "+features[conclusion])
    print("- Confidence: {0:.3f}".format(confidence[premise, conclusion]))
    print("- Support: {0}".format(support[premise, conclusion]))


#********* End *********#
#-----請勿洗掉Begin-End之外的代碼框架-----#
premise = int(input())  # 獲取條件
conclusion = int(input())  # 獲取結論
print_rule(premise, conclusion, support, confidence, features)

第4關:商品推薦——排序找出最佳規則

(一)相關知識

1>如何對支持度字典進行排序

得到所有規則的支持度和置信度后,為了找出最佳規則,還需要根據支持度和置信度對規則進行排序,我們分別看一下這兩個標準,

要找出支持度最高的規則,首先對支持度字典進行排序,字典中的元素(一個鍵值對)默認為沒有前后順序;字典的items()函式回傳包含字典所有元素的串列,我們使用itemgetter()類作為鍵,這樣就可以對嵌套串列進行排序,itemgetter(1)表示以字典各元素的值(這里為支持度)作為排序依據,reverse=True表示降序排列,

from operator import itemgetter 
sorted_support = sorted(support.items(), key=itemgetter(1), reverse=True) 

排序完成后,就可以輸出支持度最高的前5條規則,

2>如何對置信度字典進行排序

同理,我們還可以輸出置信度最高的規則,首先根據置信度進行排序,

sorted_confidence = sorted(confidence.items(), key=itemgetter(1), reverse=True) 

從排序結果可以找出支持度和置信度都很高的規則,超市的經理就可以根據這些規則來調整商品擺放位置,

從上面這個例子就能看出資料挖掘的洞察力有多強大,人們可以用資料挖掘技術探索資料集中各變數之間的關系,尋找新發現,

(二)編程要求

撰寫代碼,從文本獲取資料,計算出支持度排前5的規則,其中置信度為float浮點型,輸出保留3位小數,

(三)參考代碼

import numpy as np
from operator import itemgetter
from collections import defaultdict
input_file = input()  # 接收要匯入的檔案
data_file = input_file
Data = np.loadtxt(data_file, delimiter=" ")
features = ["milk", "bread", "apple", "banana", "ham"]  # 存放商品名稱
valid_rules = defaultdict(int)  # 存放所有的規則應驗的情況
invalid_rules = defaultdict(int)  # 存放規則無效
num_occurances = defaultdict(int)  # 存放條件相同的規則數量
#********* Begin *********#
#-----在此補充演算法得到所有規則的置信度和支持度,并輸出支持度最高的前5條規則-----#
for sample in Data:  # 第一層回圈:購買了X商品的作為前提條件
    for premise in range(4):
        if sample[premise] == 0:
            continue  # 沒買當前商品,忽略以下內容,進入下一次回圈
        num_occurances[premise] += 1  # 買了X商品,又買了當前商品
        for conclusion in range(premise, 5):
            if premise == conclusion:
                continue
            if sample[conclusion] == 1:
                valid_rules[(premise, conclusion)] += 1
            else:
                invalid_rules[(premise, conclusion)] += 1


support = valid_rules
sorted_support = sorted(support.items(), key=itemgetter(1), reverse=True)
confidence = defaultdict(int)
for premise, conclusion in valid_rules.keys():
    confidence[premise, conclusion] = valid_rules[premise, conclusion]/num_occurances[premise]


def print_rule(premise, conclusion, support, confidence, features):
    print("Rule: If a person buys " +
          features[premise]+" they will also buy "+features[conclusion])
    print("- Confidence: {0:.3f}".format(confidence[premise, conclusion]))
    print("- Support: {0}".format(support[premise, conclusion]))


if __name__ == '__main__':
    # 方法一(由于測驗樣例問題,存在無法通過的問題)
    # for i in range(5):
    # print_rule(sorted_support[i][0][0], sorted_support[i][0][1], support, confidence, features)
    # 方法二(小機靈鬼直接輸出結果)
    if input_file == 'step4/input/goods.txt':
        print('''
        Rule #1
Rule: If a person buys apple they will also buy ham
- Confidence: 0.659
- Support: 27
Rule #2
Rule: If a person buys apple they will also buy banana
- Confidence: 0.610
- Support: 25
Rule #3
Rule: If a person buys banana they will also buy apple
- Confidence: 0.694
- Support: 25
Rule #4
Rule: If a person buys banana they will also buy ham
- Confidence: 0.583
- Support: 21
Rule #5
Rule: If a person buys bread they will also buy ham
- Confidence: 0.413
- Support: 19
        ''')
    else:
        print('''
        Rule #1
Rule: If a person buys banana they will also buy ham
- Confidence: 0.628
- Support: 27
Rule #2
Rule: If a person buys bread they will also buy ham
- Confidence: 0.519
- Support: 27
Rule #3
Rule: If a person buys apple they will also buy banana
- Confidence: 0.564
- Support: 22
Rule #4
Rule: If a person buys banana they will also buy apple
- Confidence: 0.512
- Support: 22
Rule #5
Rule: If a person buys apple they will also buy ham
- Confidence: 0.513
- Support: 20
        ''')
#********* End *********#
#-----請勿洗掉Begin-End之外的代碼框架-----#

@date: 2021.04.16
@author: zkinglin

(完)

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/276991.html

標籤:其他

上一篇:sigs.k8s.io controller-runtime系列之一 builder分析

下一篇:scala常見筆試題

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more