Difference between revisions of "MIR workshop 2011 day5 lab"
Line 20: | Line 20: | ||
** Use the CAL500 user annotations as ground truth and evaluate your audio features (ROC curve or some precision measure). | ** Use the CAL500 user annotations as ground truth and evaluate your audio features (ROC curve or some precision measure). | ||
** Compare a 2D visualization of acoustic features versus UCSD user annotations. | ** Compare a 2D visualization of acoustic features versus UCSD user annotations. | ||
− | |||
Lab code is found in /usr/ccrma/courses/mir20110/cal500_new. | Lab code is found in /usr/ccrma/courses/mir20110/cal500_new. | ||
A previous version was uploaded at /usr/ccrma/courses/mir2011/cal500 but it was using filenames from my University of Montreal lab. I renamed audio files to match those of UCSD Cal500 | A previous version was uploaded at /usr/ccrma/courses/mir2011/cal500 but it was using filenames from my University of Montreal lab. I renamed audio files to match those of UCSD Cal500 | ||
+ | |||
+ | An example call for the code provided by me: | ||
+ | |||
+ | <pre> | ||
+ | %python cal500_example.py norah_jones-dont_know_why | ||
+ | 1 Cosine distance=0.0000 Track=norah_jones-dont_know_why | ||
+ | 2 Cosine distance=0.1111 Track=carole_king-youve_got_a_friend | ||
+ | 3 Cosine distance=0.1365 Track=alicia_keys-fallin | ||
+ | 4 Cosine distance=0.1387 Track=dido-here_with_me | ||
+ | 5 Cosine distance=0.1610 Track=fiona_apple-love_ridden | ||
+ | 6 Cosine distance=0.1646 Track=barry_manilow-mandy | ||
+ | 7 Cosine distance=0.1661 Track=stan_getz-corcovado_quiet_nights_of_quiet_stars | ||
+ | 8 Cosine distance=0.1696 Track=aimee_mann-wise_up | ||
+ | 9 Cosine distance=0.1758 Track=marvelettes-please_mr._postman | ||
+ | 10 Cosine distance=0.1772 Track=ben_folds_five-brick | ||
+ | 11 Cosine distance=0.1795 Track=cranberries-linger | ||
+ | 12 Cosine distance=0.1833 Track=sade-smooth_operator | ||
+ | 13 Cosine distance=0.1860 Track=john_lennon-imagine | ||
+ | 14 Cosine distance=0.1864 Track=dionne_warwick-walk_on_by | ||
+ | 15 Cosine distance=0.1918 Track=5th_dimension-one_less_bell_to_answer | ||
+ | 16 Cosine distance=0.1923 Track=carpenters-rainy_days_and_mondays | ||
+ | 17 Cosine distance=0.1932 Track=diana_ross_and_the_supremes-where_did_our_love_go | ||
+ | 18 Cosine distance=0.1939 Track=smokey_robinson_and_the_miracles-ooo_baby_baby | ||
+ | 19 Cosine distance=0.1939 Track=fleetwood_mac-say_you_love_me | ||
+ | 20 Cosine distance=0.1970 Track=rufus_wainwright-cigarettes_and_chocolate_milk | ||
+ | </pre> | ||
+ | |||
+ | |||
+ | Functions provided by me in cal500_example.py. Students can recode as they please in any language. They are free to use as much of my code as they want. | ||
+ | |||
+ | <pre> | ||
+ | def RemapFilename(infile): | ||
+ | """Maps a filename from Doug name to real cal500 name.""" | ||
+ | |||
+ | |||
+ | def RenameCal500(dest_directory='high_bitrate'): | ||
+ | """Renames cal500 files from Doug naming scheme to standard one | ||
+ | and places them in dest_directory.""" | ||
+ | |||
+ | |||
+ | def MakeFilenameMap(infile = 'cal500_doug_filenames.txt', | ||
+ | outfile = 'cal500_filename_map.txt'): | ||
+ | """Create text file mapping old (Doug) filenames to standard | ||
+ | Cal500 filenames.""" | ||
+ | |||
+ | |||
+ | def GetKeyFromAnnotationPath(annotation_path): | ||
+ | """Gets key from annnotation file path, stripping off | ||
+ | the number. | ||
+ | # Ex: norine_braun-spanish_banks_02.txt yields | ||
+ | # norine_braun-spanish_banks | ||
+ | |||
+ | |||
+ | # Mapping from text values in CAL500 annotation files to (somewhat arbitrary) numeric values. | ||
+ | ANNOTATION_MAP = { | ||
+ | 'yes': 1.0, | ||
+ | 'prominent': 1.0, | ||
+ | 'present': 0.75, | ||
+ | 'uncertain': 0.5, | ||
+ | 'no': 0.0, | ||
+ | 'none': 0.0, | ||
+ | '5': 5/5.0, | ||
+ | '4': 4/5.0, | ||
+ | '3': 3/5.0, | ||
+ | '2': 2/5.0, | ||
+ | '1': 1/5.0, | ||
+ | '0': 0.0 | ||
+ | } | ||
+ | |||
+ | |||
+ | def AddTagWeightsToDictFromAnnotationFile(annotation_path, tag_weights): | ||
+ | """Reads tag weights into a dictionary keyed by tag name | ||
+ | and adds them to the defaultdict tag_weights. Use key 'counter' | ||
+ | to track number of annotations.""" | ||
+ | |||
+ | |||
+ | def BuildTagDictionary(tag_directory='annotations'): | ||
+ | """Builds dictionary mapping cal500 key to a weighted tag vector. | ||
+ | Returns dictionary and our vocabulary of tags.""" | ||
+ | |||
+ | |||
+ | def BuildVectorDictionaryFromTagDictionary(tag_dict, vocabulary): | ||
+ | """Transforms tag dictionaries int tag vectors using vocabulary.""" | ||
+ | |||
+ | |||
+ | def CosineDistance(v1, v2): | ||
+ | """Calculates cosine distance using numpy.""" | ||
+ | |||
+ | |||
+ | def ScoreQuery(vector_dict, query): | ||
+ | """Finds nearest neigbors for query in vector_dict.""" | ||
+ | |||
+ | |||
+ | def PrintScoreDict(score_dict, query, k=20): | ||
+ | """Print score dictionary for a query.""" | ||
+ | |||
+ | |||
+ | # Here is the main function as called above. | ||
+ | if __name__=='__main__': | ||
+ | if len(sys.argv)>1: | ||
+ | query = sys.argv[1] | ||
+ | else: | ||
+ | query = 'norah_jones-dont_know_why' | ||
+ | |||
+ | # Build vectors from words. | ||
+ | tag_dict, vocabulary = BuildTagDictionary() | ||
+ | vector_dict = BuildVectorDictionaryFromTagDictionary(tag_dict, vocabulary) | ||
+ | |||
+ | # Score a query. | ||
+ | score_dict = ScoreQuery(vector_dict, query) | ||
+ | PrintScoreDict(score_dict, query) | ||
+ | |||
+ | </pre> |
Revision as of 16:31, 30 June 2011
MIR Workshop 2011 Day 5 Lab on Music Recommendation
Douglas Eck, Google
Overview
This lab covers the construction of parts of a music recommender. Focus is placed on building a similarity matrix from data and querying that matrix based on cosine distance. Fast programmers should be able to accomplish considerably more.
- The basics (some Python code available to help).
- Calculate acoustic features on CAL500 dataset (students should have already done this.)
- Read in user tag annotations for the same dataset provided by UCSD.
- Build similarity matrix based on word vectors derived from these annotations.
- Query similarity matrix with a track to get top hits based on cosine distance.
- Build second similarity matrix using acoustic features.
- Query this similarity matrix with track to get top hits based on cosine distance.
- Extra (I didn't write code for this, but can help students find examples).
- Query the EchoNest for additional acoustic features and compare to yours.
- Use the CAL500 user annotations as ground truth and evaluate your audio features (ROC curve or some precision measure).
- Compare a 2D visualization of acoustic features versus UCSD user annotations.
Lab code is found in /usr/ccrma/courses/mir20110/cal500_new.
A previous version was uploaded at /usr/ccrma/courses/mir2011/cal500 but it was using filenames from my University of Montreal lab. I renamed audio files to match those of UCSD Cal500
An example call for the code provided by me:
%python cal500_example.py norah_jones-dont_know_why 1 Cosine distance=0.0000 Track=norah_jones-dont_know_why 2 Cosine distance=0.1111 Track=carole_king-youve_got_a_friend 3 Cosine distance=0.1365 Track=alicia_keys-fallin 4 Cosine distance=0.1387 Track=dido-here_with_me 5 Cosine distance=0.1610 Track=fiona_apple-love_ridden 6 Cosine distance=0.1646 Track=barry_manilow-mandy 7 Cosine distance=0.1661 Track=stan_getz-corcovado_quiet_nights_of_quiet_stars 8 Cosine distance=0.1696 Track=aimee_mann-wise_up 9 Cosine distance=0.1758 Track=marvelettes-please_mr._postman 10 Cosine distance=0.1772 Track=ben_folds_five-brick 11 Cosine distance=0.1795 Track=cranberries-linger 12 Cosine distance=0.1833 Track=sade-smooth_operator 13 Cosine distance=0.1860 Track=john_lennon-imagine 14 Cosine distance=0.1864 Track=dionne_warwick-walk_on_by 15 Cosine distance=0.1918 Track=5th_dimension-one_less_bell_to_answer 16 Cosine distance=0.1923 Track=carpenters-rainy_days_and_mondays 17 Cosine distance=0.1932 Track=diana_ross_and_the_supremes-where_did_our_love_go 18 Cosine distance=0.1939 Track=smokey_robinson_and_the_miracles-ooo_baby_baby 19 Cosine distance=0.1939 Track=fleetwood_mac-say_you_love_me 20 Cosine distance=0.1970 Track=rufus_wainwright-cigarettes_and_chocolate_milk
Functions provided by me in cal500_example.py. Students can recode as they please in any language. They are free to use as much of my code as they want.
def RemapFilename(infile): """Maps a filename from Doug name to real cal500 name.""" def RenameCal500(dest_directory='high_bitrate'): """Renames cal500 files from Doug naming scheme to standard one and places them in dest_directory.""" def MakeFilenameMap(infile = 'cal500_doug_filenames.txt', outfile = 'cal500_filename_map.txt'): """Create text file mapping old (Doug) filenames to standard Cal500 filenames.""" def GetKeyFromAnnotationPath(annotation_path): """Gets key from annnotation file path, stripping off the number. # Ex: norine_braun-spanish_banks_02.txt yields # norine_braun-spanish_banks # Mapping from text values in CAL500 annotation files to (somewhat arbitrary) numeric values. ANNOTATION_MAP = { 'yes': 1.0, 'prominent': 1.0, 'present': 0.75, 'uncertain': 0.5, 'no': 0.0, 'none': 0.0, '5': 5/5.0, '4': 4/5.0, '3': 3/5.0, '2': 2/5.0, '1': 1/5.0, '0': 0.0 } def AddTagWeightsToDictFromAnnotationFile(annotation_path, tag_weights): """Reads tag weights into a dictionary keyed by tag name and adds them to the defaultdict tag_weights. Use key 'counter' to track number of annotations.""" def BuildTagDictionary(tag_directory='annotations'): """Builds dictionary mapping cal500 key to a weighted tag vector. Returns dictionary and our vocabulary of tags.""" def BuildVectorDictionaryFromTagDictionary(tag_dict, vocabulary): """Transforms tag dictionaries int tag vectors using vocabulary.""" def CosineDistance(v1, v2): """Calculates cosine distance using numpy.""" def ScoreQuery(vector_dict, query): """Finds nearest neigbors for query in vector_dict.""" def PrintScoreDict(score_dict, query, k=20): """Print score dictionary for a query.""" # Here is the main function as called above. if __name__=='__main__': if len(sys.argv)>1: query = sys.argv[1] else: query = 'norah_jones-dont_know_why' # Build vectors from words. tag_dict, vocabulary = BuildTagDictionary() vector_dict = BuildVectorDictionaryFromTagDictionary(tag_dict, vocabulary) # Score a query. score_dict = ScoreQuery(vector_dict, query) PrintScoreDict(score_dict, query)