项目概述
海伦使用约会网站寻找约会对象。经过一段时间之后,她发现曾交往过三种类型的人:
1、不喜欢的人
2、魅力一般的人
3、极具魅力的人
她希望:
1、工作日与魅力一般的人约会
2、周末与极具魅力的人约会
3、不喜欢的人则直接排除掉
现在她收集到了一些约会网站未曾记录的数据信息,这更有助于匹配对象的归类。
开发流程
收集数据:提供文本文件 准备数据:使用python解析文本文件 分析数据:使用Matplotlib画二维散点图 训练算法:此步骤不适用于 KNN算法 测试算法:使用海伦提供的部分数据作为测试样本。 使用算法:产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型。
收集数据:提供文本文件
海伦把这些约会对象的数据存放在文本文件中,总共有 1000 行。海伦约会的对象主要包含以下 3 种特征:
每年获得的飞行常客里程数
玩视频游戏所耗时间百分比
每周消费的冰淇淋公升数
文本文件数据格式如下:
40920 8.326976 0.953952 3 14488 7.153469 1.673904 2 26052 1.441871 0.805124 1 75136 13.147394 0.428964 1 38344 1.669788 0.134296 1
准备数据:使用python解析文本文件
将文本记录转换为Numpy的解析程序
def file2matrix(filename): """ Desc: 导入训练数据 parameters: filename: 数据文件路径 return: 数据矩阵 returnMat 和对应的类别 classLabelVector """ fr = open(filename) # 获得文件中的数据行的行数 numberOfLines = len(fr.readlines()) # 生成对应的空矩阵 # 例如:zeros(2,3)就是生成一个 2*3的矩阵,各个位置上全是 0 returnMat = zeros((numberOfLines, 3)) # prepare matrix to return classLabelVector = [] # prepare labels return fr = open(filename) index = 0 for line in fr.readlines(): # str.strip([chars]) --返回已移除字符串头尾指定字符所生成的新字符串 line = line.strip() # 以 '\t' 切割字符串 listFromLine = line.split('\t') # 每列的属性数据 returnMat[index, :] = listFromLine[0:3] # 每列的类别数据,就是 label 标签数据 classLabelVector.append(int(listFromLine[-1])) index += 1 # 返回数据矩阵returnMat和对应的类别classLabelVector return returnMat, classLabelVector
分析数据:使用 Matplotlib 画二维散点图
import matplotlibimport matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) ax.scatter(datingDataMat[:, 0], datingDataMat[:, 1], 15.0*array(datingLabels), 15.0*array(datingLabels)) plt.show()
下图中采用矩阵的第一和第二列属性得到很好的展示效果,清晰地标识了三个不同的样本分类区域,具有不同爱好的人其类别区域也不同。
归一化数据(归一化是一个让权重变为统一的过程,更多细节请参考: https://www.zhihu.com/question/19951858 )
也就是常用的欧式距离
序号 | 玩视频游戏所耗时间百分比 | 每年获得的飞行常客里程数 | 每周消费的冰淇淋公升数 | 样本分类 |
---|---|---|---|---|
1 | 0.8 | 400 | 0.5 | 1 |
2 | 12 | 134 000 | 0.9 | 3 |
3 | 0 | 20 000 | 1.1 | 2 |
4 | 67 | 32 000 | 0.1 | 2 |
样本3和样本4的距离:
归一化特征值,消除特征之间量级不同导致的影响
归一化定义: 我是这样认为的,归一化就是要把你需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。首先归一化是为了后面数据处理的方便,其次是保正程序运行时收敛加快。 方法有如下:
1.线性函数转换,表达式如下:
y=(x-MinValue)/(MaxValue-MinValue)
说明:x、y分别为转换前、后的值,MaxValue、MinValue分别为样本的最大值和最小值。
2.对数函数转换,表达式如下:
y=log10(x)
说明:以10为底的对数函数转换。
3.反余切函数转换,表达式如下:
y=arctan(x)*2/PI
4.式(1)将输入值换算为[-1,1]区间的值,在输出层用式(2)换算回初始值,其中和分别表示训练样本集中负荷的最大值和最小值。
在统计学中,归一化的具体作用是归纳统一样本的统计分布性。归一化在0-1之间是统计的概率分布,归一化在-1--+1之间是统计的坐标分布。
def autoNorm(dataSet): """ Desc: 归一化特征值,消除特征之间量级不同导致的影响 parameter: dataSet: 数据集 return: 归一化后的数据集 normDataSet. ranges和minVals即最小值与范围,并没有用到 归一化公式: Y = (X-Xmin)/(Xmax-Xmin) 其中的 min 和 max 分别是数据集中的最小特征值和最大特征值。该函数可以自动将数字特征值转化为0到1的区间。 """ # 计算每种属性的最大值、最小值、范围 minVals = dataSet.min(0) maxVals = dataSet.max(0) # 极差 ranges = maxVals - minVals normDataSet = zeros(shape(dataSet)) m = dataSet.shape[0] # 生成与最小值之差组成的矩阵 normDataSet = dataSet - tile(minVals, (m, 1)) # 将最小值之差除以范围组成矩阵 normDataSet = normDataSet / tile(ranges, (m, 1)) # element wise divide return normDataSet, ranges, minVals
训练算法:此步骤不适用于 k-近邻算法
因为测试数据每一次都要与全量的训练数据进行比较,所以这个过程是没有必要的。
KNN算法在第8天以及逐步解析过了,本案例类似,点击查看机器学习 Day 8 | K-NN算法的简单实现(2)
测试算法:使用海伦提供的部分数据作为测试样本。如果预测分类与实际类别不同,则标记为一个错误。
kNN 分类器针对约会网站的测试代码
def datingClassTest(): """ Desc: 对约会网站的测试方法 parameters: none return: 错误数 """ # 设置测试数据的的一个比例(训练数据集比例=1-hoRatio) hoRatio = 0.1 # 测试范围,一部分测试一部分作为样本 # 从文件中加载数据 datingDataMat, datingLabels = file2matrix('input/2.KNN/datingTestSet2.txt') # load data setfrom file # 归一化数据 normMat, ranges, minVals = autoNorm(datingDataMat) # m 表示数据的行数,即矩阵的第一维 m = normMat.shape[0] # 设置测试的样本数量, numTestVecs:m表示训练样本的数量 numTestVecs = int(m * hoRatio) print 'numTestVecs=', numTestVecs errorCount = 0.0 for i in range(numTestVecs): # 对数据测试 classifierResult = classify0(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3) print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i]) if (classifierResult != datingLabels[i]): errorCount += 1.0 print "the total error rate is: %f" % (errorCount / float(numTestVecs)) print errorCount
使用算法:产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型
约会网站预测函数
def classifyPerson(): resultList = ['not at all', 'in small doses', 'in large doses'] percentTats = float(raw_input("percentage of time spent playing video games ?")) ffMiles = float(raw_input("frequent filer miles earned per year?")) iceCream = float(raw_input("liters of ice cream consumed per year?")) datingDataMat, datingLabels = file2matrix('datingTestSet2.txt') normMat, ranges, minVals = autoNorm(datingDataMat) inArr = array([ffMiles, percentTats, iceCream]) classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels, 3) print "You will probably like this person: ", resultList[classifierResult - 1]
实际运行如下
>>> classifyPerson() percentage of time spent playing video games ?1frequent filer miles earned per year?1liters of ice cream consumed per year?1[670 955 410 450 717 184 965 790 457 893 928 517 411 430 541 782 630 120Ran 0 tests in 0.000s OK 889 721 803 405 733 556 428 858 81 270 857 269 657 621 195 384 177 719 778 150 87 20 688 742 942 560 451 747 469 835 49 278 321 253 964 671 956 616 111 67 529 309 980 940 929 313 510 283 986 353 202 925 836 28 378 70 757 255 132 18 968 987 779 901 874 212 399 447 552 171 750 115 224 735 98 12 801 527 379 403 37 743 61 576 632 417 982 612 247 256 656 157 995 306 308 293 896 774 845 763 643 804 421 144 361 711 387 169 644 862 72 181 335 625 640 685 533 131 985 740 105 935 236 2 550 945 791 330 369 185 615 974 548 65 161 431 730 299 479 989 249 201 495 600 532 658 266 345 230 816 496 771 48 512 694 526 191 710 218 564 904 318 960 856 118 281 860 991 427 199 436 64 820 938 744 737 182 488 637 765 907 848 473 841 346 963 93 134 47 811 678 651 371 54 687 300 953 455 22 978 638 470 618 930 505 983 149 572 675 574 661 265 994 26 530 867 903 853 524 200 501 536 662 62 503 665 305 244 357 56 514 333 689 275 86 555 540 452 739 466 151 847 205 231 755 63 613 788 490 842 642 850 696 623 628 73 45 812 53 499 21 697 396 110 91 458 285 764 259 189 32 891 362 34 780 578 762 723 140 456 449 352 328 966 459 605 50 949 707 535 338 840 992 547 208 301 29 24 731 583 777 604 950 295 913 96 180 543 734 876 187 609 972 598 706 634 142 234 163 304 196 878 103 280 194 446 141 808 229 988 453 404 504 923 673 210 865 544 593 571 407 154 445 626 772 6 101 786 468 584 377 190 439 40 315 125 268 401 137 864 467 894 738 349 879 516 102 319 381 880 1 136 79 838 31 712 787 112 260 611 830 167 222 341 969 702 145 74 156 424 979 66 179 441 127 307 373 648 414 292 745 515 41 148 245 692 197 507 408 500 311 641 720 814 60 997 437 363 668 767 954 433 27 296 267 365 877 287 130 655 320 239 852 406 939 168 117 870 471 238 175 926 553 291 888 704 415 915 539 192 59 0 614 884 727 10 931 761 825 203 243 432 759 124 206 708 751 809 568 19 186 993 682 834 705 99 337 807 126 924 728 394 551 793 589 843 581 55 768 531 800 122 766 585 883 981 871 946 143 741 587 580 484 165 601 520 732 486 660 826 193 570 967 680 409 897 162 679 534 700 984 109 176 393 478 810 322 677 334 492 286 219 254 831 999 324 674 918 68 577 339 257 921 84 900 385 795 666 919 948 932 13 558 652 823 155 619 113 781 631 775 288 882 922 736 875 794 383 23 489 916 895 659 366 348 83 390 213 715 46 248 139 215 518 789 799 594 898 153 502 866 133 282 359 650 290 119 78 701 952 538 475 805 160 690 262 340 97 413 709 71 358 289 57 402 188 263 30 82 477 4 418 909 42 329 559 241 686 590 575 158 691 422 797 769 351 620 627 272 725 998 277 15 316 513 886 443 633 104 756 519 802 724 395 785 472 629 554 849 695 649 753 39 442 961 38 839 147 310 579 298 264 43 183 209 588 990 146 934 95 885 902 327 416 368 683 107 854 653 303 152 326 75 25 624 426 703 608 549 595 370 461 376 235 204 591 462 914 460 566 9 412 217 250 420 868 821 521 603 121 347 829 367 890 123 859 464 172 226 312 819 343 562 52 128 832 817 663 545 542 16 474 698 487 975 364 174 85 672 178 639 485 242 448 899 622 173 302 233 569 332 752 284 386 784 511 586 493 933 796 917 602 646 77 454 350 973 7 271 582 958 135 716 927 693 699 822 425 977 354 237 881 523 498 170 279 506 749 971 645 44 214 207 824 198 106 423 873 80 509 100 344 522 970 89 654 760 391 606 323 69 869 8 36 389 669 937 746 317 681 482 827 90 228 419 491 770 116 537 776 465 684 773 647 872 138 374 11 855 714 223 372 676 325 959 35 429 211 494 33 481 941 996 957 480 216 908 276 798 910 920 388 94 815 497 596 392 400 912 851 220 463 5 951 331 273 227 476 88 718 355 617 114 844 567 846 754 911 164 221 906 382 861 375 129 713 546 563 667 792 274 936 440 758 232 565 726 435 58 258 748 635 252 607 356 783 297 483 525 597 51 159 336 166 573 828 664 599 261 438 944 636 444 225 108 557 892 398 528 342 561 294 943 976 380 905 3 806 76 813 17 246 610 729 240 314 508 251 592 863 833 397 887 947 14 92 434 962 818 722 837 360] {2: 3} You will probably like this person: in small doses
作者:raphah
链接:https://www.jianshu.com/p/a985611e303b
共同学习,写下你的评论
评论加载中...
作者其他优质文章